@wix/himalaya-cli 0.1367.0 → 0.1369.0

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.
Files changed (40) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/mapping-source.d.ts +3 -1
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments-contract.d.ts +44 -2
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments-wire.d.ts +14 -1
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments.d.ts +9 -3
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/apple-iap-contract.d.ts +18 -5
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/apple-iap-core.d.ts +2 -0
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/checkout-source.d.ts +8 -0
  8. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/commerce-core.d.ts +2 -0
  9. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/iap-order-backend.d.ts +3 -0
  10. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/index.d.ts +1 -0
  11. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/order-refs.d.ts +5 -1
  12. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap-checkout.mjs +167 -41
  13. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap.mjs +75 -21
  14. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +147 -30
  15. package/dist/cli.mjs +51 -15
  16. package/guides/himi-json-output.md +6 -4
  17. package/guides/iap-screen-adoption.md +3 -2
  18. package/guides/sdk-reference.json +57 -9
  19. package/package.json +2 -2
  20. package/templates/beauty-salon/dev/index.ts +49 -1
  21. package/templates/beauty-salon/tier5-src/_shared/iap-presentation.ts +4 -2
  22. package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +68 -5
  23. package/templates/branded-lite/dev/index.ts +49 -1
  24. package/templates/branded-lite/tier5-src/_shared/iap-presentation.ts +4 -2
  25. package/templates/branded-lite/tier5-src/himi-store-product/index.ts +68 -5
  26. package/templates/community-club/tier5-src/_shared/iap-presentation.ts +4 -2
  27. package/templates/events-meetups/tier5-src/_shared/iap-presentation.ts +4 -2
  28. package/templates/gym-fitness/dev/index.ts +49 -1
  29. package/templates/gym-fitness/tier5-src/_shared/iap-presentation.ts +4 -2
  30. package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +68 -5
  31. package/templates/nonprofit-cause/tier5-src/_shared/iap-presentation.ts +4 -2
  32. package/templates/podcast-creator/tier5-src/_shared/iap-presentation.ts +4 -2
  33. package/templates/portfolio-creative/dev/index.ts +49 -1
  34. package/templates/portfolio-creative/tier5-src/_shared/iap-presentation.ts +4 -2
  35. package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +68 -5
  36. package/templates/restaurant/tier5-src/_shared/iap-presentation.ts +4 -2
  37. package/templates/retail-store/dev/index.ts +49 -1
  38. package/templates/retail-store/tier5-src/_shared/iap-presentation.ts +4 -2
  39. package/templates/retail-store/tier5-src/himi-store-product/index.ts +68 -5
  40. package/templates/yoga-studio/tier5-src/_shared/iap-presentation.ts +4 -2
@@ -938,15 +938,18 @@ var sameReference = (value, reference) => isObject2(value) && value.kind === ref
938
938
 
939
939
  // ../../core/sdk/iap/src/wix-payments-contract.ts
940
940
  var HIMALAYA_SERVE_IAP_ROUTE = { prefix: "/himalaya-serve/v1/iap" };
941
- var APPLE_SALE_RULES = {
942
- onlineProgram: { appProductId: (id2) => id2, productType: "NON_CONSUMABLE" }
943
- };
941
+ var STORES_ITEM_PAYMENT_ENABLED = false;
942
+ var STORES_PRODUCT_SALE_RULE = { appProductId: (id2) => id2, productType: "NON_CONSUMABLE" };
943
+ var ONLINE_PROGRAM_SALE_RULE = { appProductId: (id2) => id2, productType: "NON_CONSUMABLE" };
944
+ var APPLE_SALE_RULES = STORES_ITEM_PAYMENT_ENABLED ? { onlineProgram: ONLINE_PROGRAM_SALE_RULE, storesProduct: STORES_PRODUCT_SALE_RULE } : { onlineProgram: ONLINE_PROGRAM_SALE_RULE };
944
945
 
945
946
  // ../../core/sdk/iap/src/mapping-source.ts
946
947
  function iapMappingSource() {
947
948
  return createWixIapMappingSource({ binding: sharedHostAppBindingSource(), call: hostWixCall });
948
949
  }
949
950
  function createWixIapMappingSource(deps) {
951
+ const rules = deps.rules ?? APPLE_SALE_RULES;
952
+ const appProductIdOf = (reference) => reference.id ? rules[reference.kind]?.appProductId(reference.id) : void 0;
950
953
  return {
951
954
  // Only a binding the host actually returned: a read that failed is re-asked on the next load.
952
955
  active: async () => await deps.binding.current() !== null,
@@ -957,14 +960,11 @@ function createWixIapMappingSource(deps) {
957
960
  if (scope.siteId && !sameId(scope.siteId, binding.siteId)) return references.map((reference) => ({ reference, route: "unavailable" }));
958
961
  const asked = [...new Set(references.flatMap((reference) => appProductIdOf(reference) ?? []))];
959
962
  const mapped = await resolveAll(deps.call, binding, asked);
960
- return references.map((reference) => decide(reference, binding, mapped));
963
+ return references.map((reference) => decide(reference, binding, mapped.get(appProductIdOf(reference) ?? ""), rules[reference.kind]));
961
964
  }
962
965
  }
963
966
  };
964
967
  }
965
- function appProductIdOf(reference) {
966
- return reference.id ? APPLE_SALE_RULES[reference.kind]?.appProductId(reference.id) : void 0;
967
- }
968
968
  var PATH = `${HIMALAYA_SERVE_IAP_ROUTE.prefix}/mappings`;
969
969
  var BATCH = 100;
970
970
  async function resolveAll(call, binding, ids) {
@@ -988,11 +988,9 @@ function decodeMappings(reply) {
988
988
  return [m.appProductId, { storeProductId: m.storeProductId, type: String(m.type ?? ""), active: m.active === true }];
989
989
  });
990
990
  }
991
- function decide(reference, binding, mapped) {
992
- const id2 = appProductIdOf(reference);
993
- const mapping = id2 ? mapped.get(id2) : void 0;
994
- if (!mapping) return { reference, route: "regular" };
995
- if (!mapping.active || mapping.type !== APPLE_SALE_RULES[reference.kind]?.productType) return { reference, route: "unavailable" };
991
+ function decide(reference, binding, mapping, rule) {
992
+ if (!mapping || !rule) return { reference, route: "regular" };
993
+ if (!mapping.active || mapping.type !== rule.productType) return { reference, route: "unavailable" };
996
994
  return { reference, route: "appleIap", productId: mapping.storeProductId, mappingRevision: `${binding.purchasesAppId}:${mapping.storeProductId}` };
997
995
  }
998
996
  function sameId(a, b) {
@@ -1289,6 +1287,15 @@ function wixApiGlobal() {
1289
1287
  function startPaymentCall(scope, wixTransactionId) {
1290
1288
  return post(scope, "/payments/start", { appId: scope.binding.purchasesAppId, wixTransactionId });
1291
1289
  }
1290
+ function startItemPaymentCall(scope, item) {
1291
+ return post(scope, "/payments/start-item", { appId: scope.binding.purchasesAppId, item: { catalogItemId: item.catalogItemId, catalogAppId: item.catalogAppId } });
1292
+ }
1293
+ function catalogItemOf(raw) {
1294
+ const item = isObject3(raw) ? raw : {};
1295
+ const { catalogItemId, catalogAppId } = item;
1296
+ const valid = typeof catalogItemId === "string" && catalogItemId.length > 0 && catalogItemId.length <= 36 && isUUID(catalogAppId);
1297
+ return valid ? { catalogItemId, catalogAppId } : null;
1298
+ }
1292
1299
  function completePaymentCall(scope, signedTransaction) {
1293
1300
  return post(scope, "/payments/complete", { appId: scope.binding.purchasesAppId, apple: { signedTransaction } });
1294
1301
  }
@@ -1303,6 +1310,12 @@ function decodeStarted(raw, expected) {
1303
1310
  const payment = decodePayment(raw.payment, expected);
1304
1311
  return payment && { payment, storeProductId: raw.storeProductId, appAccountToken: raw.appAccountToken };
1305
1312
  }
1313
+ function decodeStartedItem(raw, expected) {
1314
+ if (!isObject3(raw) || !isUUID(raw.ecomOrderId)) return null;
1315
+ const started = decodeStarted(raw, expected);
1316
+ if (!started || started.payment.appProductId !== expected.catalogItemId) return null;
1317
+ return { ...started, ecomOrderId: raw.ecomOrderId };
1318
+ }
1306
1319
  function decodePaymentAnswer(raw, expected) {
1307
1320
  return isObject3(raw) ? decodePayment(raw.payment, expected) : null;
1308
1321
  }
@@ -1425,6 +1438,19 @@ function createWixIapClient(deps) {
1425
1438
  }
1426
1439
  });
1427
1440
  }
1441
+ function startItemPayment(input) {
1442
+ const item = catalogItemOf(input.item);
1443
+ if (!item) return Promise.resolve(failure("startItemPayment", "invalidArgument"));
1444
+ return runUnrepeatable({
1445
+ operation: "startItemPayment",
1446
+ codes: START_ITEM_PAYMENT_CODES,
1447
+ request: (scope) => startItemPaymentCall(scope, item),
1448
+ decode: (raw, scope) => {
1449
+ const started = decodeStartedItem(raw, { ...expectationOf2(scope), catalogItemId: item.catalogItemId });
1450
+ return started && { status: "started", ...started };
1451
+ }
1452
+ });
1453
+ }
1428
1454
  function completePayment(transaction) {
1429
1455
  const refusal = refuseProof(transaction);
1430
1456
  if (refusal) return Promise.resolve(refusal);
@@ -1451,11 +1477,18 @@ function createWixIapClient(deps) {
1451
1477
  });
1452
1478
  }
1453
1479
  async function run(spec) {
1480
+ return (await execute(spec)).result;
1481
+ }
1482
+ async function runUnrepeatable(spec) {
1483
+ const { result, handedOff } = await execute(spec);
1484
+ return handedOff && isUndecided(result) ? outcomeUnknown(result) : result;
1485
+ }
1486
+ async function execute(spec) {
1454
1487
  const scope = await resolveScope(deps.session.current(), spec.operation);
1455
- if ("failure" in scope) return scope.failure;
1488
+ if ("failure" in scope) return { result: scope.failure, handedOff: false };
1456
1489
  const sent = await send(scope, spec);
1457
- if ("failure" in sent) return sent.failure;
1458
- return spec.decode(sent.answer, scope) ?? failure(spec.operation, "invalidResponse");
1490
+ if ("failure" in sent) return { result: sent.failure, handedOff: sent.handedOff };
1491
+ return { result: spec.decode(sent.answer, scope) ?? failure(spec.operation, "invalidResponse"), handedOff: true };
1459
1492
  }
1460
1493
  async function resolveScope(session, operation) {
1461
1494
  if (session.kind !== "member") return refused(operation, "authRequired");
@@ -1476,12 +1509,12 @@ function createWixIapClient(deps) {
1476
1509
  }
1477
1510
  async function send(scope, spec) {
1478
1511
  const transport = deps.transport ?? bridgeTransport();
1479
- if (!transport) return refused(spec.operation, "notEnabled");
1480
- if (!isCurrent(scope.session)) return refused(spec.operation, "sessionChanged");
1512
+ if (!transport) return notSent(spec.operation, "notEnabled");
1513
+ if (!isCurrent(scope.session)) return notSent(spec.operation, "sessionChanged");
1481
1514
  const expectation = boundExpectation2(scope.session, deps.transport == null);
1482
- if (expectation === "refuse") return refused(spec.operation, "notEnabled");
1515
+ if (expectation === "refuse") return notSent(spec.operation, "notEnabled");
1483
1516
  const outcome = await attempt2(transport, spec.request(scope), spec, expectation);
1484
- return isCurrent(scope.session) ? outcome : refused(spec.operation, "sessionChanged");
1517
+ return isCurrent(scope.session) ? outcome : { failure: failure(spec.operation, "sessionChanged"), handedOff: true };
1485
1518
  }
1486
1519
  function boundExpectation2(session, liveHost) {
1487
1520
  const source = deps.session;
@@ -1492,16 +1525,27 @@ function createWixIapClient(deps) {
1492
1525
  function isCurrent(session) {
1493
1526
  return deps.session.current().generation === session.generation;
1494
1527
  }
1495
- return { startPayment, completePayment, getPayment };
1528
+ return { startPayment, startItemPayment, completePayment, getPayment };
1496
1529
  }
1497
1530
  async function attempt2(transport, call, spec, expectation) {
1498
1531
  try {
1499
1532
  const answer = expectation ? await transport.call(call.method, call.path, call.body, call.headers, expectation) : await transport.call(call.method, call.path, call.body, call.headers);
1500
1533
  return { answer };
1501
1534
  } catch (error) {
1502
- return { failure: classifyFailure(error, spec.operation, spec.codes) };
1535
+ return { failure: classifyFailure(error, spec.operation, spec.codes), handedOff: true };
1503
1536
  }
1504
1537
  }
1538
+ function notSent(operation, kind) {
1539
+ return { failure: failure(operation, kind), handedOff: false };
1540
+ }
1541
+ function isUndecided(result) {
1542
+ const failed = result;
1543
+ return failed.status === "failed" && UNDECIDED.has(failed.kind);
1544
+ }
1545
+ function outcomeUnknown(failed) {
1546
+ const status = failed.httpStatus === void 0 ? {} : { httpStatus: failed.httpStatus };
1547
+ return { status: "outcomeUnknown", operation: "startItemPayment", kind: failed.kind, ...status };
1548
+ }
1505
1549
  async function read(call, operation) {
1506
1550
  try {
1507
1551
  return { value: await call() };
@@ -1537,6 +1581,14 @@ var START_PAYMENT_CODES = [
1537
1581
  "PRODUCT_NOT_AVAILABLE",
1538
1582
  "ALREADY_OWNED"
1539
1583
  ];
1584
+ var START_ITEM_PAYMENT_CODES = [
1585
+ "PRODUCT_NOT_AVAILABLE",
1586
+ "ALREADY_OWNED",
1587
+ "ITEM_NOT_AVAILABLE",
1588
+ "SITE_NOT_ACCEPTING_PAYMENTS",
1589
+ "UNSUPPORTED_ORDER"
1590
+ ];
1591
+ var UNDECIDED = /* @__PURE__ */ new Set(["unavailable", "sessionChanged", "invalidResponse"]);
1540
1592
  var COMPLETE_PAYMENT_CODES = [
1541
1593
  "INVALID_PURCHASE",
1542
1594
  "OWNED_BY_ANOTHER_CUSTOMER",
@@ -1651,6 +1703,9 @@ var HIMALAYA_SERVE_CHECKOUT_ROUTES = {
1651
1703
  function appleIapCheckoutRoutes() {
1652
1704
  return HIMALAYA_SERVE_CHECKOUT_ROUTES;
1653
1705
  }
1706
+ function itemPaymentEnabled() {
1707
+ return STORES_ITEM_PAYMENT_ENABLED;
1708
+ }
1654
1709
 
1655
1710
  // ../../stdlib/flows/iap-checkout/src/cashier-charges.ts
1656
1711
  async function ensureAppleIapCharge(bridge, route, orderId) {
@@ -1747,8 +1802,9 @@ function isFinalRefusal(status) {
1747
1802
 
1748
1803
  // ../../stdlib/flows/iap-checkout/src/order-refs.ts
1749
1804
  var NEEDS_SUPPORT_HOLD_MS = 6048e5;
1805
+ var ITEM_START_HOLD_MS = 36e5;
1750
1806
  function pruneExpiredHolds(partition, now) {
1751
- const expired = partition.refs().filter((ref) => HOLDS.has(ref.stage) && now - ref.updatedAt >= NEEDS_SUPPORT_HOLD_MS);
1807
+ const expired = partition.refs().filter((ref) => now - ref.updatedAt >= (HOLD_MS[ref.stage] ?? Infinity));
1752
1808
  return expired.filter((ref) => partition.remove(ref.key)).map((ref) => ref.key);
1753
1809
  }
1754
1810
  var MAX_ORDER_REFS = 16;
@@ -1881,8 +1937,8 @@ function isUUID3(value) {
1881
1937
  }
1882
1938
  var VERSION = 1;
1883
1939
  var PREFIX = "himi.iap.wix-checkout.v1";
1884
- var STAGES = /* @__PURE__ */ new Set(["ordered", "charged", "started", "submitted", "held", "needsSupport"]);
1885
- var HOLDS = /* @__PURE__ */ new Set(["held", "needsSupport"]);
1940
+ var STAGES = /* @__PURE__ */ new Set(["startingItem", "ordered", "charged", "started", "submitted", "held", "needsSupport"]);
1941
+ var HOLD_MS = { held: NEEDS_SUPPORT_HOLD_MS, needsSupport: NEEDS_SUPPORT_HOLD_MS, startingItem: ITEM_START_HOLD_MS };
1886
1942
  var EVICTABLE = /* @__PURE__ */ new Set(["ordered", "charged", "started"]);
1887
1943
 
1888
1944
  // ../../stdlib/flows/iap-checkout/src/wix-bridge.ts
@@ -1967,12 +2023,24 @@ function createWixOrderBackend(deps) {
1967
2023
  async function getPurchaseContext(session, catalogRef) {
1968
2024
  const sale = await saleFor(session, catalogRef);
1969
2025
  if (isStop(sale)) return contextResult(catalogRef, sale);
2026
+ const blocked = saleBlocked(sale);
2027
+ if (blocked) return contextResult(catalogRef, blocked);
2028
+ const itemPayment = deps.itemPaymentEnabled ? sale.adapter.itemPayment?.(sale.item) : null;
2029
+ return itemPayment ? startItemFor(sale, itemPayment) : startOrderFor(sale);
2030
+ }
2031
+ async function startOrderFor(sale) {
1970
2032
  const ordered = await orderFor(sale);
1971
- if (isStop(ordered)) return contextResult(catalogRef, ordered);
2033
+ if (isStop(ordered)) return contextResult(sale.catalogRef, ordered);
1972
2034
  const charged = await chargeFor(sale, ordered, { reordered: false });
1973
- if (isStop(charged)) return contextResult(catalogRef, charged);
2035
+ if (isStop(charged)) return contextResult(sale.catalogRef, charged);
1974
2036
  return startFor(sale, charged);
1975
2037
  }
2038
+ function saleBlocked(sale) {
2039
+ const stage = refAt(sale.partition, sale.catalogRef)?.stage;
2040
+ const failure3 = stage && BLOCKING_STAGES[stage];
2041
+ if (failure3) return stopWith("rejected", failure3);
2042
+ return deps.productBusy?.(sale.appleProduct.productId) ? stopWith("rejected", "paymentInProgress") : null;
2043
+ }
1976
2044
  async function saleFor(session, catalogRef) {
1977
2045
  const sold = deps.itemFor(catalogRef);
1978
2046
  const adapter = sold && adapterFor(sold.item.reference.kind);
@@ -1996,10 +2064,6 @@ function createWixOrderBackend(deps) {
1996
2064
  }
1997
2065
  async function orderFor(sale) {
1998
2066
  const existing = refAt(sale.partition, sale.catalogRef);
1999
- if (existing?.stage === "submitted") return stopWith("rejected", "paymentInProgress");
2000
- if (existing?.stage === "held") return stopWith("rejected", "paymentHeld");
2001
- if (existing?.stage === "needsSupport") return stopWith("rejected", "needsSupport");
2002
- if (deps.productBusy?.(sale.appleProduct.productId)) return stopWith("rejected", "paymentInProgress");
2003
2067
  const attempt4 = existing?.cashierOrderId && existing.verticalRef ? await reopenOrOpen(sale, { cashierOrderId: existing.cashierOrderId, verticalRef: existing.verticalRef }) : await sale.adapter.openOrder(sale.item, sale.bridge);
2004
2068
  return recordOrder(sale, existing, attempt4);
2005
2069
  }
@@ -2075,6 +2139,40 @@ function createWixOrderBackend(deps) {
2075
2139
  if (isStop(recorded)) return contextResult(sale.catalogRef, recorded);
2076
2140
  return { status: "ok", context: { productId: started.storeProductId, appAccountToken: started.appAccountToken, scopeKey: sale.member.scopeKey } };
2077
2141
  }
2142
+ async function startItemFor(sale, itemPayment) {
2143
+ const attempt4 = persist(sale, { key: sale.catalogRef, stage: "startingItem", kind: sale.adapter.kind, storeProductId: sale.appleProduct.productId, updatedAt: now() });
2144
+ if (isStop(attempt4)) return contextResult(sale.catalogRef, attempt4);
2145
+ const started = await deps.wixIap.startItemPayment({ item: itemPayment.catalogItem });
2146
+ if (started.status === "outcomeUnknown") return contextResult(sale.catalogRef, sale.bridge.isCurrent() ? OUTCOME_UNKNOWN : STALE2);
2147
+ if (started.status !== "started") return contextResult(sale.catalogRef, itemRefusal(sale, started));
2148
+ return startedItem(sale, itemPayment, started);
2149
+ }
2150
+ function startedItem(sale, itemPayment, started) {
2151
+ if (started.storeProductId !== sale.appleProduct.productId) return contextResult(sale.catalogRef, stopWith("rejected", "productChanged"));
2152
+ const { payment, storeProductId, appAccountToken } = started;
2153
+ const recorded = persist(sale, {
2154
+ key: sale.catalogRef,
2155
+ stage: "started",
2156
+ kind: sale.adapter.kind,
2157
+ verticalRef: itemPayment.verticalRefOf(started.ecomOrderId),
2158
+ wixTransactionId: payment.wixTransactionId,
2159
+ paymentId: payment.paymentId,
2160
+ storeProductId,
2161
+ appAccountToken: appAccountToken.toLowerCase(),
2162
+ ...payment.appProductId ? { appProductId: payment.appProductId } : {},
2163
+ updatedAt: now()
2164
+ });
2165
+ if (isStop(recorded)) return contextResult(sale.catalogRef, recorded);
2166
+ return { status: "ok", context: { productId: storeProductId, appAccountToken, scopeKey: sale.member.scopeKey } };
2167
+ }
2168
+ function itemRefusal(sale, failure3) {
2169
+ if (failure3.kind === "application") return undoAttempt(sale, stopWith("rejected", ITEM_REFUSALS[failure3.code]));
2170
+ return undoAttempt(sale, failure3.kind === "unrecognized" ? NOT_CONFIGURED : failureStop(failure3));
2171
+ }
2172
+ function undoAttempt(sale, stop) {
2173
+ sale.partition.remove(sale.catalogRef);
2174
+ return stop;
2175
+ }
2078
2176
  function startedMismatch(sale, started) {
2079
2177
  return sale.appleProduct.productId === started.storeProductId ? null : "productChanged";
2080
2178
  }
@@ -2199,6 +2297,20 @@ function failureStop(failure3) {
2199
2297
  var SIGN_IN = { stop: true, result: "authRequired", failure: "signInRequired" };
2200
2298
  var NOT_CONFIGURED = { stop: true, result: "rejected", failure: "notConfigured" };
2201
2299
  var UNAVAILABLE = { stop: true, result: "retryable", failure: "unavailable" };
2300
+ var OUTCOME_UNKNOWN = { stop: true, result: "rejected", failure: "outcomeUnknown" };
2301
+ var BLOCKING_STAGES = {
2302
+ startingItem: "outcomeUnknown",
2303
+ submitted: "paymentInProgress",
2304
+ held: "paymentHeld",
2305
+ needsSupport: "needsSupport"
2306
+ };
2307
+ var ITEM_REFUSALS = {
2308
+ PRODUCT_NOT_AVAILABLE: "paymentRefused",
2309
+ ALREADY_OWNED: "paymentRefused",
2310
+ ITEM_NOT_AVAILABLE: "orderRefused",
2311
+ SITE_NOT_ACCEPTING_PAYMENTS: "orderRefused",
2312
+ UNSUPPORTED_ORDER: "orderRefused"
2313
+ };
2202
2314
  var KIND_STOPS = {
2203
2315
  authRequired: SIGN_IN,
2204
2316
  notPermitted: SIGN_IN,
@@ -2280,6 +2392,7 @@ function enabledCheckout(deps) {
2280
2392
  bridge,
2281
2393
  itemFor: (key) => sales.get(key),
2282
2394
  productBusy,
2395
+ itemPaymentEnabled: deps.itemPaymentEnabled,
2283
2396
  report: onEvent
2284
2397
  });
2285
2398
  const coordinator = createPurchaseCoordinator({
@@ -2643,6 +2756,8 @@ var REFUSALS = {
2643
2756
  paymentHeld: ["disabled", "support"],
2644
2757
  needsSupport: ["disabled", "support"],
2645
2758
  invalidAssociation: ["disabled", "support"],
2759
+ // An order may exist for a StartItemPayment whose answer was lost: no second tap until it expires.
2760
+ outcomeUnknown: ["disabled", "support"],
2646
2761
  // Nothing in the checkout clears this, so the action stays tappable: a tap re-reads the order
2647
2762
  // (never a second charge) and turns into access once the vertical grants it.
2648
2763
  paymentInProgress: ["enabled", "processing"],
@@ -2743,6 +2858,7 @@ function createIapCommerceWith(deps) {
2743
2858
  stopWatchingSession = void 0;
2744
2859
  checkout = createAppleIapCheckoutWith({
2745
2860
  enabled: true,
2861
+ itemPaymentEnabled: deps.itemPaymentEnabled,
2746
2862
  wixIap: deps.wixIapClient({ host, route: routes.wixIap }),
2747
2863
  binding: deps.binding,
2748
2864
  session: deps.session,
@@ -2863,6 +2979,7 @@ function createIapCommerce(options = {}) {
2863
2979
  const binding = sharedHostAppBindingSource();
2864
2980
  return createIapCommerceWith({
2865
2981
  routes: appleIapCheckoutRoutes(),
2982
+ itemPaymentEnabled: itemPaymentEnabled(),
2866
2983
  pricing: createIapCatalogPricing({ onChange: options.onChange }),
2867
2984
  binding,
2868
2985
  session,