fix: Allow setting the status of a payment session when updating (#12809)

This commit is contained in:
Stevche Radevski
2025-06-24 13:15:10 +02:00
committed by GitHub
parent 474e97c9be
commit c0807f5496
6 changed files with 52 additions and 14 deletions

View File

@@ -38,6 +38,11 @@ export interface CreatePaymentSessionStepInput {
* Learn more in [this documentation](https://docs.medusajs.com/resources/commerce-modules/payment/payment-session#data-property).
*/
data?: Record<string, unknown>
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
}
export const createPaymentSessionStepId = "create-payment-session"
@@ -57,6 +62,7 @@ export const createPaymentSessionStep = createStep(
amount: input.amount,
data: input.data ?? {},
context: input.context,
metadata: input.metadata ?? {},
}
)

View File

@@ -581,6 +581,11 @@ export interface PaymentSessionDTO {
* @expandable
*/
payment?: PaymentDTO
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
}
/**

View File

@@ -1,5 +1,5 @@
import { BigNumberInput } from "../totals"
import { PaymentCollectionStatus } from "./common"
import { PaymentCollectionStatus, PaymentSessionStatus } from "./common"
import {
PaymentAccountHolderDTO,
PaymentCustomerDTO,
@@ -212,6 +212,11 @@ export interface CreatePaymentSessionDTO {
* Necessary context data for the associated payment provider.
*/
context?: PaymentProviderContext
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
}
/**
@@ -238,10 +243,20 @@ export interface UpdatePaymentSessionDTO {
*/
amount: BigNumberInput
/**
* The status of the payment session.
*/
status?: PaymentSessionStatus
/**
* Necessary context data for the associated payment provider.
*/
context?: PaymentProviderContext
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
}
/**

View File

@@ -257,7 +257,12 @@ export interface AuthorizePaymentOutput extends PaymentProviderOutput {
/**
* The result of updating a payment.
*/
export interface UpdatePaymentOutput extends PaymentProviderOutput {}
export interface UpdatePaymentOutput extends PaymentProviderOutput {
/**
* The status of the payment, which will be stored in the payment session's `status` field.
*/
status?: PaymentSessionStatus
}
/**
* The result of deleting a payment.

View File

@@ -401,6 +401,7 @@ export default class PaymentModuleService
currency_code: data.currency_code,
context: data.context,
data: data.data,
metadata: data.metadata,
},
sharedContext
)
@@ -415,7 +416,7 @@ export default class PaymentModuleService
): Promise<PaymentSessionDTO> {
const session = await this.paymentSessionService_.retrieve(
data.id,
{ select: ["id", "data", "provider_id"] },
{ select: ["id", "status", "data", "provider_id"] },
sharedContext
)
@@ -435,6 +436,9 @@ export default class PaymentModuleService
amount: data.amount,
currency_code: data.currency_code,
data: providerData.data,
// Allow the caller to explicitly set the status (eg. due to a webhook), fallback to the update response, and finally to the existing status.
status: data.status ?? providerData.status ?? session.status,
metadata: data.metadata,
},
sharedContext
)

View File

@@ -229,10 +229,7 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
const paymentIntent = await this.stripe_.paymentIntents.retrieve(id)
const statusResponse = this.getStatus(paymentIntent)
return {
status: statusResponse.status,
data: statusResponse.data as unknown as Record<string, unknown>,
}
return statusResponse as unknown as GetPaymentStatusOutput
}
async initiatePayment({
@@ -262,8 +259,9 @@ 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>,
...(this.getStatus(
sessionData as unknown as Stripe.PaymentIntent
) as unknown as Pick<InitiatePaymentOutput, "data" | "status">),
}
}
@@ -377,7 +375,9 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
}: UpdatePaymentInput): Promise<UpdatePaymentOutput> {
const amountNumeric = getSmallestUnit(amount, currency_code)
if (isPresent(amount) && data?.amount === amountNumeric) {
return { data }
return this.getStatus(
data as unknown as Stripe.PaymentIntent
) as unknown as UpdatePaymentOutput
}
try {
@@ -392,7 +392,9 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
}
)) as unknown as Record<string, unknown>
return { data: sessionData }
return this.getStatus(
sessionData as unknown as Stripe.PaymentIntent
) as unknown as UpdatePaymentOutput
} catch (e) {
throw this.buildError("An error occurred in updatePayment", e)
}
@@ -586,9 +588,10 @@ 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 } {
private getStatus(paymentIntent: Stripe.PaymentIntent): {
data: Stripe.PaymentIntent
status: PaymentSessionStatus
} {
switch (paymentIntent.status) {
case "requires_payment_method":
if (paymentIntent.last_payment_error) {