feat: Create payment sessions (#6549)

~~Opening a draft PR to discuss a couple of implementation details that we should align on~~

**What**

Add workflow and API endpoint for creating payment sessions for a payment collection. Endpoint is currently `POST /store/payment-collection/:id/payment-sessions`. I suggested an alternative in a comment below.

Please note, we intentionally do not want to support creating payment sessions in bulk, as this would become a mess when having to manage multiple calls to third-party providers.
This commit is contained in:
Oli Juhl authored and GitHub committed 2024-03-05 08:40:47 +00:00
1 parent 908b1dc3a2
commit 84208aafc1
30 files changed
+603 -182

No files matched your search

+13
View File
@@ -169,6 +169,19 @@ export interface FilterablePaymentCollectionProps
updated_at?: OperatorMap<string>
}
export interface FilterablePaymentSessionProps
extends BaseFilterable<PaymentSessionDTO> {
id?: string | string[]
currency_code?: string | string[]
amount?: number | OperatorMap<number>
provider_id?: string | string[]
payment_collection_id?: string | string[]
region_id?: string | string[] | OperatorMap<string>
created_at?: OperatorMap<string>
updated_at?: OperatorMap<string>
deleted_at?: OperatorMap<string>
}
/* ********** PAYMENT ********** */
export interface PaymentDTO {
/**
+27 -3
View File
@@ -186,9 +186,21 @@ export interface CreatePaymentSessionDTO {
*/
provider_id: string
/**
* The provider's context.
* The selected currency code.
*/
providerContext: Omit<PaymentProviderContext, "resource_id">
currency_code: string
/**
* The payment's amount.
*/
amount: number
/**
* The value of the payment session's `data` field.
*/
data: Record<string, unknown>
/**
* The payment session's context.
*/
context?: PaymentProviderContext
}
/**
@@ -199,10 +211,22 @@ export interface UpdatePaymentSessionDTO {
* The payment session's ID.
*/
id: string
/**
* The value of the payment session's `data` field.
*/
data: Record<string, unknown>
/**
* The selected currency code.
*/
currency_code: string
/**
* The payment's amount.
*/
amount: number
/**
* The payment session's context.
*/
providerContext: PaymentProviderContext
context?: PaymentProviderContext
}
/**
+22 -22
View File
@@ -1,6 +1,6 @@
import { PaymentSessionStatus } from "./common"
import { CustomerDTO } from "../customer"
import { AddressDTO } from "../address"
import { CustomerDTO } from "../customer"
import { PaymentSessionStatus } from "./common"
import { ProviderWebhookPayload } from "./mutations"
export type PaymentAddressDTO = Partial<AddressDTO>
@@ -43,31 +43,31 @@ export type PaymentProviderContext = {
* The customer's email.
*/
email?: string
/**
* The selected currency code.
*/
currency_code: string
/**
* The payment's amount.
*/
amount: number
/**
* The ID of the resource the payment is associated with i.e. the ID of the PaymentSession in Medusa
*/
resource_id: string
resource_id?: string
/**
* The customer associated with this payment.
*/
customer?: PaymentCustomerDTO
/**
* The context.
* The extra fields specific to the provider session.
*/
context: { payment_description?: string } & Record<string, unknown>
/**
* If the payment session hasn't been created or initiated yet, it'll be an empty object.
* If the payment session exists, it'll be the value of the payment session's `data` field.
*/
payment_session_data: Record<string, unknown>
extra?: Record<string, unknown>
}
export type CreatePaymentProviderSession = {
context: PaymentProviderContext
amount: number
currency_code: string
}
export type UpdatePaymentProviderSession = {
context: PaymentProviderContext
data: Record<string, unknown>
amount: number
currency_code: string
}
/**
@@ -142,21 +142,21 @@ export interface IPaymentProvider {
/**
* Make calls to the third-party provider to initialize the payment. For example, in Stripe this method is used to create a Payment Intent for the customer.
*
* @param {PaymentProviderContext} context - The context of the payment.
* @param {CreatePaymentProviderSession} context
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse>} Either the payment's data or an error object.
*/
initiatePayment(
context: PaymentProviderContext
data: CreatePaymentProviderSession
): Promise<PaymentProviderError | PaymentProviderSessionResponse>
/**
* This method is used to update the payment session.
*
* @param {PaymentProviderContext} context - The context of the payment.
* @param {UpdatePaymentProviderSession} context
* @returns {Promise<PaymentProviderError | PaymentProviderSessionResponse | void>} Either the payment's data or an error object.
*/
updatePayment(
context: PaymentProviderContext
context: UpdatePaymentProviderSession
): Promise<PaymentProviderError | PaymentProviderSessionResponse>
/**
+7
View File
@@ -4,6 +4,7 @@ import { Context } from "../shared-context"
import {
FilterablePaymentCollectionProps,
FilterablePaymentProps,
FilterablePaymentSessionProps,
PaymentCollectionDTO,
PaymentDTO,
PaymentSessionDTO,
@@ -387,6 +388,12 @@ export interface IPaymentModuleService extends IModuleService {
*/
cancelPayment(paymentId: string, sharedContext?: Context): Promise<PaymentDTO>
listPaymentSessions(
filters?: FilterablePaymentSessionProps,
config?: FindConfig<PaymentSessionDTO>,
sharedContext?: Context
): Promise<PaymentSessionDTO[]>
/**
* This method creates providers on load.
*