@ozura/elements 1.0.2-next.16 → 1.0.2-next.18
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 +106 -0
- package/dist/oz-elements.esm.js +138 -11
- package/dist/oz-elements.esm.js.map +1 -1
- package/dist/oz-elements.umd.js +138 -11
- package/dist/oz-elements.umd.js.map +1 -1
- package/dist/react/index.cjs.js +141 -14
- package/dist/react/index.cjs.js.map +1 -1
- package/dist/react/index.esm.js +141 -14
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/react/index.d.ts +12 -1
- package/dist/react/sdk/OzVault.d.ts +26 -0
- package/dist/react/types/index.d.ts +18 -0
- package/dist/server/sdk/OzVault.d.ts +26 -0
- package/dist/server/types/index.d.ts +18 -0
- package/dist/types/sdk/OzVault.d.ts +26 -0
- package/dist/types/types/index.d.ts +18 -0
- package/package.json +1 -1
package/dist/oz-elements.umd.js
CHANGED
|
@@ -935,7 +935,7 @@
|
|
|
935
935
|
* @internal
|
|
936
936
|
*/
|
|
937
937
|
constructor(options, waxKey, tokenizationSessionId) {
|
|
938
|
-
var _a, _b, _c;
|
|
938
|
+
var _a, _b, _c, _d;
|
|
939
939
|
this.elements = new Map();
|
|
940
940
|
this.elementsByType = new Map();
|
|
941
941
|
this.bankElementsByType = new Map();
|
|
@@ -948,6 +948,9 @@
|
|
|
948
948
|
this.tokenizerReady = false;
|
|
949
949
|
this._tokenizing = null;
|
|
950
950
|
this._destroyed = false;
|
|
951
|
+
// Incremented every time reset() cancels an active tokenization so that
|
|
952
|
+
// any in-flight wax-key refresh retry can detect it was superseded.
|
|
953
|
+
this._resetCount = 0;
|
|
951
954
|
// Tracks successful tokenizations against the per-key call budget so the SDK
|
|
952
955
|
// can proactively refresh the wax key after it has been consumed rather than
|
|
953
956
|
// waiting for the next createToken() call to fail.
|
|
@@ -967,13 +970,14 @@
|
|
|
967
970
|
this.resolvedAppearance = resolveAppearance(options.appearance);
|
|
968
971
|
this.vaultId = `vault-${uuid()}`;
|
|
969
972
|
this._maxTokenizeCalls = (_b = options.maxTokenizeCalls) !== null && _b !== void 0 ? _b : 3;
|
|
973
|
+
this._debug = (_c = options.debug) !== null && _c !== void 0 ? _c : false;
|
|
970
974
|
this.boundHandleMessage = this.handleMessage.bind(this);
|
|
971
975
|
window.addEventListener('message', this.boundHandleMessage);
|
|
972
976
|
this.boundHandleVisibility = this.handleVisibilityChange.bind(this);
|
|
973
977
|
document.addEventListener('visibilitychange', this.boundHandleVisibility);
|
|
974
978
|
this.mountTokenizerFrame();
|
|
975
979
|
if (options.onLoadError) {
|
|
976
|
-
const timeout = (
|
|
980
|
+
const timeout = (_d = options.loadTimeoutMs) !== null && _d !== void 0 ? _d : 10000;
|
|
977
981
|
this.loadErrorTimeoutId = setTimeout(() => {
|
|
978
982
|
this.loadErrorTimeoutId = null;
|
|
979
983
|
if (!this._destroyed && !this.tokenizerReady) {
|
|
@@ -983,6 +987,7 @@
|
|
|
983
987
|
}
|
|
984
988
|
this._onWaxRefresh = options.onWaxRefresh;
|
|
985
989
|
this._onReady = options.onReady;
|
|
990
|
+
this.log('vault created', { vaultId: this.vaultId, frameBaseUrl: this.frameBaseUrl, maxTokenizeCalls: this._maxTokenizeCalls });
|
|
986
991
|
}
|
|
987
992
|
/**
|
|
988
993
|
* Creates and returns a ready `OzVault` instance.
|
|
@@ -1052,6 +1057,7 @@
|
|
|
1052
1057
|
if (vault.tokenizerReady) {
|
|
1053
1058
|
vault.sendToTokenizer({ type: 'OZ_INIT', frameId: '__tokenizer__', waxKey });
|
|
1054
1059
|
}
|
|
1060
|
+
vault.log('wax key received — vault ready');
|
|
1055
1061
|
return vault;
|
|
1056
1062
|
}
|
|
1057
1063
|
/**
|
|
@@ -1193,8 +1199,13 @@
|
|
|
1193
1199
|
const readyBankElements = [accountEl, routingEl];
|
|
1194
1200
|
this._tokenizing = 'bank';
|
|
1195
1201
|
const requestId = `req-${uuid()}`;
|
|
1202
|
+
this.log('createBankToken() called');
|
|
1196
1203
|
return new Promise((resolve, reject) => {
|
|
1197
|
-
const
|
|
1204
|
+
const resetCountAtStart = this._resetCount;
|
|
1205
|
+
const cleanup = () => {
|
|
1206
|
+
if (this._resetCount === resetCountAtStart)
|
|
1207
|
+
this._tokenizing = null;
|
|
1208
|
+
};
|
|
1198
1209
|
this.bankTokenizeResolvers.set(requestId, {
|
|
1199
1210
|
resolve: (v) => { cleanup(); resolve(v); },
|
|
1200
1211
|
reject: (e) => { cleanup(); reject(e); },
|
|
@@ -1205,6 +1216,7 @@
|
|
|
1205
1216
|
});
|
|
1206
1217
|
try {
|
|
1207
1218
|
const bankChannels = readyBankElements.map(() => new MessageChannel());
|
|
1219
|
+
const bankTokenizeStartMs = Date.now();
|
|
1208
1220
|
this.sendToTokenizer({
|
|
1209
1221
|
type: 'OZ_BANK_TOKENIZE',
|
|
1210
1222
|
requestId,
|
|
@@ -1215,6 +1227,7 @@
|
|
|
1215
1227
|
lastName: options.lastName.trim(),
|
|
1216
1228
|
fieldCount: readyBankElements.length,
|
|
1217
1229
|
}, bankChannels.map(ch => ch.port1));
|
|
1230
|
+
this.log('OZ_BANK_TOKENIZE sent', { requestIdPrefix: `${requestId.slice(0, 12)}...`, fieldCount: readyBankElements.length });
|
|
1218
1231
|
readyBankElements.forEach((el, i) => el.beginCollect(requestId, bankChannels[i].port2));
|
|
1219
1232
|
const bankTimeoutId = setTimeout(() => {
|
|
1220
1233
|
if (this.bankTokenizeResolvers.has(requestId)) {
|
|
@@ -1225,8 +1238,10 @@
|
|
|
1225
1238
|
}
|
|
1226
1239
|
}, 30000);
|
|
1227
1240
|
const bankPendingEntry = this.bankTokenizeResolvers.get(requestId);
|
|
1228
|
-
if (bankPendingEntry)
|
|
1241
|
+
if (bankPendingEntry) {
|
|
1229
1242
|
bankPendingEntry.timeoutId = bankTimeoutId;
|
|
1243
|
+
bankPendingEntry.tokenizeStartMs = bankTokenizeStartMs;
|
|
1244
|
+
}
|
|
1230
1245
|
}
|
|
1231
1246
|
catch (err) {
|
|
1232
1247
|
this.bankTokenizeResolvers.delete(requestId);
|
|
@@ -1297,8 +1312,15 @@
|
|
|
1297
1312
|
}
|
|
1298
1313
|
this._tokenizing = 'card';
|
|
1299
1314
|
const requestId = `req-${uuid()}`;
|
|
1315
|
+
this.log('createToken() called');
|
|
1300
1316
|
return new Promise((resolve, reject) => {
|
|
1301
|
-
|
|
1317
|
+
// Capture the reset generation so cleanup() only zeros _tokenizing when it
|
|
1318
|
+
// still belongs to this invocation — not a newer one that started after a reset.
|
|
1319
|
+
const resetCountAtStart = this._resetCount;
|
|
1320
|
+
const cleanup = () => {
|
|
1321
|
+
if (this._resetCount === resetCountAtStart)
|
|
1322
|
+
this._tokenizing = null;
|
|
1323
|
+
};
|
|
1302
1324
|
this.tokenizeResolvers.set(requestId, {
|
|
1303
1325
|
resolve: (v) => { cleanup(); resolve(v); },
|
|
1304
1326
|
reject: (e) => { cleanup(); reject(e); },
|
|
@@ -1311,6 +1333,7 @@
|
|
|
1311
1333
|
try {
|
|
1312
1334
|
// Tell tokenizer frame to expect N field values, then tokenize
|
|
1313
1335
|
const cardChannels = readyElements.map(() => new MessageChannel());
|
|
1336
|
+
const tokenizeStartMs = Date.now();
|
|
1314
1337
|
this.sendToTokenizer({
|
|
1315
1338
|
type: 'OZ_TOKENIZE',
|
|
1316
1339
|
requestId,
|
|
@@ -1321,6 +1344,11 @@
|
|
|
1321
1344
|
lastName,
|
|
1322
1345
|
fieldCount: readyElements.length,
|
|
1323
1346
|
}, cardChannels.map(ch => ch.port1));
|
|
1347
|
+
this.log('OZ_TOKENIZE sent', { requestIdPrefix: `${requestId.slice(0, 12)}...`, fieldCount: readyElements.length });
|
|
1348
|
+
// Store start time for elapsed-ms logging on result
|
|
1349
|
+
const cardEntry = this.tokenizeResolvers.get(requestId);
|
|
1350
|
+
if (cardEntry)
|
|
1351
|
+
cardEntry.tokenizeStartMs = tokenizeStartMs;
|
|
1324
1352
|
// Tell each ready element frame to send its raw value to the tokenizer
|
|
1325
1353
|
readyElements.forEach((el, i) => el.beginCollect(requestId, cardChannels[i].port2));
|
|
1326
1354
|
const cardTimeoutId = setTimeout(() => {
|
|
@@ -1367,8 +1395,11 @@
|
|
|
1367
1395
|
reset() {
|
|
1368
1396
|
if (this._destroyed)
|
|
1369
1397
|
return;
|
|
1398
|
+
const cancelling = Boolean(this._tokenizing);
|
|
1399
|
+
this.log('reset() called', { tokenizing: this._tokenizing, cancelling });
|
|
1370
1400
|
if (this._tokenizing) {
|
|
1371
1401
|
this._tokenizing = null;
|
|
1402
|
+
this._resetCount++;
|
|
1372
1403
|
this.tokenizeResolvers.forEach(({ reject, timeoutId }, requestId) => {
|
|
1373
1404
|
if (timeoutId != null)
|
|
1374
1405
|
clearTimeout(timeoutId);
|
|
@@ -1406,6 +1437,7 @@
|
|
|
1406
1437
|
if (this._destroyed)
|
|
1407
1438
|
return;
|
|
1408
1439
|
this._destroyed = true;
|
|
1440
|
+
this.log('destroy() called');
|
|
1409
1441
|
window.removeEventListener('message', this.boundHandleMessage);
|
|
1410
1442
|
document.removeEventListener('visibilitychange', this.boundHandleVisibility);
|
|
1411
1443
|
if (this._pendingMount) {
|
|
@@ -1460,13 +1492,17 @@
|
|
|
1460
1492
|
const REFRESH_THRESHOLD_MS = 20 * 60 * 1000; // 20 minutes
|
|
1461
1493
|
if (document.hidden) {
|
|
1462
1494
|
this._hiddenAt = Date.now();
|
|
1495
|
+
this.log('tab hidden');
|
|
1463
1496
|
}
|
|
1464
1497
|
else {
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1498
|
+
const hiddenMs = this._hiddenAt !== null ? Date.now() - this._hiddenAt : 0;
|
|
1499
|
+
const willRefresh = (this._hiddenAt !== null &&
|
|
1500
|
+
hiddenMs >= REFRESH_THRESHOLD_MS &&
|
|
1501
|
+
Boolean(this._storedFetchWaxKey) &&
|
|
1468
1502
|
!this._tokenizing &&
|
|
1469
|
-
!this._waxRefreshing)
|
|
1503
|
+
!this._waxRefreshing);
|
|
1504
|
+
this.log('tab visible', { hiddenMs, willRefresh });
|
|
1505
|
+
if (willRefresh) {
|
|
1470
1506
|
this.refreshWaxKey().catch((err) => {
|
|
1471
1507
|
// Proactive refresh failure is non-fatal — the reactive path on the
|
|
1472
1508
|
// next createToken() call will handle it, including the auth retry.
|
|
@@ -1476,6 +1512,56 @@
|
|
|
1476
1512
|
this._hiddenAt = null;
|
|
1477
1513
|
}
|
|
1478
1514
|
}
|
|
1515
|
+
// ─── Debug ───────────────────────────────────────────────────────────────
|
|
1516
|
+
/**
|
|
1517
|
+
* Emits a `[OzVault]`-prefixed entry to `console.log`. No-op when `debug` is
|
|
1518
|
+
* not set. Never called with sensitive values — callers use presence flags only.
|
|
1519
|
+
*/
|
|
1520
|
+
log(message, data) {
|
|
1521
|
+
if (!this._debug)
|
|
1522
|
+
return;
|
|
1523
|
+
if (data !== undefined) {
|
|
1524
|
+
console.log(`[OzVault] ${message}`, data);
|
|
1525
|
+
}
|
|
1526
|
+
else {
|
|
1527
|
+
console.log(`[OzVault] ${message}`);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Returns a plain-object snapshot of the vault's current internal state.
|
|
1532
|
+
* Safe to attach to bug reports — no wax keys, tokens, or billing data included.
|
|
1533
|
+
*
|
|
1534
|
+
* Available on all vault instances regardless of whether `debug` was enabled.
|
|
1535
|
+
*
|
|
1536
|
+
* @example
|
|
1537
|
+
* console.log(vault.debugState());
|
|
1538
|
+
* // {
|
|
1539
|
+
* // vaultId: 'vault-abc123',
|
|
1540
|
+
* // isReady: true,
|
|
1541
|
+
* // tokenizing: null,
|
|
1542
|
+
* // destroyed: false,
|
|
1543
|
+
* // waxKeyPresent: true,
|
|
1544
|
+
* // elements: ['cardNumber', 'expirationDate', 'cvv'],
|
|
1545
|
+
* // ...
|
|
1546
|
+
* // }
|
|
1547
|
+
*/
|
|
1548
|
+
debugState() {
|
|
1549
|
+
return {
|
|
1550
|
+
vaultId: this.vaultId,
|
|
1551
|
+
isReady: this.tokenizerReady,
|
|
1552
|
+
tokenizing: this._tokenizing,
|
|
1553
|
+
destroyed: this._destroyed,
|
|
1554
|
+
waxKeyPresent: Boolean(this.waxKey),
|
|
1555
|
+
tokenizeSuccessCount: this._tokenizeSuccessCount,
|
|
1556
|
+
maxTokenizeCalls: this._maxTokenizeCalls,
|
|
1557
|
+
resetCount: this._resetCount,
|
|
1558
|
+
elements: [...this.elementsByType.keys()],
|
|
1559
|
+
bankElements: [...this.bankElementsByType.keys()],
|
|
1560
|
+
completionState: Object.fromEntries([...this.completionState.entries()].map(([id, v]) => [id.slice(0, 8), v])),
|
|
1561
|
+
pendingTokenizations: this.tokenizeResolvers.size,
|
|
1562
|
+
pendingBankTokenizations: this.bankTokenizeResolvers.size,
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1479
1565
|
mountTokenizerFrame() {
|
|
1480
1566
|
const mount = () => {
|
|
1481
1567
|
this._pendingMount = null;
|
|
@@ -1487,6 +1573,7 @@
|
|
|
1487
1573
|
iframe.src = `${this.frameBaseUrl}/frame/tokenizer-frame.html#vaultId=${encodeURIComponent(this.vaultId)}${parentOrigin ? `&parentOrigin=${encodeURIComponent(parentOrigin)}` : ''}`;
|
|
1488
1574
|
document.body.appendChild(iframe);
|
|
1489
1575
|
this.tokenizerFrame = iframe;
|
|
1576
|
+
this.log('mounting tokenizer iframe');
|
|
1490
1577
|
};
|
|
1491
1578
|
if (document.readyState === 'loading') {
|
|
1492
1579
|
this._pendingMount = mount;
|
|
@@ -1527,6 +1614,7 @@
|
|
|
1527
1614
|
`SDK expects v${PROTOCOL_VERSION}, frame reported v${typeof msg.__ozVersion === 'number' ? msg.__ozVersion : '(none)'}. ` +
|
|
1528
1615
|
'Deploy the matching frame assets to elements.ozura.com and purge the Azure CDN cache.');
|
|
1529
1616
|
}
|
|
1617
|
+
this.log('element iframe ready', { type: el.type, frameIdPrefix: frameId.slice(0, 8) });
|
|
1530
1618
|
}
|
|
1531
1619
|
// Intercept OZ_CHANGE before forwarding — handle auto-advance and CVV sync
|
|
1532
1620
|
if (msg.type === 'OZ_CHANGE') {
|
|
@@ -1550,6 +1638,7 @@
|
|
|
1550
1638
|
// Require valid too — avoids advancing at 13 digits for unknown-brand cards
|
|
1551
1639
|
// where isComplete() fires before the user has finished typing.
|
|
1552
1640
|
const justCompleted = complete && valid && !wasComplete;
|
|
1641
|
+
this.log('field changed', { type: el.type, complete, valid, justCompleted });
|
|
1553
1642
|
// Sync CVV length when card brand changes
|
|
1554
1643
|
if (el.type === 'cardNumber') {
|
|
1555
1644
|
const brand = msg.cardBrand;
|
|
@@ -1561,15 +1650,17 @@
|
|
|
1561
1650
|
// Auto-advance focus on completion
|
|
1562
1651
|
if (justCompleted) {
|
|
1563
1652
|
if (el.type === 'cardNumber') {
|
|
1653
|
+
this.log('auto-advance', { from: 'cardNumber', to: 'expirationDate' });
|
|
1564
1654
|
(_b = this.elementsByType.get('expirationDate')) === null || _b === void 0 ? void 0 : _b.focus();
|
|
1565
1655
|
}
|
|
1566
1656
|
else if (el.type === 'expirationDate') {
|
|
1657
|
+
this.log('auto-advance', { from: 'expirationDate', to: 'cvv' });
|
|
1567
1658
|
(_c = this.elementsByType.get('cvv')) === null || _c === void 0 ? void 0 : _c.focus();
|
|
1568
1659
|
}
|
|
1569
1660
|
}
|
|
1570
1661
|
}
|
|
1571
1662
|
handleTokenizerMessage(msg) {
|
|
1572
|
-
var _a, _b, _c;
|
|
1663
|
+
var _a, _b, _c, _d;
|
|
1573
1664
|
switch (msg.type) {
|
|
1574
1665
|
case 'OZ_FRAME_READY':
|
|
1575
1666
|
if (msg.__ozVersion !== PROTOCOL_VERSION) {
|
|
@@ -1589,6 +1680,7 @@
|
|
|
1589
1680
|
// sent again from create() once the key is available.
|
|
1590
1681
|
this.sendToTokenizer(Object.assign({ type: 'OZ_INIT', frameId: '__tokenizer__' }, (this.waxKey ? { waxKey: this.waxKey } : {})));
|
|
1591
1682
|
(_c = this._onReady) === null || _c === void 0 ? void 0 : _c.call(this);
|
|
1683
|
+
this.log('tokenizer iframe ready', { protocolVersion: (_d = msg.__ozVersion) !== null && _d !== void 0 ? _d : null });
|
|
1592
1684
|
break;
|
|
1593
1685
|
case 'OZ_TOKEN_RESULT': {
|
|
1594
1686
|
if (typeof msg.requestId !== 'string' || !msg.requestId) {
|
|
@@ -1613,11 +1705,18 @@
|
|
|
1613
1705
|
}
|
|
1614
1706
|
pending.resolve(Object.assign(Object.assign({ token,
|
|
1615
1707
|
cvcSession }, (card ? { card } : {})), (pending.billing ? { billing: pending.billing } : {})));
|
|
1708
|
+
this.log('token received', {
|
|
1709
|
+
elapsedMs: pending.tokenizeStartMs != null ? Date.now() - pending.tokenizeStartMs : null,
|
|
1710
|
+
tokenPresent: true,
|
|
1711
|
+
cvcSessionPresent: true,
|
|
1712
|
+
cardMetadataPresent: Boolean(card),
|
|
1713
|
+
});
|
|
1616
1714
|
// Increment the per-key success counter and proactively refresh once
|
|
1617
1715
|
// the budget is exhausted so the next createToken() call uses a fresh
|
|
1618
1716
|
// key without waiting for a vault rejection.
|
|
1619
1717
|
this._tokenizeSuccessCount++;
|
|
1620
1718
|
if (this._tokenizeSuccessCount >= this._maxTokenizeCalls) {
|
|
1719
|
+
this.log('proactive wax key refresh triggered', { tokenizeSuccessCount: this._tokenizeSuccessCount, maxTokenizeCalls: this._maxTokenizeCalls });
|
|
1621
1720
|
this.refreshWaxKey().catch((err) => {
|
|
1622
1721
|
console.warn('[OzVault] Post-budget wax key refresh failed:', err instanceof Error ? err.message : err);
|
|
1623
1722
|
});
|
|
@@ -1637,14 +1736,25 @@
|
|
|
1637
1736
|
this.tokenizeResolvers.delete(msg.requestId);
|
|
1638
1737
|
if (pending.timeoutId != null)
|
|
1639
1738
|
clearTimeout(pending.timeoutId);
|
|
1739
|
+
const willRefresh = this.isRefreshableAuthError(errorCode, raw) && !pending.retried && Boolean(this._storedFetchWaxKey);
|
|
1740
|
+
this.log('token error', { errorCode, willRefresh });
|
|
1640
1741
|
// Auto-refresh: if the wax key expired or was consumed and we haven't
|
|
1641
1742
|
// already retried for this request, transparently re-mint and retry.
|
|
1642
|
-
if (
|
|
1743
|
+
if (willRefresh) {
|
|
1744
|
+
const resetCountAtRetry = this._resetCount;
|
|
1643
1745
|
this.refreshWaxKey().then(() => {
|
|
1644
1746
|
if (this._destroyed) {
|
|
1645
1747
|
pending.reject(new OzError('Vault destroyed during wax key refresh.'));
|
|
1646
1748
|
return;
|
|
1647
1749
|
}
|
|
1750
|
+
if (this._resetCount !== resetCountAtRetry) {
|
|
1751
|
+
// reset() was called while the wax key was refreshing — the fields
|
|
1752
|
+
// have been cleared and _tokenizing was zeroed. Reject the original
|
|
1753
|
+
// promise so it doesn't stay pending, and bail out without starting
|
|
1754
|
+
// a new retry (which would tokenize against empty fields).
|
|
1755
|
+
pending.reject(new OzError('Vault was reset while tokenization was in progress.'));
|
|
1756
|
+
return;
|
|
1757
|
+
}
|
|
1648
1758
|
const newRequestId = `req-${uuid()}`;
|
|
1649
1759
|
// _tokenizing is still 'card' (cleanup() hasn't been called yet)
|
|
1650
1760
|
this.tokenizeResolvers.set(newRequestId, Object.assign(Object.assign({}, pending), { retried: true }));
|
|
@@ -1691,11 +1801,16 @@
|
|
|
1691
1801
|
if (bankPending.timeoutId != null)
|
|
1692
1802
|
clearTimeout(bankPending.timeoutId);
|
|
1693
1803
|
if (this.isRefreshableAuthError(errorCode, raw) && !bankPending.retried && this._storedFetchWaxKey) {
|
|
1804
|
+
const resetCountAtRetry = this._resetCount;
|
|
1694
1805
|
this.refreshWaxKey().then(() => {
|
|
1695
1806
|
if (this._destroyed) {
|
|
1696
1807
|
bankPending.reject(new OzError('Vault destroyed during wax key refresh.'));
|
|
1697
1808
|
return;
|
|
1698
1809
|
}
|
|
1810
|
+
if (this._resetCount !== resetCountAtRetry) {
|
|
1811
|
+
bankPending.reject(new OzError('Vault was reset while tokenization was in progress.'));
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1699
1814
|
const newRequestId = `req-${uuid()}`;
|
|
1700
1815
|
this.bankTokenizeResolvers.set(newRequestId, Object.assign(Object.assign({}, bankPending), { retried: true }));
|
|
1701
1816
|
try {
|
|
@@ -1753,9 +1868,15 @@
|
|
|
1753
1868
|
}
|
|
1754
1869
|
const bank = isBankAccountMetadata(msg.bank) ? msg.bank : undefined;
|
|
1755
1870
|
pending.resolve(Object.assign({ token }, (bank ? { bank } : {})));
|
|
1871
|
+
this.log('bank token received', {
|
|
1872
|
+
elapsedMs: pending.tokenizeStartMs != null ? Date.now() - pending.tokenizeStartMs : null,
|
|
1873
|
+
tokenPresent: true,
|
|
1874
|
+
bankMetadataPresent: Boolean(bank),
|
|
1875
|
+
});
|
|
1756
1876
|
// Same proactive refresh logic as card tokenization.
|
|
1757
1877
|
this._tokenizeSuccessCount++;
|
|
1758
1878
|
if (this._tokenizeSuccessCount >= this._maxTokenizeCalls) {
|
|
1879
|
+
this.log('proactive wax key refresh triggered', { tokenizeSuccessCount: this._tokenizeSuccessCount, maxTokenizeCalls: this._maxTokenizeCalls });
|
|
1759
1880
|
this.refreshWaxKey().catch((err) => {
|
|
1760
1881
|
console.warn('[OzVault] Post-budget wax key refresh failed:', err instanceof Error ? err.message : err);
|
|
1761
1882
|
});
|
|
@@ -1811,6 +1932,7 @@
|
|
|
1811
1932
|
}
|
|
1812
1933
|
const newSessionId = uuid();
|
|
1813
1934
|
(_a = this._onWaxRefresh) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
1935
|
+
this.log('wax key refresh started');
|
|
1814
1936
|
this._waxRefreshing = this._storedFetchWaxKey(newSessionId)
|
|
1815
1937
|
.then(newWaxKey => {
|
|
1816
1938
|
if (typeof newWaxKey !== 'string' || !newWaxKey.trim()) {
|
|
@@ -1824,6 +1946,11 @@
|
|
|
1824
1946
|
if (!this._destroyed && this.tokenizerReady) {
|
|
1825
1947
|
this.sendToTokenizer({ type: 'OZ_INIT', frameId: '__tokenizer__', waxKey: newWaxKey });
|
|
1826
1948
|
}
|
|
1949
|
+
this.log('wax key refresh succeeded');
|
|
1950
|
+
})
|
|
1951
|
+
.catch((err) => {
|
|
1952
|
+
this.log('wax key refresh failed', { error: err instanceof Error ? err.message : String(err) });
|
|
1953
|
+
throw err;
|
|
1827
1954
|
})
|
|
1828
1955
|
.finally(() => {
|
|
1829
1956
|
this._waxRefreshing = null;
|