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

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

View File

@@ -190,7 +190,8 @@ export interface UpdateAccountHolderInput extends PaymentProviderInput {
/**
* 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.
*/
@@ -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<PaymentProviderOutput & {
/**
* The ID of the payment method in the payment provider.
*/
id: string
}> {}
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.

View File

@@ -363,6 +363,7 @@ export default class PaymentModuleService
{
id: paymentSession!.id,
data: { ...input.data, ...providerPaymentSession.data },
status: providerPaymentSession.status ?? PaymentSessionStatus.PENDING,
},
sharedContext
)

View File

@@ -215,10 +215,10 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
}
}
async getPaymentStatus({
data,
}: GetPaymentStatusInput): Promise<GetPaymentStatusOutput> {
const id = data?.id as string
async getPaymentStatus(
input: GetPaymentStatusInput
): Promise<GetPaymentStatusOutput> {
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<StripeOptions> {
}
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) {
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<string, unknown>,
}
}
@@ -281,6 +262,7 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
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<string, unknown>,
}
}
@@ -288,8 +270,7 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
async authorizePayment(
input: AuthorizePaymentInput
): Promise<AuthorizePaymentOutput> {
const statusResponse = await this.getPaymentStatus(input)
return statusResponse
return this.getPaymentStatus(input)
}
async cancelPayment({
@@ -605,6 +586,34 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
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(
webhookData: ProviderWebhookPayload["payload"]
): Promise<WebhookActionResult> {