awesome-node-checkout 1.2.5 → 2.0.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/CHANGELOG.md +53 -0
- package/README.md +81 -23
- package/dist/adapters/express/index.d.ts +35 -2
- package/dist/adapters/express/index.d.ts.map +1 -1
- package/dist/adapters/express/index.js +77 -34
- package/dist/adapters/express/index.js.map +1 -1
- package/dist/checkout-configurator.d.ts +18 -1
- package/dist/checkout-configurator.d.ts.map +1 -1
- package/dist/checkout-configurator.js +58 -72
- package/dist/checkout-configurator.js.map +1 -1
- package/dist/events/checkout-event-bus.d.ts +20 -1
- package/dist/events/checkout-event-bus.d.ts.map +1 -1
- package/dist/events/checkout-event-bus.js +18 -9
- package/dist/events/checkout-event-bus.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/models/errors.d.ts +1 -1
- package/dist/models/errors.d.ts.map +1 -1
- package/dist/models/errors.js.map +1 -1
- package/dist/models/payment-result.model.d.ts +14 -1
- package/dist/models/payment-result.model.d.ts.map +1 -1
- package/dist/providers/nexi/nexi.provider.d.ts +3 -0
- package/dist/providers/nexi/nexi.provider.d.ts.map +1 -1
- package/dist/providers/nexi/nexi.provider.js +45 -5
- package/dist/providers/nexi/nexi.provider.js.map +1 -1
- package/dist/providers/paypal/paypal.provider.d.ts.map +1 -1
- package/dist/providers/paypal/paypal.provider.js +15 -2
- package/dist/providers/paypal/paypal.provider.js.map +1 -1
- package/dist/providers/satispay/satispay.provider.d.ts.map +1 -1
- package/dist/providers/satispay/satispay.provider.js +43 -4
- package/dist/providers/satispay/satispay.provider.js.map +1 -1
- package/dist/utils/ids.d.ts +10 -0
- package/dist/utils/ids.d.ts.map +1 -0
- package/dist/utils/ids.js +16 -0
- package/dist/utils/ids.js.map +1 -0
- package/dist/utils/money.d.ts +20 -0
- package/dist/utils/money.d.ts.map +1 -0
- package/dist/utils/money.js +68 -0
- package/dist/utils/money.js.map +1 -0
- package/dist/utils/parsing.util.d.ts +14 -4
- package/dist/utils/parsing.util.d.ts.map +1 -1
- package/dist/utils/parsing.util.js +32 -6
- package/dist/utils/parsing.util.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,59 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.0.0] - 2026-11-12
|
|
9
|
+
|
|
10
|
+
Every permissive default of `createCheckoutRouter` becomes an explicit, named opt-in. Resolves #29.
|
|
11
|
+
|
|
12
|
+
### Breaking
|
|
13
|
+
Migration list:
|
|
14
|
+
- **The router throws at mount without `buildPaymentRequest`.** `createCheckoutRouter(checkout)` now throws `CheckoutError` with the new code `INSECURE_CONFIGURATION`. Set `buildPaymentRequest` (server-side amount), or, only where the client may choose the amount, `allowClientPaymentRequest: true` (prints one `console.warn` at mount). The old mount warning `the client body decides the amount; set buildPaymentRequest` is gone.
|
|
15
|
+
- **The details route `GET /:provider/:id` is not mounted by default.** Add `details: { middleware: [...] }` to mount it behind your auth. `details: {}` mounts it unprotected and prints one `console.warn`. `details.enabled` is deprecated: `enabled: false` behaves as omitted (Express 404 instead of the former JSON `'Payment details route is disabled'`).
|
|
16
|
+
- **`amount` values with excess decimals now fail instead of being rounded.** Through the router, an amount with more decimals than the currency allows (`19.999` EUR, `10.5` JPY) answers `400 { success: false, code: 'INVALID_AMOUNT', error }` (new `CheckoutErrorCode`) without calling the provider; `0`, negative and non-finite amounts keep their earlier 400 (`INVALID_PAYMENT_REQUEST` from `buildPaymentRequest`, uncoded on the client-body path). Called directly, Nexi, Satispay and PayPal `createPayment` reject all of these (excess decimals, `0`, negative, non-finite) with `INVALID_AMOUNT` and return `{ success: false, status: 'FAILED', error }`, and so does `refundPayment` for a partial amount with excess decimals, `0` or a negative value (only an omitted `amount` refunds in full; Nexi and Satispay previously treated `0` and `null` as a full refund, and now reject them like PayPal). Amounts are checked against the ISO 4217 exponent of the currency (0, 2 or 3). PayPal formats payment and refund amounts with that exponent, so it now receives `'1000'` for 1000 JPY (previously the rejected `'1000.00'`) and `'1.200'` for 1.2 KWD. **Nexi and Satispay `createPayment` now reject currencies whose exponent is not 2** (JPY, KWD, …, and Nexi numeric codes such as `392`) with `{ success: false, status: 'FAILED', error }`: their outcome amounts and refunds are in hundredths, so only 2-decimal currencies keep the created, reported and refunded amounts on the same scale.
|
|
17
|
+
- **500 response bodies are generic.** Unexpected errors answer `{ success: false, error: 'Internal server error' }`. Set `exposeErrorMessages: true` to get the previous messages (including the `'Invalid provider response'` masking). The error is passed to the new `onError(err, req)` option, or logged with `console.error('[awesome-node-checkout]', err)` when `onError` is not set. `CheckoutError` 4xx responses keep their message and code.
|
|
18
|
+
- **Generated order ids changed format.** Without `orderId`, Nexi `codTrans` and Satispay `external_code` are `ORD-` + 24 random hex chars (28 chars) instead of `ORD-<Date.now()>`.
|
|
19
|
+
|
|
20
|
+
### Security
|
|
21
|
+
- **Express Adapter**: the client body can no longer decide the amount unless `allowClientPaymentRequest: true` is set explicitly; previously a missing `buildPaymentRequest` only logged a warning and `POST /checkout/paypal {"amount":0.01,…}` created a 0.01 payment. Resolves #29.
|
|
22
|
+
- **Express Adapter**: `GET /:provider/:id` is opt-in, so status, amount and currency of a payment are no longer readable by anyone who knows (or, for Nexi, guesses) a payment id. Resolves #29.
|
|
23
|
+
- **Nexi, Satispay**: generated order ids come from `crypto.randomBytes` (96 bits) instead of a millisecond timestamp: they cannot be enumerated and do not collide across instances or within the same millisecond. Resolves #29.
|
|
24
|
+
- **Nexi, Satispay, PayPal**: amounts are converted to exact minor units for the currency (`toMinorUnits`/`toMajorString`, internal); an excess decimal is rejected instead of silently rounded. PayPal no longer formats zero/three-decimal currencies with two decimals; Nexi and Satispay reject them at `createPayment`, so for payments created through this library the created, reported and refunded amounts are on the same scale (outcome amounts are still read in hundredths, whatever the `divisa`/`currency`). A refund `amount` of `0` or `null` no longer turns into a full refund on Nexi and Satispay. Resolves #29.
|
|
25
|
+
- **Express Adapter**: internal error messages (including those thrown by `buildPaymentRequest`, `onBeforeExecute`, `redirect` handlers and event listeners) no longer reach the client in 500 responses by default. Resolves #29.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- `ExpressCheckoutOptions.allowClientPaymentRequest`, `exposeErrorMessages` and `onError`. Resolves #29.
|
|
29
|
+
- `CheckoutErrorCode` values `INSECURE_CONFIGURATION` and `INVALID_AMOUNT`. Resolves #29.
|
|
30
|
+
|
|
31
|
+
### Unchanged
|
|
32
|
+
- `POST /:provider/execute` stays mounted by default: capturing an approved payment only completes the payer's own payment, and since 1.3.0 the outcome is keyed on the provider-authenticated id (#27). Documented in the README.
|
|
33
|
+
|
|
34
|
+
### Documentation
|
|
35
|
+
- README: "Secure defaults (2.0)" section, details marked *opt-in* in the Routes table, Quick Start and Express examples always build the request server-side. Resolves #29.
|
|
36
|
+
|
|
37
|
+
## [1.3.0] - 2026-09-29
|
|
38
|
+
|
|
39
|
+
### Breaking
|
|
40
|
+
- **Custom `IPaymentProvider` implementations must authenticate their outcomes.** Redirect, webhook and execute outcomes from a provider that does not set `verified: true` now fail closed: `success: false`, `verified: false`, no `paymentId`/`orderId`, error `'Payment outcome could not be verified'`.
|
|
41
|
+
- **`orderId` is no longer read from the query or unsigned body fields.** The configurator no longer reads `query.order_id`, `raw.orderId` or `raw.external_code`: a provider that relied on this must return `orderId` itself.
|
|
42
|
+
- **Listener errors are wrapped.** Direct API callers now receive `CheckoutListenerError`; the original value is in `cause`.
|
|
43
|
+
- Released as a minor version because these paths were the security holes fixed here (#27). The built-in Nexi, PayPal and Satispay providers are updated.
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
### Security
|
|
47
|
+
- **Nexi Execute**: `executePayment` is keyed on the MAC-covered `codTrans`: result `paymentId`/`orderId`, the local order lookup and the emitted event no longer use the caller's `paymentId`. A non-empty `paymentId` argument different from the outcome's `codTrans` now fails (`success: false`, `verified: false`, error `'Payment id does not match the outcome'`) and emits `payment.failed`, never `payment.completed`. The configurator applies the same check to every provider's execute outcome. Resolves #27.
|
|
48
|
+
- **Core (orderId)**: No provider takes `orderId` from the query string of a redirect or callback, or from unsigned body fields (`orderId`, `order_id`, `external_code`): `orderId` comes only from the local `paymentId -> orderId` map (keyed on the provider-authenticated `paymentId`) or from the provider's authenticated outcome. Covers the PayPal redirect, Satispay unsigned POST without `webhookPublicKey`, and Nexi under any registration name (the rule no longer depends on the provider being registered as `nexi`). Resolves #27.
|
|
49
|
+
- **Core (verified)**: Unverified callback/redirect/execute outcomes carry no `paymentId`/`orderId` and never report `success: true`; a provider outcome counts as verified only when the provider sets `verified: true` (fail closed). Resolves #27.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- **`verified` semantics**: one documented meaning on `PaymentResult`, `WebhookResult` and all events: the outcome was authenticated by a signature/MAC or by an authenticated read from the provider API. `payment.created` (and `payment.failed` from `createPayment`) is now always `verified: false`; redirect/execute outcomes with a valid MAC and `esito=KO` are `verified: true` with an error, like webhooks; `payment.refunded` reflects the provider's `verified` (PayPal/Satispay API response `true`, Nexi `false`). `PaymentResult` gains an optional `verified` field set by the built-in providers. Custom providers must now set `verified: true` on authenticated outcomes. Resolves #27.
|
|
53
|
+
- **Event bus**: errors thrown by listeners are wrapped in the new exported `CheckoutListenerError` (`message` copied, original value in `cause`, `event` name) instead of being mutated; direct API callers now receive the wrapper. Resolves #27.
|
|
54
|
+
- **Satispay Redirect**: `handleRedirect` returns `orderId` from the authenticated API `external_code` or the local transaction store (previously it was filled by the configurator from the query). Resolves #27.
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
- **Event bus**: frozen or non-extensible listener errors keep their message (previously replaced by `Cannot add property __isEventListenerError, object is not extensible`). Resolves #27.
|
|
58
|
+
- **Currency**: `parseIsoCurrency`/`parseNexiCurrency` (used by Satispay and Nexi) check alpha-3 codes against the ISO 4217 list of active currencies (`ISO_4217_ALPHA3_CODES`, from ISO 4217 List One published 2026-09-17, non-monetary codes excluded); `'XYZ'` and `'ABC'` are rejected. Resolves #27.
|
|
59
|
+
- **Documentation**: README `verified`/`paymentId`/`orderId` statements aligned with the behaviour, with a per-event `verified` table. Resolves #27.
|
|
60
|
+
|
|
8
61
|
## [1.2.5] - 2026-09-28
|
|
9
62
|
|
|
10
63
|
### Security
|
package/README.md
CHANGED
|
@@ -46,14 +46,15 @@ checkout
|
|
|
46
46
|
callbackPath: '/checkout/satispay/webhook', // Optional: defaults to /checkout/satispay/webhook
|
|
47
47
|
}));
|
|
48
48
|
|
|
49
|
-
// Use directly — no HTTP framework needed
|
|
49
|
+
// Use directly — no HTTP framework needed. The amount comes from your own order, never from the client.
|
|
50
|
+
const order = await myOrderService.getOrder('ORD-1234');
|
|
50
51
|
const result = await checkout.createPayment('paypal', {
|
|
51
|
-
amount: 49.99
|
|
52
|
-
currency: 'EUR'
|
|
53
|
-
description:
|
|
52
|
+
amount: order.totalAmount, // e.g. 49.99: at most as many decimals as the currency allows
|
|
53
|
+
currency: order.currency, // e.g. 'EUR'
|
|
54
|
+
description: `Order #${order.id}`,
|
|
54
55
|
returnUrl: 'https://myapp.com/payment/success',
|
|
55
56
|
cancelUrl: 'https://myapp.com/payment/cancel',
|
|
56
|
-
orderId:
|
|
57
|
+
orderId: order.id,
|
|
57
58
|
});
|
|
58
59
|
|
|
59
60
|
if (result.approvalUrl) {
|
|
@@ -81,7 +82,7 @@ app.use(express.urlencoded({ extended: false }));
|
|
|
81
82
|
app.use(
|
|
82
83
|
'/checkout',
|
|
83
84
|
createCheckoutRouter(checkout, {
|
|
84
|
-
//
|
|
85
|
+
// Required: verify the order and compute the amount on the server
|
|
85
86
|
buildPaymentRequest: async (req, { provider }) => {
|
|
86
87
|
const order = await myOrderService.getOrder(req.body.orderId);
|
|
87
88
|
return {
|
|
@@ -99,10 +100,6 @@ app.use(
|
|
|
99
100
|
onSuccess: (result, req) => `/orders/${result.orderId}?status=success`,
|
|
100
101
|
onFailure: (result, req) => `/orders/${result.orderId}?status=failed&error=${encodeURIComponent(result.error || '')}`,
|
|
101
102
|
},
|
|
102
|
-
// Optional: gate or disable public access to GET /:provider/:id
|
|
103
|
-
details: {
|
|
104
|
-
enabled: false, // or provide middleware: [requireAuth]
|
|
105
|
-
},
|
|
106
103
|
// Opt-in: mount POST /:provider/refund protected by admin middleware
|
|
107
104
|
refund: {
|
|
108
105
|
middleware: [requireAdminAuth],
|
|
@@ -118,13 +115,24 @@ app.use(
|
|
|
118
115
|
':provider/webhook',
|
|
119
116
|
':provider/redirect',
|
|
120
117
|
],
|
|
118
|
+
// Optional: report unexpected (500) errors; the client only sees 'Internal server error'
|
|
119
|
+
onError: (err, req) => logger.error({ err, path: req.path }, 'checkout error'),
|
|
121
120
|
}),
|
|
122
121
|
);
|
|
123
122
|
|
|
124
123
|
app.listen(3000);
|
|
125
124
|
```
|
|
126
125
|
|
|
127
|
-
> **Security Note**: Never trust client-sent amounts
|
|
126
|
+
> **Security Note**: Never trust client-sent amounts. `buildPaymentRequest` derives the amount and order parameters server-side, and since 2.0.0 it is mandatory: `createCheckoutRouter` throws `CheckoutError('INSECURE_CONFIGURATION')` at mount without it. See [Secure defaults (2.0)](#secure-defaults-20).
|
|
127
|
+
|
|
128
|
+
To expose payment status to your own front end, mount the details route explicitly and protect it:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
createCheckoutRouter(checkout, {
|
|
132
|
+
buildPaymentRequest,
|
|
133
|
+
details: { middleware: [requireAuth] }, // GET /checkout/:provider/:id
|
|
134
|
+
});
|
|
135
|
+
```
|
|
128
136
|
|
|
129
137
|
### With Fastify (or any other framework)
|
|
130
138
|
|
|
@@ -132,8 +140,17 @@ Use the `CheckoutConfigurator` methods directly in your own routes:
|
|
|
132
140
|
|
|
133
141
|
```typescript
|
|
134
142
|
fastify.post('/checkout/:provider', async (req, reply) => {
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
// Build the request from your own order: never pass req.body to createPayment
|
|
144
|
+
const order = await myOrderService.getOrder(req.body.orderId);
|
|
145
|
+
const result = await checkout.createPayment(req.params.provider, {
|
|
146
|
+
amount: order.totalAmount,
|
|
147
|
+
currency: order.currency,
|
|
148
|
+
orderId: order.id,
|
|
149
|
+
returnUrl: `https://myapp.com/checkout/${req.params.provider}/redirect`,
|
|
150
|
+
cancelUrl: 'https://myapp.com/payment/cancel',
|
|
151
|
+
});
|
|
152
|
+
const { raw, ...safeResult } = result;
|
|
153
|
+
reply.status(result.success ? 201 : 400).send(safeResult);
|
|
137
154
|
});
|
|
138
155
|
|
|
139
156
|
// Handle both POST and GET webhooks (e.g. Satispay GET callback vs Nexi/Satispay POST notification)
|
|
@@ -165,15 +182,38 @@ A full-featured reference implementation using Express 5, SQLite (`ITransactionS
|
|
|
165
182
|
|
|
166
183
|
| Method | Path | Description |
|
|
167
184
|
|-------------|-----------------------------|----------------------------------------------------------------|
|
|
168
|
-
| POST | `/:provider` | Create a payment (
|
|
185
|
+
| POST | `/:provider` | Create a payment (built by `buildPaymentRequest`) |
|
|
169
186
|
| POST | `/:provider/execute` | Execute/capture a payment (supports `onBeforeExecute`) |
|
|
170
187
|
| GET | `/:provider/redirect` | Handle provider redirect callback (supports 302 via `redirect`)|
|
|
171
|
-
| GET | `/:provider/:id` | Get payment details (*
|
|
188
|
+
| GET | `/:provider/:id` | Get payment details (*opt-in*: mounted only when `details` option is set; protect it with `details.middleware`)|
|
|
172
189
|
| POST | `/:provider/refund` | Refund a payment (*opt-in*: mounted only when `refund` option is set)|
|
|
173
190
|
| GET / POST | `/:provider/webhook` | Handle provider webhook (POST for Nexi/Satispay, GET for Satispay)|
|
|
174
191
|
|
|
175
192
|
---
|
|
176
193
|
|
|
194
|
+
## Secure defaults (2.0)
|
|
195
|
+
|
|
196
|
+
Since 2.0.0 every permissive behaviour of `createCheckoutRouter` is an explicit, named opt-in that shows up in code review.
|
|
197
|
+
|
|
198
|
+
1. **`buildPaymentRequest` is mandatory.** Without it, `createCheckoutRouter` throws `CheckoutError` with code `INSECURE_CONFIGURATION` at mount. The opt-out is `allowClientPaymentRequest: true`: the client request body becomes the `PaymentRequest`, so **the browser chooses the amount**. Never use it for a shop. It prints one `console.warn` at mount.
|
|
199
|
+
2. **`GET /:provider/:id` is opt-in.** The details route returns `success`, `status`, `amount`, `currency` and `paymentId` for any id it is given (for Nexi, the id is your order code). It is mounted only when `details` is set: `details: { middleware: [requireAuth] }`. `details: {}` mounts it unprotected and prints one `console.warn`. The old `details: { enabled: false }` is deprecated and behaves as omitted.
|
|
200
|
+
3. **Generated order ids are unpredictable.** When `orderId` is omitted, Nexi (`codTrans`) and Satispay (`external_code`) use `ORD-` + 24 random hex chars instead of `ORD-<timestamp>`, so ids cannot be enumerated and do not collide.
|
|
201
|
+
4. **Amounts are exact, in the currency's minor units.** Amounts are checked against the ISO 4217 exponent (0 for JPY, KRW, CLP…; 3 for KWD, BHD, JOD…; 2 otherwise) and never rounded: `19.999 EUR` or `10.5 JPY` fails with `INVALID_AMOUNT` instead of charging a rounded amount. The router answers `400 { success: false, code: 'INVALID_AMOUNT', error }` without calling the provider; a provider called directly returns `{ success: false, status: 'FAILED', error }`. PayPal formats payment and refund amounts with the exponent of the order's currency: it receives `'1000'` for 1000 JPY and `'1.200'` for 1.2 KWD. Nexi and Satispay accept only currencies with 2 decimal places: `createPayment` in JPY, KWD or another 0- or 3-decimal currency (including Nexi numeric codes such as `392`) returns `{ success: false, status: 'FAILED', error }`, because their outcome amounts and refund amounts are in hundredths. A refund `amount` of `0` (or `null`) fails like any invalid amount; only an omitted amount refunds in full.
|
|
202
|
+
5. **500 bodies are generic.** An unexpected error (a throwing `buildPaymentRequest`, `onBeforeExecute`, `redirect.onSuccess`/`onFailure`, event listener, or provider) answers `500 { success: false, error: 'Internal server error' }`. The error goes to `onError(err, req)`, or to `console.error` when `onError` is not set. `exposeErrorMessages: true` restores the message in the body (for development). `CheckoutError` responses (4xx) keep their message and code and are not passed to `onError`.
|
|
203
|
+
|
|
204
|
+
| Option | Default | Effect |
|
|
205
|
+
|--------|---------|--------|
|
|
206
|
+
| `buildPaymentRequest` | — (required) | Server-side `PaymentRequest` |
|
|
207
|
+
| `allowClientPaymentRequest: true` | off | Client body decides the amount (insecure) |
|
|
208
|
+
| `details: { middleware }` | not mounted | Mounts `GET /:provider/:id` |
|
|
209
|
+
| `refund: { middleware }` | not mounted | Mounts `POST /:provider/refund` |
|
|
210
|
+
| `exposeErrorMessages: true` | off | Error messages in 500 bodies |
|
|
211
|
+
| `onError(err, req)` | `console.error` | Receives every 500 error |
|
|
212
|
+
|
|
213
|
+
**`POST /:provider/execute` stays mounted by default.** Capturing an approved payment only completes the payer's own payment, and since 1.3.0 the outcome is keyed on the provider-authenticated payment id (#27), so a forged `paymentId` cannot confirm another order. Use `execute.middleware` or `execute.onBeforeExecute` to tie the capture to the current session.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
177
217
|
## Security: A Redirect Is Not Proof of Payment
|
|
178
218
|
|
|
179
219
|
Relying solely on front-end browser redirects (`GET /:provider/redirect`) to fulfill orders introduces significant risk:
|
|
@@ -182,7 +222,7 @@ Relying solely on front-end browser redirects (`GET /:provider/redirect`) to ful
|
|
|
182
222
|
- **Amount Mismatch**: Always verify that the captured payment amount matches your order ledger before fulfilling goods or services. In `awesome-node-checkout`, `success: true` strictly requires that a payment is confirmed with a valid amount.
|
|
183
223
|
|
|
184
224
|
To ensure safe fulfillment:
|
|
185
|
-
1. **Verify Amount & Currency**: `PaymentResult` and `WebhookResult` return `amount` and `currency` extracted directly from the provider. Compare amounts in minor units (cents) or with rounding to prevent floating-point discrepancies:
|
|
225
|
+
1. **Verify Amount & Currency**: `PaymentResult` and `WebhookResult` return `amount` and `currency` extracted directly from the provider. Compare amounts in minor units (cents) or with rounding to prevent floating-point discrepancies. The example below scales by 100, which is exact for currencies with at most 2 decimal places (every Nexi and Satispay payment created through this library); for a PayPal order in a 3-decimal currency such as KWD, scale by 1000:
|
|
186
226
|
```typescript
|
|
187
227
|
const result = await checkout.handleRedirect(provider, req.query);
|
|
188
228
|
if (result.success) {
|
|
@@ -229,13 +269,29 @@ checkout.events
|
|
|
229
269
|
.on('webhook.received', ({ provider, paymentId, orderId, status, error, verified, data, raw }) => { /* ... */ });
|
|
230
270
|
```
|
|
231
271
|
|
|
232
|
-
|
|
272
|
+
An error thrown by a listener propagates to the caller wrapped in a `CheckoutListenerError` (exported): its `message` is the original message (or `String(value)` for non-Error values), `cause` is the original value, untouched (frozen errors are fine), and `event` is the event name. The Express adapter answers `500` with a generic body (the message only with `exposeErrorMessages: true`) and passes the error to `onError`.
|
|
273
|
+
|
|
274
|
+
Currencies are validated against the ISO 4217 list of active alpha-3 codes (`ISO_4217_ALPHA3_CODES`, plus the mapped Nexi numeric codes such as `978`); shape-only codes like `'XYZ'` or `'ABC'` and non-monetary codes (`XXX`, `XTS`, precious metals) are rejected.
|
|
275
|
+
|
|
276
|
+
### Understanding `verified` vs `error` in Results and Events
|
|
277
|
+
|
|
278
|
+
`verified` has one meaning everywhere (`PaymentResult`, `WebhookResult` and every event payload):
|
|
279
|
+
|
|
280
|
+
> **`verified: true` means the outcome was authenticated**, either by a provider signature/MAC checked by the library (Nexi 7-field outcome MAC, Satispay HTTP Signature) or by an authenticated server-to-server read from the provider API (PayPal capture/order read with OAuth credentials, Satispay `GET /payments/{id}` signed with the merchant key). Anything else is `verified: false`.
|
|
281
|
+
|
|
282
|
+
- `success` and `verified` are independent: a genuine cancellation or failed payment (user canceled, card declined) is `verified: true, success: false` with `error: 'Payment is CANCELED'` or `error: 'Payment failed with outcome KO'`. This holds for webhooks, redirects and `executePayment` alike (e.g. a Nexi redirect or execute with `esito=KO` and a valid MAC emits `payment.failed` with `verified: true`).
|
|
283
|
+
- On a callback, redirect or execute outcome with `verified: false` (missing/tampered MAC or signature, failed API read, provider that does not assert `verified: true`), the result and the event carry **no `paymentId` and no `orderId`**, and `success` is always `false` (error e.g. `'MAC verification failed'`, `'Webhook signature verification failed'`, `'Payment outcome could not be verified'`).
|
|
284
|
+
- `orderId` is never taken from the query string of a redirect or callback, nor from unsigned body fields, for any provider and under any registration name. It comes from the local `paymentId → orderId` map filled by `createPayment` (keyed on the provider-authenticated `paymentId`), or from the provider's authenticated outcome (Nexi MAC-covered `codTrans`, Satispay API `external_code` / transaction store).
|
|
285
|
+
- `executePayment(provider, paymentId, data)` is keyed on the `paymentId` authenticated by the provider (for Nexi the MAC-covered `codTrans`), never on the argument. If a non-empty `paymentId` argument differs from the authenticated one, the call fails with `success: false, verified: false, error: 'Payment id does not match the outcome'` and emits `payment.failed` (never `payment.completed`).
|
|
286
|
+
|
|
287
|
+
| Event | `verified` |
|
|
288
|
+
|-------|------------|
|
|
289
|
+
| `payment.created` (and `payment.failed` from `createPayment`) | always `false`: creation reports no payment outcome. `paymentId`/`orderId` are the ones you just created. |
|
|
290
|
+
| `payment.completed` / `payment.failed` from `handleRedirect` / `executePayment` | `true` only for a MAC-verified (Nexi) or API-read (PayPal, Satispay) outcome, whatever its `success` |
|
|
291
|
+
| `webhook.received` | `true` only for a MAC/signature-verified notification or an authenticated API re-read |
|
|
292
|
+
| `payment.refunded` | `true` when the refund outcome comes from an authenticated provider API response (PayPal, Satispay); `false` for Nexi, whose refund response carries no MAC checked by the library |
|
|
233
293
|
|
|
234
|
-
|
|
235
|
-
- **`verified: true`**: The notification was cryptographically verified (e.g. Nexi 7-field outcome MAC or Satispay HTTP Signature) or verified via authenticated server-to-server API re-read.
|
|
236
|
-
- A genuine cancellation or failed payment (e.g. user canceled on gateway, card declined) has `verified: true, success: false, error: 'Payment is CANCELED'` or `error: 'Payment failed with outcome KO'`.
|
|
237
|
-
- **`verified: false`**: The signature/MAC was missing, tampered with, or invalid. The payload is untrusted.
|
|
238
|
-
- In this case, `success: false, verified: false, error: 'MAC verification failed'` (or `'Webhook signature verification failed'`), and `orderId` / `paymentId` from untrusted query/body are stripped to prevent parameter injection attacks.
|
|
294
|
+
Custom providers must set `verified: true` on the outcomes they have authenticated; an outcome without it is treated as unverified.
|
|
239
295
|
|
|
240
296
|
#### Satispay `verified` Semantics
|
|
241
297
|
- **With `webhookPublicKey` configured**: Inbound POST webhooks must carry a valid HTTP Signature matching Satispay's RSA public key, correct SHA-256 body digest, and fresh `Date` header. `verified: true` guarantees cryptographic authenticity.
|
|
@@ -284,7 +340,9 @@ export class StripeProvider extends BasePaymentProvider {
|
|
|
284
340
|
// ... implement other methods
|
|
285
341
|
|
|
286
342
|
async handleRedirect(query: Record<string, any>): Promise<PaymentResult> {
|
|
287
|
-
// ... handle Stripe redirect
|
|
343
|
+
// ... handle Stripe redirect: re-read the session from the Stripe API and
|
|
344
|
+
// return { success, verified: true, paymentId, orderId, amount, currency }
|
|
345
|
+
// only for an authenticated outcome (see "Understanding `verified`")
|
|
288
346
|
}
|
|
289
347
|
}
|
|
290
348
|
|
|
@@ -22,8 +22,18 @@ export interface ExpressCheckoutOptions {
|
|
|
22
22
|
* Builds the PaymentRequest on the server (amount from your own order), ignoring the client body.
|
|
23
23
|
* If the hook sends an HTTP response directly (e.g. via `ctx.res.status(403)...`),
|
|
24
24
|
* returning `null` or `undefined` halts further adapter processing without error.
|
|
25
|
+
*
|
|
26
|
+
* Required: `createCheckoutRouter` throws `CheckoutError('INSECURE_CONFIGURATION')` at mount
|
|
27
|
+
* when it is missing, unless `allowClientPaymentRequest: true` is set.
|
|
25
28
|
*/
|
|
26
29
|
buildPaymentRequest?: (req: Request, ctx: PaymentRequestContext) => PaymentRequest | null | undefined | Promise<PaymentRequest | null | undefined>;
|
|
30
|
+
/**
|
|
31
|
+
* **Insecure.** Without `buildPaymentRequest`, sends the client request body to the provider
|
|
32
|
+
* as the PaymentRequest: the browser chooses the amount, the currency and the order id.
|
|
33
|
+
* Never use this for a shop or for anything with a price; it exists for donations-style
|
|
34
|
+
* flows and tests. Ignored when `buildPaymentRequest` is set.
|
|
35
|
+
*/
|
|
36
|
+
allowClientPaymentRequest?: true;
|
|
27
37
|
/**
|
|
28
38
|
* When configured, GET /:provider/redirect responds with a 302 redirect
|
|
29
39
|
* to the URL returned by onSuccess or onFailure instead of JSON.
|
|
@@ -34,9 +44,15 @@ export interface ExpressCheckoutOptions {
|
|
|
34
44
|
};
|
|
35
45
|
/**
|
|
36
46
|
* Configuration for GET /:provider/:id (getPaymentDetails).
|
|
37
|
-
*
|
|
47
|
+
* If omitted, the details route is NOT mounted (returns 404), like `refund`.
|
|
48
|
+
* The route returns status, amount and currency for any payment id it is given:
|
|
49
|
+
* protect it with `middleware` (a console warning is printed at mount when it has none).
|
|
38
50
|
*/
|
|
39
51
|
details?: {
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated Since 2.0.0 the route is mounted only when `details` is set.
|
|
54
|
+
* `enabled: false` behaves as if `details` were omitted; any other value is ignored.
|
|
55
|
+
*/
|
|
40
56
|
enabled?: boolean;
|
|
41
57
|
middleware?: RequestHandler[];
|
|
42
58
|
};
|
|
@@ -54,6 +70,20 @@ export interface ExpressCheckoutOptions {
|
|
|
54
70
|
middleware?: RequestHandler[];
|
|
55
71
|
onBeforeExecute?: (req: Request, paymentId: string) => void | Promise<void>;
|
|
56
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* When `true`, 500 responses carry the error message (masked to 'Invalid provider response'
|
|
75
|
+
* for provider parse errors). Default `false`: 500 bodies are always
|
|
76
|
+
* `{ success: false, error: 'Internal server error' }`. `CheckoutError` 4xx responses keep
|
|
77
|
+
* their message and code either way.
|
|
78
|
+
*/
|
|
79
|
+
exposeErrorMessages?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Called with the original error (and the request) for every error answered with a 500,
|
|
82
|
+
* whatever `exposeErrorMessages` says. Not called for 4xx `CheckoutError` responses, which are
|
|
83
|
+
* client-triggerable (e.g. an unknown provider name). When omitted, the error is logged with
|
|
84
|
+
* `console.error('[awesome-node-checkout]', err)`.
|
|
85
|
+
*/
|
|
86
|
+
onError?: (err: unknown, req: Request) => void;
|
|
57
87
|
}
|
|
58
88
|
/**
|
|
59
89
|
* Matches a request path against public path patterns by segments.
|
|
@@ -72,9 +102,12 @@ export declare function isPathPublic(reqPath: string, publicPaths: (string | str
|
|
|
72
102
|
* GET /:provider/webhook → handleWebhook
|
|
73
103
|
* POST /:provider/webhook → handleWebhook
|
|
74
104
|
* GET /:provider/redirect → handleRedirect (must come before /:provider/:id)
|
|
75
|
-
* GET /:provider/:id → getPaymentDetails
|
|
105
|
+
* GET /:provider/:id → getPaymentDetails (only if options.details is configured)
|
|
76
106
|
* ```
|
|
77
107
|
*
|
|
108
|
+
* Throws `CheckoutError('INSECURE_CONFIGURATION')` when neither `buildPaymentRequest` nor
|
|
109
|
+
* `allowClientPaymentRequest: true` is set.
|
|
110
|
+
*
|
|
78
111
|
* Usage:
|
|
79
112
|
* ```typescript
|
|
80
113
|
* import { createCheckoutRouter } from 'awesome-node-checkout/express';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAIlE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAE9B;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;IAEpC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,CACpB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,qBAAqB,KACvB,cAAc,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAEpF;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,IAAI,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,EAAE;QACT,SAAS,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;QAC3D,SAAS,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;KAC5D,CAAC;IAEF;;;;;OAKG;IACH,OAAO,CAAC,EAAE;QACR;;;WAGG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;KAC/B,CAAC;IAEF;;;OAGG;IACH,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;KAC/B,CAAC;IAEF;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;QAC9B,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7E,CAAC;IAEF;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAgBzF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,GAAE,sBAA2B,GACnC,MAAM,CAmOR"}
|
|
@@ -4,6 +4,8 @@ exports.isPathPublic = isPathPublic;
|
|
|
4
4
|
exports.createCheckoutRouter = createCheckoutRouter;
|
|
5
5
|
const express_1 = require("express");
|
|
6
6
|
const errors_1 = require("../../models/errors");
|
|
7
|
+
const checkout_event_bus_1 = require("../../events/checkout-event-bus");
|
|
8
|
+
const money_1 = require("../../utils/money");
|
|
7
9
|
/**
|
|
8
10
|
* Matches a request path against public path patterns by segments.
|
|
9
11
|
* ':provider' matches any single non-empty segment.
|
|
@@ -37,9 +39,12 @@ function isPathPublic(reqPath, publicPaths) {
|
|
|
37
39
|
* GET /:provider/webhook → handleWebhook
|
|
38
40
|
* POST /:provider/webhook → handleWebhook
|
|
39
41
|
* GET /:provider/redirect → handleRedirect (must come before /:provider/:id)
|
|
40
|
-
* GET /:provider/:id → getPaymentDetails
|
|
42
|
+
* GET /:provider/:id → getPaymentDetails (only if options.details is configured)
|
|
41
43
|
* ```
|
|
42
44
|
*
|
|
45
|
+
* Throws `CheckoutError('INSECURE_CONFIGURATION')` when neither `buildPaymentRequest` nor
|
|
46
|
+
* `allowClientPaymentRequest: true` is set.
|
|
47
|
+
*
|
|
43
48
|
* Usage:
|
|
44
49
|
* ```typescript
|
|
45
50
|
* import { createCheckoutRouter } from 'awesome-node-checkout/express';
|
|
@@ -58,10 +63,14 @@ function isPathPublic(reqPath, publicPaths) {
|
|
|
58
63
|
* ```
|
|
59
64
|
*/
|
|
60
65
|
function createCheckoutRouter(checkout, options = {}) {
|
|
61
|
-
|
|
66
|
+
if (!options.buildPaymentRequest && options.allowClientPaymentRequest !== true) {
|
|
67
|
+
throw new errors_1.CheckoutError('createCheckoutRouter: set buildPaymentRequest (server-side amount) or allowClientPaymentRequest: true', 'INSECURE_CONFIGURATION');
|
|
68
|
+
}
|
|
62
69
|
if (!options.buildPaymentRequest) {
|
|
63
|
-
console.warn('[awesome-node-checkout]
|
|
70
|
+
console.warn('[awesome-node-checkout] allowClientPaymentRequest: the client body decides the amount');
|
|
64
71
|
}
|
|
72
|
+
const router = (0, express_1.Router)();
|
|
73
|
+
const sendError = (req, res, err, isProvider = true) => sendErrorResponse(req, res, options, err, isProvider);
|
|
65
74
|
// Apply shared middleware (skipping public paths by segment match)
|
|
66
75
|
if (options.middleware?.length) {
|
|
67
76
|
const publicPaths = options.publicPaths ?? [];
|
|
@@ -92,7 +101,7 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
92
101
|
});
|
|
93
102
|
}
|
|
94
103
|
catch (consumerErr) {
|
|
95
|
-
sendError(res, consumerErr, false);
|
|
104
|
+
sendError(req, res, consumerErr, false);
|
|
96
105
|
return;
|
|
97
106
|
}
|
|
98
107
|
if (res.headersSent) {
|
|
@@ -133,12 +142,22 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
133
142
|
}
|
|
134
143
|
paymentRequest = body;
|
|
135
144
|
}
|
|
145
|
+
// Exact minor units: an amount with more decimals than the currency allows is rejected,
|
|
146
|
+
// never rounded
|
|
147
|
+
try {
|
|
148
|
+
(0, money_1.toMinorUnits)(paymentRequest.amount, paymentRequest.currency);
|
|
149
|
+
}
|
|
150
|
+
catch (amountErr) {
|
|
151
|
+
if (!(0, money_1.isInvalidAmountError)(amountErr))
|
|
152
|
+
throw amountErr;
|
|
153
|
+
return res.status(400).json({ success: false, code: 'INVALID_AMOUNT', error: amountErr.message });
|
|
154
|
+
}
|
|
136
155
|
const result = await checkout.createPayment(provider, paymentRequest);
|
|
137
156
|
const { raw, ...safeResult } = result;
|
|
138
157
|
res.status(result.success ? 201 : 400).json(safeResult);
|
|
139
158
|
}
|
|
140
159
|
catch (err) {
|
|
141
|
-
sendError(res, err, true);
|
|
160
|
+
sendError(req, res, err, true);
|
|
142
161
|
}
|
|
143
162
|
});
|
|
144
163
|
// ---- POST /:provider/execute — execute payment ---------------------------
|
|
@@ -154,7 +173,7 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
154
173
|
await options.execute.onBeforeExecute(req, paymentId);
|
|
155
174
|
}
|
|
156
175
|
catch (consumerErr) {
|
|
157
|
-
sendError(res, consumerErr, false);
|
|
176
|
+
sendError(req, res, consumerErr, false);
|
|
158
177
|
return;
|
|
159
178
|
}
|
|
160
179
|
}
|
|
@@ -163,7 +182,7 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
163
182
|
res.status(result.success ? 200 : 400).json(safeResult);
|
|
164
183
|
}
|
|
165
184
|
catch (err) {
|
|
166
|
-
sendError(res, err, true);
|
|
185
|
+
sendError(req, res, err, true);
|
|
167
186
|
}
|
|
168
187
|
});
|
|
169
188
|
// ---- POST /:provider/refund — refund payment (opt-in) --------------------
|
|
@@ -180,7 +199,7 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
180
199
|
res.status(result.success ? 200 : 400).json(safeResult);
|
|
181
200
|
}
|
|
182
201
|
catch (err) {
|
|
183
|
-
sendError(res, err, true);
|
|
202
|
+
sendError(req, res, err, true);
|
|
184
203
|
}
|
|
185
204
|
});
|
|
186
205
|
}
|
|
@@ -197,7 +216,7 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
197
216
|
res.status(result.success ? 200 : 400).json(safeResult);
|
|
198
217
|
}
|
|
199
218
|
catch (err) {
|
|
200
|
-
sendError(res, err, true);
|
|
219
|
+
sendError(req, res, err, true);
|
|
201
220
|
}
|
|
202
221
|
};
|
|
203
222
|
router.get('/:provider/webhook', webhookHandler);
|
|
@@ -212,7 +231,7 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
212
231
|
result = await checkout.handleRedirect(String(req.params.provider), req.query);
|
|
213
232
|
}
|
|
214
233
|
catch (err) {
|
|
215
|
-
sendError(res, err, true);
|
|
234
|
+
sendError(req, res, err, true);
|
|
216
235
|
return;
|
|
217
236
|
}
|
|
218
237
|
if (options.redirect) {
|
|
@@ -223,7 +242,7 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
223
242
|
: options.redirect.onFailure(result, req);
|
|
224
243
|
}
|
|
225
244
|
catch (consumerErr) {
|
|
226
|
-
sendError(res, consumerErr, false);
|
|
245
|
+
sendError(req, res, consumerErr, false);
|
|
227
246
|
return;
|
|
228
247
|
}
|
|
229
248
|
return res.redirect(302, targetUrl);
|
|
@@ -231,34 +250,42 @@ function createCheckoutRouter(checkout, options = {}) {
|
|
|
231
250
|
const { raw, ...safeResult } = result;
|
|
232
251
|
res.status(result.success ? 200 : 400).json(safeResult);
|
|
233
252
|
});
|
|
234
|
-
// ---- GET /:provider/:id — get payment details
|
|
235
|
-
|
|
236
|
-
if (options.details
|
|
237
|
-
detailsHandlers
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (options.details?.enabled === false) {
|
|
241
|
-
return res.status(404).json({ success: false, error: 'Payment details route is disabled' });
|
|
253
|
+
// ---- GET /:provider/:id — get payment details (opt-in) -------------------
|
|
254
|
+
// Registered after /:provider/redirect and /:provider/webhook so that those win.
|
|
255
|
+
if (options.details && options.details.enabled !== false) {
|
|
256
|
+
const detailsHandlers = [];
|
|
257
|
+
if (options.details.middleware?.length) {
|
|
258
|
+
detailsHandlers.push(...options.details.middleware);
|
|
242
259
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const { raw, ...safeResult } = result;
|
|
246
|
-
res.status(result.success ? 200 : 404).json(safeResult);
|
|
247
|
-
}
|
|
248
|
-
catch (err) {
|
|
249
|
-
sendError(res, err, true);
|
|
260
|
+
else {
|
|
261
|
+
console.warn('[awesome-node-checkout] details route mounted without middleware: payment status and amount are readable by anyone who knows a payment id');
|
|
250
262
|
}
|
|
251
|
-
|
|
263
|
+
router.get('/:provider/:id', ...detailsHandlers, async (req, res) => {
|
|
264
|
+
try {
|
|
265
|
+
const result = await checkout.getPaymentDetails(String(req.params.provider), String(req.params.id));
|
|
266
|
+
const { raw, ...safeResult } = result;
|
|
267
|
+
res.status(result.success ? 200 : 404).json(safeResult);
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
sendError(req, res, err, true);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
252
274
|
return router;
|
|
253
275
|
}
|
|
254
276
|
// ---------------------------------------------------------------------------
|
|
255
277
|
// Helpers
|
|
256
278
|
// ---------------------------------------------------------------------------
|
|
257
|
-
function
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
279
|
+
function sendErrorResponse(req, res, options, originalErr, isProvider = true) {
|
|
280
|
+
let err = originalErr;
|
|
281
|
+
const isListenerError = err instanceof checkout_event_bus_1.CheckoutListenerError;
|
|
282
|
+
if (err instanceof checkout_event_bus_1.CheckoutListenerError && err.cause instanceof errors_1.CheckoutError) {
|
|
283
|
+
// A listener that throws a CheckoutError keeps its status mapping
|
|
284
|
+
err = err.cause;
|
|
285
|
+
}
|
|
261
286
|
if (err instanceof errors_1.CheckoutError) {
|
|
287
|
+
if (res.headersSent)
|
|
288
|
+
return;
|
|
262
289
|
const statusMap = {
|
|
263
290
|
PROVIDER_NOT_FOUND: 404,
|
|
264
291
|
WEBHOOK_NOT_SUPPORTED: 422,
|
|
@@ -266,13 +293,29 @@ function sendError(res, err, isProvider = true) {
|
|
|
266
293
|
};
|
|
267
294
|
const status = statusMap[err.code] ?? 400;
|
|
268
295
|
res.status(status).json({ success: false, error: err.message, code: err.code });
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
// Unexpected error (500): report it to the app, never to the client unless asked to
|
|
299
|
+
try {
|
|
300
|
+
if (options.onError) {
|
|
301
|
+
options.onError(originalErr, req);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
console.error('[awesome-node-checkout]', originalErr);
|
|
305
|
+
}
|
|
269
306
|
}
|
|
270
|
-
|
|
271
|
-
|
|
307
|
+
catch {
|
|
308
|
+
// A throwing onError must not prevent the response
|
|
309
|
+
}
|
|
310
|
+
if (res.headersSent)
|
|
311
|
+
return;
|
|
312
|
+
let message = 'Internal server error';
|
|
313
|
+
if (options.exposeErrorMessages === true) {
|
|
314
|
+
message = err instanceof Error ? err.message : String(err ?? 'Internal server error');
|
|
272
315
|
if (!isListenerError && isProvider && (err instanceof SyntaxError || /JSON|Unexpected token/i.test(message))) {
|
|
273
316
|
message = 'Invalid provider response';
|
|
274
317
|
}
|
|
275
|
-
res.status(500).json({ success: false, error: message });
|
|
276
318
|
}
|
|
319
|
+
res.status(500).json({ success: false, error: message });
|
|
277
320
|
}
|
|
278
321
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"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"}
|