@medusajs/payment-adyen 0.0.0-stage → 2.22.2
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 +66 -0
- package/README.md +128 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/services/adyen-provider.d.ts +50 -0
- package/dist/services/adyen-provider.d.ts.map +1 -0
- package/dist/services/adyen-provider.js +515 -0
- package/dist/services/adyen-provider.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +9 -0
- package/dist/services/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/index.d.ts +69 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/amounts.d.ts +5 -0
- package/dist/utils/amounts.d.ts.map +1 -0
- package/dist/utils/amounts.js +54 -0
- package/dist/utils/amounts.js.map +1 -0
- package/package.json +45 -4
package/AGENTS.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# @medusajs/payment-adyen
|
|
2
|
+
|
|
3
|
+
Payment Module provider for Adyen, built on the Checkout API Advanced flow (`/paymentMethods`, `/payments`, `/payments/details`). Supports cards with 3D Secure.
|
|
4
|
+
|
|
5
|
+
## Using this package
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
module.exports = defineConfig({
|
|
9
|
+
modules: [
|
|
10
|
+
{
|
|
11
|
+
resolve: "@medusajs/medusa/payment",
|
|
12
|
+
options: {
|
|
13
|
+
providers: [
|
|
14
|
+
{
|
|
15
|
+
resolve: "@medusajs/medusa/payment-adyen",
|
|
16
|
+
id: "adyen",
|
|
17
|
+
options: {
|
|
18
|
+
apiKey: process.env.ADYEN_API_KEY,
|
|
19
|
+
merchantAccount: process.env.ADYEN_MERCHANT_ACCOUNT,
|
|
20
|
+
hmacKey: process.env.ADYEN_WEBHOOK_HMAC_KEY,
|
|
21
|
+
returnUrl: process.env.ADYEN_RETURN_URL,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- Options (`AdyenOptions` in `src/types/index.ts`): `apiKey` and `merchantAccount` (required), `hmacKey`, `environment` (`TEST` or `LIVE`, default `TEST`), `liveEndpointUrlPrefix` (required in `LIVE`), `capture` (default `false` = manual capture), `returnUrl`.
|
|
32
|
+
- Provider ID is `pp_adyen_{id}`. Register one instance per merchant account, for example `id: "eu"` and `id: "us"`.
|
|
33
|
+
- Webhooks: point a standard Adyen webhook at `{server_url}/hooks/payment/adyen_{id}`.
|
|
34
|
+
- The storefront passes Drop-in's `paymentMethod`, `browserInfo`, and `details` through `sdk.store.payment.updatePaymentSession` as `client_data.payment_method`, `client_data.browser_info`, and `client_data.details`, then completes the cart. `client_data.origin` and `client_data.return_url` are optional.
|
|
35
|
+
- Docs: https://docs.medusajs.com/resources/commerce-modules/payment/payment-session.md
|
|
36
|
+
- Build a custom payment provider: https://docs.medusajs.com/resources/references/payment/provider.md
|
|
37
|
+
|
|
38
|
+
## Architecture
|
|
39
|
+
|
|
40
|
+
- `src/services/adyen-provider.ts`: `AdyenProviderService` (identifier `adyen`) with all logic.
|
|
41
|
+
- `initiatePayment` calls `/paymentMethods` and stores the response in `data.payment_methods` for Drop-in.
|
|
42
|
+
- `authorizePayment` submits `data.client.details` to `/payments/details`, or `data.client.payment_method` to `/payments`, then nulls them in the session.
|
|
43
|
+
- Capture, refund, and cancel use the Modifications API with the idempotency key Medusa passes in `context`.
|
|
44
|
+
- Account holders use the customer ID as Adyen's `shopperReference`, with no Adyen call. `initiatePayment` stores it in `data.shopper_reference` and sends it to `/paymentMethods`, which returns the shopper's saved cards.
|
|
45
|
+
- Saved cards: `/payments` sends `storePaymentMethod` when `data.client.store_payment_method` is set, and `listPaymentMethods`, `savePaymentMethod`, and `deletePaymentMethod` use the Checkout `/storedPaymentMethods` endpoints.
|
|
46
|
+
- `src/utils/amounts.ts`: converts Medusa's major units with Adyen's currency exponents, which differ from ISO 4217 for some currencies.
|
|
47
|
+
|
|
48
|
+
## Development
|
|
49
|
+
|
|
50
|
+
- `yarn build`, `yarn test` (unit tests in `src/services/__tests__` and `src/utils/__tests__`, with the Adyen client mocked).
|
|
51
|
+
|
|
52
|
+
## Gotchas
|
|
53
|
+
|
|
54
|
+
- `data.client` is written by the storefront, so amounts, currency, references, and the payment state are read only from provider-owned keys. `initiatePayment` sets all of them explicitly so data passed when initializing the session can't take their place.
|
|
55
|
+
- Adyen has no API to retrieve a payment, so `getPaymentStatus` and `retrievePayment` return the last stored state.
|
|
56
|
+
- Captures, refunds, and cancellations are confirmed asynchronously by webhooks, but Medusa records them when it requests them. Failed captures and refunds (`CAPTURE_FAILED`, `REFUND_FAILED`) are only logged.
|
|
57
|
+
- `CAPTURE` and `REFUND` webhooks return `NOT_SUPPORTED`, so captures and refunds made in the Customer Area aren't synced to Medusa.
|
|
58
|
+
- With `capture: true`, an authorized payment returns `captured`, and `cancelPayment` reverses (refunds) it instead of canceling. Each `/payments` request sets `captureDelayHours: 0` or `manualCapture`, as the merchant account's capture delay can't be relied on.
|
|
59
|
+
- Medusa doesn't pass the capture amount to providers, so the first capture captures the full amount at Adyen. Later partial captures in Medusa only record the amount and don't call Adyen.
|
|
60
|
+
- `/payments` idempotency keys are `{session_id}-{attempt}`, and `updatePayment` increments `attempt` whenever the storefront submits a payment method. Retrying the same submission is safe, and resubmitting the same card (for example, a saved card without a CVC) after a refusal is a new payment.
|
|
61
|
+
- Only cards (`scheme`), Apple Pay (`applepay`), and Google Pay (`googlepay`) are offered by `/paymentMethods` and accepted by `/payments`. Redirect and asynchronous methods could authorize without the storefront's details call, which the provider can't reconcile yet.
|
|
62
|
+
- `data.payment_methods` (the `/paymentMethods` response) is cleared once the payment is authorized, so it isn't copied into the payment's data.
|
|
63
|
+
- Async payment methods that are only confirmed by the `AUTHORISATION` webhook aren't supported yet.
|
|
64
|
+
- Saved cards are only used and stored with the provider-set `data.shopper_reference`, never one from `data.client`, so shoppers can't reach each other's cards (Adyen rejects another shopper's token with `Contract not found`). Guests get no `shopperReference`, so `store_payment_method` is ignored for them.
|
|
65
|
+
- `savePaymentMethod` (`POST /storedPaymentMethods`) needs the "API tokenise payment details" credential role and a `holderName` in the payment method. Storing a card during a payment only needs the "Merchant Recurring" role.
|
|
66
|
+
- `/payments` and modification requests send a hard-coded `applicationInfo.externalPlatform` (`APPLICATION_INFO` in `src/services/adyen-provider.ts`) that Adyen uses to attribute payments to Medusa for partner revenue sharing. Adyen matches the exact name, so don't change it or make it configurable.
|
package/README.md
CHANGED
|
@@ -1,3 +1,129 @@
|
|
|
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-adyen
|
|
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
|
+
Adyen Payment Module Provider for Medusa: processes card payments, including 3D Secure, with Adyen's Checkout API (Advanced flow). Use it with Adyen's Drop-in or Components in your storefront. It ships with `@medusajs/medusa` and is registered through the `@medusajs/medusa/payment-adyen` path.
|
|
38
|
+
|
|
39
|
+
## At a glance
|
|
40
|
+
|
|
41
|
+
| | |
|
|
42
|
+
| --------------------- | --------------------------------------------- |
|
|
43
|
+
| Package | `@medusajs/payment-adyen` |
|
|
44
|
+
| Type | Module Provider (Payment Module) |
|
|
45
|
+
| Provider ID | `pp_adyen_{id}`, for example `pp_adyen_adyen` |
|
|
46
|
+
| Registered by default | No |
|
|
47
|
+
| Import from | `@medusajs/medusa/payment-adyen` |
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
No installation needed. The provider is a dependency of `@medusajs/medusa`.
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
Register the provider in the Payment Module's `providers` array in `medusa-config.ts`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { defineConfig } from "@medusajs/framework/utils"
|
|
59
|
+
|
|
60
|
+
module.exports = defineConfig({
|
|
61
|
+
// ...
|
|
62
|
+
modules: [
|
|
63
|
+
{
|
|
64
|
+
resolve: "@medusajs/medusa/payment",
|
|
65
|
+
options: {
|
|
66
|
+
providers: [
|
|
67
|
+
{
|
|
68
|
+
resolve: "@medusajs/medusa/payment-adyen",
|
|
69
|
+
id: "adyen",
|
|
70
|
+
options: {
|
|
71
|
+
apiKey: process.env.ADYEN_API_KEY,
|
|
72
|
+
merchantAccount: process.env.ADYEN_MERCHANT_ACCOUNT,
|
|
73
|
+
hmacKey: process.env.ADYEN_WEBHOOK_HMAC_KEY,
|
|
74
|
+
returnUrl: process.env.ADYEN_RETURN_URL,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then enable the provider in a region, for example from the Medusa Admin.
|
|
85
|
+
|
|
86
|
+
In the Adyen Customer Area, create a standard webhook pointing to `{server_url}/hooks/payment/{provider_id}`, where `{provider_id}` is the registered ID without the `pp_` prefix, such as `adyen_adyen`. Generate its HMAC key and set it as `hmacKey`.
|
|
87
|
+
|
|
88
|
+
### Storefront flow
|
|
89
|
+
|
|
90
|
+
1. Initialize a payment session with the provider. The session's `data.payment_methods` holds the response of Adyen's `/paymentMethods`, which you pass to Drop-in.
|
|
91
|
+
2. In Drop-in's `onSubmit`, pass `state.data.paymentMethod` and `state.data.browserInfo` to the session with `sdk.store.payment.updatePaymentSession`, as `client_data.payment_method` and `client_data.browser_info`. Optionally pass `origin` and `return_url`.
|
|
92
|
+
3. Complete the cart. If the session's status is `requires_more`, pass its `data.action` to Drop-in.
|
|
93
|
+
4. In Drop-in's `onAdditionalDetails`, pass `state.data.details` as `client_data.details`, then complete the cart again.
|
|
94
|
+
|
|
95
|
+
If a payment is refused, the session's status is `error`. Pass a new `client_data.payment_method` to the same session to retry.
|
|
96
|
+
|
|
97
|
+
### Saved cards
|
|
98
|
+
|
|
99
|
+
For logged-in customers, the customer's account holder ID is sent to Adyen as the `shopperReference`:
|
|
100
|
+
|
|
101
|
+
- `data.payment_methods.storedPaymentMethods` lists the customer's saved cards, which Drop-in shows. Paying with one works like any other payment method.
|
|
102
|
+
- To save the card used in a payment, pass Drop-in's `state.data.storePaymentMethod` as `client_data.store_payment_method`. Enable Drop-in's `enableStoreDetails` option to show the checkbox.
|
|
103
|
+
- The Payment Module's `listPaymentMethods`, `createPaymentMethods`, and `deletePaymentMethods` methods list, save, and delete the customer's saved cards. Saving a card without a payment takes Drop-in's `state.data.paymentMethod`, including a `holderName`, as `data.payment_method`, and requires the "API tokenise payment details" role on your API credential.
|
|
104
|
+
- Deleting the account holder deletes the customer's saved cards.
|
|
105
|
+
|
|
106
|
+
### Limitations
|
|
107
|
+
|
|
108
|
+
- Only cards (including 3D Secure), Apple Pay, and Google Pay are supported, so Drop-in only shows these even if other payment methods are enabled on your merchant account. Payment methods that redirect the shopper or are confirmed asynchronously by webhook, such as iDEAL, PayPal, or bank transfers, aren't supported yet.
|
|
109
|
+
- Captures, refunds, and cancellations are recorded in Medusa when they're requested. Adyen confirms them asynchronously, and failures (for example, a refund rejected for insufficient funds) are only logged.
|
|
110
|
+
- Medusa doesn't pass capture amounts to providers, so the first capture captures the full authorized amount.
|
|
111
|
+
- Captures and refunds made in the Adyen Customer Area aren't synced to Medusa.
|
|
112
|
+
|
|
113
|
+
## Configuration
|
|
114
|
+
|
|
115
|
+
| Option | Type | Description | Default |
|
|
116
|
+
| ----------------------- | ------------------ | ------------------------------------------------------------------------------------------ | -------- |
|
|
117
|
+
| `apiKey` | `string` | Required. The API key of your Adyen API credential. | - |
|
|
118
|
+
| `merchantAccount` | `string` | Required. The merchant account to process payments with. | - |
|
|
119
|
+
| `hmacKey` | `string` | The HMAC key of the standard webhook. Webhooks are rejected without it. | - |
|
|
120
|
+
| `environment` | `"TEST" \| "LIVE"` | The Adyen environment. | `"TEST"` |
|
|
121
|
+
| `liveEndpointUrlPrefix` | `string` | Required in `LIVE`. Find it in the Customer Area under Developers > API URLs. | - |
|
|
122
|
+
| `capture` | `boolean` | Capture payments immediately instead of only authorizing them. | `false` |
|
|
123
|
+
| `returnUrl` | `string` | The URL to return shoppers to after a redirect, unless the storefront passes `return_url`. | - |
|
|
124
|
+
|
|
125
|
+
## Resources
|
|
126
|
+
|
|
127
|
+
- [Payment Module Provider](https://docs.medusajs.com/resources/commerce-modules/payment/payment-provider)
|
|
128
|
+
- [Payment Session](https://docs.medusajs.com/resources/commerce-modules/payment/payment-session)
|
|
129
|
+
- [Payment Module](https://docs.medusajs.com/resources/commerce-modules/payment)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAKA,wBAEE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
4
|
+
const services_1 = require("./services");
|
|
5
|
+
const services = [services_1.AdyenProviderService];
|
|
6
|
+
exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.PAYMENT, {
|
|
7
|
+
services,
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qDAAmE;AACnE,yCAAiD;AAEjD,MAAM,QAAQ,GAAG,CAAC,+BAAoB,CAAC,CAAA;AAEvC,kBAAe,IAAA,sBAAc,EAAC,eAAO,CAAC,OAAO,EAAE;IAC7C,QAAQ;CACT,CAAC,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { CheckoutAPI, hmacValidator, Types } from "@adyen/api-library";
|
|
2
|
+
import { AuthorizePaymentInput, AuthorizePaymentOutput, CancelPaymentInput, CancelPaymentOutput, CapturePaymentInput, CapturePaymentOutput, CreateAccountHolderInput, CreateAccountHolderOutput, DeleteAccountHolderInput, DeleteAccountHolderOutput, DeletePaymentInput, DeletePaymentOutput, GetPaymentStatusInput, GetPaymentStatusOutput, DeletePaymentMethodInput, DeletePaymentMethodOutput, InitiatePaymentInput, InitiatePaymentOutput, ListPaymentMethodsInput, ListPaymentMethodsOutput, Logger, ProviderWebhookPayload, RefundPaymentInput, RefundPaymentOutput, RetrieveAccountHolderInput, RetrieveAccountHolderOutput, RetrievePaymentInput, RetrievePaymentOutput, SavePaymentMethodInput, SavePaymentMethodOutput, UpdateAccountHolderInput, UpdateAccountHolderOutput, UpdatePaymentInput, UpdatePaymentOutput, WebhookActionResult } from "@medusajs/framework/types";
|
|
3
|
+
import { AbstractPaymentProvider, PaymentSessionStatus } from "@medusajs/framework/utils";
|
|
4
|
+
import { AdyenClientData, AdyenOptions, AdyenSessionData } from "../types";
|
|
5
|
+
type AccountHolderContext = {
|
|
6
|
+
account_holder?: {
|
|
7
|
+
data?: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
type InjectedDependencies = {
|
|
11
|
+
logger: Logger;
|
|
12
|
+
};
|
|
13
|
+
declare class AdyenProviderService extends AbstractPaymentProvider<AdyenOptions> {
|
|
14
|
+
static identifier: string;
|
|
15
|
+
protected readonly options_: AdyenOptions;
|
|
16
|
+
protected readonly logger_: Logger;
|
|
17
|
+
protected readonly checkout_: CheckoutAPI;
|
|
18
|
+
protected readonly hmacValidator_: hmacValidator;
|
|
19
|
+
static validateOptions(options: Record<string, unknown>): void;
|
|
20
|
+
constructor(container: InjectedDependencies, options: AdyenOptions);
|
|
21
|
+
initiatePayment({ amount, currency_code, data, context, }: InitiatePaymentInput): Promise<InitiatePaymentOutput>;
|
|
22
|
+
updatePayment({ amount, currency_code, data, }: UpdatePaymentInput): Promise<UpdatePaymentOutput>;
|
|
23
|
+
authorizePayment({ data, }: AuthorizePaymentInput): Promise<AuthorizePaymentOutput>;
|
|
24
|
+
getPaymentStatus({ data, }: GetPaymentStatusInput): Promise<GetPaymentStatusOutput>;
|
|
25
|
+
retrievePayment({ data, }: RetrievePaymentInput): Promise<RetrievePaymentOutput>;
|
|
26
|
+
capturePayment({ data, context, }: CapturePaymentInput): Promise<CapturePaymentOutput>;
|
|
27
|
+
refundPayment({ amount, data, context, }: RefundPaymentInput): Promise<RefundPaymentOutput>;
|
|
28
|
+
cancelPayment({ data, context, }: CancelPaymentInput): Promise<CancelPaymentOutput>;
|
|
29
|
+
deletePayment({ data, context, }: DeletePaymentInput): Promise<DeletePaymentOutput>;
|
|
30
|
+
createAccountHolder({ context, }: CreateAccountHolderInput): Promise<CreateAccountHolderOutput>;
|
|
31
|
+
retrieveAccountHolder({ id, }: RetrieveAccountHolderInput): Promise<RetrieveAccountHolderOutput>;
|
|
32
|
+
updateAccountHolder(_: UpdateAccountHolderInput): Promise<UpdateAccountHolderOutput>;
|
|
33
|
+
deleteAccountHolder({ context, }: DeleteAccountHolderInput): Promise<DeleteAccountHolderOutput>;
|
|
34
|
+
listPaymentMethods({ context, }: ListPaymentMethodsInput): Promise<ListPaymentMethodsOutput>;
|
|
35
|
+
savePaymentMethod({ data, context, }: SavePaymentMethodInput): Promise<SavePaymentMethodOutput>;
|
|
36
|
+
deletePaymentMethod({ data, context, }: DeletePaymentMethodInput): Promise<DeletePaymentMethodOutput>;
|
|
37
|
+
protected listStoredPaymentMethods(shopperReference: string): Promise<Types.checkout.StoredPaymentMethodResource[]>;
|
|
38
|
+
protected deleteStoredPaymentMethod(id: string, shopperReference: string): Promise<void>;
|
|
39
|
+
getWebhookActionAndData({ data, }: ProviderWebhookPayload["payload"]): Promise<WebhookActionResult>;
|
|
40
|
+
protected isValidNotification(item?: Types.notification.NotificationRequestItem): boolean;
|
|
41
|
+
protected buildPaymentRequest(session: AdyenSessionData, client: AdyenClientData): Types.checkout.PaymentRequest;
|
|
42
|
+
protected getStatus(session: AdyenSessionData): PaymentSessionStatus;
|
|
43
|
+
protected getAuthorizedStatus(session: AdyenSessionData): PaymentSessionStatus.AUTHORIZED | PaymentSessionStatus.CAPTURED;
|
|
44
|
+
protected getShopperReference(context?: AccountHolderContext): string | undefined;
|
|
45
|
+
protected requireShopperReference(context?: AccountHolderContext): string;
|
|
46
|
+
protected getPspReference(session: AdyenSessionData): string;
|
|
47
|
+
protected request<T>(operation: string, fn: () => Promise<T>): Promise<T>;
|
|
48
|
+
}
|
|
49
|
+
export default AdyenProviderService;
|
|
50
|
+
//# sourceMappingURL=adyen-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adyen-provider.d.ts","sourceRoot":"","sources":["../../src/services/adyen-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
7
|
+
const api_library_1 = require("@adyen/api-library");
|
|
8
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
9
|
+
const amounts_1 = require("../utils/amounts");
|
|
10
|
+
const ResultCode = api_library_1.Types.checkout.PaymentResponse.ResultCodeEnum;
|
|
11
|
+
// Cards and wallets return their result to the storefront's request. Methods
|
|
12
|
+
// that complete through a redirect or are confirmed asynchronously need the
|
|
13
|
+
// webhook to authorize the session.
|
|
14
|
+
// TODO: support them once webhook results can be stored on the session.
|
|
15
|
+
const SUPPORTED_PAYMENT_METHODS = ["scheme", "applepay", "googlepay"];
|
|
16
|
+
const CARD_ON_FILE = api_library_1.Types.checkout.PaymentRequest.RecurringProcessingModelEnum.CardOnFile;
|
|
17
|
+
const EventCode = api_library_1.Types.notification.NotificationRequestItem.EventCodeEnum;
|
|
18
|
+
// Identifies payments processed through Medusa to Adyen, for partner revenue
|
|
19
|
+
// sharing. Adyen matches on the exact name, so it must not change.
|
|
20
|
+
const APPLICATION_INFO = {
|
|
21
|
+
externalPlatform: { name: "Medusa", integrator: "medusajs" },
|
|
22
|
+
};
|
|
23
|
+
const SESSION_ID_PREFIX = "payses_";
|
|
24
|
+
const MAX_IDEMPOTENCY_KEY_LENGTH = 64;
|
|
25
|
+
const hash = (value) => crypto_1.default.createHash("sha256").update(JSON.stringify(value)).digest("hex");
|
|
26
|
+
// Adyen limits idempotency keys to 64 characters.
|
|
27
|
+
const toIdempotencyKey = (key) => {
|
|
28
|
+
if (!key || key.length <= MAX_IDEMPOTENCY_KEY_LENGTH) {
|
|
29
|
+
return key;
|
|
30
|
+
}
|
|
31
|
+
return hash(key);
|
|
32
|
+
};
|
|
33
|
+
class AdyenProviderService extends utils_1.AbstractPaymentProvider {
|
|
34
|
+
static validateOptions(options) {
|
|
35
|
+
for (const key of ["apiKey", "merchantAccount"]) {
|
|
36
|
+
if (!options[key]) {
|
|
37
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Required option \`${key}\` is missing in the Adyen payment provider`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (options.environment === "LIVE" && !options.liveEndpointUrlPrefix) {
|
|
41
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Option `liveEndpointUrlPrefix` is required when `environment` is `LIVE` in the Adyen payment provider");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
constructor(container, options) {
|
|
45
|
+
super(container, options);
|
|
46
|
+
this.hmacValidator_ = new api_library_1.hmacValidator();
|
|
47
|
+
this.options_ = options;
|
|
48
|
+
this.logger_ = container.logger;
|
|
49
|
+
this.checkout_ = new api_library_1.CheckoutAPI(new api_library_1.Client({
|
|
50
|
+
apiKey: options.apiKey,
|
|
51
|
+
environment: options.environment === "LIVE"
|
|
52
|
+
? api_library_1.EnvironmentEnum.LIVE
|
|
53
|
+
: api_library_1.EnvironmentEnum.TEST,
|
|
54
|
+
liveEndpointUrlPrefix: options.liveEndpointUrlPrefix,
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
async initiatePayment({ amount, currency_code, data, context, }) {
|
|
58
|
+
const sessionId = data?.session_id;
|
|
59
|
+
const currency = currency_code.toUpperCase();
|
|
60
|
+
const value = (0, amounts_1.toMinorUnits)(amount, currency);
|
|
61
|
+
const countryCode = data?.country_code ??
|
|
62
|
+
context?.customer?.billing_address?.country_code ??
|
|
63
|
+
undefined;
|
|
64
|
+
const shopperReference = this.getShopperReference(context);
|
|
65
|
+
// With a shopper reference, the response includes the shopper's saved
|
|
66
|
+
// cards in `storedPaymentMethods`, which Drop-in renders.
|
|
67
|
+
const paymentMethods = await this.request("initiatePayment", () => this.checkout_.PaymentsApi.paymentMethods({
|
|
68
|
+
merchantAccount: this.options_.merchantAccount,
|
|
69
|
+
amount: { currency, value },
|
|
70
|
+
countryCode: countryCode?.toUpperCase(),
|
|
71
|
+
channel: api_library_1.Types.checkout.PaymentMethodsRequest.ChannelEnum.Web,
|
|
72
|
+
shopperReference,
|
|
73
|
+
allowedPaymentMethods: SUPPORTED_PAYMENT_METHODS,
|
|
74
|
+
}));
|
|
75
|
+
// Every provider-owned key is set explicitly, so data that the storefront
|
|
76
|
+
// passed when initializing the session can't take their place.
|
|
77
|
+
const sessionData = {
|
|
78
|
+
session_id: sessionId,
|
|
79
|
+
amount: value,
|
|
80
|
+
currency,
|
|
81
|
+
capture: !!this.options_.capture,
|
|
82
|
+
shopper_email: context?.customer?.email ?? null,
|
|
83
|
+
shopper_reference: shopperReference ?? null,
|
|
84
|
+
payment_methods: paymentMethods,
|
|
85
|
+
psp_reference: null,
|
|
86
|
+
capture_psp_reference: null,
|
|
87
|
+
attempt: 0,
|
|
88
|
+
result_code: null,
|
|
89
|
+
action: null,
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
id: sessionId,
|
|
93
|
+
status: utils_1.PaymentSessionStatus.PENDING,
|
|
94
|
+
data: sessionData,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async updatePayment({ amount, currency_code, data, }) {
|
|
98
|
+
const session = data;
|
|
99
|
+
const currency = currency_code.toUpperCase();
|
|
100
|
+
const updated = {
|
|
101
|
+
...data,
|
|
102
|
+
amount: (0, amounts_1.toMinorUnits)(amount, currency),
|
|
103
|
+
currency,
|
|
104
|
+
};
|
|
105
|
+
// A new payment method after a refusal or an abandoned action starts a new
|
|
106
|
+
// attempt. Carts can't be completed with a session in the `error` status.
|
|
107
|
+
if (session.client?.payment_method &&
|
|
108
|
+
session.result_code !== ResultCode.Authorised) {
|
|
109
|
+
return {
|
|
110
|
+
status: utils_1.PaymentSessionStatus.PENDING,
|
|
111
|
+
data: {
|
|
112
|
+
...updated,
|
|
113
|
+
attempt: (session.attempt ?? 0) + 1,
|
|
114
|
+
psp_reference: null,
|
|
115
|
+
result_code: null,
|
|
116
|
+
action: null,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { data: updated };
|
|
121
|
+
}
|
|
122
|
+
async authorizePayment({ data, }) {
|
|
123
|
+
const session = data;
|
|
124
|
+
const client = session.client ?? {};
|
|
125
|
+
if (session.result_code === ResultCode.Authorised) {
|
|
126
|
+
return { status: this.getAuthorizedStatus(session), data };
|
|
127
|
+
}
|
|
128
|
+
let response;
|
|
129
|
+
if (client.details) {
|
|
130
|
+
const request = {
|
|
131
|
+
details: client.details,
|
|
132
|
+
};
|
|
133
|
+
const paymentData = session.action
|
|
134
|
+
?.paymentData;
|
|
135
|
+
if (paymentData) {
|
|
136
|
+
request.paymentData = paymentData;
|
|
137
|
+
}
|
|
138
|
+
response = await this.request("authorizePayment", () => this.checkout_.PaymentsApi.paymentsDetails(request, {
|
|
139
|
+
idempotencyKey: toIdempotencyKey(`${session.session_id}-${hash(client.details).slice(0, 16)}`),
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
else if (client.payment_method) {
|
|
143
|
+
const request = this.buildPaymentRequest(session, client);
|
|
144
|
+
// Keyed on the submission, so retrying it is safe while a new submission
|
|
145
|
+
// (for example, after a refusal) is a new payment, even with the same card.
|
|
146
|
+
response = await this.request("authorizePayment", () => this.checkout_.PaymentsApi.payments(request, {
|
|
147
|
+
idempotencyKey: toIdempotencyKey(`${session.session_id}-${session.attempt ?? 0}`),
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Nothing was submitted, for example when a webhook authorizes the session.
|
|
152
|
+
return { status: this.getStatus(session), data };
|
|
153
|
+
}
|
|
154
|
+
if (response.resultCode !== ResultCode.Authorised) {
|
|
155
|
+
this.logger_.info(`Adyen payment for session ${session.session_id} returned ${response.resultCode}${response.refusalReason ? `: ${response.refusalReason}` : ""}`);
|
|
156
|
+
}
|
|
157
|
+
const action = "action" in response && response.action ? response.action : null;
|
|
158
|
+
const isAuthorised = response.resultCode === ResultCode.Authorised;
|
|
159
|
+
const updated = {
|
|
160
|
+
...session,
|
|
161
|
+
psp_reference: response.pspReference ?? session.psp_reference,
|
|
162
|
+
result_code: response.resultCode ?? null,
|
|
163
|
+
action,
|
|
164
|
+
// Kept until authorization so the storefront can render Drop-in again,
|
|
165
|
+
// but not copied into the payment's data.
|
|
166
|
+
payment_methods: isAuthorised ? null : session.payment_methods,
|
|
167
|
+
// Don't retain the shopper's payment details once they're submitted.
|
|
168
|
+
client: {
|
|
169
|
+
...client,
|
|
170
|
+
payment_method: null,
|
|
171
|
+
browser_info: null,
|
|
172
|
+
details: null,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
return {
|
|
176
|
+
status: this.getStatus(updated),
|
|
177
|
+
data: updated,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
async getPaymentStatus({ data, }) {
|
|
181
|
+
return {
|
|
182
|
+
status: this.getStatus(data),
|
|
183
|
+
data,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
async retrievePayment({ data, }) {
|
|
187
|
+
// Adyen has no API to retrieve a payment, so the stored data is the latest known state.
|
|
188
|
+
return { data };
|
|
189
|
+
}
|
|
190
|
+
async capturePayment({ data, context, }) {
|
|
191
|
+
const session = data;
|
|
192
|
+
// Medusa doesn't pass the capture amount to providers, so the first capture
|
|
193
|
+
// is always for the full amount and later partial captures only record it.
|
|
194
|
+
// TODO: capture the requested amount once Medusa passes it.
|
|
195
|
+
if (session.capture || session.capture_psp_reference) {
|
|
196
|
+
return { data };
|
|
197
|
+
}
|
|
198
|
+
const pspReference = this.getPspReference(session);
|
|
199
|
+
// Adyen confirms the capture asynchronously with a CAPTURE webhook.
|
|
200
|
+
// TODO: reflect captures that later fail (CAPTURE_FAILED) in Medusa.
|
|
201
|
+
const response = await this.request("capturePayment", () => this.checkout_.ModificationsApi.captureAuthorisedPayment(pspReference, {
|
|
202
|
+
merchantAccount: this.options_.merchantAccount,
|
|
203
|
+
amount: { currency: session.currency, value: session.amount },
|
|
204
|
+
reference: session.session_id,
|
|
205
|
+
applicationInfo: APPLICATION_INFO,
|
|
206
|
+
}, { idempotencyKey: toIdempotencyKey(context?.idempotency_key) }));
|
|
207
|
+
return {
|
|
208
|
+
data: { ...data, capture_psp_reference: response.pspReference },
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
async refundPayment({ amount, data, context, }) {
|
|
212
|
+
const session = data;
|
|
213
|
+
const pspReference = this.getPspReference(session);
|
|
214
|
+
// Adyen confirms the refund asynchronously with a REFUND webhook.
|
|
215
|
+
// TODO: reflect refunds that later fail (REFUND_FAILED) in Medusa.
|
|
216
|
+
await this.request("refundPayment", () => this.checkout_.ModificationsApi.refundCapturedPayment(pspReference, {
|
|
217
|
+
merchantAccount: this.options_.merchantAccount,
|
|
218
|
+
amount: {
|
|
219
|
+
currency: session.currency,
|
|
220
|
+
value: (0, amounts_1.toMinorUnits)(amount, session.currency),
|
|
221
|
+
},
|
|
222
|
+
reference: session.session_id,
|
|
223
|
+
applicationInfo: APPLICATION_INFO,
|
|
224
|
+
}, { idempotencyKey: toIdempotencyKey(context?.idempotency_key) }));
|
|
225
|
+
return { data };
|
|
226
|
+
}
|
|
227
|
+
async cancelPayment({ data, context, }) {
|
|
228
|
+
const session = data;
|
|
229
|
+
if (!session.psp_reference ||
|
|
230
|
+
session.result_code !== ResultCode.Authorised) {
|
|
231
|
+
return { data };
|
|
232
|
+
}
|
|
233
|
+
const request = {
|
|
234
|
+
merchantAccount: this.options_.merchantAccount,
|
|
235
|
+
reference: session.session_id,
|
|
236
|
+
applicationInfo: APPLICATION_INFO,
|
|
237
|
+
};
|
|
238
|
+
const options = {
|
|
239
|
+
idempotencyKey: toIdempotencyKey(context?.idempotency_key),
|
|
240
|
+
};
|
|
241
|
+
// Auto-captured payments can't be canceled, only reversed (refunded).
|
|
242
|
+
await this.request("cancelPayment", () => session.capture
|
|
243
|
+
? this.checkout_.ModificationsApi.refundOrCancelPayment(session.psp_reference, request, options)
|
|
244
|
+
: this.checkout_.ModificationsApi.cancelAuthorisedPaymentByPspReference(session.psp_reference, request, options));
|
|
245
|
+
return { data };
|
|
246
|
+
}
|
|
247
|
+
async deletePayment({ data, context, }) {
|
|
248
|
+
const session = data;
|
|
249
|
+
// Release an authorization that will never be used. Auto-captured payments
|
|
250
|
+
// aren't refunded here, as deleting a session shouldn't move money.
|
|
251
|
+
if (!session?.capture) {
|
|
252
|
+
return await this.cancelPayment({ data, context });
|
|
253
|
+
}
|
|
254
|
+
return { data };
|
|
255
|
+
}
|
|
256
|
+
// Adyen has no shopper object: the `shopperReference` sent with payments is
|
|
257
|
+
// the account holder's ID.
|
|
258
|
+
async createAccountHolder({ context, }) {
|
|
259
|
+
const { account_holder, customer } = context;
|
|
260
|
+
if (account_holder?.data?.id) {
|
|
261
|
+
return { id: account_holder.data.id };
|
|
262
|
+
}
|
|
263
|
+
return { id: customer.id, data: { id: customer.id } };
|
|
264
|
+
}
|
|
265
|
+
async retrieveAccountHolder({ id, }) {
|
|
266
|
+
return { id, data: { id } };
|
|
267
|
+
}
|
|
268
|
+
async updateAccountHolder(_) {
|
|
269
|
+
return {};
|
|
270
|
+
}
|
|
271
|
+
// Deleting the account holder also deletes the shopper's saved cards, as
|
|
272
|
+
// nothing could use them afterwards.
|
|
273
|
+
async deleteAccountHolder({ context, }) {
|
|
274
|
+
const shopperReference = this.getShopperReference(context);
|
|
275
|
+
if (!shopperReference) {
|
|
276
|
+
return {};
|
|
277
|
+
}
|
|
278
|
+
// The account holder is already deleted in Medusa, so every card is
|
|
279
|
+
// attempted rather than stopping at the first failure.
|
|
280
|
+
const paymentMethods = await this.listStoredPaymentMethods(shopperReference);
|
|
281
|
+
const results = await Promise.allSettled(paymentMethods.map((paymentMethod) => this.deleteStoredPaymentMethod(paymentMethod.id, shopperReference)));
|
|
282
|
+
const failed = results.filter((result) => result.status === "rejected");
|
|
283
|
+
if (failed.length) {
|
|
284
|
+
this.logger_.error(`Adyen failed to delete ${failed.length} of ${paymentMethods.length} saved cards of shopper ${shopperReference}`);
|
|
285
|
+
}
|
|
286
|
+
return {};
|
|
287
|
+
}
|
|
288
|
+
async listPaymentMethods({ context, }) {
|
|
289
|
+
const shopperReference = this.getShopperReference(context);
|
|
290
|
+
if (!shopperReference) {
|
|
291
|
+
return [];
|
|
292
|
+
}
|
|
293
|
+
const paymentMethods = await this.listStoredPaymentMethods(shopperReference);
|
|
294
|
+
return paymentMethods.map((paymentMethod) => ({
|
|
295
|
+
id: paymentMethod.id,
|
|
296
|
+
data: paymentMethod,
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
// Stores the card that Drop-in collected, passed as `data.payment_method`,
|
|
300
|
+
// without making a payment.
|
|
301
|
+
async savePaymentMethod({ data, context, }) {
|
|
302
|
+
const shopperReference = this.requireShopperReference(context);
|
|
303
|
+
const paymentMethod = await this.request("savePaymentMethod", () => this.checkout_.RecurringApi.storedPaymentMethods({
|
|
304
|
+
merchantAccount: this.options_.merchantAccount,
|
|
305
|
+
shopperReference,
|
|
306
|
+
paymentMethod: data?.payment_method,
|
|
307
|
+
recurringProcessingModel: api_library_1.Types.checkout.StoredPaymentMethodRequest
|
|
308
|
+
.RecurringProcessingModelEnum.CardOnFile,
|
|
309
|
+
shopperEmail: context?.customer?.email,
|
|
310
|
+
}, { idempotencyKey: toIdempotencyKey(context?.idempotency_key) }));
|
|
311
|
+
return {
|
|
312
|
+
id: paymentMethod.id,
|
|
313
|
+
data: paymentMethod,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
async deletePaymentMethod({ data, context, }) {
|
|
317
|
+
await this.deleteStoredPaymentMethod(data.id, this.requireShopperReference(context));
|
|
318
|
+
return {};
|
|
319
|
+
}
|
|
320
|
+
async listStoredPaymentMethods(shopperReference) {
|
|
321
|
+
const response = await this.request("listPaymentMethods", () => this.checkout_.RecurringApi.getTokensForStoredPaymentDetails(shopperReference, this.options_.merchantAccount));
|
|
322
|
+
return response.storedPaymentMethods ?? [];
|
|
323
|
+
}
|
|
324
|
+
async deleteStoredPaymentMethod(id, shopperReference) {
|
|
325
|
+
await this.request("deletePaymentMethod", () => this.checkout_.RecurringApi.deleteTokenForStoredPaymentDetails(id, shopperReference, this.options_.merchantAccount));
|
|
326
|
+
}
|
|
327
|
+
async getWebhookActionAndData({ data, }) {
|
|
328
|
+
const notSupported = { action: utils_1.PaymentActions.NOT_SUPPORTED };
|
|
329
|
+
const items = (data?.notificationItems ?? [])
|
|
330
|
+
.map((item) => item.NotificationRequestItem)
|
|
331
|
+
.filter((item) => this.isValidNotification(item));
|
|
332
|
+
// Adyen sends a single item per JSON webhook, and the webhook route handles
|
|
333
|
+
// one action per request.
|
|
334
|
+
if (items.length > 1) {
|
|
335
|
+
this.logger_.warn(`Adyen webhook contained ${items.length} notifications, only the first is processed`);
|
|
336
|
+
}
|
|
337
|
+
const item = items[0];
|
|
338
|
+
if (!item) {
|
|
339
|
+
return notSupported;
|
|
340
|
+
}
|
|
341
|
+
const succeeded = item.success === "true";
|
|
342
|
+
const { value = 0, currency } = item.amount ?? {};
|
|
343
|
+
const result = {
|
|
344
|
+
session_id: item.merchantReference,
|
|
345
|
+
amount: currency ? (0, amounts_1.fromMinorUnits)(value, currency) : 0,
|
|
346
|
+
};
|
|
347
|
+
switch (item.eventCode) {
|
|
348
|
+
case EventCode.Authorisation:
|
|
349
|
+
if (!succeeded) {
|
|
350
|
+
return { action: utils_1.PaymentActions.FAILED, data: result };
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
action: this.options_.capture
|
|
354
|
+
? utils_1.PaymentActions.SUCCESSFUL
|
|
355
|
+
: utils_1.PaymentActions.AUTHORIZED,
|
|
356
|
+
data: result,
|
|
357
|
+
};
|
|
358
|
+
case EventCode.Cancellation:
|
|
359
|
+
return succeeded
|
|
360
|
+
? { action: utils_1.PaymentActions.CANCELED, data: result }
|
|
361
|
+
: notSupported;
|
|
362
|
+
case EventCode.Capture:
|
|
363
|
+
case EventCode.Refund:
|
|
364
|
+
if (!succeeded) {
|
|
365
|
+
// TODO: reflect failed captures and refunds in Medusa.
|
|
366
|
+
this.logger_.error(`Adyen ${item.eventCode} for session ${item.merchantReference} failed: ${item.reason}`);
|
|
367
|
+
}
|
|
368
|
+
// Captures and refunds are already recorded when Medusa requests them.
|
|
369
|
+
// TODO: sync captures and refunds made outside of Medusa, such as in the Customer Area.
|
|
370
|
+
return notSupported;
|
|
371
|
+
case EventCode.CaptureFailed:
|
|
372
|
+
case EventCode.RefundFailed:
|
|
373
|
+
// TODO: reflect failed captures and refunds in Medusa.
|
|
374
|
+
this.logger_.error(`Adyen ${item.eventCode} for session ${item.merchantReference}: ${item.reason}`);
|
|
375
|
+
return notSupported;
|
|
376
|
+
default:
|
|
377
|
+
return notSupported;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
isValidNotification(item) {
|
|
381
|
+
if (!item) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
if (!this.options_.hmacKey) {
|
|
385
|
+
this.logger_.warn("Adyen webhook rejected because the `hmacKey` option isn't set");
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
let isValid = false;
|
|
389
|
+
try {
|
|
390
|
+
isValid = this.hmacValidator_.validateHMAC(item, this.options_.hmacKey);
|
|
391
|
+
}
|
|
392
|
+
catch { }
|
|
393
|
+
if (!isValid) {
|
|
394
|
+
this.logger_.warn(`Adyen webhook for ${item.pspReference} rejected because of an invalid HMAC signature`);
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
// A webhook endpoint can be shared by merchant accounts and integrations,
|
|
398
|
+
// so only notifications for payment sessions of this account are handled.
|
|
399
|
+
return (item.merchantAccountCode === this.options_.merchantAccount &&
|
|
400
|
+
!!item.merchantReference?.startsWith(SESSION_ID_PREFIX));
|
|
401
|
+
}
|
|
402
|
+
buildPaymentRequest(session, client) {
|
|
403
|
+
const paymentMethodType = client.payment_method?.type;
|
|
404
|
+
if (paymentMethodType &&
|
|
405
|
+
!SUPPORTED_PAYMENT_METHODS.includes(paymentMethodType)) {
|
|
406
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Adyen payment method ${paymentMethodType} isn't supported`);
|
|
407
|
+
}
|
|
408
|
+
const returnUrl = client.return_url ?? this.options_.returnUrl;
|
|
409
|
+
if (!returnUrl) {
|
|
410
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Adyen requires a return URL. Set the `returnUrl` option or pass `return_url` in the payment session's client data.");
|
|
411
|
+
}
|
|
412
|
+
const shopperReference = session.shopper_reference ?? undefined;
|
|
413
|
+
const isStoredPaymentMethod = !!client.payment_method.storedPaymentMethodId;
|
|
414
|
+
// Saved cards are tied to the shopper reference set by the provider, so a
|
|
415
|
+
// shopper can't pay with or save to another shopper's cards.
|
|
416
|
+
const storePaymentMethod = !!shopperReference && !!client.store_payment_method;
|
|
417
|
+
return {
|
|
418
|
+
merchantAccount: this.options_.merchantAccount,
|
|
419
|
+
amount: { currency: session.currency, value: session.amount },
|
|
420
|
+
reference: session.session_id,
|
|
421
|
+
shopperReference,
|
|
422
|
+
...(storePaymentMethod ? { storePaymentMethod: true } : {}),
|
|
423
|
+
...(storePaymentMethod || isStoredPaymentMethod
|
|
424
|
+
? { recurringProcessingModel: CARD_ON_FILE }
|
|
425
|
+
: {}),
|
|
426
|
+
paymentMethod: client.payment_method,
|
|
427
|
+
browserInfo: client.browser_info ?? undefined,
|
|
428
|
+
origin: client.origin ?? undefined,
|
|
429
|
+
returnUrl,
|
|
430
|
+
shopperEmail: session.shopper_email ?? undefined,
|
|
431
|
+
channel: api_library_1.Types.checkout.PaymentRequest.ChannelEnum.Web,
|
|
432
|
+
shopperInteraction: api_library_1.Types.checkout.PaymentRequest.ShopperInteractionEnum.Ecommerce,
|
|
433
|
+
authenticationData: {
|
|
434
|
+
threeDSRequestData: {
|
|
435
|
+
nativeThreeDS: api_library_1.Types.checkout.ThreeDSRequestData.NativeThreeDSEnum.Preferred,
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
// Both override the merchant account's capture delay, which Medusa can't
|
|
439
|
+
// rely on: it records the payment as captured when `capture` is enabled.
|
|
440
|
+
...(session.capture
|
|
441
|
+
? { captureDelayHours: 0 }
|
|
442
|
+
: { additionalData: { manualCapture: "true" } }),
|
|
443
|
+
applicationInfo: APPLICATION_INFO,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
getStatus(session) {
|
|
447
|
+
switch (session.result_code) {
|
|
448
|
+
case ResultCode.Authorised:
|
|
449
|
+
return this.getAuthorizedStatus(session);
|
|
450
|
+
case ResultCode.RedirectShopper:
|
|
451
|
+
case ResultCode.ChallengeShopper:
|
|
452
|
+
case ResultCode.IdentifyShopper:
|
|
453
|
+
return utils_1.PaymentSessionStatus.REQUIRES_MORE;
|
|
454
|
+
case ResultCode.Cancelled:
|
|
455
|
+
return utils_1.PaymentSessionStatus.CANCELED;
|
|
456
|
+
case ResultCode.Refused:
|
|
457
|
+
case ResultCode.Error:
|
|
458
|
+
case ResultCode.PartiallyAuthorised:
|
|
459
|
+
return utils_1.PaymentSessionStatus.ERROR;
|
|
460
|
+
default:
|
|
461
|
+
return utils_1.PaymentSessionStatus.PENDING;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
getAuthorizedStatus(session) {
|
|
465
|
+
return session.capture
|
|
466
|
+
? utils_1.PaymentSessionStatus.CAPTURED
|
|
467
|
+
: utils_1.PaymentSessionStatus.AUTHORIZED;
|
|
468
|
+
}
|
|
469
|
+
getShopperReference(context) {
|
|
470
|
+
return context?.account_holder?.data?.id;
|
|
471
|
+
}
|
|
472
|
+
requireShopperReference(context) {
|
|
473
|
+
const shopperReference = this.getShopperReference(context);
|
|
474
|
+
if (!shopperReference) {
|
|
475
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Adyen saved payment methods require an account holder");
|
|
476
|
+
}
|
|
477
|
+
return shopperReference;
|
|
478
|
+
}
|
|
479
|
+
getPspReference(session) {
|
|
480
|
+
if (!session.psp_reference) {
|
|
481
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Adyen payment for session ${session.session_id} has no PSP reference`);
|
|
482
|
+
}
|
|
483
|
+
return session.psp_reference;
|
|
484
|
+
}
|
|
485
|
+
// Adyen's error details are logged, not returned, as provider errors can
|
|
486
|
+
// reach the storefront.
|
|
487
|
+
async request(operation, fn) {
|
|
488
|
+
try {
|
|
489
|
+
return await fn();
|
|
490
|
+
}
|
|
491
|
+
catch (error) {
|
|
492
|
+
const { statusCode, errorCode, responseBody, message } = error;
|
|
493
|
+
this.logger_.error(`Adyen ${operation} failed: ${[
|
|
494
|
+
statusCode,
|
|
495
|
+
errorCode,
|
|
496
|
+
message,
|
|
497
|
+
responseBody,
|
|
498
|
+
]
|
|
499
|
+
.filter(Boolean)
|
|
500
|
+
.join(" | ")}`);
|
|
501
|
+
// Validation errors (for example, invalid payment details) are the
|
|
502
|
+
// shopper's to fix, while authentication and server errors aren't.
|
|
503
|
+
const isValidationError = !!statusCode &&
|
|
504
|
+
statusCode >= 400 &&
|
|
505
|
+
statusCode < 500 &&
|
|
506
|
+
![401, 403].includes(statusCode);
|
|
507
|
+
throw new utils_1.MedusaError(isValidationError
|
|
508
|
+
? utils_1.MedusaError.Types.INVALID_DATA
|
|
509
|
+
: utils_1.MedusaError.Types.UNEXPECTED_STATE, `An error occurred in ${operation} with Adyen`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
AdyenProviderService.identifier = "adyen";
|
|
514
|
+
exports.default = AdyenProviderService;
|
|
515
|
+
//# sourceMappingURL=adyen-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adyen-provider.js","sourceRoot":"","sources":["../../src/services/adyen-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AdyenProviderService = void 0;
|
|
7
|
+
var adyen_provider_1 = require("./adyen-provider");
|
|
8
|
+
Object.defineProperty(exports, "AdyenProviderService", { enumerable: true, get: function () { return __importDefault(adyen_provider_1).default; } });
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":";;;;;;AAAA,mDAAkE;AAAzD,uIAAA,OAAO,OAAwB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/index.ts","../src/services/adyen-provider.ts","../src/services/index.ts","../src/services/__tests__/adyen-provider.spec.ts","../src/types/index.ts","../src/utils/amounts.ts","../src/utils/__tests__/amounts.spec.ts"],"version":"5.9.3"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Types } from "@adyen/api-library";
|
|
2
|
+
export type AdyenEnvironment = "TEST" | "LIVE";
|
|
3
|
+
export interface AdyenOptions {
|
|
4
|
+
apiKey: string;
|
|
5
|
+
merchantAccount: string;
|
|
6
|
+
/**
|
|
7
|
+
* The HMAC key of the standard webhook. Webhooks are rejected without it.
|
|
8
|
+
*/
|
|
9
|
+
hmacKey?: string;
|
|
10
|
+
/**
|
|
11
|
+
* @defaultValue "TEST"
|
|
12
|
+
*/
|
|
13
|
+
environment?: AdyenEnvironment;
|
|
14
|
+
/**
|
|
15
|
+
* Required when `environment` is `LIVE`. Find it in the Customer Area under Developers > API URLs.
|
|
16
|
+
*/
|
|
17
|
+
liveEndpointUrlPrefix?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Whether to capture payments immediately after authorization.
|
|
20
|
+
*
|
|
21
|
+
* @defaultValue false
|
|
22
|
+
*/
|
|
23
|
+
capture?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The URL to return the shopper to after a redirect, used when the
|
|
26
|
+
* storefront doesn't pass `return_url` in the session's `data.client`.
|
|
27
|
+
*/
|
|
28
|
+
returnUrl?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Data the storefront passes in the session's `data.client`. Treated as untrusted.
|
|
32
|
+
*/
|
|
33
|
+
export interface AdyenClientData {
|
|
34
|
+
payment_method?: Types.checkout.PaymentRequest["paymentMethod"] | null;
|
|
35
|
+
browser_info?: Types.checkout.BrowserInfo | null;
|
|
36
|
+
details?: Types.checkout.PaymentCompletionDetails | null;
|
|
37
|
+
origin?: string | null;
|
|
38
|
+
return_url?: string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Whether to save the card for future payments, from Drop-in's `state.data.storePaymentMethod`.
|
|
41
|
+
* Only applies to customers with an account holder.
|
|
42
|
+
*/
|
|
43
|
+
store_payment_method?: boolean | null;
|
|
44
|
+
}
|
|
45
|
+
export interface AdyenSessionData {
|
|
46
|
+
session_id: string;
|
|
47
|
+
/**
|
|
48
|
+
* The amount in minor units.
|
|
49
|
+
*/
|
|
50
|
+
amount: number;
|
|
51
|
+
currency: string;
|
|
52
|
+
capture: boolean;
|
|
53
|
+
shopper_email?: string | null;
|
|
54
|
+
/**
|
|
55
|
+
* The account holder's ID, which Adyen uses to store and look up saved cards.
|
|
56
|
+
*/
|
|
57
|
+
shopper_reference?: string | null;
|
|
58
|
+
payment_methods?: Types.checkout.PaymentMethodsResponse | null;
|
|
59
|
+
psp_reference: string | null;
|
|
60
|
+
capture_psp_reference: string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Incremented for every payment method the storefront submits, to key `/payments` requests.
|
|
63
|
+
*/
|
|
64
|
+
attempt: number;
|
|
65
|
+
result_code: string | null;
|
|
66
|
+
action: Types.checkout.PaymentResponseAction | null;
|
|
67
|
+
client?: AdyenClientData;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE1C,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,CAAA;AAE9C,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,GAAG,IAAI,CAAA;IACtE,YAAY,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAA;IAChD,OAAO,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,wBAAwB,GAAG,IAAI,CAAA;IACxD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,eAAe,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,sBAAsB,GAAG,IAAI,CAAA;IAC9D,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,qBAAqB,GAAG,IAAI,CAAA;IACnD,MAAM,CAAC,EAAE,eAAe,CAAA;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BigNumberInput } from "@medusajs/framework/types";
|
|
2
|
+
export declare function getCurrencyExponent(currency: string): number;
|
|
3
|
+
export declare function toMinorUnits(amount: BigNumberInput, currency: string): number;
|
|
4
|
+
export declare function fromMinorUnits(amount: number, currency: string): number;
|
|
5
|
+
//# sourceMappingURL=amounts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amounts.d.ts","sourceRoot":"","sources":["../../src/utils/amounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAkC1D,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY5D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI7E;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIvE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCurrencyExponent = getCurrencyExponent;
|
|
4
|
+
exports.toMinorUnits = toMinorUnits;
|
|
5
|
+
exports.fromMinorUnits = fromMinorUnits;
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
7
|
+
// Adyen's own exponents, which differ from ISO 4217 for some currencies
|
|
8
|
+
// (for example, CLP and ISK have 2 decimals and IDR has 0).
|
|
9
|
+
// https://docs.adyen.com/development-resources/currency-codes
|
|
10
|
+
const ZERO_DECIMAL_CURRENCIES = new Set([
|
|
11
|
+
"CVE",
|
|
12
|
+
"DJF",
|
|
13
|
+
"GNF",
|
|
14
|
+
"IDR",
|
|
15
|
+
"JPY",
|
|
16
|
+
"KMF",
|
|
17
|
+
"KRW",
|
|
18
|
+
"PYG",
|
|
19
|
+
"RWF",
|
|
20
|
+
"UGX",
|
|
21
|
+
"VND",
|
|
22
|
+
"VUV",
|
|
23
|
+
"XAF",
|
|
24
|
+
"XOF",
|
|
25
|
+
"XPF",
|
|
26
|
+
]);
|
|
27
|
+
const THREE_DECIMAL_CURRENCIES = new Set([
|
|
28
|
+
"BHD",
|
|
29
|
+
"IQD",
|
|
30
|
+
"JOD",
|
|
31
|
+
"KWD",
|
|
32
|
+
"LYD",
|
|
33
|
+
"OMR",
|
|
34
|
+
"TND",
|
|
35
|
+
]);
|
|
36
|
+
function getCurrencyExponent(currency) {
|
|
37
|
+
const code = currency.toUpperCase();
|
|
38
|
+
if (ZERO_DECIMAL_CURRENCIES.has(code)) {
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
if (THREE_DECIMAL_CURRENCIES.has(code)) {
|
|
42
|
+
return 3;
|
|
43
|
+
}
|
|
44
|
+
return 2;
|
|
45
|
+
}
|
|
46
|
+
function toMinorUnits(amount, currency) {
|
|
47
|
+
const multiplier = 10 ** getCurrencyExponent(currency);
|
|
48
|
+
return utils_1.MathBN.convert(utils_1.MathBN.mult(amount, multiplier), 0).toNumber();
|
|
49
|
+
}
|
|
50
|
+
function fromMinorUnits(amount, currency) {
|
|
51
|
+
const multiplier = 10 ** getCurrencyExponent(currency);
|
|
52
|
+
return utils_1.MathBN.div(amount, multiplier).toNumber();
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=amounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amounts.js","sourceRoot":"","sources":["../../src/utils/amounts.ts"],"names":[],"mappings":";;AAkCA,kDAYC;AAED,oCAIC;AAED,wCAIC;AAzDD,qDAAkD;AAElD,wEAAwE;AACxE,4DAA4D;AAC5D,8DAA8D;AAC9D,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC,CAAA;AAEF,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC;IACvC,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC,CAAA;AAEF,SAAgB,mBAAmB,CAAC,QAAgB;IAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAA;IAEnC,IAAI,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,CAAA;IACV,CAAC;IAED,IAAI,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,CAAA;IACV,CAAC;IAED,OAAO,CAAC,CAAA;AACV,CAAC;AAED,SAAgB,YAAY,CAAC,MAAsB,EAAE,QAAgB;IACnE,MAAM,UAAU,GAAG,EAAE,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAA;IAEtD,OAAO,cAAM,CAAC,OAAO,CAAC,cAAM,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;AACtE,CAAC;AAED,SAAgB,cAAc,CAAC,MAAc,EAAE,QAAgB;IAC7D,MAAM,UAAU,GAAG,EAAE,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAA;IAEtD,OAAO,cAAM,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAA;AAClD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medusajs/payment-adyen",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "2.22.2",
|
|
4
|
+
"description": "Adyen payment provider for Medusa",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/medusajs/medusa.git",
|
|
9
|
+
"directory": "packages/modules/providers/payment-adyen"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/medusajs/medusa/issues"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"AGENTS.md",
|
|
17
|
+
"!dist/**/__tests__",
|
|
18
|
+
"!dist/**/__mocks__",
|
|
19
|
+
"!dist/**/__fixtures__"
|
|
20
|
+
],
|
|
21
|
+
"llms": "https://docs.medusajs.com/llms.txt",
|
|
22
|
+
"llmsFull": "https://docs.medusajs.com/llms-full.txt",
|
|
23
|
+
"mcpServer": "https://docs.medusajs.com/mcp",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22.22.0"
|
|
26
|
+
},
|
|
27
|
+
"author": "Medusa",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"test": "../../../../node_modules/.bin/jest --passWithNoTests src",
|
|
31
|
+
"build": "yarn run -T rimraf dist && yarn run -T tsc --build ./tsconfig.json",
|
|
32
|
+
"watch": "yarn run -T tsc --watch"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@medusajs/framework": "2.22.2"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@medusajs/framework": "2.22.2"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@adyen/api-library": "^32.2.0"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"medusa-plugin",
|
|
45
|
+
"medusa-plugin-payment"
|
|
46
|
+
]
|
|
47
|
+
}
|