Skip to content

Commit

Permalink
feat(stripe): extend webhook config for test mode secrets (#732)
Browse files Browse the repository at this point in the history
add two configuration entries in the webhook config for accountTest and connectTest webhook secrets
allowing you to register test mode webhooks to the same endpoint.

re #731

Co-authored-by: Dennis von der Bey <fermentfan@users.noreply.github.com>
  • Loading branch information
fermentfan and fermentfan authored May 3, 2024
1 parent d6593e9 commit d7bba4b
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 6 deletions.
6 changes: 5 additions & 1 deletion packages/stripe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ Import and add `StripeModule` to the `imports` section of the consuming module (
Stripe secrets you can get from your Dashboard’s [Webhooks settings](https://dashboard.stripe.com/webhooks). Select an endpoint that you want to obtain the secret for, then click the Click to reveal button.

`account` - The webhook secret registered in the Stripe Dashboard for events on your accounts
`account_test` - The webhook secret registered in the Stripe Dashboard for events on your accounts in test mode
`connect` - The webhook secret registered in the Stripe Dashboard for events on Connected accounts
`connect_test` - The webhook secret registered in the Stripe Dashboard for events on Connected accounts in test mode

```typescript
import { StripeModule } from '@golevelup/nestjs-stripe';
Expand All @@ -54,7 +56,9 @@ import { StripeModule } from '@golevelup/nestjs-stripe';
webhookConfig: {
stripeSecrets: {
account: 'abc',
connect: 'cba',
accountTest: 'cba',
connect: 'foo',
connectTest: 'bar',
},
},
}),
Expand Down
9 changes: 8 additions & 1 deletion packages/stripe/src/stripe.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ interface StripeSecrets {
* The webhook secret registered in the Stripe Dashboard for events on your accounts
*/
account?: string;

/**
* The webhook secret registered in the Stripe Dashboard for events on your accounts in test mode
*/
accountTest?: string;
/**
* The webhook secret registered in the Stripe Dashboard for events on Connected accounts
*/
connect?: string;
/**
* The webhook secret registered in the Stripe Dashboard for events on Connected accounts in test mode
*/
connectTest?: string;
}

export interface StripeModuleConfig extends Partial<Stripe.StripeConfig> {
Expand Down
4 changes: 3 additions & 1 deletion packages/stripe/src/stripe.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ export class StripeModule
const noOneSecretProvided =
this.stripeModuleConfig.webhookConfig &&
!this.stripeModuleConfig.webhookConfig?.stripeSecrets.account &&
!this.stripeModuleConfig.webhookConfig?.stripeSecrets.connect;
!this.stripeModuleConfig.webhookConfig?.stripeSecrets.accountTest &&
!this.stripeModuleConfig.webhookConfig?.stripeSecrets.connect &&
!this.stripeModuleConfig.webhookConfig?.stripeSecrets.connectTest;

if (noOneSecretProvided) {
const errorMessage =
Expand Down
25 changes: 22 additions & 3 deletions packages/stripe/src/stripe.payload.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import { StripeModuleConfig } from './stripe.interfaces';
@Injectable()
export class StripePayloadService {
private readonly stripeWebhookSecret: string;
private readonly stripeWebhookTestSecret: string;
private readonly stripeConnectWebhookSecret: string;
private readonly stripeConnectWebhookTestSecret: string;

constructor(
@InjectStripeModuleConfig()
Expand All @@ -20,20 +22,37 @@ export class StripePayloadService {
) {
this.stripeWebhookSecret =
this.config.webhookConfig?.stripeSecrets.account || '';
this.stripeWebhookTestSecret =
this.config.webhookConfig?.stripeSecrets.accountTest || '';
this.stripeConnectWebhookSecret =
this.config.webhookConfig?.stripeSecrets.connect || '';
this.stripeConnectWebhookTestSecret =
this.config.webhookConfig?.stripeSecrets.connectTest || '';
}
tryHydratePayload(signature: string, payload: Buffer): { type: string } {
const decodedPayload = JSON.parse(
Buffer.isBuffer(payload) ? payload.toString('utf8') : payload
);

let secretToUse: string;
if (!decodedPayload.account && decodedPayload.livemode) {
secretToUse = this.stripeWebhookSecret;
} else if (!decodedPayload.account && !decodedPayload.livemode) {
secretToUse = this.stripeWebhookTestSecret;
} else if (decodedPayload.account && decodedPayload.livemode) {
secretToUse = this.stripeConnectWebhookSecret;
} else if (decodedPayload.account && !decodedPayload.livemode) {
secretToUse = this.stripeConnectWebhookTestSecret;
} else {
throw new Error(
'Could not determine which secret to use for this webhook call!'
);
}

return this.stripeClient.webhooks.constructEvent(
payload,
signature,
decodedPayload.account
? this.stripeConnectWebhookSecret
: this.stripeWebhookSecret
secretToUse
);
}
}

0 comments on commit d7bba4b

Please sign in to comment.