feat: Add support for creating payment methods to payment module (#11063)
CLOSES CLO-407
This commit is contained in:
@@ -2543,7 +2543,6 @@ medusaIntegrationTestRunner({
|
|||||||
await paymentModule.createPaymentCollections({
|
await paymentModule.createPaymentCollections({
|
||||||
amount: 5001,
|
amount: 5001,
|
||||||
currency_code: "dkk",
|
currency_code: "dkk",
|
||||||
region_id: defaultRegion.id,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const paymentSession = await paymentModule.createPaymentSession(
|
const paymentSession = await paymentModule.createPaymentSession(
|
||||||
@@ -2615,7 +2614,6 @@ medusaIntegrationTestRunner({
|
|||||||
await paymentModule.createPaymentCollections({
|
await paymentModule.createPaymentCollections({
|
||||||
amount: 5000,
|
amount: 5000,
|
||||||
currency_code: "dkk",
|
currency_code: "dkk",
|
||||||
region_id: defaultRegion.id,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const paymentSession = await paymentModule.createPaymentSession(
|
const paymentSession = await paymentModule.createPaymentSession(
|
||||||
|
|||||||
@@ -1330,7 +1330,6 @@ medusaIntegrationTestRunner({
|
|||||||
).data.shipping_option
|
).data.shipping_option
|
||||||
|
|
||||||
paymentCollection = await paymentService.createPaymentCollections({
|
paymentCollection = await paymentService.createPaymentCollections({
|
||||||
region_id: region.id,
|
|
||||||
amount: 1000,
|
amount: 1000,
|
||||||
currency_code: "usd",
|
currency_code: "usd",
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -585,18 +585,6 @@ export interface PaymentProviderDTO {
|
|||||||
is_enabled: boolean
|
is_enabled: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PaymentMethodDTO {
|
|
||||||
/**
|
|
||||||
* The ID of the payment method in the payment provider's system.
|
|
||||||
*/
|
|
||||||
id: string
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The data of the payment method, as returned by the payment provider.
|
|
||||||
*/
|
|
||||||
data: Record<string, unknown>
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The filters to apply on the retrieved payment providers.
|
* The filters to apply on the retrieved payment providers.
|
||||||
*/
|
*/
|
||||||
@@ -657,3 +645,20 @@ export interface RefundReasonDTO {
|
|||||||
*/
|
*/
|
||||||
updated_at: Date | string
|
updated_at: Date | string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PaymentMethodDTO {
|
||||||
|
/**
|
||||||
|
* The ID of the payment method.
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data of the payment method, as returned by the payment provider.
|
||||||
|
*/
|
||||||
|
data: Record<string, unknown>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ID of the associated payment provider.
|
||||||
|
*/
|
||||||
|
provider_id: string
|
||||||
|
}
|
||||||
|
|||||||
@@ -318,3 +318,23 @@ export interface UpdateRefundReasonDTO {
|
|||||||
*/
|
*/
|
||||||
metadata?: Record<string, unknown> | null
|
metadata?: Record<string, unknown> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The payment method to be created.
|
||||||
|
*/
|
||||||
|
export interface CreatePaymentMethodDTO {
|
||||||
|
/**
|
||||||
|
* The provider's ID.
|
||||||
|
*/
|
||||||
|
provider_id: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Necessary data for the associated payment provider to process the payment.
|
||||||
|
*/
|
||||||
|
data: Record<string, unknown>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Necessary context data for the associated payment provider.
|
||||||
|
*/
|
||||||
|
context: PaymentProviderContext
|
||||||
|
}
|
||||||
|
|||||||
@@ -78,6 +78,18 @@ export type CreatePaymentProviderSession = {
|
|||||||
currency_code: string
|
currency_code: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SavePaymentMethod = {
|
||||||
|
/**
|
||||||
|
* Any data that should be used by the provider for saving the payment method.
|
||||||
|
*/
|
||||||
|
data: Record<string, unknown>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The context of the payment provider, such as the customer ID.
|
||||||
|
*/
|
||||||
|
context: PaymentProviderContext
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
*
|
*
|
||||||
@@ -118,6 +130,18 @@ export type PaymentProviderSessionResponse = {
|
|||||||
data: Record<string, unknown>
|
data: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SavePaymentMethodResponse = {
|
||||||
|
/**
|
||||||
|
* The ID of the payment method in the payment provider.
|
||||||
|
*/
|
||||||
|
id: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data returned from the payment provider after saving the payment method.
|
||||||
|
*/
|
||||||
|
data: Record<string, unknown>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface
|
* @interface
|
||||||
*
|
*
|
||||||
@@ -254,10 +278,14 @@ export interface IPaymentProvider {
|
|||||||
paymentSessionData: Record<string, unknown>
|
paymentSessionData: Record<string, unknown>
|
||||||
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
|
): Promise<PaymentProviderError | PaymentProviderSessionResponse["data"]>
|
||||||
|
|
||||||
listPaymentMethods(
|
listPaymentMethods?(
|
||||||
context: PaymentProviderContext
|
context: PaymentProviderContext
|
||||||
): Promise<PaymentMethodResponse[]>
|
): Promise<PaymentMethodResponse[]>
|
||||||
|
|
||||||
|
savePaymentMethod?(
|
||||||
|
input: SavePaymentMethod
|
||||||
|
): Promise<PaymentProviderError | SavePaymentMethodResponse>
|
||||||
|
|
||||||
getPaymentStatus(
|
getPaymentStatus(
|
||||||
paymentSessionData: Record<string, unknown>
|
paymentSessionData: Record<string, unknown>
|
||||||
): Promise<PaymentSessionStatus>
|
): Promise<PaymentSessionStatus>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
CaptureDTO,
|
CaptureDTO,
|
||||||
FilterableCaptureProps,
|
FilterableCaptureProps,
|
||||||
FilterablePaymentCollectionProps,
|
FilterablePaymentCollectionProps,
|
||||||
|
FilterablePaymentMethodProps,
|
||||||
FilterablePaymentProps,
|
FilterablePaymentProps,
|
||||||
FilterablePaymentProviderProps,
|
FilterablePaymentProviderProps,
|
||||||
FilterablePaymentSessionProps,
|
FilterablePaymentSessionProps,
|
||||||
@@ -13,6 +14,7 @@ import {
|
|||||||
FilterableRefundReasonProps,
|
FilterableRefundReasonProps,
|
||||||
PaymentCollectionDTO,
|
PaymentCollectionDTO,
|
||||||
PaymentDTO,
|
PaymentDTO,
|
||||||
|
PaymentMethodDTO,
|
||||||
PaymentProviderDTO,
|
PaymentProviderDTO,
|
||||||
PaymentSessionDTO,
|
PaymentSessionDTO,
|
||||||
RefundDTO,
|
RefundDTO,
|
||||||
@@ -749,6 +751,74 @@ export interface IPaymentModuleService extends IModuleService {
|
|||||||
sharedContext?: Context
|
sharedContext?: Context
|
||||||
): Promise<[PaymentProviderDTO[], number]>
|
): Promise<[PaymentProviderDTO[], number]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method retrieves all payment methods based on the context and configuration.
|
||||||
|
*
|
||||||
|
* @param {FilterablePaymentMethodProps} filters - The filters to apply on the retrieved payment methods.
|
||||||
|
* @param {FindConfig<PaymentMethodDTO>} config - The configurations determining how the payment method is retrieved. Its properties, such as `select` or `relations`, accept the
|
||||||
|
* attributes or relations associated with a payment method.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<PaymentMethodDTO[]>} The list of payment methods.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* To retrieve a list of payment methods for a customer:
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const paymentMethods =
|
||||||
|
* await paymentModuleService.listPaymentMethods({
|
||||||
|
* provider_id: "pp_stripe_stripe",
|
||||||
|
* context: {
|
||||||
|
* customer: {
|
||||||
|
* id: "cus_123",
|
||||||
|
* metadata: {
|
||||||
|
* pp_stripe_stripe_customer_id: "str_1234"
|
||||||
|
* }
|
||||||
|
* },
|
||||||
|
* },
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
listPaymentMethods(
|
||||||
|
filters: FilterablePaymentMethodProps,
|
||||||
|
config: FindConfig<PaymentMethodDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PaymentMethodDTO[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method retrieves all payment methods along with the total count of available payment methods, based on the context and configuration.
|
||||||
|
*
|
||||||
|
* @param {FilterablePaymentMethodProps} filters - The filters to apply on the retrieved payment methods.
|
||||||
|
* @param {FindConfig<PaymentMethodDTO>} config - The configurations determining how the payment method is retrieved. Its properties, such as `select` or `relations`, accept the
|
||||||
|
* attributes or relations associated with a payment method.
|
||||||
|
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
|
||||||
|
* @returns {Promise<[PaymentMethodDTO[], number]>} The list of payment methods along with their total count.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* To retrieve a list of payment methods for a customer:
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* const [paymentMethods, count] =
|
||||||
|
* await paymentModuleService.listAndCountPaymentMethods({
|
||||||
|
* provider_id: "pp_stripe_stripe",
|
||||||
|
* context: {
|
||||||
|
* customer: {
|
||||||
|
* id: "cus_123",
|
||||||
|
* metadata: {
|
||||||
|
* pp_stripe_stripe_customer_id: "str_1234"
|
||||||
|
* }
|
||||||
|
* },
|
||||||
|
* },
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
listAndCountPaymentMethods(
|
||||||
|
filters: FilterablePaymentMethodProps,
|
||||||
|
config: FindConfig<PaymentMethodDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<[PaymentMethodDTO[], number]>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method retrieves a paginated list of captures based on optional filters and configuration.
|
* This method retrieves a paginated list of captures based on optional filters and configuration.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
CreatePaymentProviderSession,
|
CreatePaymentProviderSession,
|
||||||
IPaymentProvider,
|
IPaymentProvider,
|
||||||
PaymentMethodResponse,
|
|
||||||
PaymentProviderContext,
|
|
||||||
PaymentProviderError,
|
PaymentProviderError,
|
||||||
PaymentProviderSessionResponse,
|
PaymentProviderSessionResponse,
|
||||||
PaymentSessionStatus,
|
PaymentSessionStatus,
|
||||||
@@ -625,59 +623,6 @@ export abstract class AbstractPaymentProvider<TConfig = Record<string, unknown>>
|
|||||||
context: UpdatePaymentProviderSession
|
context: UpdatePaymentProviderSession
|
||||||
): Promise<PaymentProviderError | PaymentProviderSessionResponse>
|
): Promise<PaymentProviderError | PaymentProviderSessionResponse>
|
||||||
|
|
||||||
/**
|
|
||||||
* List the payment methods associated with the context (eg. customer) of the payment provider, if any.
|
|
||||||
*
|
|
||||||
* @param context - The context for which the payment methods are listed. Usually the customer should be provided.
|
|
||||||
* @returns An object whose `payment_methods` property is set to the data returned by the payment provider.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* // other imports...
|
|
||||||
* import {
|
|
||||||
* PaymentProviderContext,
|
|
||||||
* PaymentProviderError,
|
|
||||||
* PaymentMethodResponse
|
|
||||||
* PaymentProviderSessionResponse,
|
|
||||||
* } from "@medusajs/framework/types"
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* class MyPaymentProviderService extends AbstractPaymentProvider<
|
|
||||||
* Options
|
|
||||||
* > {
|
|
||||||
* async listPaymentMethods(
|
|
||||||
* context: PaymentProviderContext
|
|
||||||
* ): Promise<PaymentMethodResponse> {
|
|
||||||
* const {
|
|
||||||
* customer,
|
|
||||||
* } = context
|
|
||||||
* const externalCustomerId = customer.metadata.stripe_id
|
|
||||||
*
|
|
||||||
* try {
|
|
||||||
* // assuming you have a client that updates the payment
|
|
||||||
* const response = await this.client.listPaymentMethods(
|
|
||||||
* {customer: externalCustomerId}
|
|
||||||
* )
|
|
||||||
*
|
|
||||||
* return response.map((method) => ({
|
|
||||||
* id: method.id,
|
|
||||||
* data: method
|
|
||||||
* }))
|
|
||||||
* } catch (e) {
|
|
||||||
* return {
|
|
||||||
* error: e,
|
|
||||||
* code: "unknown",
|
|
||||||
* detail: e
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
abstract listPaymentMethods(
|
|
||||||
context: PaymentProviderContext
|
|
||||||
): Promise<PaymentMethodResponse[]>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is executed when a webhook event is received from the third-party payment provider. Use it
|
* This method is executed when a webhook event is received from the third-party payment provider. Use it
|
||||||
* to process the action of the payment provider.
|
* to process the action of the payment provider.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
CreatePaymentProviderSession,
|
CreatePaymentProviderSession,
|
||||||
PaymentMethodResponse,
|
|
||||||
PaymentProviderError,
|
PaymentProviderError,
|
||||||
PaymentProviderSessionResponse,
|
PaymentProviderSessionResponse,
|
||||||
ProviderWebhookPayload,
|
ProviderWebhookPayload,
|
||||||
@@ -73,10 +72,6 @@ export class SystemProviderService extends AbstractPaymentProvider {
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
async listPaymentMethods(_): Promise<PaymentMethodResponse[]> {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
async getWebhookActionAndData(
|
async getWebhookActionAndData(
|
||||||
data: ProviderWebhookPayload["payload"]
|
data: ProviderWebhookPayload["payload"]
|
||||||
): Promise<WebhookActionResult> {
|
): Promise<WebhookActionResult> {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
Context,
|
Context,
|
||||||
CreateCaptureDTO,
|
CreateCaptureDTO,
|
||||||
CreatePaymentCollectionDTO,
|
CreatePaymentCollectionDTO,
|
||||||
|
CreatePaymentMethodDTO,
|
||||||
CreatePaymentSessionDTO,
|
CreatePaymentSessionDTO,
|
||||||
CreateRefundDTO,
|
CreateRefundDTO,
|
||||||
DAL,
|
DAL,
|
||||||
@@ -914,10 +915,16 @@ export default class PaymentModuleService
|
|||||||
config: FindConfig<PaymentMethodDTO> = {},
|
config: FindConfig<PaymentMethodDTO> = {},
|
||||||
@MedusaContext() sharedContext?: Context
|
@MedusaContext() sharedContext?: Context
|
||||||
): Promise<PaymentMethodDTO[]> {
|
): Promise<PaymentMethodDTO[]> {
|
||||||
return await this.paymentProviderService_.listPaymentMethods(
|
const res = await this.paymentProviderService_.listPaymentMethods(
|
||||||
filters.provider_id,
|
filters.provider_id,
|
||||||
filters.context
|
filters.context
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return res.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
data: item.data,
|
||||||
|
provider_id: filters.provider_id,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@InjectManager()
|
@InjectManager()
|
||||||
@@ -932,7 +939,48 @@ export default class PaymentModuleService
|
|||||||
filters.context
|
filters.context
|
||||||
)
|
)
|
||||||
|
|
||||||
return [paymentMethods, paymentMethods.length]
|
const normalizedResponse = paymentMethods.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
data: item.data,
|
||||||
|
provider_id: filters.provider_id,
|
||||||
|
}))
|
||||||
|
|
||||||
|
return [normalizedResponse, paymentMethods.length]
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
createPaymentMethods(
|
||||||
|
data: CreatePaymentCollectionDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PaymentCollectionDTO>
|
||||||
|
|
||||||
|
createPaymentMethods(
|
||||||
|
data: CreatePaymentMethodDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<PaymentMethodDTO[]>
|
||||||
|
@InjectManager()
|
||||||
|
async createPaymentMethods(
|
||||||
|
data: CreatePaymentMethodDTO | CreatePaymentMethodDTO[],
|
||||||
|
@MedusaContext() sharedContext?: Context
|
||||||
|
): Promise<PaymentMethodDTO | PaymentMethodDTO[]> {
|
||||||
|
const input = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
|
const result = await promiseAll(
|
||||||
|
input.map((item) =>
|
||||||
|
this.paymentProviderService_.savePaymentMethod(item.provider_id, item)
|
||||||
|
),
|
||||||
|
{ aggregateErrors: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
const normalizedResponse = result.map((item, i) => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
data: item.data,
|
||||||
|
provider_id: input[i].provider_id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return Array.isArray(data) ? normalizedResponse : normalizedResponse[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
@InjectManager()
|
@InjectManager()
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import {
|
|||||||
PaymentProviderSessionResponse,
|
PaymentProviderSessionResponse,
|
||||||
PaymentSessionStatus,
|
PaymentSessionStatus,
|
||||||
ProviderWebhookPayload,
|
ProviderWebhookPayload,
|
||||||
|
SavePaymentMethod,
|
||||||
|
SavePaymentMethodResponse,
|
||||||
UpdatePaymentProviderSession,
|
UpdatePaymentProviderSession,
|
||||||
WebhookActionResult,
|
WebhookActionResult,
|
||||||
} from "@medusajs/framework/types"
|
} from "@medusajs/framework/types"
|
||||||
@@ -73,7 +75,7 @@ Please make sure that the provider is registered in the container and it is conf
|
|||||||
async updateSession(
|
async updateSession(
|
||||||
providerId: string,
|
providerId: string,
|
||||||
sessionInput: UpdatePaymentProviderSession
|
sessionInput: UpdatePaymentProviderSession
|
||||||
): Promise<Record<string, unknown> | undefined> {
|
): Promise<PaymentProviderSessionResponse["data"]> {
|
||||||
const provider = this.retrieveProvider(providerId)
|
const provider = this.retrieveProvider(providerId)
|
||||||
|
|
||||||
const paymentResponse = await provider.updatePayment(sessionInput)
|
const paymentResponse = await provider.updatePayment(sessionInput)
|
||||||
@@ -157,9 +159,37 @@ Please make sure that the provider is registered in the container and it is conf
|
|||||||
context: PaymentProviderContext
|
context: PaymentProviderContext
|
||||||
): Promise<PaymentMethodResponse[]> {
|
): Promise<PaymentMethodResponse[]> {
|
||||||
const provider = this.retrieveProvider(providerId)
|
const provider = this.retrieveProvider(providerId)
|
||||||
|
if (!provider.listPaymentMethods) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_DATA,
|
||||||
|
`Provider ${providerId} does not support listing payment methods`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return await provider.listPaymentMethods(context)
|
return await provider.listPaymentMethods(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async savePaymentMethod(
|
||||||
|
providerId: string,
|
||||||
|
input: SavePaymentMethod
|
||||||
|
): Promise<SavePaymentMethodResponse> {
|
||||||
|
const provider = this.retrieveProvider(providerId)
|
||||||
|
if (!provider.savePaymentMethod) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_DATA,
|
||||||
|
`Provider ${providerId} does not support saving payment methods`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await provider.savePaymentMethod(input)
|
||||||
|
|
||||||
|
if (isPaymentProviderError(res)) {
|
||||||
|
this.throwPaymentProviderError(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res as SavePaymentMethodResponse
|
||||||
|
}
|
||||||
|
|
||||||
async getWebhookActionAndData(
|
async getWebhookActionAndData(
|
||||||
providerId: string,
|
providerId: string,
|
||||||
data: ProviderWebhookPayload["payload"]
|
data: ProviderWebhookPayload["payload"]
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import {
|
|||||||
PaymentProviderError,
|
PaymentProviderError,
|
||||||
PaymentProviderSessionResponse,
|
PaymentProviderSessionResponse,
|
||||||
ProviderWebhookPayload,
|
ProviderWebhookPayload,
|
||||||
|
SavePaymentMethod,
|
||||||
|
SavePaymentMethodResponse,
|
||||||
UpdatePaymentProviderSession,
|
UpdatePaymentProviderSession,
|
||||||
WebhookActionResult,
|
WebhookActionResult,
|
||||||
} from "@medusajs/framework/types"
|
} from "@medusajs/framework/types"
|
||||||
@@ -319,6 +321,27 @@ abstract class StripeBase extends AbstractPaymentProvider<StripeOptions> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async savePaymentMethod(
|
||||||
|
input: SavePaymentMethod
|
||||||
|
): Promise<PaymentProviderError | SavePaymentMethodResponse> {
|
||||||
|
const { context, data } = input
|
||||||
|
const customer = context?.customer
|
||||||
|
|
||||||
|
if (!customer?.metadata?.stripe_id) {
|
||||||
|
return this.buildError(
|
||||||
|
"Account holder not set while saving a payment method",
|
||||||
|
new Error("Missing account holder")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await this.stripe_.setupIntents.create({
|
||||||
|
customer: customer.metadata.stripe_id as string,
|
||||||
|
...data,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { id: resp.id, data: resp as unknown as Record<string, unknown> }
|
||||||
|
}
|
||||||
|
|
||||||
async getWebhookActionAndData(
|
async getWebhookActionAndData(
|
||||||
webhookData: ProviderWebhookPayload["payload"]
|
webhookData: ProviderWebhookPayload["payload"]
|
||||||
): Promise<WebhookActionResult> {
|
): Promise<WebhookActionResult> {
|
||||||
|
|||||||
Reference in New Issue
Block a user