From c0807f54966256fd40f5980bc5dea8aa7122314b Mon Sep 17 00:00:00 2001 From: Stevche Radevski Date: Tue, 24 Jun 2025 13:15:10 +0200 Subject: [PATCH] fix: Allow setting the status of a payment session when updating (#12809) --- .../steps/create-payment-session.ts | 6 +++++ packages/core/types/src/payment/common.ts | 5 ++++ packages/core/types/src/payment/mutations.ts | 17 ++++++++++++- packages/core/types/src/payment/provider.ts | 7 +++++- .../payment/src/services/payment-module.ts | 6 ++++- .../payment-stripe/src/core/stripe-base.ts | 25 +++++++++++-------- 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/packages/core/core-flows/src/payment-collection/steps/create-payment-session.ts b/packages/core/core-flows/src/payment-collection/steps/create-payment-session.ts index 5e7efe58ee..b4a3241b54 100644 --- a/packages/core/core-flows/src/payment-collection/steps/create-payment-session.ts +++ b/packages/core/core-flows/src/payment-collection/steps/create-payment-session.ts @@ -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 + + /** + * Holds custom data in key-value pairs. + */ + metadata?: Record } 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 ?? {}, } ) diff --git a/packages/core/types/src/payment/common.ts b/packages/core/types/src/payment/common.ts index e75f85ebb3..eed7b15fa2 100644 --- a/packages/core/types/src/payment/common.ts +++ b/packages/core/types/src/payment/common.ts @@ -581,6 +581,11 @@ export interface PaymentSessionDTO { * @expandable */ payment?: PaymentDTO + + /** + * Holds custom data in key-value pairs. + */ + metadata?: Record } /** diff --git a/packages/core/types/src/payment/mutations.ts b/packages/core/types/src/payment/mutations.ts index 4749991ac0..7a0369dcc6 100644 --- a/packages/core/types/src/payment/mutations.ts +++ b/packages/core/types/src/payment/mutations.ts @@ -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 } /** @@ -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 } /** diff --git a/packages/core/types/src/payment/provider.ts b/packages/core/types/src/payment/provider.ts index 270616fc62..86b5b5501d 100644 --- a/packages/core/types/src/payment/provider.ts +++ b/packages/core/types/src/payment/provider.ts @@ -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. diff --git a/packages/modules/payment/src/services/payment-module.ts b/packages/modules/payment/src/services/payment-module.ts index f8f01c03e6..adb6558a17 100644 --- a/packages/modules/payment/src/services/payment-module.ts +++ b/packages/modules/payment/src/services/payment-module.ts @@ -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 { 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 ) 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 7a519a4851..9c041d0cf6 100644 --- a/packages/modules/providers/payment-stripe/src/core/stripe-base.ts +++ b/packages/modules/providers/payment-stripe/src/core/stripe-base.ts @@ -229,10 +229,7 @@ abstract class StripeBase extends AbstractPaymentProvider { const paymentIntent = await this.stripe_.paymentIntents.retrieve(id) const statusResponse = this.getStatus(paymentIntent) - return { - status: statusResponse.status, - data: statusResponse.data as unknown as Record, - } + return statusResponse as unknown as GetPaymentStatusOutput } async initiatePayment({ @@ -262,8 +259,9 @@ 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, + ...(this.getStatus( + sessionData as unknown as Stripe.PaymentIntent + ) as unknown as Pick), } } @@ -377,7 +375,9 @@ abstract class StripeBase extends AbstractPaymentProvider { }: UpdatePaymentInput): Promise { 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 { } )) as unknown as Record - 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 { return { id: resp.id, data: resp as unknown as Record } } - private getStatus( - paymentIntent: Stripe.PaymentIntent - ): Omit & { 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) {