docs: document payment changes + account holder (#11242)
* docs: document payment changes + account holder * added version
This commit is contained in:
@@ -18,11 +18,106 @@ Read-only links are used to query data across modules, but the relations aren't
|
||||
|
||||
</Note>
|
||||
|
||||
- [`Customer` data model \<\> `AccountHolder` data model of Payment Module](#payment-module).
|
||||
- [`Cart` data model of Cart Module \<\> `Customer` data model](#cart-module). (Read-only).
|
||||
- [`Order` data model of Order Module \<\> `Customer` data model](#order-module). (Read-only).
|
||||
|
||||
---
|
||||
|
||||
## Payment Module
|
||||
|
||||
Medusa defines a link between the `Customer` and `AccountHolder` data models, allowing payment providers to save payment methods for a customer, if the payment provider supports it.
|
||||
|
||||
<Note>
|
||||
|
||||
This link is available starting from Medusa `v2.5.0`.
|
||||
|
||||
</Note>
|
||||
|
||||
### Retrieve with Query
|
||||
|
||||
To retrieve the account holder associated with a customer with [Query](!docs!/learn/fundamentals/module-links/query), pass `customer.*` in `fields`:
|
||||
|
||||
<CodeTabs group="relation-query">
|
||||
<CodeTab label="query.graph" value="method">
|
||||
|
||||
```ts
|
||||
const { data: customers } = await query.graph({
|
||||
entity: "customer",
|
||||
fields: [
|
||||
"account_holder.*",
|
||||
],
|
||||
})
|
||||
|
||||
// customers.account_holder
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="useQueryGraphStep" value="step">
|
||||
|
||||
```ts
|
||||
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
|
||||
|
||||
// ...
|
||||
|
||||
const { data: customers } = useQueryGraphStep({
|
||||
entity: "customer",
|
||||
fields: [
|
||||
"account_holder.*",
|
||||
],
|
||||
})
|
||||
|
||||
// customers.account_holder
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
### Manage with Link
|
||||
|
||||
To manage the account holders of a customer, use [Link](!docs!/learn/fundamentals/module-links/link):
|
||||
|
||||
<CodeTabs group="relation-link">
|
||||
<CodeTab label="link.create" value="method">
|
||||
|
||||
```ts
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
// ...
|
||||
|
||||
await link.create({
|
||||
[Modules.CUSTOMER]: {
|
||||
customer_id: "cus_123",
|
||||
},
|
||||
[Modules.PAYMENT]: {
|
||||
account_holder_id: "acchld_123",
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="createRemoteLinkStep" value="step">
|
||||
|
||||
```ts
|
||||
import { createRemoteLinkStep } from "@medusajs/medusa/core-flows"
|
||||
|
||||
// ...
|
||||
|
||||
createRemoteLinkStep({
|
||||
[Modules.CUSTOMER]: {
|
||||
customer_id: "cus_123",
|
||||
},
|
||||
[Modules.PAYMENT]: {
|
||||
account_holder_id: "acchld_123",
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
---
|
||||
|
||||
## Cart Module
|
||||
|
||||
Medusa defines a read-only link between the `Customer` data model and the [Cart Module](../../cart/page.mdx)'s `Cart` data model. This means you can retrieve the details of a customer's carts, but you don't manage the links in a pivot table in the database. The customer of a cart is determined by the `customer_id` property of the `Cart` data model.
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
export const metadata = {
|
||||
title: `Account Holders and Saved Payment Methods`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this documentation, you'll learn about account holders, and how they're used to save payment methods in third-party payment providers.
|
||||
|
||||
<Note>
|
||||
|
||||
Account holders are available starting from Medusa `v2.5.0`.
|
||||
|
||||
</Note>
|
||||
|
||||
## What's an Account Holder?
|
||||
|
||||
An account holder represents a customer that can have saved payment methods in a third-party service. It's represented by the `AccountHolder` data model.
|
||||
|
||||
It holds fields retrieved from the third-party provider, such as:
|
||||
|
||||
- `external_id`: The ID of the equivalent customer or account holder in the third-party provider.
|
||||
- `data`: Data returned by the payment provider when the account holder is created.
|
||||
|
||||
A payment provider that supports saving payment methods for customers would create the equivalent of an account holder in the third-party provider. Then, whenever a payment method is saved, it would be saved under the account holder in the third-party provider.
|
||||
|
||||
---
|
||||
|
||||
## Save Payment Methods
|
||||
|
||||
If a payment provider supports saving payment methods for a customer, they must implement the following methods:
|
||||
|
||||
- `createAccountHolder`: Creates an account holder in the payment provider. The Payment Module uses this method before creating the account holder in Medusa, and uses the returned data to set fields like `external_id` and `data` in the created `AccountHolder` record.
|
||||
- `deleteAccountHolder`: Deletes an account holder in the payment provider. The Payment Module uses this method when an account holder is deleted in Medusa.
|
||||
- `savePaymentMethod`: Saves a payment method for an account holder in the payment provider.
|
||||
- `listPaymentMethods`: Lists saved payment methods in the third-party service for an account holder. This is useful when displaying the customer's saved payment methods in the storefront.
|
||||
|
||||
Learn more about implementing these methods in the [Create Payment Provider guide](/references/payment/provider).
|
||||
|
||||
---
|
||||
|
||||
## Account Holder in Medusa Payment Flows
|
||||
|
||||
In the Medusa application, when a payment session is created for a registered customer, the Medusa application uses the Payment Module to create an account holder for the customer.
|
||||
|
||||
Consequently, the Payment Module uses the payment provider to create an account holder in the third-party service, then creates the account holder in Medusa.
|
||||
|
||||
This flow is only supported if the chosen payment provider has implemented the necessary [save payment methods](#save-payment-methods).
|
||||
@@ -13,6 +13,7 @@ This document showcases the module links defined between the Payment Module and
|
||||
The Payment Module has the following links to other modules:
|
||||
|
||||
- [`Cart` data model of Cart Module \<\> `PaymentCollection` data model](#cart-module).
|
||||
- [`Customer` data model of Customer Module \<\> `AccountHolder` data model](#customer-module).
|
||||
- [`Order` data model of Order Module \<\> `PaymentCollection` data model](#order-module).
|
||||
- [`OrderClaim` data model of Order Module \<\> `PaymentCollection` data model](#order-module).
|
||||
- [`OrderExchange` data model of Order Module \<\> `PaymentCollection` data model](#order-module).
|
||||
@@ -112,6 +113,100 @@ createRemoteLinkStep({
|
||||
|
||||
---
|
||||
|
||||
## Customer Module
|
||||
|
||||
Medusa defines a link between the `Customer` and `AccountHolder` data models, allowing payment providers to save payment methods for a customer, if the payment provider supports it.
|
||||
|
||||
<Note>
|
||||
|
||||
This link is available starting from Medusa `v2.5.0`.
|
||||
|
||||
</Note>
|
||||
|
||||
### Retrieve with Query
|
||||
|
||||
To retrieve the customer associated with an account holder with [Query](!docs!/learn/fundamentals/module-links/query), pass `customer.*` in `fields`:
|
||||
|
||||
<CodeTabs group="relation-query">
|
||||
<CodeTab label="query.graph" value="method">
|
||||
|
||||
```ts
|
||||
const { data: accountHolders } = await query.graph({
|
||||
entity: "account_holder",
|
||||
fields: [
|
||||
"customer.*",
|
||||
],
|
||||
})
|
||||
|
||||
// accountHolders.customer
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="useQueryGraphStep" value="step">
|
||||
|
||||
```ts
|
||||
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
|
||||
|
||||
// ...
|
||||
|
||||
const { data: accountHolders } = useQueryGraphStep({
|
||||
entity: "account_holder",
|
||||
fields: [
|
||||
"customer.*",
|
||||
],
|
||||
})
|
||||
|
||||
// accountHolders.customer
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
### Manage with Link
|
||||
|
||||
To manage the account holders of a customer, use [Link](!docs!/learn/fundamentals/module-links/link):
|
||||
|
||||
<CodeTabs group="relation-link">
|
||||
<CodeTab label="link.create" value="method">
|
||||
|
||||
```ts
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
// ...
|
||||
|
||||
await link.create({
|
||||
[Modules.CUSTOMER]: {
|
||||
customer_id: "cus_123",
|
||||
},
|
||||
[Modules.PAYMENT]: {
|
||||
account_holder_id: "acchld_123",
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="createRemoteLinkStep" value="step">
|
||||
|
||||
```ts
|
||||
import { createRemoteLinkStep } from "@medusajs/medusa/core-flows"
|
||||
|
||||
// ...
|
||||
|
||||
createRemoteLinkStep({
|
||||
[Modules.CUSTOMER]: {
|
||||
customer_id: "cus_123",
|
||||
},
|
||||
[Modules.PAYMENT]: {
|
||||
account_holder_id: "acchld_123",
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
---
|
||||
|
||||
## Order Module
|
||||
|
||||
An order's payment details are stored in a payment collection. This also applies for claims and exchanges.
|
||||
|
||||
@@ -21,6 +21,7 @@ Learn more about why modules are isolated in [this documentation](!docs!/learn/f
|
||||
- [Authorize, Capture, and Refund Payments](./payment/page.mdx): Authorize, capture, and refund payments for a single resource.
|
||||
- [Payment Collection Management](./payment-collection/page.mdx): Store and manage all payments of a single resources, such as a cart, in payment collections.
|
||||
- [Integrate Third-Party Payment Providers](./payment-provider/page.mdx): Use payment providers like [Stripe](./payment-provider/stripe/page.mdx) to handle and process payments, or integrate custom payment providers.
|
||||
- [Saved Payment Methods](./account-holder/page.mdx): Save payment methods for customers in third-party payment providers.
|
||||
- [Handle Webhook Events](./webhook-events/page.mdx): Handle webhook events from third-party providers and process the associated payment.
|
||||
|
||||
---
|
||||
|
||||
@@ -52,7 +52,7 @@ export const generatedEditDates = {
|
||||
"app/commerce-modules/payment/payment-provider/page.mdx": "2024-10-09T11:07:27.269Z",
|
||||
"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/page.mdx": "2025-01-16T10:33:31.791Z",
|
||||
"app/commerce-modules/payment/page.mdx": "2025-01-31T09:38:17.917Z",
|
||||
"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",
|
||||
"app/commerce-modules/pricing/concepts/page.mdx": "2024-10-09T13:37:25.678Z",
|
||||
@@ -2124,7 +2124,7 @@ export const generatedEditDates = {
|
||||
"app/commerce-modules/order/edit/page.mdx": "2024-10-09T08:50:05.334Z",
|
||||
"app/commerce-modules/order/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.604Z",
|
||||
"app/commerce-modules/order/order-change/page.mdx": "2024-10-09T09:59:40.745Z",
|
||||
"app/commerce-modules/payment/links-to-other-modules/page.mdx": "2025-01-06T11:19:35.593Z",
|
||||
"app/commerce-modules/payment/links-to-other-modules/page.mdx": "2025-01-31T09:22:05.326Z",
|
||||
"references/core_flows/Common/Steps_Common/functions/core_flows.Common.Steps_Common.useQueryGraphStep/page.mdx": "2025-01-13T17:30:23.157Z",
|
||||
"references/core_flows/Payment/Workflows_Payment/functions/core_flows.Payment.Workflows_Payment.processPaymentWorkflow/page.mdx": "2025-01-27T11:43:50.940Z",
|
||||
"references/helper_steps/functions/helper_steps.useQueryGraphStep/page.mdx": "2025-01-17T16:43:22.242Z",
|
||||
@@ -5737,7 +5737,7 @@ export const generatedEditDates = {
|
||||
"app/commerce-modules/tax/admin-widget-zones/page.mdx": "2024-12-24T08:47:13.176Z",
|
||||
"app/commerce-modules/user/admin-widget-zones/page.mdx": "2024-12-24T08:48:14.186Z",
|
||||
"app/commerce-modules/currency/links-to-other-modules/page.mdx": "2024-12-24T14:47:10.556Z",
|
||||
"app/commerce-modules/customer/links-to-other-modules/page.mdx": "2024-12-24T14:48:54.689Z",
|
||||
"app/commerce-modules/customer/links-to-other-modules/page.mdx": "2025-01-31T09:26:54.541Z",
|
||||
"app/commerce-modules/fulfillment/events/page.mdx": "2024-12-31T09:37:49.253Z",
|
||||
"app/commerce-modules/payment/events/page.mdx": "2024-12-31T09:41:56.582Z",
|
||||
"references/core_flows/Payment/Steps_Payment/functions/core_flows.Payment.Steps_Payment.refundPaymentsStep/page.mdx": "2025-01-27T11:43:50.929Z",
|
||||
@@ -5902,6 +5902,7 @@ export const generatedEditDates = {
|
||||
"references/types/HttpTypes/interfaces/types.HttpTypes.StoreProductTypeResponse/page.mdx": "2025-01-27T11:43:54.212Z",
|
||||
"references/types/interfaces/types.BaseProductTypeListParams/page.mdx": "2025-01-27T11:43:54.550Z",
|
||||
"references/core_flows/Order/Steps_Order/variables/core_flows.Order.Steps_Order.updateOrderChangesStepId/page.mdx": "2025-01-27T11:43:49.278Z",
|
||||
"app/commerce-modules/payment/account-holder/page.mdx": "2025-01-31T09:37:41.595Z",
|
||||
"app/troubleshooting/test-errors/page.mdx": "2025-01-31T13:08:42.639Z",
|
||||
"app/commerce-modules/product/variant-inventory/page.mdx": "2025-02-03T12:19:45.706Z",
|
||||
"app/examples/guides/custom-item-price/page.mdx": "2025-02-07T09:21:11.170Z"
|
||||
|
||||
@@ -431,6 +431,10 @@ export const filesMap = [
|
||||
"filePath": "/www/apps/resources/app/commerce-modules/page.mdx",
|
||||
"pathname": "/commerce-modules"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/commerce-modules/payment/account-holder/page.mdx",
|
||||
"pathname": "/commerce-modules/payment/account-holder"
|
||||
},
|
||||
{
|
||||
"filePath": "/www/apps/resources/app/commerce-modules/payment/events/page.mdx",
|
||||
"pathname": "/commerce-modules/payment/events"
|
||||
|
||||
@@ -8369,6 +8369,14 @@ export const generatedSidebar = [
|
||||
"title": "Payment Provider Module",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
"type": "link",
|
||||
"path": "/commerce-modules/payment/account-holder",
|
||||
"title": "Account Holder",
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"loaded": true,
|
||||
"isPathHref": true,
|
||||
|
||||
@@ -43,6 +43,11 @@ export const paymentSidebar = [
|
||||
path: "/commerce-modules/payment/payment-provider",
|
||||
title: "Payment Provider Module",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/commerce-modules/payment/account-holder",
|
||||
title: "Account Holder",
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
path: "/commerce-modules/payment/webhook-events",
|
||||
|
||||
Reference in New Issue
Block a user