Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
bb188be
Stubs for payments.service.spec.ts and unit tests, including prelimin…
SamNie2027 Oct 10, 2025
b581c7e
Stubs for Payments.module.ts and better mock for payments.service.ts
SamNie2027 Oct 10, 2025
51d6f41
Stricter paymentIntent param validation, Strict payment method types
SamNie2027 Oct 13, 2025
c98d11c
Initial Impl for retrievePaymentIntent
SamNie2027 Oct 13, 2025
ac4aed7
Changing tests to fit the shape of returns, slowly writing tests to m…
SamNie2027 Oct 13, 2025
90aad90
Merge branch 'main' into 16-Payment-Integration-Setup-Stripe
SamNie2027 Oct 15, 2025
a554a1e
Initial implementation for createSubscription
SamNie2027 Oct 16, 2025
394c453
Initial Impl for createSubscription, Fixing Stripe API mock for tests
SamNie2027 Oct 16, 2025
00b58e8
testing validateCreatePaymentIntentParams thoroughly with edge cases
SamNie2027 Oct 16, 2025
4bffefc
More params checking for createSubscription, and also checking that i…
SamNie2027 Oct 16, 2025
c65d261
Changing retrieve payment intent to be closer to ticket
SamNie2027 Oct 18, 2025
494d694
Expanding return object for paymentIntentResponse (without changing t…
SamNie2027 Oct 20, 2025
a2f95b7
Changed tests to reflect expanded paymentIntent return
SamNie2027 Oct 20, 2025
d3c6133
Initial Stripe.MD overview
SamNie2027 Oct 20, 2025
5f30782
Small documentation change as sandbox != test mode
SamNie2027 Oct 20, 2025
5c723f8
Merge branch 'main' into 16-Payment-Integration-Setup-Stripe
SamNie2027 Oct 20, 2025
f86c4f9
Added documentation and comment cleanup
SamNie2027 Oct 20, 2025
11bdcf6
fix: typo and register payments module
thaninbew Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { AuthModule } from './auth/auth.module';
import { PaymentsModule } from './payments/payments.module';
import AppDataSource from './data-source';

@Module({
imports: [
TypeOrmModule.forRoot(AppDataSource.options),
UsersModule,
AuthModule,
PaymentsModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
77 changes: 77 additions & 0 deletions apps/backend/src/payments/STRIPE.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Stripe Integration Documentation

This document outlines our Stripe integration for handling payments and subscriptions in the application.

Configuration

The application uses Stripe for payment processing. The integration requires the following environment variables:

STRIPE_SECRET_KEY: Used for server-side API calls to Stripe
STRIPE_PUBLISHABLE_KEY: Used for client-side Stripe Elements integration

To acquire these keys

1. Login to Stripe using the FCC gmail and password posted in Slack: https://dashboard.stripe.com/
2. Confirm that the top says "You're testing in a sandbox—your place to experiment with Stripe functionality." or there's some sort of indication that you're in the sandbox environment
3. On the bottom left click the "Developers" dropdown heading
4. Click the "API keys" dropdown option
5. Under the "Standard keys" section and under the "Token" heading in the table, copy each key

Implementation Overview

The Stripe integration is implemented in the PaymentsModule and PaymentsService classes.

The PaymentsModule configures the Stripe client as a provider

The PaymentsService class implements methods that call Stripe API and return data with the expectation that it will be passed to the front end

The PaymentsService provides the following methods:

async createPaymentIntent(
amount: number - Payment amount in the smallest currency unit (e.g., cents for USD)
currency: string - Three-letter ISO currency code (e.g., "usd")
metadata?: PaymentIntentMetadata - Optional key-value pairs to attach to the payment intent
): Promise<PaymentIntentResponse>

async retrievePaymentIntent(
paymentIntentId: string - Stripe payment intent ID to retrieve
): Promise<PaymentIntentResponse>


Where PaymentIntentResponse is:
id: string;
clientSecret: string;
amount: number;
currency: string;
status: DonationStatus;
metadata?: Record<string, unknown>;
paymentMethodId?: string;
paymentMethodTypes: string[];
created: number;
requiresAction: boolean;
nextAction?: unknown;
lastPaymentError?: {
code: string;
message: string;
type: string;
};
canceledAt?: number;

async createSubscription(
customerId: string - Stripe customer ID (must start with "cus_")
priceId: string - Stripe price ID (must start with "price_")
): Promise<{
id: string;
customerId: string;
priceId: string;
interval: RecurringInterval;
status: string;
}>

Testing

The Stripe integration can be tested using:

- Stripe's test mode or sandbox with test API keys
- Stripe's test cards found from: https://docs.stripe.com/testing
- The provided unit tests with mocked Stripe responses
22 changes: 22 additions & 0 deletions apps/backend/src/payments/payments.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import Stripe from 'stripe';
import { PaymentsService } from './payments.service';

@Module({
imports: [ConfigModule],
providers: [
{
provide: 'STRIPE_CLIENT',
useFactory: (configService: ConfigService) => {
return new Stripe(configService.get<string>('STRIPE_SECRET_KEY'), {
apiVersion: '2025-09-30.clover',
});
},
inject: [ConfigService],
},
PaymentsService
],
exports: [PaymentsService],
})
export class PaymentsModule {}
Loading
Loading