docs: improve payment related guides (#12502)
* improve guide * update guides * small change
This commit is contained in:
+14829
-15342
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
||||
export const metadata = {
|
||||
title: `Payment Steps in Checkout Flow`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this guide, you'll learn about Medusa's accept payment flow that's used in checkout.
|
||||
|
||||
## Overview of the Payment Flow in Checkout
|
||||
|
||||
The Medusa application has a built-in payment flow that allows you to accept payments from customers, typically during checkout.
|
||||
|
||||
This flow is designed to be flexible and extensible, allowing you to integrate with various payment providers.
|
||||
|
||||
The payment flow consists of the following steps:
|
||||
|
||||

|
||||
|
||||
- [Create Payment Collection](!api!/store#payment-collections_postpaymentcollections): Create a payment collection associated with a cart.
|
||||
- This payment collection will hold all details related to the payment operations.
|
||||
- [Show Payment Providers](!api!/store#payment-providers_getpaymentproviders): Show the customer the available payment providers to choose from.
|
||||
- You can integrate any [payment provider](../payment-provider/page.mdx), and you can enable them per region.
|
||||
- [Create and Initialize Payment Session](!api!/store#payment-collections_postpaymentcollectionsidpaymentsessions): Create a payment session for the selected payment provider in the Medusa application, and initialize the session in the third-party payment provider.
|
||||
- [Complete Cart](!api!/store#carts_postcartsidcomplete): Once the customer places the order, complete the cart, which involves:
|
||||
- Authorizing the payment session with the third-party payment provider.
|
||||
- If the third-party payment provider requires performing additional actions, show them to the customer, then retry cart completion.
|
||||
|
||||
---
|
||||
|
||||
## Implement Payment Checkout Step in Storefront
|
||||
|
||||
If you're using the [Next.js Starter Storefront](../../../nextjs-starter/page.mdx), the checkout flow is already implemented with the payment step.
|
||||
|
||||
If you're building a custom storefront, or you want to customize the checkout flow, you can follow the [Checkout in Storefront](../../../storefront-development/checkout/page.mdx) guide to learn how to build the checkout flow in the storefront, including the payment step.
|
||||
|
||||
---
|
||||
|
||||
{/* TODO add section on customizng the payment flow */}
|
||||
|
||||
## Build a Custom Payment Flow
|
||||
|
||||
You can also build a custom payment flow using workflows or the Payment Module's main service.
|
||||
|
||||
Refer to the [Accept Payment Flow](../payment-flow/page.mdx) guide to learn more.
|
||||
@@ -1,18 +1,26 @@
|
||||
import { CodeTabs, CodeTab } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Accept Payment Flow`,
|
||||
title: `Accept Payment in Checkout Flow`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this document, you’ll learn how to implement an accept-payment flow using workflows or the Payment Module's main service.
|
||||
In this guide, you'll learn how to implement it using workflows or the Payment Module.
|
||||
|
||||
<Note>
|
||||
## Why Implement the Payment Flow?
|
||||
|
||||
It's highly recommended to use Medusa's workflows to implement this flow. Use the Payment Module's main service for more complex cases.
|
||||
Medusa already provides a built-in payment flow that allows you to accept payments from customers, which you can learn about in the [Accept Payment Flow in Checkout](../payment-checkout-flow/page.mdx) guide.
|
||||
|
||||
</Note>
|
||||
You may need to implement a custom payment flow if you have a different use case, or you're using the Payment Module separately from the Medusa application.
|
||||
|
||||
This guide will help you understand how to implement a payment flow using the Payment Module's main service or workflows.
|
||||
|
||||
You can also follow this guide to get a general understanding of how the payment flow works in the Medusa application.
|
||||
|
||||
---
|
||||
|
||||
## How to Implement the Accept Payment Flow?
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
@@ -20,16 +28,18 @@ For a guide on how to implement this flow in the storefront, check out [this gui
|
||||
|
||||
</Note>
|
||||
|
||||
## Flow Overview
|
||||
<Note>
|
||||
|
||||

|
||||
It's highly recommended to use Medusa's workflows to implement this flow. Use the Payment Module's main service for more complex cases.
|
||||
|
||||
---
|
||||
</Note>
|
||||
|
||||
## 1. Create a Payment Collection
|
||||
### 1. Create a Payment Collection
|
||||
|
||||
A payment collection holds all details related to a resource’s payment operations. So, you start off by creating a payment collection.
|
||||
|
||||
In the Medusa application, you associate the payment collection with a cart, which is the resource that the customer is trying to pay for.
|
||||
|
||||
For example:
|
||||
|
||||
<CodeTabs group="workflow-service">
|
||||
@@ -40,7 +50,7 @@ import { createPaymentCollectionForCartWorkflow } from "@medusajs/medusa/core-fl
|
||||
|
||||
// ...
|
||||
|
||||
await createPaymentCollectionForCartWorkflow(req.scope)
|
||||
await createPaymentCollectionForCartWorkflow(container)
|
||||
.run({
|
||||
input: {
|
||||
cart_id: "cart_123",
|
||||
@@ -62,13 +72,50 @@ const paymentCollection =
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
---
|
||||
### 2. Show Payment Providers
|
||||
|
||||
## 2. Create Payment Sessions
|
||||
Next, you'll show the customer the available payment providers to choose from.
|
||||
|
||||
In the Medusa application, you need to use [Query](!docs!/learn/fundamentals/module-links/query) to retrieve the available payment providers in a region.
|
||||
|
||||
<CodeTabs group="query-service">
|
||||
<CodeTab label="Using Query" value="query">
|
||||
|
||||
```ts
|
||||
const query = container.resolve("query")
|
||||
|
||||
const { data: regionPaymentProviders } = await query.graph({
|
||||
entryPoint: "region_payment_provider",
|
||||
variables: {
|
||||
filters: {
|
||||
region_id: "reg_123",
|
||||
},
|
||||
},
|
||||
fields: ["payment_providers.*"],
|
||||
})
|
||||
|
||||
const paymentProviders = regionPaymentProviders.map(
|
||||
(relation) => relation.payment_providers
|
||||
)
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="Using Service" value="service">
|
||||
|
||||
```ts
|
||||
const paymentProviders = await paymentModuleService.listPaymentProviders()
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
### 3. Create Payment Sessions
|
||||
|
||||
The payment collection has one or more payment sessions, each being a payment amount to be authorized by a payment provider.
|
||||
|
||||
So, after creating the payment collection, create at least one payment session for a provider.
|
||||
So, once the customer selects a payment provider, create a payment session for the selected payment provider.
|
||||
|
||||
This will also initialize the payment session in the third-party payment provider.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -80,11 +127,11 @@ import { createPaymentSessionsWorkflow } from "@medusajs/medusa/core-flows"
|
||||
|
||||
// ...
|
||||
|
||||
const { result: paymentSesion } = await createPaymentSessionsWorkflow(req.scope)
|
||||
const { result: paymentSesion } = await createPaymentSessionsWorkflow(container)
|
||||
.run({
|
||||
input: {
|
||||
payment_collection_id: "paycol_123",
|
||||
provider_id: "stripe",
|
||||
provider_id: "pp_stripe_stripe",
|
||||
},
|
||||
})
|
||||
```
|
||||
@@ -97,7 +144,7 @@ const paymentSession =
|
||||
await paymentModuleService.createPaymentSession(
|
||||
paymentCollection.id,
|
||||
{
|
||||
provider_id: "stripe",
|
||||
provider_id: "pp_stripe_stripe",
|
||||
currency_code: "usd",
|
||||
amount: 5000,
|
||||
data: {
|
||||
@@ -111,11 +158,9 @@ const paymentSession =
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
---
|
||||
### 4. Authorize Payment Session
|
||||
|
||||
## 3. Authorize Payment Session
|
||||
|
||||
Once the customer chooses a payment session, start the authorization process. This may involve some action performed by the third-party payment provider, such as entering a 3DS code.
|
||||
Once the customer places the order, you need to authorize the payment session with the third-party payment provider.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -148,7 +193,7 @@ const payment = authorizePaymentSessionStep({
|
||||
|
||||
When the payment authorization is successful, a payment is created and returned.
|
||||
|
||||
### Handling Additional Action
|
||||
#### Handling Additional Action
|
||||
|
||||
<Note>
|
||||
|
||||
@@ -184,14 +229,13 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Payment Flow Complete
|
||||
### 5. Payment Flow Complete
|
||||
|
||||
The payment flow is complete once the payment session is authorized and the payment is created.
|
||||
|
||||
You can then:
|
||||
|
||||
- Complete the cart using the [completeCartWorkflow](/references/medusa-workflows/completeCartWorkflow) if you're using the Medusa application.
|
||||
- Capture the payment either using the [capturePaymentWorkflow](/references/medusa-workflows/capturePaymentWorkflow) or [capturePayment method](/references/payment/capturePayment).
|
||||
- Refund captured amounts using the [refundPaymentWorkflow](/references/medusa-workflows/refundPaymentWorkflow) or [refundPayment method](/references/payment/refundPayment).
|
||||
|
||||
|
||||
@@ -18,9 +18,23 @@ A payment collection can have multiple payment sessions. Using this feature, you
|
||||
|
||||
## data Property
|
||||
|
||||
Payment providers may need additional data to process the payment later. The `PaymentSession` data model has a `data` property used to store that data.
|
||||
Payment providers may need additional data to process the payment later. For example, the ID of the session in the third-party provider.
|
||||
|
||||
For example, the customer's ID in Stripe is stored in the `data` property.
|
||||
The `PaymentSession` data model has a `data` property used to store that data. It's set by the [payment provider in Medusa](../payment-provider/page.mdx) when the payment is initialized.
|
||||
|
||||
Then, when the payment session is authorized, the `data` property is used by the payment provider in Medusa to process the payment with the third-party provider.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
If you're building a custom payment provider, learn more about initializing the payment session and setting the `data` property in the [Create Payment Provider](/references/payment/provider) guide.
|
||||
|
||||
</Note>
|
||||
|
||||
### data Property in the Storefront
|
||||
|
||||
This `data` property is accessible in the storefront as well. So, only store in it data that can be publicly shared, and data that is useful in the storefront.
|
||||
|
||||
For example, you can also store the client token used to initialize the payment session in the storefront with the third-party provider.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -35,3 +35,19 @@ When a payment is refunded, a refund, represented by the [Refund data model](/re
|
||||
A payment can be refunded multiple times, and each time a refund record is created.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## data Property
|
||||
|
||||
Payment providers may need additional data to process the payment later. For example, the ID of the associated payment in the third-party provider.
|
||||
|
||||
The `Payment` data model has a `data` property used to store that data. The first time it's set is when the [payment provider in Medusa](../payment-provider/page.mdx) authorizes the payment.
|
||||
|
||||
Then, the `data` property is passed to the Medusa payment provider when the payment is captured or refunded, allowing the payment provider to utilize the data to process the payment with the third-party provider.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
If you're building a custom payment provider, learn more about authorizing and capturing the payments and setting the `data` property in the [Create Payment Provider](/references/payment/provider) guide.
|
||||
|
||||
</Note>
|
||||
@@ -1,38 +1,58 @@
|
||||
export const metadata = {
|
||||
title: `Webhook Events`,
|
||||
title: `Payment Webhook Events`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this document, you’ll learn how the Payment Module supports listening to webhook events.
|
||||
In this guide, you’ll learn how you can handle payment webhook events in your Medusa application and using the Payment Module.
|
||||
|
||||
## What's a Webhook Event?
|
||||
## What's a Payment Webhook Event?
|
||||
|
||||
A webhook event is sent from a third-party payment provider to your application. It indicates a change in a payment’s status.
|
||||
A payment webhook event is a request sent from a third-party payment provider to your application. It indicates a change in a payment’s status.
|
||||
|
||||
This is useful in many cases such as when a payment is being processed asynchronously or when a request is interrupted and the payment provider is sending details on the process later.
|
||||
This is useful in many cases such as:
|
||||
|
||||
- When a payment is processed (authorized or captured) asynchronously.
|
||||
- When a payment is managed on the third-party payment provider's side.
|
||||
- When a payment action on the frontend was interrupted, leading the payment to be processed without an order being created in the Medusa application.
|
||||
|
||||
So, it's essential to handle webhook events to ensure that your application is aware of updated payment statuses and can take appropriate actions.
|
||||
|
||||
---
|
||||
|
||||
## getWebhookActionAndData Method
|
||||
## How to Handle Payment Webhook Events
|
||||
|
||||
The Payment Module’s main service has a [getWebhookActionAndData method](/references/payment/getWebhookActionAndData) used to handle incoming webhook events from third-party payment services. The method delegates the handling to the associated payment provider, which returns the event's details.
|
||||
### Webhook Listener API Route
|
||||
|
||||
Medusa implements a webhook listener route at the `/hooks/payment/[identifier]_[provider]` API route, where:
|
||||
The Medusa application has a `/hooks/payment/[identifier]_[provider]` API route out-of-the-box that allows you to listen to webhook events from third-party payment providers, where:
|
||||
|
||||
- `[identifier]` is the `identifier` static property defined in the payment provider. For example, `stripe`.
|
||||
- `[provider]` is the ID of the provider. For example, `stripe`.
|
||||
|
||||
For example, when integrating basic Stripe payments with the [Stripe Module Provider](../payment-provider/stripe/page.mdx), the webhook listener route is `/hooks/payment/stripe_stripe`. If you're integrating Stripe's Bancontact payments, the webhook listener route is `/hooks/payment/stripe-bancontact_stripe`.
|
||||
For example, when integrating basic Stripe payments with the [Stripe Module Provider](../payment-provider/stripe/page.mdx), the webhook listener route is `/hooks/payment/stripe_stripe`.
|
||||
|
||||
Use that webhook listener in your third-party payment provider's configurations.
|
||||
You can use this webhook listener when configuring webhook events in your third-party payment provider.
|
||||
|
||||
### getWebhookActionAndData Method
|
||||
|
||||
The webhook listener API route executes the [getWebhookActionAndData method](/references/payment/getWebhookActionAndData) of the Payment Module's main service. This method delegates handling of incoming webhook events to the relevant payment provider.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
Payment providers have a similar [getWebhookActionAndData method](/references/payment/provider) to process the webhook event. So, if you're implementing a custom payment provider, make sure to implement it to handle webhook events.
|
||||
|
||||
</Note>
|
||||
|
||||

|
||||
|
||||
If the event's details indicate that the payment should be authorized, then the [authorizePaymentSession method of the main service](/references/payment/authorizePaymentSession) is executed on the specified payment session.
|
||||
If the `getWebhookActionAndData` method returns an `authorized` or `captured` action, the Medusa application will perform one of the following actions:
|
||||
|
||||
If the event's details indicate that the payment should be captured, then the [capturePayment method of the main service](/references/payment/capturePayment) is executed on the payment of the specified payment session.
|
||||
<Note>
|
||||
|
||||
### Actions After Webhook Payment Processing
|
||||
View the full flow of the webhook event processing in the [processPaymentWorkflow](/references/medusa-workflows/processPaymentWorkflow) reference.
|
||||
|
||||
After the payment webhook actions are processed and the payment is authorized or captured, the Medusa application completes the cart associated with the payment's collection if it's not completed yet.
|
||||
</Note>
|
||||
|
||||
- If the method returns an `authorized` action, Medusa will set the associated payment session to `authorized`.
|
||||
- If the method returns a `captured` action, Medusa will set the associated payment session to `captured`.
|
||||
- In either cases, if the cart associated with the payment session is not completed yet, Medusa will complete the cart.
|
||||
|
||||
@@ -45,13 +45,13 @@ export const generatedEditDates = {
|
||||
"app/commerce-modules/payment/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00",
|
||||
"app/commerce-modules/payment/_events/page.mdx": "2024-07-03T19:27:13+03:00",
|
||||
"app/commerce-modules/payment/module-options/page.mdx": "2024-10-15T12:51:40.574Z",
|
||||
"app/commerce-modules/payment/payment/page.mdx": "2024-10-09T10:59:08.463Z",
|
||||
"app/commerce-modules/payment/payment/page.mdx": "2025-05-15T15:13:47.920Z",
|
||||
"app/commerce-modules/payment/payment-collection/page.mdx": "2024-10-09T10:56:49.510Z",
|
||||
"app/commerce-modules/payment/payment-flow/page.mdx": "2025-01-16T10:43:25.958Z",
|
||||
"app/commerce-modules/payment/payment-flow/page.mdx": "2025-05-15T15:00:46.800Z",
|
||||
"app/commerce-modules/payment/payment-provider/stripe/page.mdx": "2025-04-25T12:43:03.674Z",
|
||||
"app/commerce-modules/payment/payment-provider/page.mdx": "2025-05-09T11:29:10.212Z",
|
||||
"app/commerce-modules/payment/payment-session/page.mdx": "2024-10-09T10:58:00.960Z",
|
||||
"app/commerce-modules/payment/webhook-events/page.mdx": "2024-11-19T11:45:02.167Z",
|
||||
"app/commerce-modules/payment/payment-session/page.mdx": "2025-05-15T15:11:33.262Z",
|
||||
"app/commerce-modules/payment/webhook-events/page.mdx": "2025-05-15T13:18:09.356Z",
|
||||
"app/commerce-modules/payment/page.mdx": "2025-04-17T08:48:11.702Z",
|
||||
"app/commerce-modules/pricing/_events/_events-table/page.mdx": "2024-07-03T19:27:13+03:00",
|
||||
"app/commerce-modules/pricing/_events/page.mdx": "2024-07-03T19:27:13+03:00",
|
||||
@@ -6480,5 +6480,6 @@ export const generatedEditDates = {
|
||||
"references/core_flows/Product/Steps_Product/functions/core_flows.Product.Steps_Product.normalizeCsvStep/page.mdx": "2025-05-15T08:05:21.388Z",
|
||||
"references/core_flows/Product/Steps_Product/variables/core_flows.Product.Steps_Product.normalizeCsvStepId/page.mdx": "2025-05-15T08:05:21.385Z",
|
||||
"references/core_flows/types/core_flows.NormalizeProductCsvStepInput/page.mdx": "2025-05-15T08:05:23.806Z",
|
||||
"references/utils/ProductUtils/classes/utils.ProductUtils.CSVNormalizer/page.mdx": "2025-05-15T08:05:33.996Z"
|
||||
"references/utils/ProductUtils/classes/utils.ProductUtils.CSVNormalizer/page.mdx": "2025-05-15T08:05:33.996Z",
|
||||
"app/commerce-modules/payment/payment-checkout-flow/page.mdx": "2025-05-15T15:06:08.891Z"
|
||||
}
|
||||
@@ -359,6 +359,10 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/app/commerce-modules/payment/payment/page.mdx",
|
||||
"pathname": "/commerce-modules/payment/payment"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/commerce-modules/payment/payment-checkout-flow/page.mdx",
|
||||
"pathname": "/commerce-modules/payment/payment-checkout-flow"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/commerce-modules/payment/payment-collection/page.mdx",
|
||||
"pathname": "/commerce-modules/payment/payment-collection"
|
||||
@@ -13571,26 +13575,6 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/references/medusa/types/medusa.SubscriberConfig/page.mdx",
|
||||
"pathname": "/references/medusa/types/medusa.SubscriberConfig"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/medusa_config/interfaces/medusa_config.AdminOptions/page.mdx",
|
||||
"pathname": "/references/medusa_config/interfaces/medusa_config.AdminOptions"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/medusa_config/interfaces/medusa_config.ConfigModule/page.mdx",
|
||||
"pathname": "/references/medusa_config/interfaces/medusa_config.ConfigModule"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/medusa_config/interfaces/medusa_config.HttpCompressionOptions/page.mdx",
|
||||
"pathname": "/references/medusa_config/interfaces/medusa_config.HttpCompressionOptions"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/medusa_config/interfaces/medusa_config.ProjectConfigOptions/page.mdx",
|
||||
"pathname": "/references/medusa_config/interfaces/medusa_config.ProjectConfigOptions"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/medusa_config/types/medusa_config.PluginDetails/page.mdx",
|
||||
"pathname": "/references/medusa_config/types/medusa_config.PluginDetails"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/module_events/module_events.Auth/page.mdx",
|
||||
"pathname": "/references/module_events/module_events.Auth"
|
||||
@@ -13735,10 +13719,6 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/references/modules/medusa/page.mdx",
|
||||
"pathname": "/references/modules/medusa"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/modules/medusa_config/page.mdx",
|
||||
"pathname": "/references/modules/medusa_config"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/modules/module_events/page.mdx",
|
||||
"pathname": "/references/modules/module_events"
|
||||
@@ -13815,10 +13795,6 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/references/modules/sales_channel_models/page.mdx",
|
||||
"pathname": "/references/modules/sales_channel_models"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/modules/search/page.mdx",
|
||||
"pathname": "/references/modules/search"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/modules/stock_location_next/page.mdx",
|
||||
"pathname": "/references/modules/stock_location_next"
|
||||
@@ -17783,10 +17759,6 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/references/sales_channel_models/variables/sales_channel_models.SalesChannel/page.mdx",
|
||||
"pathname": "/references/sales_channel_models/variables/sales_channel_models.SalesChannel"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/search/classes/search.AbstractSearchService/page.mdx",
|
||||
"pathname": "/references/search/classes/search.AbstractSearchService"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/references/stock_location_next/IMessageAggregator/methods/stock_location_next.IMessageAggregator.clearMessages/page.mdx",
|
||||
"pathname": "/references/stock_location_next/IMessageAggregator/methods/stock_location_next.IMessageAggregator.clearMessages"
|
||||
|
||||
@@ -9081,6 +9081,14 @@ const generatedgeneratedCommerceModulesSidebarSidebar = {
|
||||
"title": "Payment Module Provider",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/commerce-modules/payment/payment-checkout-flow",
|
||||
"title": "Payment in Checkout",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
|
||||
@@ -4874,11 +4874,6 @@ export const slugChanges = [
|
||||
"newSlug": "/references/locking-module-provider",
|
||||
"filePath": "/www/apps/resources/references/locking/interfaces/locking.ILockingProvider/page.mdx"
|
||||
},
|
||||
{
|
||||
"origSlug": "/references/medusa_config/interfaces/medusa_config.ConfigModule",
|
||||
"newSlug": "/references/medusa-config",
|
||||
"filePath": "/www/apps/resources/references/medusa_config/interfaces/medusa_config.ConfigModule/page.mdx"
|
||||
},
|
||||
{
|
||||
"origSlug": "/references/module_events/module_events.Auth",
|
||||
"newSlug": "/references/auth/events",
|
||||
@@ -7064,11 +7059,6 @@ export const slugChanges = [
|
||||
"newSlug": "/references/sales-channel/models/SalesChannel",
|
||||
"filePath": "/www/apps/resources/references/sales_channel_models/variables/sales_channel_models.SalesChannel/page.mdx"
|
||||
},
|
||||
{
|
||||
"origSlug": "/references/search/classes/search.AbstractSearchService",
|
||||
"newSlug": "/references/search-service",
|
||||
"filePath": "/www/apps/resources/references/search/classes/search.AbstractSearchService/page.mdx"
|
||||
},
|
||||
{
|
||||
"origSlug": "/references/stock_location_next/IStockLocationService/methods/stock_location_next.IStockLocationService.createStockLocations",
|
||||
"newSlug": "/references/stock-location-next/createStockLocations",
|
||||
|
||||
+142
-29
@@ -76,6 +76,8 @@ export default MyPaymentProviderService
|
||||
The constructor allows you to access resources from the [module's container](https://docs.medusajs.com/learn/fundamentals/modules/container)
|
||||
using the first parameter, and the module's options using the second parameter.
|
||||
|
||||
If you're creating a client or establishing a connection with a third-party service, do it in the constructor.
|
||||
|
||||
:::note
|
||||
|
||||
A module's options are passed when you register it in the Medusa application.
|
||||
@@ -125,7 +127,7 @@ export default MyPaymentProviderService
|
||||
|
||||
#### Parameters
|
||||
|
||||
<TypeList types={[{"name":"cradle","type":"`Record<string, unknown>`","description":"The module's container cradle used to resolve resources.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="AbstractPaymentProvider"/>
|
||||
<TypeList types={[{"name":"cradle","type":"`Record<string, unknown>`","description":"The module's container used to resolve resources.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="AbstractPaymentProvider"/>
|
||||
|
||||
### identifier
|
||||
|
||||
@@ -146,13 +148,30 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### authorizePayment
|
||||
|
||||
This method authorizes a payment session. When authorized successfully, a payment is created by the Payment
|
||||
Module which can be later captured using the [capturePayment](page.mdx#capturepayment) method.
|
||||
This method authorizes a payment session using the third-party payment provider.
|
||||
|
||||
Refer to [this guide](https://docs.medusajs.com/resources/commerce-modules/payment/payment-flow#3-authorize-payment-session)
|
||||
to learn more about how this fits into the payment flow and how to handle required actions.
|
||||
During checkout, the customer may need to perform actions required by the payment provider,
|
||||
such as entering their card details or confirming the payment. Once that is done,
|
||||
the customer can place their order.
|
||||
|
||||
To automatically capture the payment after authorization, return the status `captured`.
|
||||
During cart-completion before placing the order, this method is used to authorize the cart's payment session with the
|
||||
third-party payment provider. The payment can later be captured
|
||||
using the [capturePayment](page.mdx#capturepayment) method.
|
||||
|
||||

|
||||
|
||||
When authorized successfully, a `Payment` is created by the Payment
|
||||
Module, and it's associated with the order.
|
||||
|
||||
#### Understanding `data` property
|
||||
|
||||
The `data` property of the method's parameter contains the `PaymentSession` record's `data` property, which was
|
||||
returned by the [initiatePayment](page.mdx#initiatepayment) method.
|
||||
|
||||
The `data` property returned by this method is then stored in the created `Payment` record. You can store data relevant to later capture or process the payment.
|
||||
For example, you can store the ID of the payment in the third-party provider to reference it later.
|
||||
|
||||

|
||||
|
||||
#### Example
|
||||
|
||||
@@ -195,7 +214,18 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### cancelPayment
|
||||
|
||||
This method cancels a payment.
|
||||
This method cancels a payment in the third-party payment provider. It's used when
|
||||
the admin user cancels an order. The order can only be canceled if the payment
|
||||
is not captured yet.
|
||||
|
||||
#### Understanding `data` property
|
||||
|
||||
The `data` property of the method's parameter contains the `Payment` record's `data` property, which was
|
||||
returned by the [authorizePayment](page.mdx#authorizepayment) method.
|
||||
|
||||
The `data` property returned by this method is then stored in the `Payment` record. You can store data relevant for any further processing of the payment.
|
||||
|
||||

|
||||
|
||||
#### Example
|
||||
|
||||
@@ -233,13 +263,24 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### capturePayment
|
||||
|
||||
This method is used to capture a payment. The payment is captured in one of the following scenarios:
|
||||
This method captures a payment using the third-party provider. In this method, use the third-party provider to capture the payment.
|
||||
|
||||
- The [authorizePayment](page.mdx#authorizepayment) method returns the status `captured`, which automatically executed this method after authorization.
|
||||
- The merchant requests to capture the payment after its associated payment session was authorized.
|
||||
- A webhook event occurred that instructs the payment provider to capture the payment session. Learn more about handing webhook events in [this guide](https://docs.medusajs.com/resources/commerce-modules/payment/webhook-events).
|
||||
When an order is placed, the payment is authorized using the [authorizePayment](page.mdx#authorizepayment) method. Then, the admin
|
||||
user can capture the payment, which triggers this method.
|
||||
|
||||
In this method, use the third-party provider to capture the payment.
|
||||

|
||||
|
||||
This method can also be triggered by a webhook event if the [getWebhookActionAndData](page.mdx#getwebhookactionanddata) method returns the action `captured`.
|
||||
|
||||
#### Understanding `data` property
|
||||
|
||||
The `data` property of the input parameter contains data that was previously stored in the Payment record's `data` property, which was
|
||||
returned by the [authorizePayment](page.mdx#authorizepayment) method.
|
||||
|
||||
The `data` property returned by this method is then stored in the `Payment` record. You can store data relevant to later refund or process the payment.
|
||||
For example, you can store the ID of the payment in the third-party provider to reference it later.
|
||||
|
||||

|
||||
|
||||
#### Example
|
||||
|
||||
@@ -260,7 +301,12 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
// assuming you have a client that captures the payment
|
||||
const newData = await this.client.capturePayment(externalId)
|
||||
return {data: newData}
|
||||
return {
|
||||
data: {
|
||||
...newData,
|
||||
id: externalId,
|
||||
}
|
||||
}
|
||||
}
|
||||
// ...
|
||||
}
|
||||
@@ -398,9 +444,22 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### deletePayment
|
||||
|
||||
This method is used when a payment session is deleted, which can only happen if it isn't authorized, yet.
|
||||
This method deletes a payment session in the third-party payment provider.
|
||||
|
||||
Use this to delete or cancel the payment in the third-party service.
|
||||
When a customer chooses a payment method during checkout, then chooses a different one,
|
||||
this method is triggered to delete the previous payment session.
|
||||
|
||||
If your provider doesn't support deleting a payment session, you can just return an empty object or
|
||||
an object that contains the same received `data` property.
|
||||
|
||||

|
||||
|
||||
#### Understanding `data` property
|
||||
|
||||
The `data` property of the method's parameter contains the `PaymentSession` record's `data` property, which was
|
||||
returned by the [initiatePayment](page.mdx#initiatepayment) method.
|
||||
|
||||

|
||||
|
||||
#### Example
|
||||
|
||||
@@ -421,7 +480,9 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
// assuming you have a client that cancels the payment
|
||||
await this.client.cancelPayment(externalId)
|
||||
return {}
|
||||
return {
|
||||
data: input.data
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
@@ -487,10 +548,11 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### getWebhookActionAndData
|
||||
|
||||
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.
|
||||
This method is executed when a webhook event is received from the third-party payment provider. Medusa uses
|
||||
the data returned by this method to perform actions in the Medusa application, such as completing the associated cart
|
||||
if the payment was authorized successfully.
|
||||
|
||||
Learn more in [this documentation](https://docs.medusajs.com/resources/commerce-modules/payment/webhook-events)
|
||||
Learn more in the [Webhook Events](https://docs.medusajs.com/resources/commerce-modules/payment/webhook-events) documentation.
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -522,6 +584,8 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
return {
|
||||
action: "authorized",
|
||||
data: {
|
||||
// assuming the session_id is stored in the metadata of the payment
|
||||
// in the third-party provider
|
||||
session_id: (data.metadata as Record<string, any>).session_id,
|
||||
amount: new BigNumber(data.amount as number)
|
||||
}
|
||||
@@ -530,19 +594,27 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
return {
|
||||
action: "captured",
|
||||
data: {
|
||||
// assuming the session_id is stored in the metadata of the payment
|
||||
// in the third-party provider
|
||||
session_id: (data.metadata as Record<string, any>).session_id,
|
||||
amount: new BigNumber(data.amount as number)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return {
|
||||
action: "not_supported"
|
||||
action: "not_supported",
|
||||
data: {
|
||||
session_id: "",
|
||||
amount: new BigNumber(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
action: "failed",
|
||||
data: {
|
||||
// assuming the session_id is stored in the metadata of the payment
|
||||
// in the third-party provider
|
||||
session_id: (data.metadata as Record<string, any>).session_id,
|
||||
amount: new BigNumber(data.amount as number)
|
||||
}
|
||||
@@ -560,12 +632,32 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
#### Returns
|
||||
|
||||
<TypeList types={[{"name":"Promise","type":"Promise<[WebhookActionResult](../../../types/interfaces/types.WebhookActionResult/page.mdx)>","optional":false,"defaultValue":"","description":"The webhook result. If the `action`'s value is `captured`, the payment is captured within Medusa as well.\nIf the `action`'s value is `authorized`, the associated payment session is authorized within Medusa.","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="getWebhookActionAndData"/>
|
||||
<TypeList types={[{"name":"Promise","type":"Promise<[WebhookActionResult](../../../types/interfaces/types.WebhookActionResult/page.mdx)>","optional":false,"defaultValue":"","description":"The webhook result. If the `action`'s value is `captured`, the payment is captured within Medusa as well.\nIf the `action`'s value is `authorized`, the associated payment session is authorized within Medusa and the associated cart\nwill be completed to create an order.","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="getWebhookActionAndData"/>
|
||||
|
||||
### initiatePayment
|
||||
|
||||
This method is used when a payment session is created. It can be used to initiate the payment
|
||||
in the third-party session, before authorizing or capturing the payment later.
|
||||
This method initializes a payment session with the third-party payment provider.
|
||||
|
||||
When a customer chooses a payment method during checkout, this method is triggered to
|
||||
perform any initialization action with the third-party provider, such as creating a payment session.
|
||||
|
||||

|
||||
|
||||
#### Understanding `data` property
|
||||
|
||||
The `data` property returned by this method will be stored in the created `PaymentSession` record. You can store data relevant to later authorize or process the payment.
|
||||
For example, you can store the ID of the payment session in the third-party provider to reference it later.
|
||||
|
||||
The `data` property is also available to storefronts, allowing you to store data necessary for the storefront to integrate
|
||||
the payment provider in the checkout flow. For example, you can store the client token to use with the payment provider's SDK.
|
||||
|
||||
:::note
|
||||
|
||||
This also means you shouldn't store sensitive data and tokens in the `data` property, as it's publicly accessible.
|
||||
|
||||
:::
|
||||
|
||||

|
||||
|
||||
#### Example
|
||||
|
||||
@@ -672,7 +764,25 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### refundPayment
|
||||
|
||||
This method refunds an amount of a payment previously captured.
|
||||
This method refunds an amount using the third-party payment provider. This method
|
||||
is triggered when the admin user refunds a payment of an order.
|
||||
|
||||
#### Understanding `data` property
|
||||
|
||||
The `data` property of the method's parameter contains the `Payment` record's `data` property, which was
|
||||
returned by the [capturePayment](page.mdx#capturepayment) or [refundPayment](page.mdx#refundpayment) method.
|
||||
|
||||
The `data` property returned by this method is then stored in the `Payment` record. You can store data relevant to later refund or process the payment.
|
||||
For example, you can store the ID of the payment in the third-party provider to reference it later.
|
||||
|
||||
:::note
|
||||
|
||||
A payment may be refunded multiple times with different amounts. In this case, the `data` property
|
||||
of the input parameter contains the data from the last refund.
|
||||
|
||||
:::
|
||||
|
||||

|
||||
|
||||
#### Example
|
||||
|
||||
@@ -697,7 +807,9 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
input.amount
|
||||
)
|
||||
|
||||
return {data: newData}
|
||||
return {
|
||||
data: input.data,
|
||||
}
|
||||
}
|
||||
// ...
|
||||
}
|
||||
@@ -713,7 +825,7 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### retrievePayment
|
||||
|
||||
Retrieves the payment's data from the third-party service.
|
||||
This method retrieves the payment's data from the third-party payment provider.
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -870,7 +982,7 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
|
||||
### updatePayment
|
||||
|
||||
Update a payment in the third-party service that was previously initiated with the [initiatePayment](page.mdx#initiatepayment) method.
|
||||
This method updates a payment in the third-party service that was previously initiated with the [initiatePayment](page.mdx#initiatepayment) method.
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -923,7 +1035,8 @@ class MyPaymentProviderService extends AbstractPaymentProvider<
|
||||
### validateOptions
|
||||
|
||||
This method validates the options of the provider set in `medusa-config.ts`.
|
||||
Implementing this method is optional. It's useful if your provider requires custom validation.
|
||||
Implementing this method is optional, but it's useful to ensure that the required
|
||||
options are passed to the provider, or if you have any custom validation logic.
|
||||
|
||||
If the options aren't valid, throw an error.
|
||||
|
||||
@@ -944,7 +1057,7 @@ class MyPaymentProviderService extends AbstractPaymentProvider<Options> {
|
||||
|
||||
#### Parameters
|
||||
|
||||
<TypeList types={[{"name":"options","type":"`Record<any, any>`","description":"The provider's options.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="validateOptions"/>
|
||||
<TypeList types={[{"name":"options","type":"`Record<any, any>`","description":"The provider's options passed in `medusa-config.ts`.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="validateOptions"/>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -42,6 +42,11 @@ export const paymentSidebar = [
|
||||
path: "/commerce-modules/payment/payment-provider",
|
||||
title: "Payment Module Provider",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/commerce-modules/payment/payment-checkout-flow",
|
||||
title: "Payment in Checkout",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/commerce-modules/payment/account-holder",
|
||||
|
||||
Reference in New Issue
Block a user