@zendfi/sdk 1.0.2 → 1.0.3
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/dist/{chunk-3ACJUM6V.mjs → chunk-6CFQXFNR.mjs} +0 -1
- package/dist/{chunk-DAJL2Q36.mjs → chunk-B5LO34Q6.mjs} +20 -24
- package/dist/express.d.mts +1 -2
- package/dist/express.d.ts +1 -2
- package/dist/express.js +0 -1
- package/dist/express.mjs +1 -1
- package/dist/helpers/index.d.mts +0 -1
- package/dist/helpers/index.d.ts +0 -1
- package/dist/helpers/index.js +20 -24
- package/dist/helpers/index.mjs +1 -1
- package/dist/index.d.mts +14 -9
- package/dist/index.d.ts +14 -9
- package/dist/index.js +230 -85
- package/dist/index.mjs +212 -62
- package/dist/nextjs.d.mts +1 -2
- package/dist/nextjs.d.ts +1 -2
- package/dist/nextjs.js +0 -1
- package/dist/nextjs.mjs +1 -1
- package/dist/{webhook-handler-61UWBtDI.d.mts → webhook-handler-hUfWh-_Y.d.mts} +102 -8
- package/dist/{webhook-handler-61UWBtDI.d.ts → webhook-handler-hUfWh-_Y.d.ts} +102 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -200,12 +200,12 @@ var ConfigLoader = class {
|
|
|
200
200
|
const env = this.detectEnvironment();
|
|
201
201
|
if (mode === "live" && env === "development") {
|
|
202
202
|
console.warn(
|
|
203
|
-
"
|
|
203
|
+
"Warning: Using a live API key (zfi_live_) in development environment. This will create real mainnet transactions. Use a test key (zfi_test_) for devnet testing."
|
|
204
204
|
);
|
|
205
205
|
}
|
|
206
206
|
if (mode === "test" && env === "production") {
|
|
207
207
|
console.warn(
|
|
208
|
-
"
|
|
208
|
+
"Warning: Using a test API key (zfi_test_) in production environment. This will create devnet transactions only. Use a live key (zfi_live_) for mainnet."
|
|
209
209
|
);
|
|
210
210
|
}
|
|
211
211
|
}
|
|
@@ -307,10 +307,10 @@ var ZendFiError2 = class _ZendFiError extends Error {
|
|
|
307
307
|
let message = `[${this.code}] ${this.message}`;
|
|
308
308
|
if (this.suggestion) {
|
|
309
309
|
message += `
|
|
310
|
-
|
|
310
|
+
Suggestion: ${this.suggestion}`;
|
|
311
311
|
}
|
|
312
312
|
message += `
|
|
313
|
-
|
|
313
|
+
Docs: ${this.docs_url}`;
|
|
314
314
|
return message;
|
|
315
315
|
}
|
|
316
316
|
/**
|
|
@@ -334,7 +334,7 @@ var AuthenticationError2 = class extends ZendFiError2 {
|
|
|
334
334
|
code,
|
|
335
335
|
message,
|
|
336
336
|
type: "authentication_error",
|
|
337
|
-
suggestion: suggestion || "Check your API key in the dashboard at https://
|
|
337
|
+
suggestion: suggestion || "Check your API key in the dashboard at https://dashboard.zendfi.tech",
|
|
338
338
|
statusCode: 401
|
|
339
339
|
});
|
|
340
340
|
this.name = "AuthenticationError";
|
|
@@ -442,25 +442,19 @@ function createZendFiError(statusCode, responseBody, message) {
|
|
|
442
442
|
return new ApiError(errorMessage, errorCode, statusCode, responseBody);
|
|
443
443
|
}
|
|
444
444
|
var ERROR_CODES = {
|
|
445
|
-
// Authentication
|
|
446
445
|
INVALID_API_KEY: "invalid_api_key",
|
|
447
446
|
API_KEY_EXPIRED: "api_key_expired",
|
|
448
447
|
API_KEY_REVOKED: "api_key_revoked",
|
|
449
|
-
// Payment
|
|
450
448
|
INSUFFICIENT_BALANCE: "insufficient_balance",
|
|
451
449
|
PAYMENT_DECLINED: "payment_declined",
|
|
452
450
|
PAYMENT_EXPIRED: "payment_expired",
|
|
453
451
|
INVALID_AMOUNT: "invalid_amount",
|
|
454
452
|
INVALID_CURRENCY: "invalid_currency",
|
|
455
|
-
// Validation
|
|
456
453
|
MISSING_REQUIRED_FIELD: "missing_required_field",
|
|
457
454
|
INVALID_PARAMETER: "invalid_parameter",
|
|
458
|
-
// Network
|
|
459
455
|
NETWORK_ERROR: "network_error",
|
|
460
456
|
TIMEOUT: "timeout",
|
|
461
|
-
// Rate limiting
|
|
462
457
|
RATE_LIMIT_EXCEEDED: "rate_limit_exceeded",
|
|
463
|
-
// Webhook
|
|
464
458
|
WEBHOOK_SIGNATURE_INVALID: "webhook_signature_invalid",
|
|
465
459
|
WEBHOOK_TIMESTAMP_TOO_OLD: "webhook_timestamp_too_old"
|
|
466
460
|
};
|
|
@@ -987,6 +981,18 @@ function verifyWebhookSignature(payload, signature, secret) {
|
|
|
987
981
|
}
|
|
988
982
|
|
|
989
983
|
// src/embedded-checkout.ts
|
|
984
|
+
var Icons = {
|
|
985
|
+
clipboard: `<svg class="icon" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" /></svg>`,
|
|
986
|
+
checkCircle: `<svg class="icon icon-lg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>`,
|
|
987
|
+
xCircle: `<svg class="icon icon-lg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>`,
|
|
988
|
+
check: `<svg class="icon icon-sm" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>`,
|
|
989
|
+
refresh: `<svg class="icon icon-sm" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" /></svg>`,
|
|
990
|
+
clock: `<svg class="icon icon-sm" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>`,
|
|
991
|
+
loader: `<svg class="icon icon-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>`,
|
|
992
|
+
bank: `<svg class="icon" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 21v-8.25M15.75 21v-8.25M8.25 21v-8.25M3 9l9-6 9 6m-1.5 12V10.332A48.36 48.36 0 0012 9.75c-2.551 0-5.056.2-7.5.582V21M3 21h18M12 6.75h.008v.008H12V6.75z" /></svg>`,
|
|
993
|
+
clocklg: `<svg class="icon icon-lg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>`,
|
|
994
|
+
hammer: `<svg class="icon" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M11.42 15.17L17.25 21A2.652 2.652 0 0021 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 11-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 004.486-6.336l-3.276 3.277a3.004 3.004 0 01-2.25-2.25l3.276-3.276a4.5 4.5 0 00-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437l1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008z" /></svg>`
|
|
995
|
+
};
|
|
990
996
|
var ZendFiEmbeddedCheckout = class {
|
|
991
997
|
config;
|
|
992
998
|
container = null;
|
|
@@ -994,8 +1000,6 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
994
1000
|
pollInterval = null;
|
|
995
1001
|
mounted = false;
|
|
996
1002
|
paymentProcessed = false;
|
|
997
|
-
// Prevent duplicate success callbacks
|
|
998
|
-
// Bank payment state
|
|
999
1003
|
bankPaymentState = {};
|
|
1000
1004
|
constructor(config) {
|
|
1001
1005
|
this.config = {
|
|
@@ -1209,13 +1213,28 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1209
1213
|
*/
|
|
1210
1214
|
renderHeader() {
|
|
1211
1215
|
if (!this.checkoutData) return "";
|
|
1216
|
+
const testnetBadge = this.checkoutData.solana_network === "devnet" || this.checkoutData.solana_network === "testnet" ? `<span style="font-size: 9px; font-weight: 500; color: #d97706; background: #fef3c7; padding: 2px 6px; border-radius: 4px; margin-left: 6px;">Testnet</span>` : "";
|
|
1212
1217
|
return `
|
|
1213
|
-
<div class="zendfi-checkout-header" style="padding: 24px; border-bottom: 1px solid #e5e7eb;">
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1218
|
+
<div class="zendfi-checkout-header" style="padding: 24px; text-align: center; border-bottom: 1px solid #e5e7eb;">
|
|
1219
|
+
<!-- Merchant Badge -->
|
|
1220
|
+
<div style="display: inline-flex; items-center; gap: 8px; padding: 6px 12px; background: white; border: 1px solid #e5e7eb; border-radius: 20px; margin-bottom: 16px;">
|
|
1221
|
+
<div style="width: 20px; height: 20px; border-radius: 50%; background: #1f2937; display: flex; align-items: center; justify-content: center;">
|
|
1222
|
+
<span style="font-size: 10px; font-weight: 600; color: white;">
|
|
1223
|
+
${this.checkoutData.merchant_name.charAt(0).toUpperCase()}
|
|
1224
|
+
</span>
|
|
1225
|
+
</div>
|
|
1226
|
+
<span style="font-size: 12px; font-weight: 500; color: #374151;">${this.checkoutData.merchant_name}</span>
|
|
1227
|
+
${testnetBadge}
|
|
1228
|
+
</div>
|
|
1229
|
+
|
|
1230
|
+
<!-- Amount -->
|
|
1231
|
+
<div style="font-size: 40px; font-weight: 600; color: #1f2937; margin-bottom: 4px;">
|
|
1232
|
+
$${this.checkoutData.amount_usd.toFixed(2)}
|
|
1233
|
+
</div>
|
|
1234
|
+
<p style="margin: 0; font-size: 13px; color: #6b7280;">${this.checkoutData.token} on Solana</p>
|
|
1235
|
+
|
|
1217
1236
|
${this.checkoutData.description ? `
|
|
1218
|
-
<p style="margin:
|
|
1237
|
+
<p style="margin: 12px auto 0; color: #9ca3af; font-size: 13px; max-width: 280px;">
|
|
1219
1238
|
${this.checkoutData.description}
|
|
1220
1239
|
</p>
|
|
1221
1240
|
` : ""}
|
|
@@ -1299,21 +1318,22 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1299
1318
|
renderQRCodeMethod() {
|
|
1300
1319
|
if (!this.checkoutData) return "";
|
|
1301
1320
|
return `
|
|
1302
|
-
<div class="zendfi-payment-method" style="padding:
|
|
1321
|
+
<div class="zendfi-payment-method" style="padding: 20px; border: 1px solid #e5e7eb; border-radius: 12px; margin-bottom: 16px; background: white; transition: all 0.2s;" onmouseover="this.style.borderColor='#d1d5db'; this.style.boxShadow='0 2px 8px rgba(0,0,0,0.05)';" onmouseout="this.style.borderColor='#e5e7eb'; this.style.boxShadow='none';">
|
|
1303
1322
|
<div style="text-align: center;">
|
|
1304
|
-
<
|
|
1305
|
-
|
|
1323
|
+
<h4 style="margin: 0 0 12px 0; font-size: 15px; font-weight: 600; color: #374151;">Scan QR Code</h4>
|
|
1324
|
+
<p style="font-size: 13px; color: #6b7280; margin-bottom: 16px;">
|
|
1325
|
+
Use any Solana wallet app
|
|
1306
1326
|
</p>
|
|
1307
|
-
<div id="zendfi-qr-container" style="display: flex; justify-content: center; margin-bottom: 16px;">
|
|
1327
|
+
<div id="zendfi-qr-container" style="display: flex; justify-content: center; margin-bottom: 16px; padding: 12px; background: #fafbfc; border-radius: 8px;">
|
|
1308
1328
|
<canvas id="zendfi-qr-code"></canvas>
|
|
1309
1329
|
</div>
|
|
1310
1330
|
<button
|
|
1311
1331
|
id="zendfi-copy-address"
|
|
1312
|
-
style="padding: 10px 20px; background: #f3f4f6; border: 1px solid #d1d5db; border-radius: 8px; cursor: pointer; font-size: 14px; color: #374151; transition: all 0.2s;"
|
|
1332
|
+
style="padding: 10px 20px; background: #f3f4f6; border: 1px solid #d1d5db; border-radius: 8px; cursor: pointer; font-size: 14px; color: #374151; font-weight: 500; transition: all 0.2s; display: inline-flex; align-items: center; gap: 6px;"
|
|
1313
1333
|
onmouseover="this.style.background='#e5e7eb'"
|
|
1314
1334
|
onmouseout="this.style.background='#f3f4f6'"
|
|
1315
1335
|
>
|
|
1316
|
-
|
|
1336
|
+
${Icons.clipboard} Copy Address
|
|
1317
1337
|
</button>
|
|
1318
1338
|
</div>
|
|
1319
1339
|
</div>
|
|
@@ -1323,15 +1343,16 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1323
1343
|
* Render browser wallet method
|
|
1324
1344
|
*/
|
|
1325
1345
|
renderWalletMethod() {
|
|
1346
|
+
const walletIcon = `<svg style="width: 20px; height: 20px; display: inline-block; vertical-align: middle; margin-right: 8px;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a2.25 2.25 0 00-2.25-2.25H15a3 3 0 11-6 0H5.25A2.25 2.25 0 003 12m18 0v6a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 18v-6m18 0V9M3 12V9m18 0a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 9m18 0V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v3" /></svg>`;
|
|
1326
1347
|
return `
|
|
1327
1348
|
<div class="zendfi-payment-method" style="margin-bottom: 16px;">
|
|
1328
1349
|
<button
|
|
1329
1350
|
id="zendfi-connect-wallet"
|
|
1330
|
-
style="width: 100%; padding: 16px; background:
|
|
1331
|
-
onmouseover="this.style.transform='translateY(-
|
|
1332
|
-
onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0
|
|
1351
|
+
style="width: 100%; padding: 16px; background: #1f2937; color: white; border: none; border-radius: 12px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.2s; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center;"
|
|
1352
|
+
onmouseover="this.style.transform='translateY(-1px)'; this.style.boxShadow='0 4px 12px rgba(0, 0, 0, 0.15)'; this.style.background='#111827';"
|
|
1353
|
+
onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 2px 6px rgba(0, 0, 0, 0.1)'; this.style.background='#1f2937';"
|
|
1333
1354
|
>
|
|
1334
|
-
|
|
1355
|
+
${walletIcon} Connect Wallet
|
|
1335
1356
|
</button>
|
|
1336
1357
|
</div>
|
|
1337
1358
|
`;
|
|
@@ -1340,15 +1361,16 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1340
1361
|
* Render WalletConnect method
|
|
1341
1362
|
*/
|
|
1342
1363
|
renderWalletConnectMethod() {
|
|
1364
|
+
const qrIcon = `<svg style="width: 20px; height: 20px; display: inline-block; vertical-align: middle; margin-right: 8px;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 013.75 9.375v-4.5zM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 01-1.125-1.125v-4.5zM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0113.5 9.375v-4.5z" /><path stroke-linecap="round" stroke-linejoin="round" d="M6.75 6.75h.75v.75h-.75v-.75zM6.75 16.5h.75v.75h-.75v-.75zM16.5 6.75h.75v.75h-.75v-.75zM13.5 13.5h.75v.75h-.75v-.75zM13.5 19.5h.75v.75h-.75v-.75zM19.5 13.5h.75v.75h-.75v-.75zM19.5 19.5h.75v.75h-.75v-.75zM16.5 16.5h.75v.75h-.75v-.75z" /></svg>`;
|
|
1343
1365
|
return `
|
|
1344
|
-
<div class="zendfi-payment-method">
|
|
1366
|
+
<div class="zendfi-payment-method" style="margin-bottom: 16px;">
|
|
1345
1367
|
<button
|
|
1346
1368
|
id="zendfi-wallet-connect"
|
|
1347
|
-
style="width: 100%; padding: 16px; background: white; color: #1f2937; border: 2px solid #
|
|
1348
|
-
onmouseover="this.style.borderColor='#
|
|
1349
|
-
onmouseout="this.style.borderColor='#
|
|
1369
|
+
style="width: 100%; padding: 16px; background: white; color: #1f2937; border: 2px solid #d1d5db; border-radius: 12px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center;"
|
|
1370
|
+
onmouseover="this.style.borderColor='#9ca3af'; this.style.background='#f9fafb';"
|
|
1371
|
+
onmouseout="this.style.borderColor='#d1d5db'; this.style.background='white';"
|
|
1350
1372
|
>
|
|
1351
|
-
|
|
1373
|
+
${qrIcon} WalletConnect
|
|
1352
1374
|
</button>
|
|
1353
1375
|
</div>
|
|
1354
1376
|
`;
|
|
@@ -1361,13 +1383,13 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1361
1383
|
const isEmailStep = !this.bankPaymentState.orderId;
|
|
1362
1384
|
const isBankDetailsStep = !!this.bankPaymentState.bankDetails;
|
|
1363
1385
|
return `
|
|
1364
|
-
<div class="zendfi-payment-method" style="padding:
|
|
1386
|
+
<div class="zendfi-payment-method" style="padding: 20px; border: 2px solid #10b981; border-radius: 12px; margin-bottom: 16px; background: #f0fdf4; transition: all 0.2s;" onmouseover="this.style.boxShadow='0 2px 8px rgba(16,185,129,0.15)';" onmouseout="this.style.boxShadow='none';">
|
|
1365
1387
|
<div style="margin-bottom: 12px;">
|
|
1366
|
-
<h4 style="margin: 0 0 4px 0; font-size: 16px; font-weight: 600; color: #065f46; display: flex; align-items: center;">
|
|
1367
|
-
|
|
1388
|
+
<h4 style="margin: 0 0 4px 0; font-size: 16px; font-weight: 600; color: #065f46; display: flex; align-items: center; gap: 8px;">
|
|
1389
|
+
${Icons.bank} Pay with Bank Transfer
|
|
1368
1390
|
</h4>
|
|
1369
|
-
<p style="margin: 0; font-size:
|
|
1370
|
-
|
|
1391
|
+
<p style="margin: 0; font-size: 13px; color: #047857;">
|
|
1392
|
+
Nigerian bank account \u2022 Instant confirmation
|
|
1371
1393
|
</p>
|
|
1372
1394
|
</div>
|
|
1373
1395
|
|
|
@@ -1432,8 +1454,8 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1432
1454
|
return `
|
|
1433
1455
|
<div id="zendfi-bank-details-step">
|
|
1434
1456
|
<div style="background: white; border: 1px solid #d1d5db; border-radius: 8px; padding: 16px; margin-bottom: 16px;">
|
|
1435
|
-
<h5 style="margin: 0 0 12px 0; font-size: 14px; font-weight: 600; color: #374151;">
|
|
1436
|
-
|
|
1457
|
+
<h5 style="margin: 0 0 12px 0; font-size: 14px; font-weight: 600; color: #374151; display: flex; align-items: center; gap: 6px;">
|
|
1458
|
+
${Icons.bank} Transfer to this account:
|
|
1437
1459
|
</h5>
|
|
1438
1460
|
|
|
1439
1461
|
<div style="margin-bottom: 8px;">
|
|
@@ -1476,14 +1498,14 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1476
1498
|
<div style="color: #6b7280; font-size: 14px;" id="zendfi-bank-status-text">
|
|
1477
1499
|
Waiting for bank transfer... (<span id="zendfi-bank-timer">0:00</span>)
|
|
1478
1500
|
</div>
|
|
1479
|
-
<div style="font-size: 12px; color: #9ca3af; margin-top: 4px;">
|
|
1480
|
-
|
|
1501
|
+
<div style="font-size: 12px; color: #9ca3af; margin-top: 4px; display: inline-flex; align-items: center; gap: 4px;">
|
|
1502
|
+
${Icons.clock} Usually takes 10-30 seconds
|
|
1481
1503
|
</div>
|
|
1482
1504
|
<button
|
|
1483
1505
|
id="zendfi-refresh-status"
|
|
1484
|
-
style="margin-top: 12px; padding: 8px 16px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; cursor: pointer; color: #6b7280; font-size: 14px;"
|
|
1506
|
+
style="margin-top: 12px; padding: 8px 16px; background: white; border: 1px solid #e5e7eb; border-radius: 8px; cursor: pointer; color: #6b7280; font-size: 14px; display: inline-flex; align-items: center; gap: 6px;"
|
|
1485
1507
|
>
|
|
1486
|
-
|
|
1508
|
+
${Icons.refresh} Refresh Status
|
|
1487
1509
|
</button>
|
|
1488
1510
|
</div>
|
|
1489
1511
|
</div>
|
|
@@ -1493,10 +1515,13 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1493
1515
|
* Render footer
|
|
1494
1516
|
*/
|
|
1495
1517
|
renderFooter() {
|
|
1518
|
+
const lockIcon = `<svg style="width: 14px; height: 14px; display: inline-block; vertical-align: middle; margin-right: 4px;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z" /></svg>`;
|
|
1496
1519
|
return `
|
|
1497
1520
|
<div class="zendfi-checkout-footer" style="padding: 16px 24px; border-top: 1px solid #e5e7eb; text-align: center;">
|
|
1498
|
-
<p style="margin: 0; font-size: 12px; color: #9ca3af;">
|
|
1499
|
-
|
|
1521
|
+
<p style="margin: 0; font-size: 12px; color: #9ca3af; display: flex; align-items: center; justify-content: center; gap: 4px;">
|
|
1522
|
+
${lockIcon}
|
|
1523
|
+
<span>Secured by</span>
|
|
1524
|
+
<a href="https://zendfi.tech" target="_blank" style="color: #667eea; text-decoration: none; font-weight: 600; transition: opacity 0.2s;" onmouseover="this.style.opacity='0.7'" onmouseout="this.style.opacity='1'">ZendFi</a>
|
|
1500
1525
|
</p>
|
|
1501
1526
|
</div>
|
|
1502
1527
|
`;
|
|
@@ -1508,7 +1533,7 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1508
1533
|
if (!this.container) return;
|
|
1509
1534
|
this.container.innerHTML = `
|
|
1510
1535
|
<div class="zendfi-checkout-success" style="${this.getSuccessStyles()}">
|
|
1511
|
-
<div style="
|
|
1536
|
+
<div style="color: #10b981; margin-bottom: 16px;">${Icons.checkCircle}</div>
|
|
1512
1537
|
<h3 style="margin: 0 0 8px 0; font-size: 24px; font-weight: 600; color: #059669;">
|
|
1513
1538
|
Payment Successful!
|
|
1514
1539
|
</h3>
|
|
@@ -1518,6 +1543,91 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1518
1543
|
</div>
|
|
1519
1544
|
`;
|
|
1520
1545
|
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Render payment under review state
|
|
1548
|
+
*/
|
|
1549
|
+
renderUnderReview() {
|
|
1550
|
+
if (!this.container) return;
|
|
1551
|
+
const customerEmail = this.bankPaymentState.customerEmail || "unknown";
|
|
1552
|
+
const orderId = this.bankPaymentState.orderId || "N/A";
|
|
1553
|
+
this.container.innerHTML = `
|
|
1554
|
+
<div class="zendfi-checkout-under-review" style="padding: 32px 24px; text-align: center;">
|
|
1555
|
+
<div style="width: 64px; height: 64px; background: #fef3c7; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 16px; color: #d97706;">
|
|
1556
|
+
${Icons.clock}
|
|
1557
|
+
</div>
|
|
1558
|
+
|
|
1559
|
+
<h3 style="margin: 0 0 8px 0; font-size: 20px; font-weight: 600; color: #1f2937;">
|
|
1560
|
+
Payment Under Review
|
|
1561
|
+
</h3>
|
|
1562
|
+
<p style="margin: 0 0 24px 0; color: #6b7280; font-size: 14px; line-height: 1.5;">
|
|
1563
|
+
We're still processing your bank transfer. This is taking longer than usual.
|
|
1564
|
+
</p>
|
|
1565
|
+
|
|
1566
|
+
<!-- What's Happening -->
|
|
1567
|
+
<div style="background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 12px; padding: 16px; margin-bottom: 16px; text-align: left;">
|
|
1568
|
+
<h4 style="margin: 0 0 12px 0; font-size: 14px; font-weight: 600; color: #1e3a8a;">What's happening?</h4>
|
|
1569
|
+
<ul style="margin: 0; padding: 0 0 0 20px; font-size: 13px; color: #1e40af; line-height: 1.6;">
|
|
1570
|
+
<li style="margin-bottom: 8px;">Our team has been notified and is investigating</li>
|
|
1571
|
+
<li style="margin-bottom: 8px;">We're coordinating with our payment partner</li>
|
|
1572
|
+
<li>You'll receive an update via email within 24 hours</li>
|
|
1573
|
+
</ul>
|
|
1574
|
+
</div>
|
|
1575
|
+
|
|
1576
|
+
<!-- Guarantee -->
|
|
1577
|
+
<div style="background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 12px; padding: 16px; margin-bottom: 16px; text-align: left;">
|
|
1578
|
+
<div style="display: flex; align-items: start; gap: 12px;">
|
|
1579
|
+
<div style="color: #16a34a; flex-shrink: 0;">${Icons.checkCircle}</div>
|
|
1580
|
+
<div>
|
|
1581
|
+
<h4 style="margin: 0 0 4px 0; font-size: 14px; font-weight: 600; color: #15803d;">You're Protected</h4>
|
|
1582
|
+
<p style="margin: 0; font-size: 13px; color: #166534; line-height: 1.5;">
|
|
1583
|
+
If we can't deliver your USDC, you'll receive a <strong>full refund</strong> to your bank account within 3-5 business days.
|
|
1584
|
+
</p>
|
|
1585
|
+
</div>
|
|
1586
|
+
</div>
|
|
1587
|
+
</div>
|
|
1588
|
+
|
|
1589
|
+
<!-- Contact Support -->
|
|
1590
|
+
<div style="background: #f9fafb; border-radius: 12px; padding: 16px; text-align: left;">
|
|
1591
|
+
<h4 style="margin: 0 0 8px 0; font-size: 14px; font-weight: 600; color: #1f2937;">Need help?</h4>
|
|
1592
|
+
<p style="margin: 0 0 12px 0; font-size: 13px; color: #6b7280;">
|
|
1593
|
+
Contact our support team if you have questions:
|
|
1594
|
+
</p>
|
|
1595
|
+
<a
|
|
1596
|
+
href="mailto:tosinoyinboblessed@gmail.com?subject=Payment%20Review%20-%20${orderId}&body=Order%20ID:%20${orderId}%0AEmail:%20${customerEmail}"
|
|
1597
|
+
style="display: block; width: 100%; padding: 12px; background: #1f2937; color: white; text-decoration: none; border-radius: 8px; font-size: 14px; font-weight: 600; text-align: center; transition: background 0.2s;"
|
|
1598
|
+
onmouseover="this.style.background='#111827'"
|
|
1599
|
+
onmouseout="this.style.background='#1f2937'"
|
|
1600
|
+
>
|
|
1601
|
+
Email Support
|
|
1602
|
+
</a>
|
|
1603
|
+
<p style="margin: 12px 0 0 0; font-size: 12px; color: #9ca3af; text-align: center;">
|
|
1604
|
+
Reference: ${orderId.slice(0, 8)}
|
|
1605
|
+
</p>
|
|
1606
|
+
</div>
|
|
1607
|
+
</div>
|
|
1608
|
+
`;
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Handle payment timeout (15 minutes)
|
|
1612
|
+
*/
|
|
1613
|
+
handlePaymentTimeout() {
|
|
1614
|
+
if (this.bankPaymentState.pollingInterval) {
|
|
1615
|
+
clearInterval(this.bankPaymentState.pollingInterval);
|
|
1616
|
+
this.bankPaymentState.pollingInterval = void 0;
|
|
1617
|
+
}
|
|
1618
|
+
if (this.bankPaymentState.timerInterval) {
|
|
1619
|
+
clearInterval(this.bankPaymentState.timerInterval);
|
|
1620
|
+
}
|
|
1621
|
+
this.renderUnderReview();
|
|
1622
|
+
this.config.onError({
|
|
1623
|
+
code: "PAYMENT_TIMEOUT",
|
|
1624
|
+
message: "Payment is taking longer than expected and is now under review",
|
|
1625
|
+
details: {
|
|
1626
|
+
orderId: this.bankPaymentState.orderId,
|
|
1627
|
+
customerEmail: this.bankPaymentState.customerEmail
|
|
1628
|
+
}
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1521
1631
|
/**
|
|
1522
1632
|
* Render error state
|
|
1523
1633
|
*/
|
|
@@ -1525,7 +1635,7 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1525
1635
|
if (!this.container) return;
|
|
1526
1636
|
this.container.innerHTML = `
|
|
1527
1637
|
<div class="zendfi-checkout-error" style="${this.getErrorStyles()}">
|
|
1528
|
-
<div style="
|
|
1638
|
+
<div style="color: #ef4444; margin-bottom: 16px;">${Icons.xCircle}</div>
|
|
1529
1639
|
<h3 style="margin: 0 0 8px 0; font-size: 24px; font-weight: 600; color: #dc2626;">
|
|
1530
1640
|
Payment Failed
|
|
1531
1641
|
</h3>
|
|
@@ -1547,9 +1657,9 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1547
1657
|
if (copyBtn && this.checkoutData) {
|
|
1548
1658
|
copyBtn.addEventListener("click", () => {
|
|
1549
1659
|
navigator.clipboard.writeText(this.checkoutData.wallet_address);
|
|
1550
|
-
copyBtn.
|
|
1660
|
+
copyBtn.innerHTML = `${Icons.check} Copied!`;
|
|
1551
1661
|
setTimeout(() => {
|
|
1552
|
-
copyBtn.
|
|
1662
|
+
copyBtn.innerHTML = `${Icons.clipboard} Copy Address`;
|
|
1553
1663
|
}, 2e3);
|
|
1554
1664
|
});
|
|
1555
1665
|
}
|
|
@@ -1597,13 +1707,13 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1597
1707
|
}
|
|
1598
1708
|
const connectBtn = document.getElementById("zendfi-connect-wallet");
|
|
1599
1709
|
if (connectBtn) {
|
|
1600
|
-
connectBtn.
|
|
1710
|
+
connectBtn.innerHTML = `${Icons.loader} Connecting...`;
|
|
1601
1711
|
connectBtn.disabled = true;
|
|
1602
1712
|
}
|
|
1603
1713
|
await provider.connect();
|
|
1604
1714
|
const publicKey = provider.publicKey.toString();
|
|
1605
1715
|
if (connectBtn) {
|
|
1606
|
-
connectBtn.
|
|
1716
|
+
connectBtn.innerHTML = `${Icons.hammer} Building transaction...`;
|
|
1607
1717
|
}
|
|
1608
1718
|
const response = await fetch(
|
|
1609
1719
|
`${this.config.apiUrl}/api/v1/payments/${this.checkoutData.payment_id}/build-transaction`,
|
|
@@ -1621,14 +1731,14 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1621
1731
|
}
|
|
1622
1732
|
const { transaction: transactionBase64, is_gasless } = await response.json();
|
|
1623
1733
|
if (connectBtn) {
|
|
1624
|
-
connectBtn.
|
|
1734
|
+
connectBtn.innerHTML = `${Icons.loader} Signing...`;
|
|
1625
1735
|
}
|
|
1626
1736
|
const solanaWeb3 = window.solanaWeb3;
|
|
1627
1737
|
const transactionBuffer = Uint8Array.from(atob(transactionBase64), (c) => c.charCodeAt(0));
|
|
1628
1738
|
const transaction = solanaWeb3.Transaction.from(transactionBuffer);
|
|
1629
1739
|
const signedTransaction = await provider.signTransaction(transaction);
|
|
1630
1740
|
if (connectBtn) {
|
|
1631
|
-
connectBtn.
|
|
1741
|
+
connectBtn.innerHTML = `${Icons.loader} Submitting...`;
|
|
1632
1742
|
}
|
|
1633
1743
|
if (is_gasless) {
|
|
1634
1744
|
const serialized = signedTransaction.serialize();
|
|
@@ -1668,13 +1778,13 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1668
1778
|
}
|
|
1669
1779
|
}
|
|
1670
1780
|
if (connectBtn) {
|
|
1671
|
-
connectBtn.
|
|
1781
|
+
connectBtn.innerHTML = `${Icons.loader} Confirming...`;
|
|
1672
1782
|
}
|
|
1673
1783
|
} catch (error) {
|
|
1674
1784
|
console.error("Wallet connection error:", error);
|
|
1675
1785
|
const connectBtn = document.getElementById("zendfi-connect-wallet");
|
|
1676
1786
|
if (connectBtn) {
|
|
1677
|
-
connectBtn.textContent = "
|
|
1787
|
+
connectBtn.textContent = "Connect Wallet";
|
|
1678
1788
|
connectBtn.disabled = false;
|
|
1679
1789
|
}
|
|
1680
1790
|
this.config.onError({
|
|
@@ -1737,6 +1847,38 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1737
1847
|
@keyframes zendfi-spin {
|
|
1738
1848
|
to { transform: rotate(360deg); }
|
|
1739
1849
|
}
|
|
1850
|
+
|
|
1851
|
+
.zendfi-embedded-checkout .icon {
|
|
1852
|
+
width: 20px;
|
|
1853
|
+
height: 20px;
|
|
1854
|
+
display: inline-block;
|
|
1855
|
+
vertical-align: middle;
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
.zendfi-embedded-checkout .icon-sm {
|
|
1859
|
+
width: 16px;
|
|
1860
|
+
height: 16px;
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
.zendfi-embedded-checkout .icon-lg {
|
|
1864
|
+
width: 64px;
|
|
1865
|
+
height: 64px;
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
.zendfi-embedded-checkout .icon-spin {
|
|
1869
|
+
animation: zendfi-spin 0.8s linear infinite;
|
|
1870
|
+
width: 40px;
|
|
1871
|
+
height: 40px;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
.zendfi-spinner {
|
|
1875
|
+
width: 40px;
|
|
1876
|
+
height: 40px;
|
|
1877
|
+
border: 4px solid #f3f4f6;
|
|
1878
|
+
border-top-color: #667eea;
|
|
1879
|
+
border-radius: 50%;
|
|
1880
|
+
animation: zendfi-spin 0.8s linear infinite;
|
|
1881
|
+
}
|
|
1740
1882
|
`;
|
|
1741
1883
|
document.head.appendChild(style);
|
|
1742
1884
|
}
|
|
@@ -1788,9 +1930,10 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1788
1930
|
font-family: ${theme.fontFamily};
|
|
1789
1931
|
background: ${theme.backgroundColor};
|
|
1790
1932
|
border-radius: ${theme.borderRadius};
|
|
1791
|
-
|
|
1933
|
+
border: 1px solid #e5e7eb;
|
|
1934
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
|
1792
1935
|
overflow: hidden;
|
|
1793
|
-
max-width:
|
|
1936
|
+
max-width: 480px;
|
|
1794
1937
|
margin: 0 auto;
|
|
1795
1938
|
`.replace(/\s+/g, " ").trim();
|
|
1796
1939
|
}
|
|
@@ -1847,7 +1990,9 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1847
1990
|
otp,
|
|
1848
1991
|
fiat_amount: this.checkoutData.amount_usd,
|
|
1849
1992
|
currency: this.checkoutData.currency,
|
|
1850
|
-
payment_link_id: this.checkoutData.payment_link_id
|
|
1993
|
+
payment_link_id: this.checkoutData.payment_link_id,
|
|
1994
|
+
amount_ngn: this.checkoutData.amount_ngn,
|
|
1995
|
+
payer_service_charge: this.checkoutData.payer_service_charge
|
|
1851
1996
|
})
|
|
1852
1997
|
});
|
|
1853
1998
|
if (!response.ok) {
|
|
@@ -1877,7 +2022,8 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1877
2022
|
body: JSON.stringify({
|
|
1878
2023
|
customer_email: email,
|
|
1879
2024
|
fiat_amount: this.checkoutData.amount_usd,
|
|
1880
|
-
payment_link_id: this.checkoutData.payment_link_id
|
|
2025
|
+
payment_link_id: this.checkoutData.payment_link_id,
|
|
2026
|
+
amount_ngn: this.checkoutData.amount_ngn
|
|
1881
2027
|
})
|
|
1882
2028
|
});
|
|
1883
2029
|
if (!response.ok) {
|
|
@@ -1903,6 +2049,7 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1903
2049
|
startBankStatusPolling() {
|
|
1904
2050
|
if (!this.bankPaymentState.orderId) return;
|
|
1905
2051
|
let startTime = Date.now();
|
|
2052
|
+
const TIMEOUT_MS = 15 * 60 * 1e3;
|
|
1906
2053
|
const timerInterval = setInterval(() => {
|
|
1907
2054
|
const elapsed = Math.floor((Date.now() - startTime) / 1e3);
|
|
1908
2055
|
const minutes = Math.floor(elapsed / 60);
|
|
@@ -1911,6 +2058,9 @@ var ZendFiEmbeddedCheckout = class {
|
|
|
1911
2058
|
if (timerEl) {
|
|
1912
2059
|
timerEl.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
|
1913
2060
|
}
|
|
2061
|
+
if (Date.now() - startTime > TIMEOUT_MS) {
|
|
2062
|
+
this.handlePaymentTimeout();
|
|
2063
|
+
}
|
|
1914
2064
|
}, 1e3);
|
|
1915
2065
|
const pollInterval = setInterval(async () => {
|
|
1916
2066
|
await this.checkBankPaymentStatus();
|
|
@@ -2102,7 +2252,6 @@ async function processWebhook(a, b, c) {
|
|
|
2102
2252
|
isProcessed: cfg.isProcessed,
|
|
2103
2253
|
onProcessed: cfg.onProcessed,
|
|
2104
2254
|
onError: cfg.onError,
|
|
2105
|
-
// Forward compatibility for alternate names and flags
|
|
2106
2255
|
enableDeduplication: cfg.enableDeduplication,
|
|
2107
2256
|
checkDuplicate: cfg.checkDuplicate,
|
|
2108
2257
|
markProcessed: cfg.markProcessed
|
|
@@ -2509,7 +2658,6 @@ var TransactionPoller = class {
|
|
|
2509
2658
|
switch (commitment) {
|
|
2510
2659
|
case "processed":
|
|
2511
2660
|
return true;
|
|
2512
|
-
// Any status means processed
|
|
2513
2661
|
case "confirmed":
|
|
2514
2662
|
return status.confirmationStatus === "confirmed" || status.confirmationStatus === "finalized";
|
|
2515
2663
|
case "finalized":
|
|
@@ -2630,7 +2778,6 @@ var TransactionMonitor = class {
|
|
|
2630
2778
|
const status = await TransactionPoller.waitForConfirmation(signature, {
|
|
2631
2779
|
...options,
|
|
2632
2780
|
maxAttempts: 1
|
|
2633
|
-
// Single check per interval
|
|
2634
2781
|
});
|
|
2635
2782
|
if (status.confirmed) {
|
|
2636
2783
|
this.stopMonitoring(signature);
|
|
@@ -2758,7 +2905,6 @@ var DevTools = class {
|
|
|
2758
2905
|
sessionWallet: keypair.publicKey.toString(),
|
|
2759
2906
|
privateKey: keypair.secretKey,
|
|
2760
2907
|
budget: 10
|
|
2761
|
-
// $10 test budget
|
|
2762
2908
|
};
|
|
2763
2909
|
}
|
|
2764
2910
|
/**
|
|
@@ -2770,14 +2916,13 @@ var DevTools = class {
|
|
|
2770
2916
|
address: mockAddress,
|
|
2771
2917
|
publicKey: { toString: () => mockAddress },
|
|
2772
2918
|
signTransaction: async (tx) => {
|
|
2773
|
-
console.log("
|
|
2919
|
+
console.log("Mock wallet: Signing transaction");
|
|
2774
2920
|
return tx;
|
|
2775
2921
|
},
|
|
2776
2922
|
signMessage: async (_msg) => {
|
|
2777
|
-
console.log("
|
|
2923
|
+
console.log("Mock wallet: Signing message");
|
|
2778
2924
|
return {
|
|
2779
2925
|
signature: new Uint8Array(64)
|
|
2780
|
-
// Mock signature
|
|
2781
2926
|
};
|
|
2782
2927
|
},
|
|
2783
2928
|
isConnected: () => true,
|
|
@@ -2792,26 +2937,26 @@ var DevTools = class {
|
|
|
2792
2937
|
static logTransactionFlow(paymentId) {
|
|
2793
2938
|
console.log(`
|
|
2794
2939
|
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
2795
|
-
\u2551 TRANSACTION FLOW
|
|
2940
|
+
\u2551 TRANSACTION FLOW \u2551
|
|
2796
2941
|
\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
|
|
2797
|
-
\u2551
|
|
2798
|
-
\u2551 Payment ID: ${paymentId}
|
|
2799
|
-
\u2551
|
|
2800
|
-
\u2551 1.
|
|
2942
|
+
\u2551 \u2551
|
|
2943
|
+
\u2551 Payment ID: ${paymentId} \u2551
|
|
2944
|
+
\u2551 \u2551
|
|
2945
|
+
\u2551 1. Create Payment Intent \u2551
|
|
2801
2946
|
\u2551 \u2514\u2500> POST /api/v1/ai/smart-payment \u2551
|
|
2802
|
-
\u2551
|
|
2803
|
-
\u2551 2.
|
|
2804
|
-
\u2551 \u2514\u2500> Client-side signing with cached keypair
|
|
2805
|
-
\u2551
|
|
2806
|
-
\u2551 3.
|
|
2807
|
-
\u2551 \u2514\u2500> POST /api/v1/ai/payments/{id}/submit-signed
|
|
2808
|
-
\u2551
|
|
2809
|
-
\u2551 4.
|
|
2810
|
-
\u2551 \u2514\u2500> Poll Solana RPC (~30-60 seconds)
|
|
2811
|
-
\u2551
|
|
2812
|
-
\u2551 5.
|
|
2813
|
-
\u2551 \u2514\u2500> Webhook fired: payment.confirmed
|
|
2814
|
-
\u2551
|
|
2947
|
+
\u2551 \u2551
|
|
2948
|
+
\u2551 2. Sign Transaction (Device-Bound) \u2551
|
|
2949
|
+
\u2551 \u2514\u2500> Client-side signing with cached keypair \u2551
|
|
2950
|
+
\u2551 \u2551
|
|
2951
|
+
\u2551 3. Submit Signed Transaction \u2551
|
|
2952
|
+
\u2551 \u2514\u2500> POST /api/v1/ai/payments/{id}/submit-signed \u2551
|
|
2953
|
+
\u2551 \u2551
|
|
2954
|
+
\u2551 4. Wait for Blockchain Confirmation \u2551
|
|
2955
|
+
\u2551 \u2514\u2500> Poll Solana RPC (~30-60 seconds) \u2551
|
|
2956
|
+
\u2551 \u2551
|
|
2957
|
+
\u2551 5. Payment Confirmed \u2551
|
|
2958
|
+
\u2551 \u2514\u2500> Webhook fired: payment.confirmed \u2551
|
|
2959
|
+
\u2551 \u2551
|
|
2815
2960
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
2816
2961
|
`);
|
|
2817
2962
|
}
|