@alipay/ams-checkout 0.0.1783663570-dev.7 → 0.0.1783663570-dev.8

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.
@@ -30,7 +30,7 @@ export var v2AppMarmotMap = {
30
30
  light_sandbox: 'https://checkout.antom.com',
31
31
  prod: 'https://checkout.antom.com'
32
32
  };
33
- export var sdkVersion = "0.0.1783663570-dev.7";
33
+ export var sdkVersion = "0.0.1783663570-dev.8";
34
34
 
35
35
  /**
36
36
  * @description: 目前应用层分为v1和v2,会存在两个应用版本号不是同步发布的情况。所以需要把默认的应用版本号配置抽离出来。
@@ -38,6 +38,8 @@ export declare class ModernElementController implements IElementController {
38
38
  private _merchantCurrency;
39
39
  /** 当前选中的支付方式类型(如 'APPLEPAY', 'CARD'),通过 paymentMethodChanged 事件更新 */
40
40
  private currentPaymentMethodType;
41
+ /** 提交进行中标志:submitPayment 执行期间为 true,用于拒绝并发重入,避免旧闭包串扰/重复拉起钱包 */
42
+ private isSubmitting;
41
43
  constructor({ onStatusChange, ...options }: ModernElementControllerOptions);
42
44
  mount(renderOptions: PaymentMountOptions, sdkSelector: string): Promise<ICommonApiResponse>;
43
45
  /**
@@ -196,6 +196,8 @@ export var ModernElementController = /*#__PURE__*/function () {
196
196
  _defineProperty(this, "_merchantCurrency", null);
197
197
  /** 当前选中的支付方式类型(如 'APPLEPAY', 'CARD'),通过 paymentMethodChanged 事件更新 */
198
198
  _defineProperty(this, "currentPaymentMethodType", '');
199
+ /** 提交进行中标志:submitPayment 执行期间为 true,用于拒绝并发重入,避免旧闭包串扰/重复拉起钱包 */
200
+ _defineProperty(this, "isSubmitting", false);
199
201
  this.options = options;
200
202
  this.onStatusChange = onStatusChange;
201
203
  if (options.sessionData) {
@@ -398,7 +400,7 @@ export var ModernElementController = /*#__PURE__*/function () {
398
400
  request.setGlobalOptions({
399
401
  hostSign: parseHostSign(sessionData),
400
402
  env: this.options.environment,
401
- sdkVersion: "0.0.1783663570-dev.7" || '',
403
+ sdkVersion: "0.0.1783663570-dev.8" || '',
402
404
  tracker: sdkTracker
403
405
  });
404
406
  isConnect = !!(parseData !== null && parseData !== void 0 && (_parseData$connectFac = parseData.connectFactor) !== null && _parseData$connectFac !== void 0 && _parseData$connectFac.enableConnect);
@@ -494,7 +496,7 @@ export var ModernElementController = /*#__PURE__*/function () {
494
496
  // 新sdk字段
495
497
  locale: locale,
496
498
  // 新sdk字段
497
- sdkVersion: "0.0.1783663570-dev.7" || '',
499
+ sdkVersion: "0.0.1783663570-dev.8" || '',
498
500
  // 新sdk字段
499
501
  merchantId: (sdkQueryResult === null || sdkQueryResult === void 0 || (_sdkQueryResult$data = sdkQueryResult.data) === null || _sdkQueryResult$data === void 0 ? void 0 : _sdkQueryResult$data.merchantId) || '',
500
502
  // 新sdk字段
@@ -1240,10 +1242,8 @@ export var ModernElementController = /*#__PURE__*/function () {
1240
1242
  key: "submitPayment",
1241
1243
  value: function () {
1242
1244
  var _submitPayment = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(params) {
1243
- var _this$options$loading7,
1244
- _this$options$loading8,
1245
- _this8 = this;
1246
- var isApplePay, _ref5, onBeforeConfirm, serializableParams, startTime, _yield$executeWithTim2, shouldContinue, timedOut, hasBeforeConfirmForApplePay, hasAmount, hasCurrency, _result$error, resultPromise, result, _this$options$loading9, _this$options$loading10;
1245
+ var _this8 = this;
1246
+ var _this$options$loading7, _this$options$loading8, isApplePay, _ref5, onBeforeConfirm, serializableParams, startTime, _yield$executeWithTim2, shouldContinue, timedOut, hasBeforeConfirmForApplePay, hasAmount, hasCurrency, cleanups, _result$error, resultPromise, result, _this$options$loading9, _this$options$loading10;
1247
1247
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
1248
1248
  while (1) switch (_context6.prev = _context6.next) {
1249
1249
  case 0:
@@ -1262,10 +1262,25 @@ export var ModernElementController = /*#__PURE__*/function () {
1262
1262
  }
1263
1263
  });
1264
1264
  case 3:
1265
+ if (!this.isSubmitting) {
1266
+ _context6.next = 6;
1267
+ break;
1268
+ }
1269
+ trackError('submit_in_progress', {});
1270
+ return _context6.abrupt("return", {
1271
+ status: 'FAIL',
1272
+ error: {
1273
+ code: 'UI_STATE_ERROR',
1274
+ message: 'submit already in progress'
1275
+ }
1276
+ });
1277
+ case 6:
1278
+ this.isSubmitting = true;
1279
+ _context6.prev = 7;
1265
1280
  isApplePay = this.currentPaymentMethodType === 'APPLEPAY'; // 剥除 onBeforeConfirm 函数,避免 postMessage 序列化报错
1266
1281
  _ref5 = params || {}, onBeforeConfirm = _ref5.onBeforeConfirm, serializableParams = _objectWithoutProperties(_ref5, _excluded2); // ── 非 Apple Pay:同步执行 onBeforeConfirm(submit 前拦截,对齐老 ElementController) ──
1267
1282
  if (!(onBeforeConfirm && !isApplePay)) {
1268
- _context6.next = 26;
1283
+ _context6.next = 31;
1269
1284
  break;
1270
1285
  }
1271
1286
  logger.logInfo({
@@ -1274,18 +1289,18 @@ export var ModernElementController = /*#__PURE__*/function () {
1274
1289
  paymentMethodType: this.currentPaymentMethodType || 'UNKNOWN',
1275
1290
  path: 'nonApplePay_sync'
1276
1291
  });
1277
- _context6.prev = 7;
1292
+ _context6.prev = 12;
1278
1293
  startTime = Date.now();
1279
- _context6.next = 11;
1294
+ _context6.next = 16;
1280
1295
  return executeWithTimeout(function () {
1281
1296
  return onBeforeConfirm();
1282
1297
  });
1283
- case 11:
1298
+ case 16:
1284
1299
  _yield$executeWithTim2 = _context6.sent;
1285
1300
  shouldContinue = _yield$executeWithTim2.result;
1286
1301
  timedOut = _yield$executeWithTim2.timedOut;
1287
1302
  if (!(timedOut || !shouldContinue || Date.now() - startTime >= BEFORE_CONFIRM_TIMEOUT_MS)) {
1288
- _context6.next = 17;
1303
+ _context6.next = 22;
1289
1304
  break;
1290
1305
  }
1291
1306
  if (timedOut) {
@@ -1310,18 +1325,18 @@ export var ModernElementController = /*#__PURE__*/function () {
1310
1325
  message: 'Merchant canceled payment.'
1311
1326
  }
1312
1327
  });
1313
- case 17:
1328
+ case 22:
1314
1329
  logger.logInfo({
1315
1330
  title: 'sdk_before_confirm_success'
1316
1331
  }, {
1317
1332
  paymentMethodType: this.currentPaymentMethodType || 'UNKNOWN',
1318
1333
  path: 'nonApplePay_sync'
1319
1334
  });
1320
- _context6.next = 24;
1335
+ _context6.next = 29;
1321
1336
  break;
1322
- case 20:
1323
- _context6.prev = 20;
1324
- _context6.t0 = _context6["catch"](7);
1337
+ case 25:
1338
+ _context6.prev = 25;
1339
+ _context6.t0 = _context6["catch"](12);
1325
1340
  logger.logError({
1326
1341
  title: 'sdk_before_confirm_error'
1327
1342
  }, {
@@ -1336,10 +1351,10 @@ export var ModernElementController = /*#__PURE__*/function () {
1336
1351
  message: 'Merchant canceled payment.'
1337
1352
  }
1338
1353
  });
1339
- case 24:
1340
- _context6.next = 27;
1354
+ case 29:
1355
+ _context6.next = 32;
1341
1356
  break;
1342
- case 26:
1357
+ case 31:
1343
1358
  if (!onBeforeConfirm) {
1344
1359
  logger.logInfo({
1345
1360
  title: 'sdk_before_confirm_skip'
@@ -1348,7 +1363,7 @@ export var ModernElementController = /*#__PURE__*/function () {
1348
1363
  path: isApplePay ? 'applePay_eventBridge' : 'nonApplePay_sync'
1349
1364
  });
1350
1365
  }
1351
- case 27:
1366
+ case 32:
1352
1367
  // Apple Pay: 标记是否有 beforeConfirm,供 SUBMIT 消息的 hasBeforeConfirm 字段使用
1353
1368
  hasBeforeConfirmForApplePay = isApplePay && !!onBeforeConfirm; // ── amount/currency 校验 + 缓存(对齐老 ElementController 逻辑) ──
1354
1369
  hasAmount = !!(serializableParams !== null && serializableParams !== void 0 && serializableParams.amount);
@@ -1368,24 +1383,28 @@ export var ModernElementController = /*#__PURE__*/function () {
1368
1383
  trackElement('submit_start', {
1369
1384
  d1: this.notRedirectAfterComplete ? 'if_required' : 'always'
1370
1385
  });
1371
- _context6.prev = 35;
1386
+ // 收集本轮 once 监听的 cleanup:submitPayment 每次注册四类监听,但一轮只会命中部分,
1387
+ // 未命中的 once wrapper 绑着旧闭包(旧 onBeforeConfirm / 旧 resolve)会残留并串扰后续提交,
1388
+ // 在 submit 终态统一释放(二次 off 幂等,已命中的 once 已自行 off)。
1389
+ cleanups = [];
1390
+ _context6.prev = 41;
1372
1391
  resultPromise = new Promise(function (resolve) {
1373
1392
  // 先注册事件监听,再发送 SUBMIT,避免 webapp 快速响应导致消息丢失
1374
1393
  // PC 非 Safari:webapp 委托 SDK 拉起 Apple Pay 拿 token
1375
- _this8.bridge.once(AMSMessageType.GET_APPLE_PAY_TOKEN, function (payload) {
1394
+ cleanups.push(_this8.bridge.once(AMSMessageType.GET_APPLE_PAY_TOKEN, function (payload) {
1376
1395
  _this8.handleGetApplePayToken(payload, onBeforeConfirm).then(function () {
1377
1396
  // token 已回传 webapp,继续等 SUBMIT_REPLY
1378
1397
  });
1379
- });
1398
+ }));
1380
1399
  // Web element GP:webapp 委托 SDK/父 frame 调 loadPaymentData 拿 token
1381
- _this8.bridge.once(AMSMessageType.GET_GOOGLE_PAY_TOKEN, function (payload) {
1400
+ cleanups.push(_this8.bridge.once(AMSMessageType.GET_GOOGLE_PAY_TOKEN, function (payload) {
1382
1401
  _this8.handleGetGooglePayToken(payload);
1383
- });
1402
+ }));
1384
1403
  // Safari:webapp 请求执行商户 onBeforeConfirm 回调
1385
- _this8.bridge.once(AMSMessageType.BEFORE_CONFIRM, function () {
1404
+ cleanups.push(_this8.bridge.once(AMSMessageType.BEFORE_CONFIRM, function () {
1386
1405
  _this8.handleBeforeConfirmInternal(onBeforeConfirm || null);
1387
- });
1388
- _this8.bridge.once(MessageType.SUBMIT_REPLY, resolve);
1406
+ }));
1407
+ cleanups.push(_this8.bridge.once(MessageType.SUBMIT_REPLY, resolve));
1389
1408
  }); // 监听注册完成后再发送 SUBMIT,确保不会遗漏快速响应
1390
1409
  this.send(MessageType.SUBMIT, _objectSpread(_objectSpread({}, serializableParams), {}, {
1391
1410
  redirect: this.notRedirectAfterComplete ? 'if_required' : 'always',
@@ -1394,32 +1413,43 @@ export var ModernElementController = /*#__PURE__*/function () {
1394
1413
  amount: serializableParams.amount,
1395
1414
  currency: serializableParams.currency
1396
1415
  } : {}));
1397
- _context6.next = 40;
1416
+ _context6.next = 46;
1398
1417
  return resultPromise;
1399
- case 40:
1418
+ case 46:
1400
1419
  result = _context6.sent;
1401
1420
  trackElement('submit_reply', {
1402
1421
  d1: (result === null || result === void 0 ? void 0 : result.status) || '',
1403
1422
  d2: (result === null || result === void 0 || (_result$error = result.error) === null || _result$error === void 0 ? void 0 : _result$error.code) || ''
1404
1423
  });
1405
1424
  return _context6.abrupt("return", adaptSubmitResult(result));
1406
- case 45:
1407
- _context6.prev = 45;
1408
- _context6.t1 = _context6["catch"](35);
1425
+ case 51:
1426
+ _context6.prev = 51;
1427
+ _context6.t1 = _context6["catch"](41);
1409
1428
  trackError('submit_error', {
1410
1429
  d1: (_context6.t1 === null || _context6.t1 === void 0 ? void 0 : _context6.t1.code) || 'UNKNOWN',
1411
1430
  d2: (_context6.t1 === null || _context6.t1 === void 0 ? void 0 : _context6.t1.message) || ''
1412
1431
  });
1413
1432
  throw _context6.t1;
1414
- case 49:
1415
- _context6.prev = 49;
1433
+ case 55:
1434
+ _context6.prev = 55;
1435
+ cleanups.forEach(function (fn) {
1436
+ try {
1437
+ fn();
1438
+ } catch (_unused4) {
1439
+ /* ignore cleanup error */
1440
+ }
1441
+ });
1416
1442
  (_this$options$loading9 = this.options.loading) === null || _this$options$loading9 === void 0 || (_this$options$loading10 = _this$options$loading9.onEndLoading) === null || _this$options$loading10 === void 0 || _this$options$loading10.call(_this$options$loading9);
1417
- return _context6.finish(49);
1418
- case 52:
1443
+ return _context6.finish(55);
1444
+ case 59:
1445
+ _context6.prev = 59;
1446
+ this.isSubmitting = false;
1447
+ return _context6.finish(59);
1448
+ case 62:
1419
1449
  case "end":
1420
1450
  return _context6.stop();
1421
1451
  }
1422
- }, _callee6, this, [[7, 20], [35, 45, 49, 52]]);
1452
+ }, _callee6, this, [[7,, 59, 62], [12, 25], [41, 51, 55, 59]]);
1423
1453
  }));
1424
1454
  function submitPayment(_x8) {
1425
1455
  return _submitPayment.apply(this, arguments);
@@ -1683,7 +1713,7 @@ export var ModernElementController = /*#__PURE__*/function () {
1683
1713
  if (iframeOrigin && iframeOrigin !== 'null') {
1684
1714
  modalBridge.setOrigin(iframeOrigin);
1685
1715
  }
1686
- } catch (_unused4) {
1716
+ } catch (_unused5) {
1687
1717
  // URL 解析失败时保持默认 origin
1688
1718
  }
1689
1719
  // 如果 payload 有 appearance,通过 TRANSFER_MODAL_APPEARANCE 消息发送给 modal