From b116f75fbff645003a2df753b06ce5c21614f89a Mon Sep 17 00:00:00 2001 From: Stevche Radevski Date: Sat, 21 Jun 2025 20:36:58 +0200 Subject: [PATCH] fix(payment): Return and set the correct status when a session is created with stripe (#12769) --- packages/core/types/src/payment/provider.ts | 22 ++++-- .../payment/src/services/payment-module.ts | 1 + .../payment-stripe/src/core/stripe-base.ts | 67 +++++++++++-------- 3 files changed, 54 insertions(+), 36 deletions(-) diff --git a/packages/core/types/src/payment/provider.ts b/packages/core/types/src/payment/provider.ts index 09e9b25928..270616fc62 100644 --- a/packages/core/types/src/payment/provider.ts +++ b/packages/core/types/src/payment/provider.ts @@ -190,7 +190,8 @@ export interface UpdateAccountHolderInput extends PaymentProviderInput { /** * The data to delete an account holder. */ -export interface DeleteAccountHolderInput extends Omit { +export interface DeleteAccountHolderInput + extends Omit { /** * The context of deleting the account holder. */ @@ -237,6 +238,10 @@ export interface InitiatePaymentOutput extends PaymentProviderOutput { * The ID of the payment session in the payment provider. */ id: string + /** + * The status of the payment session, which will be stored in the payment session's `status` field. + */ + status?: PaymentSessionStatus } /** @@ -305,12 +310,15 @@ export interface DeleteAccountHolderOutput extends PaymentProviderOutput {} /** * The result of listing payment methods for an account holder in the third-party payment provider. */ -export interface ListPaymentMethodsOutput extends Array {} +export interface ListPaymentMethodsOutput + extends Array< + PaymentProviderOutput & { + /** + * The ID of the payment method in the payment provider. + */ + id: string + } + > {} /** * The result of saving a payment method. diff --git a/packages/modules/payment/src/services/payment-module.ts b/packages/modules/payment/src/services/payment-module.ts index eeb2dfb4f4..f8f01c03e6 100644 --- a/packages/modules/payment/src/services/payment-module.ts +++ b/packages/modules/payment/src/services/payment-module.ts @@ -363,6 +363,7 @@ export default class PaymentModuleService { id: paymentSession!.id, data: { ...input.data, ...providerPaymentSession.data }, + status: providerPaymentSession.status ?? PaymentSessionStatus.PENDING, }, sharedContext ) diff --git a/packages/modules/providers/payment-stripe/src/core/stripe-base.ts b/packages/modules/providers/payment-stripe/src/core/stripe-base.ts index 9ec14c3298..7a519a4851 100644 --- a/packages/modules/providers/payment-stripe/src/core/stripe-base.ts +++ b/packages/modules/providers/payment-stripe/src/core/stripe-base.ts @@ -215,10 +215,10 @@ abstract class StripeBase extends AbstractPaymentProvider { } } - async getPaymentStatus({ - data, - }: GetPaymentStatusInput): Promise { - const id = data?.id as string + async getPaymentStatus( + input: GetPaymentStatusInput + ): Promise { + const id = input?.data?.id as string if (!id) { throw this.buildError( "No payment intent ID provided while getting payment status", @@ -227,30 +227,11 @@ abstract class StripeBase extends AbstractPaymentProvider { } const paymentIntent = await this.stripe_.paymentIntents.retrieve(id) - const dataResponse = paymentIntent as unknown as Record + const statusResponse = this.getStatus(paymentIntent) - switch (paymentIntent.status) { - case "requires_payment_method": - if (paymentIntent.last_payment_error) { - return { status: PaymentSessionStatus.ERROR, data: dataResponse } - } - return { status: PaymentSessionStatus.PENDING, data: dataResponse } - case "requires_confirmation": - case "processing": - return { status: PaymentSessionStatus.PENDING, data: dataResponse } - case "requires_action": - return { - status: PaymentSessionStatus.REQUIRES_MORE, - data: dataResponse, - } - case "canceled": - return { status: PaymentSessionStatus.CANCELED, data: dataResponse } - case "requires_capture": - return { status: PaymentSessionStatus.AUTHORIZED, data: dataResponse } - case "succeeded": - return { status: PaymentSessionStatus.CAPTURED, data: dataResponse } - default: - return { status: PaymentSessionStatus.PENDING, data: dataResponse } + return { + status: statusResponse.status, + data: statusResponse.data as unknown as Record, } } @@ -281,6 +262,7 @@ abstract class StripeBase extends AbstractPaymentProvider { const isPaymentIntent = "id" in sessionData return { id: isPaymentIntent ? sessionData.id : (data?.session_id as string), + status: isPaymentIntent ? this.getStatus(sessionData).status : undefined, data: sessionData as unknown as Record, } } @@ -288,8 +270,7 @@ abstract class StripeBase extends AbstractPaymentProvider { async authorizePayment( input: AuthorizePaymentInput ): Promise { - const statusResponse = await this.getPaymentStatus(input) - return statusResponse + return this.getPaymentStatus(input) } async cancelPayment({ @@ -605,6 +586,34 @@ abstract class StripeBase extends AbstractPaymentProvider { return { id: resp.id, data: resp as unknown as Record } } + private getStatus( + paymentIntent: Stripe.PaymentIntent + ): Omit & { data: Stripe.PaymentIntent } { + switch (paymentIntent.status) { + case "requires_payment_method": + if (paymentIntent.last_payment_error) { + return { status: PaymentSessionStatus.ERROR, data: paymentIntent } + } + return { status: PaymentSessionStatus.PENDING, data: paymentIntent } + case "requires_confirmation": + case "processing": + return { status: PaymentSessionStatus.PENDING, data: paymentIntent } + case "requires_action": + return { + status: PaymentSessionStatus.REQUIRES_MORE, + data: paymentIntent, + } + case "canceled": + return { status: PaymentSessionStatus.CANCELED, data: paymentIntent } + case "requires_capture": + return { status: PaymentSessionStatus.AUTHORIZED, data: paymentIntent } + case "succeeded": + return { status: PaymentSessionStatus.CAPTURED, data: paymentIntent } + default: + return { status: PaymentSessionStatus.PENDING, data: paymentIntent } + } + } + async getWebhookActionAndData( webhookData: ProviderWebhookPayload["payload"] ): Promise {