Skip to main content
Skip to main content

How to Create a Payment Provider

In this document, you’ll learn how to create a Payment Provider to be used with the Payment Module.

Overview

A payment provider is used to handle and process payments, such as authorizing, capturing, and refund payments.

Refer to this guide to learn more about payment providers.

Refer to this guide to learn more about the payment flow.


How to Create a Payment Provider

A payment provider is a TypeScript or JavaScript class that extends the AbstractPaymentProvider class imported from @medusajsa/utils.

You can create the payment provider in a module or plugin, then pass that module/plugin in the Payment Module's providers option. You can also pass the path to the file that defines the provider if it's created in the Medusa application's codebase.

For example:

abstract class MyPayment extends AbstractPaymentProvider<MyConfigurations> {
// ...
}

Configuration Type Parameter

The AbstractPaymentProvider class accepts an optional type parameter that defines the type of configuration that your payment provider expects.

For example:

interface MyConfigurations {
apiKey: string
}

abstract class MyPayment extends AbstractPaymentProvider<MyConfigurations> {
// ...
}

Identifier Property

The PaymentProvider data model has 2 properties: id and is_enabled.

class MyPaymentProvider extends AbstractPaymentProvider<MyConfigurations> {
static identifier = "my-payment"
// ...
}

PROVIDER Property

The PROVIDER static property is used when registering the provider in the dependency container. Typically, it would have the same value as the identifier property.

class MyPaymentProvider extends AbstractPaymentProvider<MyConfigurations> {
static PROVIDER = "my-payment"
// ...
}

PaymentProviderError

Before diving into the methods of the Payment Provider, you'll notice that part of the expected return signature of these method includes PaymentProviderError.

interface PaymentProviderError {
error: string
code?: string
detail?: any
}

While implementing the Payment Provider's methods, if you need to inform the Payment Module that an error occurred at a certain stage, return an object having the attributes defined in the PaymentProviderError interface.

For example, the Stripe payment provider has the following method to create the error object, which is used within other methods:

abstract class StripeBase extends AbstractPaymentProvider {
// ...
protected buildError(
message: string,
error: Stripe.StripeRawError | PaymentProviderError | Error
): PaymentProviderError {
return {
error: message,
code: "code" in error ? error.code : "unknown",
detail: isPaymentProviderError(error)
? `${error.error}${EOL}${error.detail ?? ""}`
: "detail" in error
? error.detail
: error.message ?? "",
}
}

// used in other methods
async retrievePayment(
paymentSessionData: Record<string, unknown>
): Promise<
PaymentProviderError |
PaymentProviderSessionResponse["session_data"]
> {
try {
// ...
} catch (e) {
return this.buildError(
"An error occurred in retrievePayment",
e
)
}
}
}

Type parameters

TConfigobjectRequired

constructor

You can use the constructor of your Payment Provider to have access to resources in your application through the dependency container.

You can also use the constructor to initialize your integration with the third-party provider. For example, if you use a client to connect to the third-party provider’s APIs, you can initialize it in the constructor and use it in other methods in the service.

The payment provider also can access the configurations of the module or plugin it's created in as a second parameter.

Example

class MyPaymentProvider extends AbstractPaymentProvider<MyConfigurations> {
// ...
constructor(container, config) {
super(container, config)
// you can access options here

// you can also initialize a client that
// communicates with a third-party service.
this.client = new Client(options)
}
// ...
}

Parameters

containerMedusaContainerRequired
An instance of MedusaContainer that allows you to access other resources in the dependency container
configTConfigRequired
If this provider processor is created in a module or plugin, their options are passed in this parameter.

capturePayment

Parameters

paymentSessionDataRecord<string, unknown>Required

Returns

PromisePromise<Record<string, unknown> | PaymentProviderError>Required

authorizePayment

Parameters

paymentSessionDataRecord<string, unknown>Required
contextRecord<string, unknown>Required

Returns

PromisePromise<PaymentProviderError | object>Required

cancelPayment

Parameters

paymentSessionDataRecord<string, unknown>Required

Returns

PromisePromise<Record<string, unknown> | PaymentProviderError>Required

initiatePayment

Parameters

contextCreatePaymentProviderSessionRequired

Returns

PromisePromise<PaymentProviderError | PaymentProviderSessionResponse>Required

deletePayment

Parameters

paymentSessionDataRecord<string, unknown>Required

Returns

PromisePromise<Record<string, unknown> | PaymentProviderError>Required

getPaymentStatus

Parameters

paymentSessionDataRecord<string, unknown>Required

Returns

PromisePromise<PaymentSessionStatus>Required

refundPayment

Parameters

paymentSessionDataRecord<string, unknown>Required
refundAmountnumberRequired

Returns

PromisePromise<Record<string, unknown> | PaymentProviderError>Required

retrievePayment

Parameters

paymentSessionDataRecord<string, unknown>Required

Returns

PromisePromise<Record<string, unknown> | PaymentProviderError>Required

updatePayment

Parameters

contextUpdatePaymentProviderSessionRequired

Returns

PromisePromise<PaymentProviderError | PaymentProviderSessionResponse>Required

getWebhookActionAndData

Parameters

dataobjectRequired
data.dataRecord<string, unknown>Required
The parsed webhook body.
data.rawDatastring | BufferRequired
The raw webhook request body.
data.headersRecord<string, unknown>Required
The headers of the webhook request.

Returns

PromisePromise<WebhookActionResult>Required
Was this section helpful?