Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
✨ Add Stripe sources endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
AnandChowdhary committed Nov 2, 2020
1 parent a7aa4e1 commit f39edda
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/config/configuration.interface.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Stripe from 'stripe';

export interface Configuration {
frontendUrl: string;

Expand Down Expand Up @@ -41,5 +43,8 @@ export interface Configuration {
payments: {
stripeApiKey: string;
stripeProductId: string;
paymentMethodTypes: Array<
Stripe.Checkout.SessionCreateParams.PaymentMethodType
>;
};
}
1 change: 1 addition & 0 deletions src/config/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const configuration: Configuration = {
payments: {
stripeApiKey: process.env.STRIPE_API_KEY ?? '',
stripeProductId: process.env.STRIPE_PRODUCT_ID ?? '',
paymentMethodTypes: ['card'],
},
};

Expand Down
55 changes: 55 additions & 0 deletions src/modules/stripe/stripe-sources.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
Controller,
Delete,
Get,
Param,
ParseIntPipe,
Post,
Query,
} from '@nestjs/common';
import Stripe from 'stripe';
import { CursorPipe } from '../../pipes/cursor.pipe';
import { OptionalIntPipe } from '../../pipes/optional-int.pipe';
import { Scopes } from '../auth/scope.decorator';
import { StripeService } from './stripe.service';

@Controller('groups/:groupId/sources')
export class StripeBillingController {
constructor(private stripeService: StripeService) {}

@Post()
@Scopes('group-{groupId}:write-source')
async create(
@Param('groupId', ParseIntPipe) groupId: number,
): Promise<Stripe.Checkout.Session> {
return this.stripeService.createSession(groupId, 'setup');
}

@Get()
@Scopes('group-{groupId}:read-source')
async getAll(
@Param('groupId', ParseIntPipe) groupId: number,
@Query('take', OptionalIntPipe) take?: number,
@Query('cursor', CursorPipe) cursor?: { id: string },
): Promise<Stripe.CustomerSource[]> {
return this.stripeService.getSources(groupId, { take, cursor });
}

@Get(':id')
@Scopes('group-{groupId}:read-source-{id}')
async get(
@Param('groupId', ParseIntPipe) groupId: number,
@Param('id') id: string,
): Promise<Stripe.Source> {
return this.stripeService.getSource(groupId, id);
}

@Delete(':id')
@Scopes('group-{groupId}:delete-source-{id}')
async remove(
@Param('groupId', ParseIntPipe) groupId: number,
@Param('id') id: string,
): Promise<void> {
return this.stripeService.deleteSource(groupId, id);
}
}
48 changes: 48 additions & 0 deletions src/modules/stripe/stripe.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,54 @@ export class StripeService {
return result;
}

async getSources(
groupId: number,
params: {
take?: number;
cursor?: { id: string };
},
): Promise<Stripe.CustomerSource[]> {
const stripeId = await this.stripeId(groupId);
const result = await this.stripe.customers.listSources(stripeId, {
limit: params.take,
starting_after: params.cursor?.id,
});
return this.list<Stripe.CustomerSource>(result);
}

async getSource(groupId: number, sourceId: string): Promise<Stripe.Source> {
const stripeId = await this.stripeId(groupId);
const result = await this.stripe.sources.retrieve(sourceId);
if (result.customer !== stripeId)
throw new NotFoundException('Source not found');
return result;
}

async deleteSource(groupId: number, sourceId: string): Promise<void> {
const stripeId = await this.stripeId(groupId);
const result = await this.stripe.sources.retrieve(sourceId);
if (result.customer !== stripeId)
throw new NotFoundException('Source not found');
await this.stripe.customers.deleteSource(stripeId, sourceId);
}

async createSession(
groupId: number,
mode: Stripe.Checkout.SessionCreateParams.Mode,
): Promise<Stripe.Checkout.Session> {
const stripeId = await this.stripeId(groupId);
const result = await this.stripe.checkout.sessions.create({
customer: stripeId,
mode,
payment_method_types: this.configService.get<
Array<Stripe.Checkout.SessionCreateParams.PaymentMethodType>
>('payments.paymentMethodTypes') ?? ['card'],
success_url: '',
cancel_url: '',
});
return result;
}

private list<T>(result: Stripe.Response<Stripe.ApiList<T>>) {
return result.data;
}
Expand Down

0 comments on commit f39edda

Please sign in to comment.