@pandait.tech/payment-nuvei 1.0.0 → 1.0.1
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/README.md +12 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,11 +110,17 @@ export const POST = createChargeHandler({
|
|
|
110
110
|
|
|
111
111
|
Apply the same pattern to the remaining handlers — each one is documented inline with its own `XHandlerDeps` interface.
|
|
112
112
|
|
|
113
|
-
###
|
|
113
|
+
### The webhook is OPTIONAL — and if you expose it, secure it
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
First, set expectations correctly:
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
- **Payments are confirmed by the synchronous `/debit` response** (`createChargeHandler` reads `transaction.status === "success" && status_detail === 3`), plus the 3DS `term_url` callback + `verify` polling for challenged transactions. **That path fully confirms a payment without any webhook.**
|
|
118
|
+
- Paymentez's transaction-notification **callback** (`developers.paymentez.com/api/#webhook`) is an **optional, redundant async channel** — Paymentez POSTs transaction status to a URL you register *with Paymentez during integration* (there is no documented self-serve dashboard; for many accounts it is simply never wired up). In a real production consumer we observed Paymentez never calling it at all.
|
|
119
|
+
- So `createWebhookHandler` is a reconciliation backstop you can mount **if** your Paymentez account is configured to notify it. It is **not required** to take payments.
|
|
120
|
+
|
|
121
|
+
Because the endpoint is nonetheless a **public POST** route, if you mount it you must authenticate it — otherwise anyone who knows an `orderId` could POST a fake "paid" notification (`status_detail: 3`) and mark an order paid. Paymentez callbacks are **not signed**, so use a shared secret:
|
|
122
|
+
|
|
123
|
+
1. Pass a secret to the handler (or via `NUVEI_WEBHOOK_SECRET`):
|
|
118
124
|
|
|
119
125
|
```ts
|
|
120
126
|
export const POST = createWebhookHandler({
|
|
@@ -125,7 +131,7 @@ Paymentez/Nuvei DMNs (webhooks) are **not signed**, so the webhook endpoint must
|
|
|
125
131
|
});
|
|
126
132
|
```
|
|
127
133
|
|
|
128
|
-
2.
|
|
134
|
+
2. If/when you register the notification URL with Paymentez, append the secret as a query param:
|
|
129
135
|
|
|
130
136
|
```
|
|
131
137
|
https://your-shop.com/api/webhooks/nuvei?key=YOUR_SECRET
|
|
@@ -133,9 +139,9 @@ Paymentez/Nuvei DMNs (webhooks) are **not signed**, so the webhook endpoint must
|
|
|
133
139
|
|
|
134
140
|
(The secret is also accepted as the `x-webhook-key` header.)
|
|
135
141
|
|
|
136
|
-
Requests without a matching key get `401` and are not processed (constant-time compared). If `webhookSecret` is **unset**, the handler still processes but logs a loud warning
|
|
142
|
+
Requests without a matching key get `401` and are not processed (constant-time compared). If `webhookSecret` is **unset**, the handler still processes but logs a loud warning. If you never register the URL with Paymentez, setting the secret simply seals the endpoint (everything → 401), which is a safe default.
|
|
137
143
|
|
|
138
|
-
> `onPaymentSucceeded` fires once, on the transition into `paid` (idempotent across
|
|
144
|
+
> `onPaymentSucceeded` fires once, on the transition into `paid` (idempotent across retries).
|
|
139
145
|
|
|
140
146
|
## Hosting & deployment (3DS callback + Nuvei egress)
|
|
141
147
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pandait.tech/payment-nuvei",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Nuvei Ecuador payment gateway adapter for Next.js: charge handler, webhook, 3DS flow, refunds, tokenized cards, and payment links. Part of panda-commerce-kit.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|