Skip to content

Commit

Permalink
feat(payments-plugin): Allow additional options on Stripe payment int…
Browse files Browse the repository at this point in the history
…ent creation (#3194)
  • Loading branch information
shingoaoyama1 authored Nov 15, 2024
1 parent dffd123 commit 3f66216
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
40 changes: 40 additions & 0 deletions packages/payments-plugin/e2e/stripe-payment.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,46 @@ describe('Stripe payments', () => {
StripePlugin.options.paymentIntentCreateParams = undefined;
});

// https://github.com/vendure-ecommerce/vendure/issues/3183
it('should attach additional options to payment intent using requestOptions', async () => {
StripePlugin.options.requestOptions = async (injector, ctx, currentOrder) => {
return {
stripeAccount: 'acct_connected',
};
};
let connectedAccountHeader: any;
let createPaymentIntentPayload: any;
const { activeOrder } = await shopClient.query<GetActiveOrderQuery>(GET_ACTIVE_ORDER);
nock('https://api.stripe.com/', {
reqheaders: {
'Stripe-Account': headerValue => {
connectedAccountHeader = headerValue;
return true;
},
},
})
.post('/v1/payment_intents', body => {
createPaymentIntentPayload = body;
return true;
})
.reply(200, {
client_secret: 'test-client-secret',
});
const { createStripePaymentIntent } = await shopClient.query(CREATE_STRIPE_PAYMENT_INTENT);
expect(createPaymentIntentPayload).toEqual({
amount: activeOrder?.totalWithTax.toString(),
currency: activeOrder?.currencyCode?.toLowerCase(),
customer: 'new-customer-id',
'automatic_payment_methods[enabled]': 'true',
'metadata[channelToken]': E2E_DEFAULT_CHANNEL_TOKEN,
'metadata[orderId]': '1',
'metadata[orderCode]': activeOrder?.code,
});
expect(connectedAccountHeader).toEqual('acct_connected');
expect(createStripePaymentIntent).toEqual('test-client-secret');
StripePlugin.options.paymentIntentCreateParams = undefined;
});

// https://github.com/vendure-ecommerce/vendure/issues/2412
it('should attach additional params to customer using customerCreateParams', async () => {
StripePlugin.options.customerCreateParams = async (injector, ctx, currentOrder) => {
Expand Down
10 changes: 9 additions & 1 deletion packages/payments-plugin/src/stripe/stripe.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export class StripeService {
ctx,
order,
);
const additionalOptions = await this.options.requestOptions?.(
new Injector(this.moduleRef),
ctx,
order,
);
const metadata = sanitizeMetadata({
...(typeof this.options.metadata === 'function'
? await this.options.metadata(new Injector(this.moduleRef), ctx, order)
Expand All @@ -69,7 +74,10 @@ export class StripeService {
...(additionalParams ?? {}),
metadata: allMetadata,
},
{ idempotencyKey: `${order.code}_${amountInMinorUnits}` },
{
idempotencyKey: `${order.code}_${amountInMinorUnits}`,
...(additionalOptions ?? {}),
},
);

if (!client_secret) {
Expand Down
37 changes: 37 additions & 0 deletions packages/payments-plugin/src/stripe/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type AdditionalPaymentIntentCreateParams = Partial<
Omit<Stripe.PaymentIntentCreateParams, 'amount' | 'currency' | 'customer'>
>;

type AdditionalRequestOptions = Partial<Omit<Stripe.RequestOptions, 'idempotencyKey'>>;

type AdditionalCustomerCreateParams = Partial<Omit<Stripe.CustomerCreateParams, 'email'>>;

/**
Expand Down Expand Up @@ -107,6 +109,41 @@ export interface StripePluginOptions {
order: Order,
) => AdditionalPaymentIntentCreateParams | Promise<AdditionalPaymentIntentCreateParams>;

/**
* @description
* Provide additional options to the Stripe payment intent creation. By default,
* the plugin will already pass the `idempotencyKey` parameter.
*
* For example, if you want to provide a `stripeAccount` for the payment intent, you can do so like this:
*
* @example
* ```ts
* import { VendureConfig } from '\@vendure/core';
* import { StripePlugin } from '\@vendure/payments-plugin/package/stripe';
*
* export const config: VendureConfig = {
* // ...
* plugins: [
* StripePlugin.init({
* requestOptions: (injector, ctx, order) => {
* return {
* stripeAccount: ctx.channel.seller?.customFields.connectedAccountId
* },
* }
* }),
* ],
* };
* ```
*
* @since 3.1.0
*
*/
requestOptions?: (
injector: Injector,
ctx: RequestContext,
order: Order,
) => AdditionalRequestOptions | Promise<AdditionalRequestOptions>;

/**
* @description
* Provide additional parameters to the Stripe customer creation. By default,
Expand Down

0 comments on commit 3f66216

Please sign in to comment.