@medusajs/payment 2.22.0-snapshot-20261020204851 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +67 -0
- package/README.md +106 -2
- package/package.json +8 -4
package/AGENTS.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @medusajs/payment
|
|
2
|
+
|
|
3
|
+
Payment Module (`Modules.PAYMENT`): payment collections, sessions, payments, captures and refunds, with the provider-specific work delegated to payment providers (Stripe lives in `packages/modules/providers/payment-stripe`).
|
|
4
|
+
|
|
5
|
+
## Using this package
|
|
6
|
+
|
|
7
|
+
- Registered by default as `@medusajs/medusa/payment`; it always registers the system provider (`pp_system_default`, no external calls).
|
|
8
|
+
- Options (`PaymentModuleOptions` in `src/types/index.ts`): `providers[]` of `{ resolve, id, options? }`. `packages/core/types/src/payment/service.ts` also types `webhook_delay` and `webhook_retries`. A private `cloud` object (`api_key`, `endpoint`, `webhook_secret`, `payment_accounts`, `environment_handle` / `sandbox_handle`) is injected by `defineConfig` on Medusa Cloud.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
module.exports = defineConfig({
|
|
12
|
+
modules: [
|
|
13
|
+
{
|
|
14
|
+
resolve: "@medusajs/medusa/payment",
|
|
15
|
+
options: {
|
|
16
|
+
providers: [
|
|
17
|
+
{
|
|
18
|
+
resolve: "@medusajs/medusa/payment-stripe",
|
|
19
|
+
id: "stripe",
|
|
20
|
+
options: { apiKey: process.env.STRIPE_API_KEY },
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- Provider IDs stored and used as `provider_id` are `pp_<identifier>_<id>` (e.g. `pp_stripe_stripe`). A provider class without a static `identifier` throws on registration.
|
|
30
|
+
- Resolve: `container.resolve(Modules.PAYMENT)` (`IPaymentModuleService`). Checkout and order payment flows should use `@medusajs/core-flows` workflows (`createPaymentSessionsWorkflow`, `capturePaymentWorkflow`, `refundPaymentWorkflow`, `processPaymentWorkflow`).
|
|
31
|
+
|
|
32
|
+
**Data models** (`src/models`): `PaymentCollection` (`pay_col_`, `amount`, `authorized_amount`, `captured_amount`, `refunded_amount`, `status`, many-to-many `payment_providers`) -> `PaymentSession` (`payses_`, `status`, `data`, `context`, `authorized_at`) -> `Payment` (`pay_`, `captured_at`, `canceled_at`) -> `Capture` (`capt_`) / `Refund` (`ref_`, `status`, `idempotency_key`, optional `RefundReason`). `AccountHolder` (`acchld_`, unique per `provider_id` + `external_id`) stores a customer's account at a provider. `PaymentProvider` (`id`, `is_enabled`). `PaymentMethod` is not a table: `listPaymentMethods` / `createPaymentMethods` proxy to the provider.
|
|
33
|
+
|
|
34
|
+
**Custom service methods** (`src/services/payment-module.ts`): `createPaymentSession`, `updatePaymentSession`, `deletePaymentSession`, `authorizePaymentSession`, `capturePayment`, `refundPayment`, `cancelPayment`, `updatePayment`, `completePaymentCollections`, `create/update/deleteAccountHolder`, `list[AndCount]PaymentMethods`, `createPaymentMethods`, `deletePaymentMethods`, `list[AndCount]PaymentProviders`, `getWebhookActionAndData`.
|
|
35
|
+
|
|
36
|
+
**Events**: `PaymentEvents.CAPTURED` (`payment.captured`) and `PaymentEvents.REFUNDED` (`payment.refunded`) are emitted by core-flows; `POST /hooks/payment/:provider` (`packages/medusa/src/api/hooks/payment/[provider]/route.ts`) emits `payment.webhook_received` (5s delay, 3 attempts by default), handled through `getWebhookActionAndData` + `processPaymentWorkflow`.
|
|
37
|
+
|
|
38
|
+
**Module links** (in `packages/modules/link-modules`): `cart_payment_collection`, `order_payment_collection` (deleting the order cascades to the collection), `region_payment_provider`, `customer_account_holder`. `order_claim_payment_collection` / `order_exchange_payment_collection` definitions exist but are not exported, so they are not loaded.
|
|
39
|
+
|
|
40
|
+
Docs: https://docs.medusajs.com/resources/commerce-modules/payment.md, https://docs.medusajs.com/resources/commerce-modules/payment/module-options.md, https://docs.medusajs.com/resources/commerce-modules/payment/payment-flow.md, https://docs.medusajs.com/resources/commerce-modules/payment/payment-session.md, https://docs.medusajs.com/resources/commerce-modules/payment/payment-provider.md, https://docs.medusajs.com/resources/commerce-modules/payment/webhook-events.md, https://docs.medusajs.com/resources/commerce-modules/payment/account-holder.md
|
|
41
|
+
|
|
42
|
+
## Architecture
|
|
43
|
+
|
|
44
|
+
- `src/loaders/providers.ts`: registers the system provider (`id: "default"`), one Medusa Payments provider (`src/providers/payment-medusa`) per `cloud.payment_accounts` entry when all cloud options are set, then configured providers as `pp_<identifier>_<id>`; upserts all registered IDs into `payment_provider` with `is_enabled: true`.
|
|
45
|
+
- `src/services/payment-provider.ts` resolves `pp_*` from the container and calls the `AbstractPaymentProvider` methods.
|
|
46
|
+
|
|
47
|
+
## Development
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd packages/modules/payment
|
|
51
|
+
yarn build
|
|
52
|
+
yarn test
|
|
53
|
+
yarn test:integration # needs Postgres
|
|
54
|
+
../../../node_modules/.bin/jest integration-tests/__tests__/services/payment-module/index.spec.ts -t "refund"
|
|
55
|
+
yarn migration:create # after any change in src/models
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- Integration tests: `integration-tests/__tests__/services/payment-module/` (`index.spec.ts`, `medusa-payments.ts`) and `integration-tests/__tests__/loaders/providers.spec.ts`.
|
|
59
|
+
|
|
60
|
+
## Gotchas
|
|
61
|
+
|
|
62
|
+
- `createPaymentSession` creates the row, then calls the provider with `session_id` in `data` and `idempotency_key` = session ID; on failure it deletes the provider session and the row.
|
|
63
|
+
- `authorizePaymentSession` is idempotent (returns the existing payment if `authorized_at` is set); returns `null` for `pending` authorization; throws `NOT_ALLOWED` for other non-authorized statuses; a provider `captured` status creates the payment and captures it immediately.
|
|
64
|
+
- `capturePayment` / `refundPayment` lock the payment row (`FOR UPDATE`) and throw `UNEXPECTED_STATE` if not run inside a transaction. Amounts must be > 0; refunds cannot exceed captured minus refunded (within currency epsilon); capture of a canceled payment throws.
|
|
65
|
+
- Refund `idempotency_key`: same key + same amount replays a succeeded refund or retries a failed one, different amount throws, a recent `pending` one throws `CONFLICT` (a stale pending one is retried). Failed provider refunds are marked `failed` and soft-deleted.
|
|
66
|
+
- Providers removed from config are not disabled: the loader only lists rows whose IDs are currently registered, so stale `payment_provider` rows keep their `is_enabled` value.
|
|
67
|
+
- `getWebhookActionAndData` prefixes `pp_` to `provider` if missing.
|
package/README.md
CHANGED
|
@@ -1,3 +1,107 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://www.medusajs.com">
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
|
|
6
|
+
<img alt="Medusa logo" src="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
|
|
7
|
+
</picture>
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
<h1 align="center">
|
|
11
|
+
@medusajs/payment
|
|
12
|
+
</h1>
|
|
2
13
|
|
|
3
|
-
|
|
14
|
+
<h4 align="center">
|
|
15
|
+
<a href="https://docs.medusajs.com">Documentation</a> |
|
|
16
|
+
<a href="https://www.medusajs.com">Website</a>
|
|
17
|
+
</h4>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
Building blocks for digital commerce
|
|
21
|
+
</p>
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="https://github.com/medusajs/medusa/blob/develop/LICENSE">
|
|
24
|
+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Medusa is released under the MIT license." />
|
|
25
|
+
</a>
|
|
26
|
+
<a href="https://github.com/medusajs/medusa/blob/develop/CONTRIBUTING.md">
|
|
27
|
+
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
|
|
28
|
+
</a>
|
|
29
|
+
<a href="https://discord.gg/xpCwq3Kfn8">
|
|
30
|
+
<img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
|
|
31
|
+
</a>
|
|
32
|
+
<a href="https://twitter.com/intent/follow?screen_name=medusajs">
|
|
33
|
+
<img src="https://img.shields.io/twitter/follow/medusajs.svg?label=Follow%20@medusajs" alt="Follow @medusajs" />
|
|
34
|
+
</a>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
Payment Module for Medusa: manages payment collections, payment sessions, payments, captures, refunds, refund reasons, account holders, and payment providers. Use it to process payments for carts, orders, or any resource through pluggable payment providers. It ships with `@medusajs/medusa` and is registered by default, so Medusa applications don't install it directly.
|
|
38
|
+
|
|
39
|
+
## At a glance
|
|
40
|
+
|
|
41
|
+
| | |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| Package | `@medusajs/payment` |
|
|
44
|
+
| Type | Commerce Module |
|
|
45
|
+
| Module key | `Modules.PAYMENT` (`"payment"`) |
|
|
46
|
+
| Registered by default | Yes |
|
|
47
|
+
| Import from | `@medusajs/medusa/payment` |
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- Group payment sessions and payments for a resource in a payment collection.
|
|
52
|
+
- Authorize, capture, and refund payments, with refund reasons.
|
|
53
|
+
- Store account holders to save customers' payment methods with a provider.
|
|
54
|
+
- Handle provider webhook events.
|
|
55
|
+
|
|
56
|
+
## Payment providers
|
|
57
|
+
|
|
58
|
+
The module delegates payment processing to Payment Module Providers, registered through the `providers` option. A system provider (`pp_system_default`) is always registered for manual payments.
|
|
59
|
+
|
|
60
|
+
Official providers in this repository:
|
|
61
|
+
|
|
62
|
+
- [`@medusajs/payment-stripe`](../providers/payment-stripe) (Stripe)
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
No installation needed. The module is included in `@medusajs/medusa` and registered by default.
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
Register payment providers in `medusa-config.ts`:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { defineConfig } from "@medusajs/framework/utils"
|
|
74
|
+
|
|
75
|
+
module.exports = defineConfig({
|
|
76
|
+
// ...
|
|
77
|
+
modules: [
|
|
78
|
+
{
|
|
79
|
+
resolve: "@medusajs/medusa/payment",
|
|
80
|
+
options: {
|
|
81
|
+
providers: [
|
|
82
|
+
{
|
|
83
|
+
resolve: "@medusajs/medusa/payment-stripe",
|
|
84
|
+
id: "stripe",
|
|
85
|
+
options: {
|
|
86
|
+
apiKey: process.env.STRIPE_API_KEY,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
| Option | Type | Description | Default |
|
|
99
|
+
| --- | --- | --- | --- |
|
|
100
|
+
| `providers` | `{ resolve: string, id: string, options?: Record<string, unknown> }[]` | Payment Module Providers to register. | `[]` |
|
|
101
|
+
|
|
102
|
+
## Resources
|
|
103
|
+
|
|
104
|
+
- [Payment Module](https://docs.medusajs.com/resources/commerce-modules/payment)
|
|
105
|
+
- [Payment Module options](https://docs.medusajs.com/resources/commerce-modules/payment/module-options)
|
|
106
|
+
- [Payment Module Providers](https://docs.medusajs.com/resources/commerce-modules/payment/payment-provider)
|
|
107
|
+
- [Stripe Module Provider](https://docs.medusajs.com/resources/commerce-modules/payment/payment-provider/stripe)
|
package/package.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medusajs/payment",
|
|
3
|
-
"version": "2.22.0
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"description": "Medusa Payment module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
9
|
+
"AGENTS.md",
|
|
9
10
|
"!dist/**/__tests__",
|
|
10
11
|
"!dist/**/__mocks__",
|
|
11
12
|
"!dist/**/__fixtures__"
|
|
12
13
|
],
|
|
14
|
+
"llms": "https://docs.medusajs.com/llms.txt",
|
|
15
|
+
"llmsFull": "https://docs.medusajs.com/llms-full.txt",
|
|
16
|
+
"mcpServer": "https://docs.medusajs.com/mcp",
|
|
13
17
|
"engines": {
|
|
14
18
|
"node": ">=22.22.0"
|
|
15
19
|
},
|
|
@@ -39,11 +43,11 @@
|
|
|
39
43
|
"orm:cache:clear": "MIKRO_ORM_CLI_CONFIG=./mikro-orm.config.dev.ts MIKRO_ORM_ALLOW_GLOBAL_CLI=true medusa-mikro-orm cache:clear"
|
|
40
44
|
},
|
|
41
45
|
"devDependencies": {
|
|
42
|
-
"@medusajs/framework": "2.22.0
|
|
43
|
-
"@medusajs/test-utils": "2.22.0
|
|
46
|
+
"@medusajs/framework": "2.22.0",
|
|
47
|
+
"@medusajs/test-utils": "2.22.0"
|
|
44
48
|
},
|
|
45
49
|
"peerDependencies": {
|
|
46
|
-
"@medusajs/framework": "2.22.0
|
|
50
|
+
"@medusajs/framework": "2.22.0"
|
|
47
51
|
},
|
|
48
52
|
"dependencies": {
|
|
49
53
|
"stripe": "19.1.0"
|