cinetpay-seamless 0.1.3 → 0.1.5
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 +52 -11
- package/dist/checkout.d.ts.map +1 -1
- package/dist/cinetpay-seamless.js +145 -123
- package/dist/cinetpay-seamless.js.map +1 -1
- package/dist/cinetpay-seamless.umd.cjs +2 -2
- package/dist/cinetpay-seamless.umd.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +34 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ npm install cinetpay-seamless
|
|
|
36
36
|
### CDN
|
|
37
37
|
|
|
38
38
|
```html
|
|
39
|
-
<script src="https://unpkg.com/cinetpay-seamless@0.1.
|
|
39
|
+
<script src="https://unpkg.com/cinetpay-seamless@0.1.5/dist/cinetpay-seamless.umd.cjs"></script>
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
## Démarrage rapide
|
|
@@ -44,8 +44,8 @@ npm install cinetpay-seamless
|
|
|
44
44
|
```typescript
|
|
45
45
|
import { CinetPaySeamless } from 'cinetpay-seamless'
|
|
46
46
|
|
|
47
|
-
// 1. Obtenir le paymentToken depuis votre backend
|
|
48
|
-
const { paymentToken } = await fetch('/api/pay', {
|
|
47
|
+
// 1. Obtenir le paymentToken et, idéalement, paymentUrl depuis votre backend
|
|
48
|
+
const { paymentToken, paymentUrl } = await fetch('/api/pay', {
|
|
49
49
|
method: 'POST',
|
|
50
50
|
headers: { 'Content-Type': 'application/json' },
|
|
51
51
|
body: JSON.stringify({ amount: 5000, orderId: 'ORDER-001' }),
|
|
@@ -54,6 +54,7 @@ const { paymentToken } = await fetch('/api/pay', {
|
|
|
54
54
|
// 2. Ouvrir la popup
|
|
55
55
|
CinetPaySeamless.open({
|
|
56
56
|
paymentToken,
|
|
57
|
+
paymentUrl, // recommandé en production: URL CinetPay exacte renvoyée par l'API
|
|
57
58
|
onPaymentSuccess: (data) => {
|
|
58
59
|
console.log('Paiement réussi !', data.amount, data.currency)
|
|
59
60
|
},
|
|
@@ -68,7 +69,7 @@ CinetPaySeamless.open({
|
|
|
68
69
|
```html
|
|
69
70
|
<button id="pay-btn">Payer 5 000 XOF</button>
|
|
70
71
|
|
|
71
|
-
<script src="https://unpkg.com/cinetpay-seamless@0.1.
|
|
72
|
+
<script src="https://unpkg.com/cinetpay-seamless@0.1.5/dist/cinetpay-seamless.umd.cjs"></script>
|
|
72
73
|
<script>
|
|
73
74
|
document.getElementById('pay-btn').addEventListener('click', function() {
|
|
74
75
|
// Appeler votre backend pour obtenir le paymentToken
|
|
@@ -81,6 +82,7 @@ CinetPaySeamless.open({
|
|
|
81
82
|
.then(function(data) {
|
|
82
83
|
CinetPaySeamless.open({
|
|
83
84
|
paymentToken: data.paymentToken,
|
|
85
|
+
paymentUrl: data.paymentUrl,
|
|
84
86
|
onPaymentSuccess: function(result) {
|
|
85
87
|
alert('Merci ! ' + result.amount + ' ' + result.currency)
|
|
86
88
|
},
|
|
@@ -152,6 +154,9 @@ Ouvre la popup de paiement CinetPay.
|
|
|
152
154
|
| Option | Type | Default | Description |
|
|
153
155
|
|---|---|---|---|
|
|
154
156
|
| `paymentToken` | `string` | **requis** | Token obtenu via votre backend (`POST /v1/payment`) |
|
|
157
|
+
| `environment` | `'sandbox' \| 'production'` | `'sandbox'` | Environnement utilisé si `paymentUrl` n'est pas fourni |
|
|
158
|
+
| `paymentUrl` | `string` | - | URL complète renvoyée par CinetPay, prioritaire sur `environment` |
|
|
159
|
+
| `checkoutBaseUrl` | `string` | selon `environment` | Host checkout personnalisé |
|
|
155
160
|
| `statusUrl` | `string \| (ctx) => string` | - | Endpoint de votre backend pour vérifier le statut canonique |
|
|
156
161
|
| `checkStatus` | `(ctx) => Promise<object>` | - | Fonction personnalisée de vérification statut |
|
|
157
162
|
| `statusPollInterval` | `number` | `3000` | Intervalle de vérification statut en ms |
|
|
@@ -163,6 +168,39 @@ Ouvre la popup de paiement CinetPay.
|
|
|
163
168
|
| `onClose` | `({ status }) => void` | - | Modal fermé |
|
|
164
169
|
| `onError` | `(error) => void` | - | Erreur technique |
|
|
165
170
|
|
|
171
|
+
### Éviter les 404 en production
|
|
172
|
+
|
|
173
|
+
En production, privilégiez toujours l'URL complète renvoyée par CinetPay dans la
|
|
174
|
+
réponse de `POST /v1/payment` (`payment_url`). Ne reconstruisez pas vous-même une
|
|
175
|
+
URL checkout si cette URL est disponible.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// Backend: renvoyer les deux champs utiles au frontend
|
|
179
|
+
res.json({
|
|
180
|
+
paymentToken: payment.paymentToken ?? payment.payment_token,
|
|
181
|
+
paymentUrl: payment.paymentUrl ?? payment.payment_url,
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
// Frontend: ouvrir l'URL exacte CinetPay
|
|
185
|
+
CinetPaySeamless.open({
|
|
186
|
+
paymentToken,
|
|
187
|
+
paymentUrl,
|
|
188
|
+
environment: 'production',
|
|
189
|
+
})
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Le SDK accepte aussi les noms bruts CinetPay côté JavaScript :
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
CinetPaySeamless.open({
|
|
196
|
+
payment_token: data.payment_token,
|
|
197
|
+
payment_url: data.payment_url,
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Si `paymentUrl` / `payment_url` est fourni, il est prioritaire et le SDK ne
|
|
202
|
+
reconstruit pas `https://secure.cinetpay.co/checkout/{paymentToken}`.
|
|
203
|
+
|
|
166
204
|
### `CinetPaySeamless.on(event, handler)`
|
|
167
205
|
|
|
168
206
|
| Événement | Donnée | Description |
|
|
@@ -289,7 +327,10 @@ app.post('/api/pay', async (req, res) => {
|
|
|
289
327
|
channel: 'PUSH',
|
|
290
328
|
}, 'CI')
|
|
291
329
|
|
|
292
|
-
res.json({
|
|
330
|
+
res.json({
|
|
331
|
+
paymentToken: payment.paymentToken ?? payment.payment_token,
|
|
332
|
+
paymentUrl: payment.paymentUrl ?? payment.payment_url,
|
|
333
|
+
})
|
|
293
334
|
})
|
|
294
335
|
```
|
|
295
336
|
|
|
@@ -310,9 +351,9 @@ async function pay(amount: number) {
|
|
|
310
351
|
phone: '+2250707000000',
|
|
311
352
|
}),
|
|
312
353
|
})
|
|
313
|
-
const { paymentToken } = await res.json()
|
|
354
|
+
const { paymentToken, paymentUrl } = await res.json()
|
|
314
355
|
|
|
315
|
-
CinetPaySeamless.open({ paymentToken, debug: true })
|
|
356
|
+
CinetPaySeamless.open({ paymentToken, paymentUrl, debug: true })
|
|
316
357
|
}
|
|
317
358
|
```
|
|
318
359
|
|
|
@@ -536,7 +577,7 @@ async function pay() {
|
|
|
536
577
|
<meta charset="UTF-8">
|
|
537
578
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
538
579
|
<title>Paiement</title>
|
|
539
|
-
<script src="https://unpkg.com/cinetpay-seamless@0.1.
|
|
580
|
+
<script src="https://unpkg.com/cinetpay-seamless@0.1.5/dist/cinetpay-seamless.umd.cjs"></script>
|
|
540
581
|
</head>
|
|
541
582
|
<body>
|
|
542
583
|
<form id="payment-form">
|
|
@@ -637,7 +678,7 @@ CinetPaySeamless.open({ paymentToken: 'abc...', debug: true })
|
|
|
637
678
|
|
|
638
679
|
```
|
|
639
680
|
[CinetPay Seamless] CinetPaySeamless.open() called
|
|
640
|
-
[CinetPay Seamless] Opening popup { paymentUrl: 'https://secure.cinetpay.
|
|
681
|
+
[CinetPay Seamless] Opening popup { paymentUrl: 'https://secure.cinetpay.co/payment/abc...' }
|
|
641
682
|
[CinetPay Seamless] Iframe loaded — checkout ready
|
|
642
683
|
[CinetPay Seamless] Payment response: ACCEPTED { amount: 5000, currency: 'XOF', ... }
|
|
643
684
|
[CinetPay Seamless] Payment accepted
|
|
@@ -665,8 +706,8 @@ Commiter le .env dans git Ajouter .env dans .gitignore
|
|
|
665
706
|
|
|
666
707
|
| Préfixe de clé | Environnement | Usage |
|
|
667
708
|
|---|---|---|
|
|
668
|
-
| `sk_test_...` | Sandbox
|
|
669
|
-
| `sk_live_...` | Production
|
|
709
|
+
| `sk_test_...` | Sandbox API `api.cinetpay.net`, checkout `secure.cinetpay.net` | Développement et tests |
|
|
710
|
+
| `sk_live_...` | Production API `api.cinetpay.co`, checkout `secure.cinetpay.co` | Transactions réelles |
|
|
670
711
|
|
|
671
712
|
**Règles importantes :**
|
|
672
713
|
- Ne **jamais** utiliser des clés `sk_live_` en développement
|
package/dist/checkout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const g = `
|
|
2
2
|
.cp-seamless-overlay {
|
|
3
3
|
position: fixed;
|
|
4
4
|
inset: 0;
|
|
@@ -79,7 +79,7 @@ const f = `
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
`;
|
|
82
|
-
const
|
|
82
|
+
const a = class a {
|
|
83
83
|
constructor(t) {
|
|
84
84
|
this.overlay = null, this.popup = null, this.pollTimer = null, this.statusTimer = null, this.closeTimer = null, this.messageHandler = null, this.lastStatus = "UNKNOWN", this.lastDispatchKey = "", this.finalStatusDispatched = !1, this.statusCheckInFlight = !1, this.isClosing = !1, this.previousBodyOverflow = "", this.logger = t.logger, this.emitter = t.emitter, this.onReadyCallback = t.onReady, this.onPaymentSuccessCallback = t.onPaymentSuccess, this.onPaymentFailedCallback = t.onPaymentFailed, this.onPaymentPendingCallback = t.onPaymentPending, this.onCloseCallback = t.onClose, this.onErrorCallback = t.onError, this.statusChecker = t.statusChecker, this.statusPollInterval = Math.max(
|
|
85
85
|
1e3,
|
|
@@ -127,16 +127,16 @@ const n = class n {
|
|
|
127
127
|
}
|
|
128
128
|
static childRecords(t) {
|
|
129
129
|
const e = [];
|
|
130
|
-
for (const
|
|
131
|
-
const
|
|
132
|
-
|
|
130
|
+
for (const s of ["details", "transaction", "payment", "result", "data"]) {
|
|
131
|
+
const n = t[s];
|
|
132
|
+
a.isRecord(n) && e.push(n);
|
|
133
133
|
}
|
|
134
134
|
return e.push(t), e;
|
|
135
135
|
}
|
|
136
136
|
static findValue(t, e) {
|
|
137
|
-
for (const
|
|
138
|
-
for (const
|
|
139
|
-
if (
|
|
137
|
+
for (const s of a.childRecords(t))
|
|
138
|
+
for (const n of e)
|
|
139
|
+
if (s[n] !== void 0 && s[n] !== null) return s[n];
|
|
140
140
|
}
|
|
141
141
|
static asString(t) {
|
|
142
142
|
if (t != null)
|
|
@@ -160,9 +160,9 @@ const n = class n {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
static normalizeStatus(t, e) {
|
|
163
|
-
const
|
|
164
|
-
if (
|
|
165
|
-
if (["ACCEPTED", "SUCCESS", "SUCCEEDED", "SUCCESSFUL", "PAID", "VALIDATED", "APPROVED"].includes(
|
|
163
|
+
const s = t == null ? void 0 : t.trim().toUpperCase().replace(/[\s-]+/g, "_");
|
|
164
|
+
if (s) {
|
|
165
|
+
if (["ACCEPTED", "SUCCESS", "SUCCEEDED", "SUCCESSFUL", "PAID", "VALIDATED", "APPROVED"].includes(s))
|
|
166
166
|
return "ACCEPTED";
|
|
167
167
|
if ([
|
|
168
168
|
"REFUSED",
|
|
@@ -176,11 +176,11 @@ const n = class n {
|
|
|
176
176
|
"CANCELLED",
|
|
177
177
|
"CANCEL",
|
|
178
178
|
"INSUFFICIENT_BALANCE"
|
|
179
|
-
].includes(
|
|
179
|
+
].includes(s))
|
|
180
180
|
return "REFUSED";
|
|
181
|
-
if (["PENDING", "INITIATED", "EXPIRED"].includes(
|
|
182
|
-
return
|
|
183
|
-
if (["WAITING", "PROCESSING", "IN_PROGRESS"].includes(
|
|
181
|
+
if (["PENDING", "INITIATED", "EXPIRED"].includes(s))
|
|
182
|
+
return s;
|
|
183
|
+
if (["WAITING", "PROCESSING", "IN_PROGRESS"].includes(s))
|
|
184
184
|
return "PENDING";
|
|
185
185
|
}
|
|
186
186
|
switch (e) {
|
|
@@ -202,39 +202,39 @@ const n = class n {
|
|
|
202
202
|
return t === "ACCEPTED" || t === "REFUSED";
|
|
203
203
|
}
|
|
204
204
|
static buildPaymentResponse(t) {
|
|
205
|
-
const e =
|
|
205
|
+
const e = a.asString(a.findValue(t, [
|
|
206
206
|
"status",
|
|
207
207
|
"transaction_status",
|
|
208
208
|
"trans_status",
|
|
209
209
|
"payment_status"
|
|
210
|
-
])),
|
|
210
|
+
])), s = a.asOptionalNumber(a.findValue(t, ["code"])), n = a.normalizeStatus(e, s);
|
|
211
211
|
return {
|
|
212
|
-
amount:
|
|
213
|
-
currency:
|
|
214
|
-
status:
|
|
212
|
+
amount: a.asNumber(a.findValue(t, ["amount"])),
|
|
213
|
+
currency: a.asString(a.findValue(t, ["currency"])) ?? "",
|
|
214
|
+
status: n,
|
|
215
215
|
rawStatus: e,
|
|
216
|
-
apiCode:
|
|
217
|
-
paymentMethod:
|
|
218
|
-
description:
|
|
219
|
-
metadata:
|
|
220
|
-
operatorId:
|
|
221
|
-
paymentDate:
|
|
222
|
-
transactionId:
|
|
216
|
+
apiCode: s,
|
|
217
|
+
paymentMethod: a.asString(a.findValue(t, ["payment_method", "paymentMethod"])) ?? "",
|
|
218
|
+
description: a.asString(a.findValue(t, ["description", "designation", "message"])) ?? "",
|
|
219
|
+
metadata: a.asString(a.findValue(t, ["metadata", "custom"])),
|
|
220
|
+
operatorId: a.asString(a.findValue(t, ["operator_id", "operatorId"])),
|
|
221
|
+
paymentDate: a.asString(a.findValue(t, ["payment_date", "paymentDate"])),
|
|
222
|
+
transactionId: a.asString(a.findValue(t, ["transaction_id", "transactionId", "merchant_transaction_id"])) ?? ""
|
|
223
223
|
};
|
|
224
224
|
}
|
|
225
225
|
/** Dispatche la réponse vers le bon callback selon le statut. */
|
|
226
226
|
dispatchResponse(t) {
|
|
227
|
-
var
|
|
228
|
-
const e = `${t.status}:${t.rawStatus ?? ""}:${t.apiCode ?? ""}`,
|
|
229
|
-
if (!(
|
|
230
|
-
switch (this.lastDispatchKey = e, this.lastStatus = t.status,
|
|
227
|
+
var n, r, o;
|
|
228
|
+
const e = `${t.status}:${t.rawStatus ?? ""}:${t.apiCode ?? ""}`, s = a.isFinalStatus(t.status);
|
|
229
|
+
if (!(s && this.finalStatusDispatched) && e !== this.lastDispatchKey)
|
|
230
|
+
switch (this.lastDispatchKey = e, this.lastStatus = t.status, s && (this.finalStatusDispatched = !0, this.stopStatusPolling()), this.logger.debug(`Payment response: ${t.status}`, {
|
|
231
231
|
amount: t.amount,
|
|
232
232
|
currency: t.currency,
|
|
233
233
|
transactionId: t.transactionId,
|
|
234
234
|
paymentMethod: t.paymentMethod
|
|
235
235
|
}), t.status) {
|
|
236
236
|
case "ACCEPTED":
|
|
237
|
-
this.logger.debug("Payment accepted"), this.emitter.emit("payment.success", t), (
|
|
237
|
+
this.logger.debug("Payment accepted"), this.emitter.emit("payment.success", t), (n = this.onPaymentSuccessCallback) == null || n.call(this, t);
|
|
238
238
|
break;
|
|
239
239
|
case "REFUSED":
|
|
240
240
|
this.logger.warn("Payment refused"), this.emitter.emit("payment.failed", t), (r = this.onPaymentFailedCallback) == null || r.call(this, t);
|
|
@@ -250,7 +250,7 @@ const n = class n {
|
|
|
250
250
|
injectStyles() {
|
|
251
251
|
if (document.getElementById("cp-seamless-styles")) return;
|
|
252
252
|
const t = document.createElement("style");
|
|
253
|
-
t.id = "cp-seamless-styles", t.textContent =
|
|
253
|
+
t.id = "cp-seamless-styles", t.textContent = g, document.head.appendChild(t);
|
|
254
254
|
}
|
|
255
255
|
createOverlay() {
|
|
256
256
|
this.overlay = document.createElement("div"), this.overlay.className = "cp-seamless-overlay";
|
|
@@ -258,10 +258,10 @@ const n = class n {
|
|
|
258
258
|
t.className = "cp-seamless-wrapper";
|
|
259
259
|
const e = document.createElement("div");
|
|
260
260
|
e.className = "cp-seamless-waiting";
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
|
|
261
|
+
const s = document.createElement("div");
|
|
262
|
+
s.className = "cp-seamless-spinner", e.appendChild(s);
|
|
263
|
+
const n = document.createElement("p");
|
|
264
|
+
n.className = "cp-seamless-waiting-title", n.textContent = "Paiement en cours...", e.appendChild(n);
|
|
265
265
|
const r = document.createElement("p");
|
|
266
266
|
r.className = "cp-seamless-waiting-msg", r.textContent = "Finalisez votre paiement dans la fenêtre CinetPay.", e.appendChild(r);
|
|
267
267
|
const o = document.createElement("button");
|
|
@@ -271,22 +271,22 @@ const n = class n {
|
|
|
271
271
|
* Ouvre la popup centrée sur l'écran.
|
|
272
272
|
*/
|
|
273
273
|
openPopup(t) {
|
|
274
|
-
var o,
|
|
275
|
-
const
|
|
274
|
+
var o, h;
|
|
275
|
+
const n = Math.max(0, (screen.width - 500) / 2), r = Math.max(0, (screen.height - 700) / 2);
|
|
276
276
|
if (this.popup = window.open(
|
|
277
277
|
t,
|
|
278
278
|
"CinetPayCheckout",
|
|
279
|
-
`width=500,height=700,left=${
|
|
279
|
+
`width=500,height=700,left=${n},top=${r},scrollbars=yes,resizable=yes`
|
|
280
280
|
), !this.popup) {
|
|
281
281
|
this.logger.error("Popup blocked by browser");
|
|
282
|
-
const
|
|
282
|
+
const p = {
|
|
283
283
|
code: "POPUP_BLOCKED",
|
|
284
284
|
message: "La fenêtre de paiement a été bloquée par le navigateur. Autorisez les popups pour ce site."
|
|
285
285
|
};
|
|
286
|
-
this.emitter.emit("error",
|
|
286
|
+
this.emitter.emit("error", p), (o = this.onErrorCallback) == null || o.call(this, p), this.close();
|
|
287
287
|
return;
|
|
288
288
|
}
|
|
289
|
-
this.logger.debug("Popup opened"), this.emitter.emit("ready"), (
|
|
289
|
+
this.logger.debug("Popup opened"), this.emitter.emit("ready"), (h = this.onReadyCallback) == null || h.call(this);
|
|
290
290
|
}
|
|
291
291
|
/**
|
|
292
292
|
* Poll toutes les 500ms pour détecter si la popup a été fermée
|
|
@@ -316,12 +316,12 @@ const n = class n {
|
|
|
316
316
|
this.statusCheckInFlight = !0;
|
|
317
317
|
try {
|
|
318
318
|
this.logger.debug("Checking payment status", { reason: t });
|
|
319
|
-
const
|
|
320
|
-
if (!
|
|
321
|
-
const
|
|
322
|
-
(
|
|
323
|
-
} catch (
|
|
324
|
-
this.logger.warn("Payment status check failed",
|
|
319
|
+
const s = await this.statusChecker();
|
|
320
|
+
if (!a.isRecord(s)) return;
|
|
321
|
+
const n = a.buildPaymentResponse(s), r = (e = n.rawStatus) == null ? void 0 : e.trim().toUpperCase();
|
|
322
|
+
(n.status !== "UNKNOWN" || r && r !== "OK") && this.dispatchResponse(n), a.isFinalStatus(n.status) && this.finishClose();
|
|
323
|
+
} catch (s) {
|
|
324
|
+
this.logger.warn("Payment status check failed", s);
|
|
325
325
|
} finally {
|
|
326
326
|
this.statusCheckInFlight = !1;
|
|
327
327
|
}
|
|
@@ -330,55 +330,57 @@ const n = class n {
|
|
|
330
330
|
/** Écoute les messages postMessage de la popup CinetPay. */
|
|
331
331
|
listenForMessages() {
|
|
332
332
|
this.messageHandler = (t) => {
|
|
333
|
-
var e,
|
|
334
|
-
if (
|
|
333
|
+
var e, s;
|
|
334
|
+
if (a.ALLOWED_ORIGINS.some((n) => t.origin === n))
|
|
335
335
|
try {
|
|
336
|
-
const
|
|
337
|
-
if (!
|
|
338
|
-
const r =
|
|
336
|
+
const n = typeof t.data == "string" ? JSON.parse(t.data) : t.data;
|
|
337
|
+
if (!a.isRecord(n)) return;
|
|
338
|
+
const r = a.buildPaymentResponse(n), o = (e = r.rawStatus) == null ? void 0 : e.trim().toUpperCase();
|
|
339
339
|
(r.status !== "UNKNOWN" || o && o !== "OK") && this.dispatchResponse(r);
|
|
340
|
-
const
|
|
341
|
-
if (
|
|
340
|
+
const h = a.findValue(n, ["error"]), p = a.asString(a.findValue(n, ["code"]));
|
|
341
|
+
if (h || p === "ERROR") {
|
|
342
342
|
const d = {
|
|
343
|
-
code:
|
|
344
|
-
message:
|
|
343
|
+
code: p ?? "UNKNOWN",
|
|
344
|
+
message: a.asString(a.findValue(n, ["message"])) ?? a.asString(h) ?? "An error occurred"
|
|
345
345
|
};
|
|
346
|
-
this.logger.error("Payment error from popup", d), this.emitter.emit("error", d), (
|
|
346
|
+
this.logger.error("Payment error from popup", d), this.emitter.emit("error", d), (s = this.onErrorCallback) == null || s.call(this, d);
|
|
347
347
|
}
|
|
348
|
-
(
|
|
348
|
+
(n.action === "CLOSE" || n.type === "close") && this.close();
|
|
349
349
|
} catch {
|
|
350
350
|
}
|
|
351
351
|
}, window.addEventListener("message", this.messageHandler);
|
|
352
352
|
}
|
|
353
353
|
};
|
|
354
|
-
|
|
354
|
+
a.ALLOWED_ORIGINS = [
|
|
355
355
|
"https://secure.cinetpay.net",
|
|
356
|
+
"https://secure.cinetpay.co",
|
|
356
357
|
"https://secure.cinetpay.com",
|
|
357
358
|
"https://checkout.cinetpay.net",
|
|
359
|
+
"https://checkout.cinetpay.co",
|
|
358
360
|
"https://checkout.cinetpay.com",
|
|
359
361
|
"https://api.cinetpay.net",
|
|
360
362
|
"https://api.cinetpay.co"
|
|
361
363
|
];
|
|
362
|
-
let
|
|
363
|
-
const
|
|
364
|
-
class
|
|
364
|
+
let m = a;
|
|
365
|
+
const l = "[CinetPay Seamless]";
|
|
366
|
+
class S {
|
|
365
367
|
constructor(t) {
|
|
366
368
|
this.enabled = t;
|
|
367
369
|
}
|
|
368
370
|
/** Log de debug — requêtes, réponses, événements */
|
|
369
371
|
debug(t, e) {
|
|
370
|
-
this.enabled && (e !== void 0 ? console.debug(`${
|
|
372
|
+
this.enabled && (e !== void 0 ? console.debug(`${l} ${t}`, e) : console.debug(`${l} ${t}`));
|
|
371
373
|
}
|
|
372
374
|
/** Log d'avertissement — credentials exposés, statuts inattendus */
|
|
373
375
|
warn(t, e) {
|
|
374
|
-
this.enabled && (e !== void 0 ? console.warn(`${
|
|
376
|
+
this.enabled && (e !== void 0 ? console.warn(`${l} ${t}`, e) : console.warn(`${l} ${t}`));
|
|
375
377
|
}
|
|
376
378
|
/** Log d'erreur — erreurs API, timeouts, postMessage invalides */
|
|
377
379
|
error(t, e) {
|
|
378
|
-
this.enabled && (e !== void 0 ? console.error(`${
|
|
380
|
+
this.enabled && (e !== void 0 ? console.error(`${l} ${t}`, e) : console.error(`${l} ${t}`));
|
|
379
381
|
}
|
|
380
382
|
}
|
|
381
|
-
class
|
|
383
|
+
class C {
|
|
382
384
|
constructor() {
|
|
383
385
|
this.listeners = /* @__PURE__ */ new Map();
|
|
384
386
|
}
|
|
@@ -406,8 +408,8 @@ class g {
|
|
|
406
408
|
* @param handler - Référence du handler à supprimer
|
|
407
409
|
*/
|
|
408
410
|
off(t, e) {
|
|
409
|
-
var
|
|
410
|
-
(
|
|
411
|
+
var s;
|
|
412
|
+
(s = this.listeners.get(t)) == null || s.delete(e);
|
|
411
413
|
}
|
|
412
414
|
/**
|
|
413
415
|
* Enregistre un handler qui ne sera appelé qu'une seule fois.
|
|
@@ -423,21 +425,21 @@ class g {
|
|
|
423
425
|
* ```
|
|
424
426
|
*/
|
|
425
427
|
once(t, e) {
|
|
426
|
-
const
|
|
427
|
-
this.off(t,
|
|
428
|
+
const s = ((...n) => {
|
|
429
|
+
this.off(t, s), e(...n);
|
|
428
430
|
});
|
|
429
|
-
this.on(t,
|
|
431
|
+
this.on(t, s);
|
|
430
432
|
}
|
|
431
433
|
/**
|
|
432
434
|
* Émet un événement — appelle tous les handlers enregistrés.
|
|
433
435
|
* @internal
|
|
434
436
|
*/
|
|
435
437
|
emit(t, ...e) {
|
|
436
|
-
const
|
|
437
|
-
if (
|
|
438
|
-
for (const
|
|
438
|
+
const s = this.listeners.get(t);
|
|
439
|
+
if (s)
|
|
440
|
+
for (const n of s)
|
|
439
441
|
try {
|
|
440
|
-
|
|
442
|
+
n(...e);
|
|
441
443
|
} catch {
|
|
442
444
|
}
|
|
443
445
|
}
|
|
@@ -449,38 +451,47 @@ class g {
|
|
|
449
451
|
this.listeners.clear();
|
|
450
452
|
}
|
|
451
453
|
}
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
454
|
+
const y = {
|
|
455
|
+
sandbox: "https://secure.cinetpay.net",
|
|
456
|
+
production: "https://secure.cinetpay.co"
|
|
457
|
+
};
|
|
458
|
+
function c(i, t) {
|
|
459
|
+
const e = i;
|
|
460
|
+
for (const n of t) {
|
|
461
|
+
const r = e[n];
|
|
457
462
|
if (typeof r == "function") return r;
|
|
458
463
|
}
|
|
459
|
-
const
|
|
460
|
-
for (const [
|
|
461
|
-
if (
|
|
464
|
+
const s = new Set(t.map((n) => n.toLowerCase()));
|
|
465
|
+
for (const [n, r] of Object.entries(e))
|
|
466
|
+
if (s.has(n.toLowerCase()) && typeof r == "function")
|
|
462
467
|
return r;
|
|
463
468
|
}
|
|
464
|
-
function
|
|
465
|
-
const e =
|
|
466
|
-
for (const
|
|
467
|
-
if (e[
|
|
468
|
-
const
|
|
469
|
-
for (const [
|
|
470
|
-
if (
|
|
469
|
+
function u(i, t) {
|
|
470
|
+
const e = i;
|
|
471
|
+
for (const n of t)
|
|
472
|
+
if (e[n] !== void 0) return e[n];
|
|
473
|
+
const s = new Set(t.map((n) => n.toLowerCase()));
|
|
474
|
+
for (const [n, r] of Object.entries(e))
|
|
475
|
+
if (s.has(n.toLowerCase())) return r;
|
|
476
|
+
}
|
|
477
|
+
function f(i) {
|
|
478
|
+
return u(i, ["paymentToken", "payment_token"]);
|
|
471
479
|
}
|
|
472
|
-
function
|
|
473
|
-
|
|
480
|
+
function E(i) {
|
|
481
|
+
return u(i, ["paymentUrl", "paymentURL", "payment_url", "checkoutUrl", "checkout_url"]);
|
|
482
|
+
}
|
|
483
|
+
function P(i) {
|
|
484
|
+
const t = { paymentToken: f(i) ?? "" }, e = c(i, [
|
|
474
485
|
"checkStatus",
|
|
475
486
|
"checkPaymentStatus",
|
|
476
487
|
"checkTransactionStatus"
|
|
477
488
|
]);
|
|
478
489
|
if (e)
|
|
479
490
|
return () => e(t);
|
|
480
|
-
const
|
|
481
|
-
if (
|
|
491
|
+
const s = u(i, ["statusUrl", "statusURL"]);
|
|
492
|
+
if (s)
|
|
482
493
|
return async () => {
|
|
483
|
-
const
|
|
494
|
+
const n = typeof s == "function" ? s(t) : s, r = await fetch(n, {
|
|
484
495
|
method: "GET",
|
|
485
496
|
credentials: "same-origin",
|
|
486
497
|
headers: { Accept: "application/json" }
|
|
@@ -490,11 +501,20 @@ function S(a) {
|
|
|
490
501
|
return r.json();
|
|
491
502
|
};
|
|
492
503
|
}
|
|
493
|
-
|
|
504
|
+
function b(i) {
|
|
505
|
+
const t = E(i);
|
|
506
|
+
if (t) return t;
|
|
507
|
+
const e = f(i);
|
|
508
|
+
if (!e)
|
|
509
|
+
throw new Error("Invalid paymentToken format — expected alphanumeric string (10-128 chars)");
|
|
510
|
+
const s = u(i, ["environment", "env"]) ?? "sandbox";
|
|
511
|
+
return `${(u(i, ["checkoutBaseUrl", "secureBaseUrl"]) ?? y[s] ?? y.sandbox).replace(/\/+$/, "")}/checkout/${e}`;
|
|
512
|
+
}
|
|
513
|
+
const k = {
|
|
494
514
|
/** Instance du checkout actuellement ouvert */
|
|
495
515
|
_checkout: null,
|
|
496
516
|
/** Event emitter partagé */
|
|
497
|
-
_emitter: new
|
|
517
|
+
_emitter: new C(),
|
|
498
518
|
/**
|
|
499
519
|
* Enregistre un listener d'événement (style événementiel).
|
|
500
520
|
*
|
|
@@ -510,20 +530,20 @@ const E = {
|
|
|
510
530
|
* unsub() // Se désabonner
|
|
511
531
|
* ```
|
|
512
532
|
*/
|
|
513
|
-
on(
|
|
514
|
-
return this._emitter.on(
|
|
533
|
+
on(i, t) {
|
|
534
|
+
return this._emitter.on(i, t);
|
|
515
535
|
},
|
|
516
536
|
/**
|
|
517
537
|
* Supprime un listener.
|
|
518
538
|
*/
|
|
519
|
-
off(
|
|
520
|
-
this._emitter.off(
|
|
539
|
+
off(i, t) {
|
|
540
|
+
this._emitter.off(i, t);
|
|
521
541
|
},
|
|
522
542
|
/**
|
|
523
543
|
* Enregistre un listener appelé une seule fois.
|
|
524
544
|
*/
|
|
525
|
-
once(
|
|
526
|
-
this._emitter.once(
|
|
545
|
+
once(i, t) {
|
|
546
|
+
this._emitter.once(i, t);
|
|
527
547
|
},
|
|
528
548
|
/**
|
|
529
549
|
* Ouvre le checkout CinetPay.
|
|
@@ -545,26 +565,28 @@ const E = {
|
|
|
545
565
|
* })
|
|
546
566
|
* ```
|
|
547
567
|
*/
|
|
548
|
-
open(
|
|
568
|
+
open(i) {
|
|
549
569
|
this.close();
|
|
550
|
-
const t = new
|
|
551
|
-
|
|
570
|
+
const t = new S(i.debug ?? !1);
|
|
571
|
+
t.debug("CinetPaySeamless.open() called");
|
|
572
|
+
const e = f(i);
|
|
573
|
+
if (e && !/^[a-zA-Z0-9_-]{10,128}$/.test(e))
|
|
552
574
|
throw new Error("Invalid paymentToken format — expected alphanumeric string (10-128 chars)");
|
|
553
|
-
const
|
|
554
|
-
this._checkout = new
|
|
575
|
+
const s = b(i);
|
|
576
|
+
this._checkout = new m({
|
|
555
577
|
logger: t,
|
|
556
578
|
emitter: this._emitter,
|
|
557
|
-
statusChecker:
|
|
558
|
-
statusPollInterval:
|
|
559
|
-
onReady:
|
|
560
|
-
onPaymentSuccess:
|
|
579
|
+
statusChecker: P(i),
|
|
580
|
+
statusPollInterval: u(i, ["statusPollInterval", "statusCheckInterval"]),
|
|
581
|
+
onReady: c(i, ["onReady"]),
|
|
582
|
+
onPaymentSuccess: c(i, [
|
|
561
583
|
"onPaymentSuccess",
|
|
562
584
|
"onSuccess",
|
|
563
585
|
"onPaymentsuccess",
|
|
564
586
|
"onpaymentSuccess",
|
|
565
587
|
"onpaymentsuccess"
|
|
566
588
|
]),
|
|
567
|
-
onPaymentFailed:
|
|
589
|
+
onPaymentFailed: c(i, [
|
|
568
590
|
"onPaymentFailed",
|
|
569
591
|
"onPaymentFail",
|
|
570
592
|
"onPaymentFailure",
|
|
@@ -573,21 +595,21 @@ const E = {
|
|
|
573
595
|
"onpaymentFailed",
|
|
574
596
|
"onpaymentfailed"
|
|
575
597
|
]),
|
|
576
|
-
onPaymentPending:
|
|
577
|
-
onClose:
|
|
578
|
-
onError:
|
|
579
|
-
}), this._checkout.open(
|
|
598
|
+
onPaymentPending: c(i, ["onPaymentPending", "onPending"]),
|
|
599
|
+
onClose: c(i, ["onClose"]),
|
|
600
|
+
onError: c(i, ["onError"])
|
|
601
|
+
}), this._checkout.open(s);
|
|
580
602
|
},
|
|
581
603
|
/**
|
|
582
604
|
* Ferme le checkout (popup + overlay).
|
|
583
605
|
*/
|
|
584
606
|
close() {
|
|
585
|
-
var
|
|
586
|
-
(
|
|
607
|
+
var i;
|
|
608
|
+
(i = this._checkout) == null || i.close(), this._checkout = null;
|
|
587
609
|
}
|
|
588
610
|
};
|
|
589
|
-
typeof window < "u" && (window.CinetPaySeamless =
|
|
611
|
+
typeof window < "u" && (window.CinetPaySeamless = k);
|
|
590
612
|
export {
|
|
591
|
-
|
|
613
|
+
k as CinetPaySeamless
|
|
592
614
|
};
|
|
593
615
|
//# sourceMappingURL=cinetpay-seamless.js.map
|