fix(payment): Return and set the correct status when a session is created with stripe (#12769)

This commit is contained in:
Stevche Radevski authored and GitHub committed 2025-06-21 20:36:58 +02:00
1 parent a263d8818d
commit b116f75fbf
3 files changed
+54 -36

No files matched your search

+15 -7
View File
@@ -190,7 +190,8 @@ export interface UpdateAccountHolderInput extends PaymentProviderInput {
/** /**
* The data to delete an account holder. * The data to delete an account holder.
*/ */
export interface DeleteAccountHolderInput extends Omit<PaymentProviderInput, "context"> { export interface DeleteAccountHolderInput
extends Omit<PaymentProviderInput, "context"> {
/** /**
* The context of deleting the account holder. * 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. * The ID of the payment session in the payment provider.
*/ */
id: string 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. * The result of listing payment methods for an account holder in the third-party payment provider.
*/ */
export interface ListPaymentMethodsOutput extends Array<PaymentProviderOutput & { export interface ListPaymentMethodsOutput
/** extends Array<
* The ID of the payment method in the payment provider. PaymentProviderOutput & {
*/ /**
id: string * The ID of the payment method in the payment provider.
}> {} */
id: string
}
> {}
/** /**
* The result of saving a payment method. * The result of saving a payment method.
@@ -363,6 +363,7 @@ export default class PaymentModuleService
{ {
id: paymentSession!.id, id: paymentSession!.id,
data: { ...input.data, ...providerPaymentSession.data }, data: { ...input.data, ...providerPaymentSession.data },
status: providerPaymentSession.status ?? PaymentSessionStatus.PENDING,
}, },
sharedContext sharedContext
) )
@@ -215,10 +215,10 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
} }
} }
async getPaymentStatus({ async getPaymentStatus(
data, input: GetPaymentStatusInput
}: GetPaymentStatusInput): Promise<GetPaymentStatusOutput> { ): Promise<GetPaymentStatusOutput> {
const id = data?.id as string const id = input?.data?.id as string
if (!id) { if (!id) {
throw this.buildError( throw this.buildError(
"No payment intent ID provided while getting payment status", "No payment intent ID provided while getting payment status",
@@ -227,30 +227,11 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
} }
const paymentIntent = await this.stripe_.paymentIntents.retrieve(id) const paymentIntent = await this.stripe_.paymentIntents.retrieve(id)
const dataResponse = paymentIntent as unknown as Record<string, unknown> const statusResponse = this.getStatus(paymentIntent)
switch (paymentIntent.status) { return {
case "requires_payment_method": status: statusResponse.status,
if (paymentIntent.last_payment_error) { data: statusResponse.data as unknown as Record<string, unknown>,
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 }
} }
} }
@@ -281,6 +262,7 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
const isPaymentIntent = "id" in sessionData const isPaymentIntent = "id" in sessionData
return { return {
id: isPaymentIntent ? sessionData.id : (data?.session_id as string), id: isPaymentIntent ? sessionData.id : (data?.session_id as string),
status: isPaymentIntent ? this.getStatus(sessionData).status : undefined,
data: sessionData as unknown as Record<string, unknown>, data: sessionData as unknown as Record<string, unknown>,
} }
} }
@@ -288,8 +270,7 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
async authorizePayment( async authorizePayment(
input: AuthorizePaymentInput input: AuthorizePaymentInput
): Promise<AuthorizePaymentOutput> { ): Promise<AuthorizePaymentOutput> {
const statusResponse = await this.getPaymentStatus(input) return this.getPaymentStatus(input)
return statusResponse
} }
async cancelPayment({ async cancelPayment({
@@ -605,6 +586,34 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
return { id: resp.id, data: resp as unknown as Record<string, unknown> } return { id: resp.id, data: resp as unknown as Record<string, unknown> }
} }
private getStatus(
paymentIntent: Stripe.PaymentIntent
): Omit<GetPaymentStatusOutput, "data"> & { 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( async getWebhookActionAndData(
webhookData: ProviderWebhookPayload["payload"] webhookData: ProviderWebhookPayload["payload"]
): Promise<WebhookActionResult> { ): Promise<WebhookActionResult> {