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
@@ -38,6 +38,11 @@ export interface CreatePaymentSessionStepInput {
* Learn more in [this documentation](https://docs.medusajs.com/resources/commerce-modules/payment/payment-session#data-property). * Learn more in [this documentation](https://docs.medusajs.com/resources/commerce-modules/payment/payment-session#data-property).
*/ */
data?: Record<string, unknown> data?: Record<string, unknown>
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
} }
export const createPaymentSessionStepId = "create-payment-session" export const createPaymentSessionStepId = "create-payment-session"
@@ -57,6 +62,7 @@ export const createPaymentSessionStep = createStep(
amount: input.amount, amount: input.amount,
data: input.data ?? {}, data: input.data ?? {},
context: input.context, context: input.context,
metadata: input.metadata ?? {},
} }
) )
@@ -581,6 +581,11 @@ export interface PaymentSessionDTO {
* @expandable * @expandable
*/ */
payment?: PaymentDTO payment?: PaymentDTO
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
} }
/** /**
+16 -1
View File
@@ -1,5 +1,5 @@
import { BigNumberInput } from "../totals" import { BigNumberInput } from "../totals"
import { PaymentCollectionStatus } from "./common" import { PaymentCollectionStatus, PaymentSessionStatus } from "./common"
import { import {
PaymentAccountHolderDTO, PaymentAccountHolderDTO,
PaymentCustomerDTO, PaymentCustomerDTO,
@@ -212,6 +212,11 @@ export interface CreatePaymentSessionDTO {
* Necessary context data for the associated payment provider. * Necessary context data for the associated payment provider.
*/ */
context?: PaymentProviderContext context?: PaymentProviderContext
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
} }
/** /**
@@ -238,10 +243,20 @@ export interface UpdatePaymentSessionDTO {
*/ */
amount: BigNumberInput amount: BigNumberInput
/**
* The status of the payment session.
*/
status?: PaymentSessionStatus
/** /**
* Necessary context data for the associated payment provider. * Necessary context data for the associated payment provider.
*/ */
context?: PaymentProviderContext context?: PaymentProviderContext
/**
* Holds custom data in key-value pairs.
*/
metadata?: Record<string, unknown>
} }
/** /**
+6 -1
View File
@@ -257,7 +257,12 @@ export interface AuthorizePaymentOutput extends PaymentProviderOutput {
/** /**
* The result of updating a payment. * 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. * The result of deleting a payment.
@@ -401,6 +401,7 @@ export default class PaymentModuleService
currency_code: data.currency_code, currency_code: data.currency_code,
context: data.context, context: data.context,
data: data.data, data: data.data,
metadata: data.metadata,
}, },
sharedContext sharedContext
) )
@@ -415,7 +416,7 @@ export default class PaymentModuleService
): Promise<PaymentSessionDTO> { ): Promise<PaymentSessionDTO> {
const session = await this.paymentSessionService_.retrieve( const session = await this.paymentSessionService_.retrieve(
data.id, data.id,
{ select: ["id", "data", "provider_id"] }, { select: ["id", "status", "data", "provider_id"] },
sharedContext sharedContext
) )
@@ -435,6 +436,9 @@ export default class PaymentModuleService
amount: data.amount, amount: data.amount,
currency_code: data.currency_code, currency_code: data.currency_code,
data: providerData.data, 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 sharedContext
) )
@@ -229,10 +229,7 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
const paymentIntent = await this.stripe_.paymentIntents.retrieve(id) const paymentIntent = await this.stripe_.paymentIntents.retrieve(id)
const statusResponse = this.getStatus(paymentIntent) const statusResponse = this.getStatus(paymentIntent)
return { return statusResponse as unknown as GetPaymentStatusOutput
status: statusResponse.status,
data: statusResponse.data as unknown as Record<string, unknown>,
}
} }
async initiatePayment({ async initiatePayment({
@@ -262,8 +259,9 @@ 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, ...(this.getStatus(
data: sessionData as unknown as Record<string, unknown>, 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> { }: UpdatePaymentInput): Promise<UpdatePaymentOutput> {
const amountNumeric = getSmallestUnit(amount, currency_code) const amountNumeric = getSmallestUnit(amount, currency_code)
if (isPresent(amount) && data?.amount === amountNumeric) { if (isPresent(amount) && data?.amount === amountNumeric) {
return { data } return this.getStatus(
data as unknown as Stripe.PaymentIntent
) as unknown as UpdatePaymentOutput
} }
try { try {
@@ -392,7 +392,9 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
} }
)) as unknown as Record<string, unknown> )) as unknown as Record<string, unknown>
return { data: sessionData } return this.getStatus(
sessionData as unknown as Stripe.PaymentIntent
) as unknown as UpdatePaymentOutput
} catch (e) { } catch (e) {
throw this.buildError("An error occurred in updatePayment", 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> } return { id: resp.id, data: resp as unknown as Record<string, unknown> }
} }
private getStatus( private getStatus(paymentIntent: Stripe.PaymentIntent): {
paymentIntent: Stripe.PaymentIntent data: Stripe.PaymentIntent
): Omit<GetPaymentStatusOutput, "data"> & { data: Stripe.PaymentIntent } { status: PaymentSessionStatus
} {
switch (paymentIntent.status) { switch (paymentIntent.status) {
case "requires_payment_method": case "requires_payment_method":
if (paymentIntent.last_payment_error) { if (paymentIntent.last_payment_error) {