@wix/himalaya-cli 0.1634.0 → 0.1635.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 (53) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-config.d.ts +1 -0
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-module.d.ts +2 -0
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments-contract.d.ts +22 -10
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments-wire.d.ts +16 -6
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/iap/src/wix-payments.d.ts +11 -4
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +6 -0
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/flows/iap-checkout/src/apple-iap-contract.d.ts +10 -4
  8. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap-checkout.mjs +84 -16
  9. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/iap.mjs +67 -10
  10. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/screens.mjs +83 -15
  11. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +1 -0
  12. package/dist/browser-plane/assets.json +5 -5
  13. package/dist/browser-plane/preview-deferred/{c3457ce58c96b65f303fec0ddf5f06733004eaf9e21e62302b155ec63a7765f7.bin → 67feb362281a3040ee05592769227c58a98ec3c8073dac95ecb5629141c67061.bin} +1 -1
  14. package/dist/browser-plane/sw.js +7 -7
  15. package/dist/cli.mjs +220 -49
  16. package/dist/preview-assets.generated.bin +0 -0
  17. package/fixtures/wix-canned.json +3 -0
  18. package/guides/designing-himi-screens.md +5 -1
  19. package/guides/himi-json-output.md +14 -1
  20. package/guides/iap-products.md +8 -0
  21. package/guides/sdk-reference.json +22 -8
  22. package/guides/skill.md +1 -0
  23. package/package.json +2 -2
  24. package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +0 -1
  25. package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +0 -1
  26. package/templates/branded-lite/dev/index.ts +226 -2060
  27. package/templates/branded-lite/l10n/en.json +3 -5
  28. package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +0 -1
  29. package/templates/branded-lite/tier5-src/_shared/himi-cms.ts +2 -1
  30. package/templates/branded-lite/tier5-src/himi-branded-lite-cms/index.ts +160 -39
  31. package/templates/community-club/dev/index.ts +210 -2044
  32. package/templates/community-club/tier5-src/_shared/collection-contract.ts +0 -1
  33. package/templates/community-club/tier5-src/_shared/himi-cms.ts +2 -1
  34. package/templates/community-club/tier5-src/himi-branded-lite-cms/index.ts +160 -39
  35. package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +0 -1
  36. package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +0 -1
  37. package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +0 -1
  38. package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +0 -1
  39. package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +0 -1
  40. package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +0 -1
  41. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +0 -1
  42. package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +0 -1
  43. package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +0 -1
  44. package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +0 -1
  45. package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +0 -1
  46. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +0 -1
  47. package/templates/restaurant/tier5-src/_shared/collection-contract.ts +0 -1
  48. package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +0 -1
  49. package/templates/retail-store/tier5-src/_shared/collection-contract.ts +0 -1
  50. package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +0 -1
  51. package/templates/salon-spa/tier5-src/_shared/collection-contract.ts +0 -1
  52. package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +0 -1
  53. package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +0 -1
@@ -84,6 +84,7 @@ export interface NavigationConfig {
84
84
  /** Signed release allowlist for contained browser Tier-5 `_stream` requests. */
85
85
  streamPolicy?: StreamPolicy;
86
86
  topBarLogo?: import("@wix/himalaya/core").TopBarLogo;
87
+ presentationQueue?: boolean;
87
88
  splash?: SplashConfig;
88
89
  locale?: LocaleConfig;
89
90
  backAffordance?: BackAffordanceConfig;
@@ -237,6 +237,8 @@ export interface DerivedAppMeta {
237
237
  /** Forwarded from AppConfig.navigation.topBarLogo — the app-wide logo for tab-stack roots
238
238
  * (RFC 0066 amendment "top-bar gap items"). */
239
239
  topBarLogo?: import("@wix/himalaya/core").TopBarLogo;
240
+ /** Forwarded from AppConfig.navigation.presentationQueue — the opt-in host alert queue (#4662). */
241
+ presentationQueue?: boolean;
240
242
  /** Forwarded from AppConfig.`splash` — the in-app splash surface. NOTE the
241
243
  * asymmetry with the fields above: this reads the TOP-LEVEL `config.splash`, not
242
244
  * `config.navigation.splash`, because the same block also drives the build-time
@@ -121,11 +121,12 @@ export interface WixIapPayment {
121
121
  canceledDate?: string;
122
122
  refundedDate?: string;
123
123
  }
124
- export type WixIapOperation = "startPayment" | "startItemPayment" | "completePayment" | "getPayment";
124
+ export type WixIapOperation = "startPayment" | "startItemPayment" | "completePayment" | "cancelPayment" | "getPayment";
125
125
  export type StartPaymentErrorCode = "NOT_PENDING" | "WRONG_PAYMENT_METHOD" | "NOT_ORDER_BUYER" | "UNSUPPORTED_ORDER" | "PRODUCT_NOT_AVAILABLE" | "ALREADY_OWNED" | "APP_NOT_CONFIGURED" | "SUBSCRIPTION_NOT_IN_APP" | "ALREADY_SUBSCRIBED";
126
- export type StartItemPaymentErrorCode = "PRODUCT_NOT_AVAILABLE" | "ALREADY_OWNED" | "ITEM_NOT_AVAILABLE" | "SITE_NOT_ACCEPTING_PAYMENTS" | "UNSUPPORTED_ORDER";
126
+ export type StartItemPaymentErrorCode = "PRODUCT_NOT_AVAILABLE" | "ALREADY_OWNED" | "ITEM_NOT_AVAILABLE" | "SITE_NOT_ACCEPTING_PAYMENTS" | "UNSUPPORTED_ORDER" | "CATALOG_NOT_SUPPORTED" | "VERTICAL_ACCESS_DENIED" | "EVENT_CHECKOUT_NOT_ECOM" | "ALREADY_SUBSCRIBED" | "SUBSCRIPTION_NOT_IN_APP" | "BILLING_COUNTRY_REQUIRED" | "APP_NOT_CONFIGURED" | "NOT_BOOKING_OWNER" | "BOOKING_PAYMENT_PENDING";
127
127
  export type CompletePaymentErrorCode = "INVALID_PURCHASE" | "OWNED_BY_ANOTHER_CUSTOMER" | "PURCHASE_REVOKED" | "NOT_PURCHASED" | "ZERO_PRICE" | "NO_MATCHING_PAYMENT" | "PAYMENT_NOT_PENDING" | "APP_NOT_CONFIGURED";
128
128
  export type GetPaymentErrorCode = "NOT_FOUND";
129
+ export type CancelPaymentErrorCode = "NOT_PENDING" | "APP_NOT_CONFIGURED" | "NOT_FOUND";
129
130
  /** Why a call gave no usable answer, other than a named application error.
130
131
  * `unavailable` and `sessionChanged` say nothing about whether the request took effect.
131
132
  * `unrecognized` is an HTTP refusal this client cannot name: never treat it as terminal.
@@ -155,12 +156,15 @@ export type StartPaymentResult = {
155
156
  storeProductId: string;
156
157
  appAccountToken: string;
157
158
  } | WixIapFailure<StartPaymentErrorCode>;
158
- /** One item a Wix catalog sells through eCom, as eCom's `catalogReference` names it: for Wix Stores,
159
- * the product id and the Stores app id. The purchases catalog sells it under `catalogItemId` as its
160
- * `appProductId`. Variants and options are not supported, and the quantity is always 1. */
159
+ /** One item a Wix catalog sells, as eCom's `catalogReference` names it: the item id and its catalog
160
+ * app. The purchases catalog sells it under `catalogItemId` as its `appProductId`. `options` go to
161
+ * eCom unchanged and are each vertical's own: a plan's `{type: "PLAN", planOptions: {pricingVariantId}}`,
162
+ * a booking's `{bookingId}`, a ticket's `{eventId}`, a Stores variant's `{variantId}`. Plain JSON only.
163
+ * The quantity is always 1. */
161
164
  export interface EcomCatalogReference {
162
165
  catalogItemId: string;
163
166
  catalogAppId: string;
167
+ options?: Record<string, unknown>;
164
168
  }
165
169
  /** StartItemPayment was handed to the transport and gave no answer this client can act on: an
166
170
  * outage, a lost or late answer, or a 2xx it could not decode. The service may have placed an
@@ -172,16 +176,18 @@ export interface StartItemPaymentOutcomeUnknown {
172
176
  kind: WixIapFailureKind;
173
177
  httpStatus?: number;
174
178
  }
175
- /** StartItemPayment places the member's eCom order for one catalog item, charges it with
176
- * `appleIAP` and starts its Payment, all server-side. Four different ids come back: the eCom
177
- * order (`ecomOrderId`), the Wix Payments charge (`payment.wixTransactionId`), the wix-iap
178
- * Payment (`payment.paymentId`) and the StoreKit `appAccountToken`. Keep them out of screen state. */
179
+ /** StartItemPayment places the member's order for one catalog item, charges it with `appleIAP` and
180
+ * starts its Payment, all server-side. Four different ids come back: the vertical's record (the eCom
181
+ * order, `ecomOrderId`; for Online Programs the join application, `joinApplicationId`, and no eCom
182
+ * order), the Wix Payments charge (`payment.wixTransactionId`), the wix-iap Payment
183
+ * (`payment.paymentId`) and the StoreKit `appAccountToken`. Keep them out of screen state. */
179
184
  export type StartItemPaymentResult = {
180
185
  status: "started";
181
186
  payment: WixIapPayment;
182
187
  storeProductId: string;
183
188
  appAccountToken: string;
184
- ecomOrderId: string;
189
+ ecomOrderId?: string;
190
+ joinApplicationId?: string;
185
191
  } | WixIapFailure<StartItemPaymentErrorCode> | StartItemPaymentOutcomeUnknown;
186
192
  /** `matched`: the server verified the proof and paid the payment whose token the Apple transaction
187
193
  * carries. Its status may still be `approving`. */
@@ -193,3 +199,9 @@ export type GetPaymentResult = {
193
199
  status: "found";
194
200
  payment: WixIapPayment;
195
201
  } | WixIapFailure<GetPaymentErrorCode>;
202
+ /** `answered`: the Payment as CancelPayment left it, `canceling`, `canceled`, or `approved` when a
203
+ * purchase the store already reported paid it instead. Only `canceled` means nothing was paid. */
204
+ export type CancelPaymentResult = {
205
+ status: "answered";
206
+ payment: WixIapPayment;
207
+ } | WixIapFailure<CancelPaymentErrorCode>;
@@ -10,13 +10,19 @@ export interface CallScope {
10
10
  prefix: string;
11
11
  }
12
12
  export declare function startPaymentCall(scope: CallScope, wixTransactionId: string): WixIapCall;
13
- /** The app by its bundle, like every device call (catalyst-server #24546), and only the two ids
14
- * StartItemPaymentRequest.item has: no quantity, options or member. */
15
- export declare function startItemPaymentCall(scope: CallScope, item: EcomCatalogReference): WixIapCall;
16
- /** CatalogReference's limits: `catalog_item_id` 1–36 characters, `catalog_app_id` a GUID. */
13
+ /** The app by its bundle, like every device call (catalyst-server #24546), and only what
14
+ * StartItemPaymentRequest has: the item's ids and options, and StoreKit's storefront country, which
15
+ * a Pricing Plans order bills in (#24878). Never a quantity or the member. */
16
+ export declare function startItemPaymentCall(scope: CallScope, item: EcomCatalogReference, storeCountryCode?: string): WixIapCall;
17
+ /** CatalogReference's limits: `catalog_item_id` 1–36 characters, `catalog_app_id` a GUID, `options` a
18
+ * protobuf Struct, so plain JSON. Empty options are dropped; any other shape refuses the item. */
17
19
  export declare function catalogItemOf(raw: unknown): EcomCatalogReference | null;
20
+ /** StoreKit's `Storefront.countryCode`: ISO 3166-1 alpha-3, uppercase. */
21
+ export declare function isStoreCountryCode(value: unknown): value is string;
18
22
  /** The JWS goes byte-for-byte: the server derives the member, and the proof names the product. */
19
23
  export declare function completePaymentCall(scope: CallScope, signedTransaction: string): WixIapCall;
24
+ /** The member's own Payment, by id; the bundle names the app as on every device call (#24894). */
25
+ export declare function cancelPaymentCall(scope: CallScope, paymentId: string): WixIapCall;
20
26
  export declare function paymentCall(scope: CallScope, paymentId: string): WixIapCall;
21
27
  /** A gateway path such as `/_api/<service>/v1`: absolute, no trailing slash, query or scheme. */
22
28
  export declare function isRoutePrefix(prefix: string): boolean;
@@ -34,10 +40,14 @@ export interface StartedPayment {
34
40
  }
35
41
  /** D61: the token is this payment's purchase intent; no other field may stand in for it. */
36
42
  export declare function decodeStarted(raw: unknown, expected: PaymentExpectation): StartedPayment | null;
43
+ /** An eCom order for every catalog but Online Programs, which answers its join application instead
44
+ * (#24880). */
37
45
  export interface StartedItemPayment extends StartedPayment {
38
- ecomOrderId: string;
46
+ ecomOrderId?: string;
47
+ joinApplicationId?: string;
39
48
  }
40
- /** As StartPayment's answer, plus the member's eCom order. The Payment must name the requested
49
+ /** As StartPayment's answer, plus the member's eCom order or, for Online Programs, join application.
50
+ * The Payment must name the requested
41
51
  * item: StartItemPayment builds it from the catalog entry it looked up, whose `appProductId` is
42
52
  * the catalog item id, so a Payment that names none is not known to be this item's. */
43
53
  export declare function decodeStartedItem(raw: unknown, expected: PaymentExpectation & {
@@ -1,6 +1,6 @@
1
1
  import type { AppleTransaction } from "./index.js";
2
2
  import type { SessionProvider } from "./delivery-contract.js";
3
- import type { AppBindingSource, EcomCatalogReference, StartItemPaymentResult, CompletePaymentResult, GetPaymentResult, IapAppHost, MemberIdentitySource, StartPaymentResult, WixIapRoute, WixTransport } from "./wix-payments-contract.js";
3
+ import type { AppBindingSource, CancelPaymentResult, EcomCatalogReference, StartItemPaymentResult, CompletePaymentResult, GetPaymentResult, IapAppHost, MemberIdentitySource, StartPaymentResult, WixIapRoute, WixTransport } from "./wix-payments-contract.js";
4
4
  export interface WixIapClientDependencies {
5
5
  /** The trusted host session; each call is bound to the generation current when it starts. */
6
6
  session: SessionProvider;
@@ -18,11 +18,13 @@ export interface WixIapClient {
18
18
  startPayment(input: {
19
19
  wixTransactionId: string;
20
20
  }): Promise<StartPaymentResult>;
21
- /** StartItemPayment for one catalog item: the service places the member's eCom order, charges it
22
- * and starts its Payment. Every call places a new order, so `outcomeUnknown` must never be
23
- * resent as if nothing happened. Returns the store product, the token and the eCom order. */
21
+ /** StartItemPayment for one catalog item: the service places the member's order, charges it and
22
+ * starts its Payment. Every call places a new order, so `outcomeUnknown` must never be resent as
23
+ * if nothing happened. `storeCountryCode` is StoreKit's storefront country (alpha-3), sent when
24
+ * known. Returns the store product, the token and the eCom order or join application. */
24
25
  startItemPayment(input: {
25
26
  item: EcomCatalogReference;
27
+ storeCountryCode?: string;
26
28
  }): Promise<StartItemPaymentResult>;
27
29
  /** CompletePayment with held Apple proof, sent unchanged: the service pays the payment whose
28
30
  * token the transaction carries. Success can still be `approving`. */
@@ -31,6 +33,11 @@ export interface WixIapClient {
31
33
  getPayment(input: {
32
34
  paymentId: string;
33
35
  }): Promise<GetPaymentResult>;
36
+ /** CancelPayment: the member dismissed the store sheet. The service cancels the pending Payment and
37
+ * releases what its vertical held, unless a purchase the store already reported paid it. */
38
+ cancelPayment(input: {
39
+ paymentId: string;
40
+ }): Promise<CancelPaymentResult>;
34
41
  }
35
42
  /**
36
43
  * Creates a client for Wix's in-app-purchase payments service (`mobile-apps-wix-iap`), which pays
@@ -3005,6 +3005,12 @@ export interface NavigationConfig {
3005
3005
  site?: SiteNavConfig;
3006
3006
  /** RFC 0066 amendment "top-bar gap items" — app-wide logo for tab-stack roots. */
3007
3007
  topBarLogo?: TopBarLogo;
3008
+ /** Opt-in alert queue. `true` ⇒ every presented alert (worker `ui.alert`, the descriptor nav
3009
+ * `alert` verb, app services) shows one at a time in FIFO order per shell, instead of replacing
3010
+ * each other or rejecting `ui_busy`. At most 5 wait (a 6th worker call rejects `ui_queue_full`);
3011
+ * identical consecutive alerts show once. An inline `AlertDialog` component never enters the
3012
+ * queue. Absent ⇒ today's behaviour. */
3013
+ presentationQueue?: boolean;
3008
3014
  scheme: string;
3009
3015
  deepLinkPatterns: DeepLinkPattern[];
3010
3016
  linkableScreens: LinkableScreen[];
@@ -107,12 +107,18 @@ export interface OpeningGuard {
107
107
  * `held`: still unknown, and it blocks this sale. `unrelated`: still unknown, but it targets other
108
108
  * inventory than this sale's. */
109
109
  export type OpeningResolution = "released" | "held" | "unrelated" | "unavailable" | "sessionChanged";
110
- /** An item wix-iap orders itself (StartItemPayment): the item as eCom's catalog reference, and how
111
- * the adapter finds the eCom order that call placed. */
110
+ /** What StartItemPayment placed: an eCom order, or for Online Programs a join application. */
111
+ export interface PlacedItem {
112
+ ecomOrderId?: string;
113
+ joinApplicationId?: string;
114
+ }
115
+ /** An item wix-iap orders itself (StartItemPayment): the item as its catalog reference, and how the
116
+ * adapter finds what that call placed. */
112
117
  export interface ItemPayment {
113
118
  catalogItem: EcomCatalogReference;
114
- /** The reference `readAccess` reads for the eCom order StartItemPayment placed. */
115
- verticalRefOf(ecomOrderId: string): VerticalRef;
119
+ /** The reference `readAccess` reads for what StartItemPayment placed; null when the answer names
120
+ * nothing this adapter reads. */
121
+ verticalRefOf(placed: PlacedItem): VerticalRef | null;
116
122
  }
117
123
  /** What every vertical answers. Every call goes through the session-bound bridge it is given. */
118
124
  export interface IapAdapterBase {
@@ -1066,18 +1066,45 @@ function wixApiGlobal() {
1066
1066
  function startPaymentCall(scope, wixTransactionId) {
1067
1067
  return post(scope, "/payments/start", { appleBundleId: scope.binding.bundleId, wixTransactionId });
1068
1068
  }
1069
- function startItemPaymentCall(scope, item) {
1070
- return post(scope, "/payments/start-item", { appleBundleId: scope.binding.bundleId, item: { catalogItemId: item.catalogItemId, catalogAppId: item.catalogAppId } });
1069
+ function startItemPaymentCall(scope, item, storeCountryCode) {
1070
+ const { catalogItemId, catalogAppId, options } = item;
1071
+ return post(scope, "/payments/start-item", {
1072
+ appleBundleId: scope.binding.bundleId,
1073
+ item: { catalogItemId, catalogAppId, ...options ? { options } : {} },
1074
+ ...storeCountryCode ? { storeCountryCode } : {}
1075
+ });
1071
1076
  }
1072
1077
  function catalogItemOf(raw) {
1073
1078
  const item = isObject3(raw) ? raw : {};
1074
- const { catalogItemId, catalogAppId } = item;
1079
+ const { catalogItemId, catalogAppId, options } = item;
1075
1080
  const valid = typeof catalogItemId === "string" && catalogItemId.length > 0 && catalogItemId.length <= 36 && isUUID(catalogAppId);
1076
- return valid ? { catalogItemId, catalogAppId } : null;
1081
+ if (!valid || options !== void 0 && !isJsonObject(options)) return null;
1082
+ return options && Object.keys(options).length > 0 ? { catalogItemId, catalogAppId, options } : { catalogItemId, catalogAppId };
1083
+ }
1084
+ function isStoreCountryCode(value) {
1085
+ return typeof value === "string" && /^[A-Z]{3}$/.test(value);
1086
+ }
1087
+ var MAX_JSON_DEPTH = 32;
1088
+ function isJsonObject(value, depth = 0) {
1089
+ return depth < MAX_JSON_DEPTH && isPlainObject(value) && Object.values(value).every((v) => isJsonValue(v, depth + 1));
1090
+ }
1091
+ function isJsonValue(value, depth) {
1092
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
1093
+ if (typeof value === "number") return Number.isFinite(value);
1094
+ if (Array.isArray(value)) return depth < MAX_JSON_DEPTH && value.every((v) => isJsonValue(v, depth + 1));
1095
+ return isJsonObject(value, depth);
1096
+ }
1097
+ function isPlainObject(value) {
1098
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1099
+ const proto = Object.getPrototypeOf(value);
1100
+ return proto === Object.prototype || proto === null;
1077
1101
  }
1078
1102
  function completePaymentCall(scope, signedTransaction) {
1079
1103
  return post(scope, "/payments/complete", { appleBundleId: scope.binding.bundleId, apple: { signedTransaction } });
1080
1104
  }
1105
+ function cancelPaymentCall(scope, paymentId) {
1106
+ return post(scope, `/payments/${encodeURIComponent(paymentId)}/cancel`, { appleBundleId: scope.binding.bundleId });
1107
+ }
1081
1108
  function paymentCall(scope, paymentId) {
1082
1109
  return get2(scope, `/payments/${encodeURIComponent(paymentId)}`);
1083
1110
  }
@@ -1090,10 +1117,17 @@ function decodeStarted(raw, expected) {
1090
1117
  return payment && { payment, storeProductId: raw.storeProductId, appAccountToken: raw.appAccountToken };
1091
1118
  }
1092
1119
  function decodeStartedItem(raw, expected) {
1093
- if (!isObject3(raw) || !isUUID(raw.ecomOrderId)) return null;
1120
+ if (!isObject3(raw)) return null;
1121
+ const ecomOrderId = optionalId(raw.ecomOrderId);
1122
+ const joinApplicationId = optionalId(raw.joinApplicationId);
1123
+ if (ecomOrderId === null || joinApplicationId === null || !ecomOrderId && !joinApplicationId) return null;
1094
1124
  const started = decodeStarted(raw, expected);
1095
1125
  if (!started || started.payment.appProductId !== expected.catalogItemId) return null;
1096
- return { ...started, ecomOrderId: raw.ecomOrderId };
1126
+ return { ...started, ...ecomOrderId ? { ecomOrderId } : {}, ...joinApplicationId ? { joinApplicationId } : {} };
1127
+ }
1128
+ function optionalId(value) {
1129
+ if (value === void 0 || value === "") return void 0;
1130
+ return isUUID(value) ? value : null;
1097
1131
  }
1098
1132
  function decodePaymentAnswer(raw, expected) {
1099
1133
  return isObject3(raw) ? decodePayment(raw.payment, expected) : null;
@@ -1219,11 +1253,12 @@ function createWixIapClient(deps) {
1219
1253
  }
1220
1254
  function startItemPayment(input) {
1221
1255
  const item = catalogItemOf(input.item);
1222
- if (!item) return Promise.resolve(failure("startItemPayment", "invalidArgument"));
1256
+ const country = input.storeCountryCode;
1257
+ if (!item || country !== void 0 && !isStoreCountryCode(country)) return Promise.resolve(failure("startItemPayment", "invalidArgument"));
1223
1258
  return runUnrepeatable({
1224
1259
  operation: "startItemPayment",
1225
1260
  codes: START_ITEM_PAYMENT_CODES,
1226
- request: (scope) => startItemPaymentCall(scope, item),
1261
+ request: (scope) => startItemPaymentCall(scope, item, country),
1227
1262
  decode: (raw, scope) => {
1228
1263
  const started = decodeStartedItem(raw, { ...expectationOf2(scope), catalogItemId: item.catalogItemId });
1229
1264
  return started && { status: "started", ...started };
@@ -1255,6 +1290,18 @@ function createWixIapClient(deps) {
1255
1290
  }
1256
1291
  });
1257
1292
  }
1293
+ function cancelPayment(input) {
1294
+ if (!isUUID(input.paymentId)) return Promise.resolve(failure("cancelPayment", "invalidArgument"));
1295
+ return run({
1296
+ operation: "cancelPayment",
1297
+ codes: CANCEL_PAYMENT_CODES,
1298
+ request: (scope) => cancelPaymentCall(scope, input.paymentId),
1299
+ decode: (raw, scope) => {
1300
+ const payment = decodePaymentAnswer(raw, { ...expectationOf2(scope), paymentId: input.paymentId });
1301
+ return payment && { status: "answered", payment };
1302
+ }
1303
+ });
1304
+ }
1258
1305
  async function run(spec) {
1259
1306
  return (await execute(spec)).result;
1260
1307
  }
@@ -1304,7 +1351,7 @@ function createWixIapClient(deps) {
1304
1351
  function isCurrent(session) {
1305
1352
  return deps.session.current().generation === session.generation;
1306
1353
  }
1307
- return { startPayment, startItemPayment, completePayment, getPayment };
1354
+ return { startPayment, startItemPayment, completePayment, getPayment, cancelPayment };
1308
1355
  }
1309
1356
  async function attempt(transport, call, spec, expectation) {
1310
1357
  try {
@@ -1368,8 +1415,18 @@ var START_ITEM_PAYMENT_CODES = [
1368
1415
  "ALREADY_OWNED",
1369
1416
  "ITEM_NOT_AVAILABLE",
1370
1417
  "SITE_NOT_ACCEPTING_PAYMENTS",
1371
- "UNSUPPORTED_ORDER"
1418
+ "UNSUPPORTED_ORDER",
1419
+ "CATALOG_NOT_SUPPORTED",
1420
+ "VERTICAL_ACCESS_DENIED",
1421
+ "EVENT_CHECKOUT_NOT_ECOM",
1422
+ "ALREADY_SUBSCRIBED",
1423
+ "SUBSCRIPTION_NOT_IN_APP",
1424
+ "BILLING_COUNTRY_REQUIRED",
1425
+ "APP_NOT_CONFIGURED",
1426
+ "NOT_BOOKING_OWNER",
1427
+ "BOOKING_PAYMENT_PENDING"
1372
1428
  ];
1429
+ var CANCEL_PAYMENT_CODES = ["NOT_PENDING", "APP_NOT_CONFIGURED", "NOT_FOUND"];
1373
1430
  var UNDECIDED = /* @__PURE__ */ new Set(["unavailable", "sessionChanged", "invalidResponse"]);
1374
1431
  var COMPLETE_PAYMENT_CODES = [
1375
1432
  "INVALID_PURCHASE",
@@ -2065,7 +2122,7 @@ function createWixOrderBackend(deps) {
2065
2122
  const attempt3 = existing?.cashierOrderId && existing.verticalRef ? await reopenOrOpen(sale, { cashierOrderId: existing.cashierOrderId, verticalRef: existing.verticalRef }) : await sale.adapter.openOrder(sale.item, sale.bridge, beforeCreate, afterCreate);
2066
2123
  if (prevented) return prevented;
2067
2124
  if (guarded !== void 0 && attempt3.status === "open" && !stillGuarded(sale, guarded)) return retry("unavailable");
2068
- const ref = recordOrder(sale, existing, attempt3);
2125
+ const ref = recordOrder(sale, existing, attempt3, guarded);
2069
2126
  return isStop(ref) ? ref : { ref, placed: isPlaced(attempt3) };
2070
2127
  }
2071
2128
  function stillGuarded(sale, guarded) {
@@ -2077,8 +2134,8 @@ function createWixOrderBackend(deps) {
2077
2134
  const closed = reopened.status === "refused" && reopened.reason === "orderClosed";
2078
2135
  return closed && !sale.adapter.repeatable ? sale.adapter.openOrder(sale.item, sale.bridge) : reopened;
2079
2136
  }
2080
- function recordOrder(sale, existing, attempt3) {
2081
- if (attempt3.noOrderCreated && refAt(sale.partition, sale.catalogRef)?.stage === "openingOrder" && !sale.partition.remove(sale.catalogRef)) {
2137
+ function recordOrder(sale, existing, attempt3, guarded) {
2138
+ if (attempt3.noOrderCreated && guarded !== void 0 && stillGuarded(sale, guarded) && !sale.partition.remove(sale.catalogRef)) {
2082
2139
  return stopWith("rejected", "storageUnavailable");
2083
2140
  }
2084
2141
  if (attempt3.status === "granted") return alreadyOwned(sale);
@@ -2159,12 +2216,14 @@ function createWixOrderBackend(deps) {
2159
2216
  }
2160
2217
  function startedItem(sale, itemPayment2, started) {
2161
2218
  if (started.storeProductId !== sale.appleProduct.productId) return contextResult(sale.catalogRef, stopWith("rejected", "productChanged"));
2219
+ const verticalRef = itemPayment2.verticalRefOf(started);
2220
+ if (!verticalRef) return contextResult(sale.catalogRef, OUTCOME_UNKNOWN);
2162
2221
  const { payment, storeProductId, appAccountToken } = started;
2163
2222
  const recorded = persist(sale, {
2164
2223
  key: sale.catalogRef,
2165
2224
  stage: "started",
2166
2225
  kind: sale.adapter.kind,
2167
- verticalRef: itemPayment2.verticalRefOf(started.ecomOrderId),
2226
+ verticalRef,
2168
2227
  wixTransactionId: payment.wixTransactionId,
2169
2228
  paymentId: payment.paymentId,
2170
2229
  storeProductId,
@@ -2329,7 +2388,16 @@ var ITEM_REFUSALS = {
2329
2388
  ALREADY_OWNED: "paymentRefused",
2330
2389
  ITEM_NOT_AVAILABLE: "orderRefused",
2331
2390
  SITE_NOT_ACCEPTING_PAYMENTS: "sitePaymentUnavailable",
2332
- UNSUPPORTED_ORDER: "orderRefused"
2391
+ UNSUPPORTED_ORDER: "orderRefused",
2392
+ CATALOG_NOT_SUPPORTED: "unsupportedItem",
2393
+ EVENT_CHECKOUT_NOT_ECOM: "unsupportedItem",
2394
+ VERTICAL_ACCESS_DENIED: "notConfigured",
2395
+ APP_NOT_CONFIGURED: "notConfigured",
2396
+ ALREADY_SUBSCRIBED: "paymentRefused",
2397
+ SUBSCRIPTION_NOT_IN_APP: "paymentRefused",
2398
+ BILLING_COUNTRY_REQUIRED: "orderRefused",
2399
+ NOT_BOOKING_OWNER: "orderRefused",
2400
+ BOOKING_PAYMENT_PENDING: "paymentInProgress"
2333
2401
  };
2334
2402
  var KIND_STOPS = {
2335
2403
  authRequired: SIGN_IN,
@@ -3360,7 +3428,7 @@ function eligibility(item) {
3360
3428
  return catalog && !variant && isNonEmpty3(catalog.appId) && catalog.appId.toLowerCase() === WIX_STORES_APP && catalog.catalogItemId === item.reference.id ? single : UNSUPPORTED;
3361
3429
  }
3362
3430
  function itemPayment(item) {
3363
- return { catalogItem: { catalogItemId: item.reference.id, catalogAppId: WIX_STORES_APP }, verticalRefOf: (orderId) => ({ orderId }) };
3431
+ return { catalogItem: { catalogItemId: item.reference.id, catalogAppId: WIX_STORES_APP }, verticalRefOf: ({ ecomOrderId }) => ecomOrderId ? { orderId: ecomOrderId } : null };
3364
3432
  }
3365
3433
  function classifyCart(lines) {
3366
3434
  if (lines.length === 0 || lines.some((line) => line.route === "resolving" || line.route === "unavailable")) return "blocked";
@@ -1070,18 +1070,45 @@ function wixApiGlobal() {
1070
1070
  function startPaymentCall(scope, wixTransactionId) {
1071
1071
  return post(scope, "/payments/start", { appleBundleId: scope.binding.bundleId, wixTransactionId });
1072
1072
  }
1073
- function startItemPaymentCall(scope, item) {
1074
- return post(scope, "/payments/start-item", { appleBundleId: scope.binding.bundleId, item: { catalogItemId: item.catalogItemId, catalogAppId: item.catalogAppId } });
1073
+ function startItemPaymentCall(scope, item, storeCountryCode) {
1074
+ const { catalogItemId, catalogAppId, options } = item;
1075
+ return post(scope, "/payments/start-item", {
1076
+ appleBundleId: scope.binding.bundleId,
1077
+ item: { catalogItemId, catalogAppId, ...options ? { options } : {} },
1078
+ ...storeCountryCode ? { storeCountryCode } : {}
1079
+ });
1075
1080
  }
1076
1081
  function catalogItemOf(raw) {
1077
1082
  const item = isObject3(raw) ? raw : {};
1078
- const { catalogItemId, catalogAppId } = item;
1083
+ const { catalogItemId, catalogAppId, options } = item;
1079
1084
  const valid = typeof catalogItemId === "string" && catalogItemId.length > 0 && catalogItemId.length <= 36 && isUUID(catalogAppId);
1080
- return valid ? { catalogItemId, catalogAppId } : null;
1085
+ if (!valid || options !== void 0 && !isJsonObject(options)) return null;
1086
+ return options && Object.keys(options).length > 0 ? { catalogItemId, catalogAppId, options } : { catalogItemId, catalogAppId };
1087
+ }
1088
+ function isStoreCountryCode(value) {
1089
+ return typeof value === "string" && /^[A-Z]{3}$/.test(value);
1090
+ }
1091
+ var MAX_JSON_DEPTH = 32;
1092
+ function isJsonObject(value, depth = 0) {
1093
+ return depth < MAX_JSON_DEPTH && isPlainObject(value) && Object.values(value).every((v) => isJsonValue(v, depth + 1));
1094
+ }
1095
+ function isJsonValue(value, depth) {
1096
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
1097
+ if (typeof value === "number") return Number.isFinite(value);
1098
+ if (Array.isArray(value)) return depth < MAX_JSON_DEPTH && value.every((v) => isJsonValue(v, depth + 1));
1099
+ return isJsonObject(value, depth);
1100
+ }
1101
+ function isPlainObject(value) {
1102
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1103
+ const proto = Object.getPrototypeOf(value);
1104
+ return proto === Object.prototype || proto === null;
1081
1105
  }
1082
1106
  function completePaymentCall(scope, signedTransaction) {
1083
1107
  return post(scope, "/payments/complete", { appleBundleId: scope.binding.bundleId, apple: { signedTransaction } });
1084
1108
  }
1109
+ function cancelPaymentCall(scope, paymentId) {
1110
+ return post(scope, `/payments/${encodeURIComponent(paymentId)}/cancel`, { appleBundleId: scope.binding.bundleId });
1111
+ }
1085
1112
  function paymentCall(scope, paymentId) {
1086
1113
  return get(scope, `/payments/${encodeURIComponent(paymentId)}`);
1087
1114
  }
@@ -1094,10 +1121,17 @@ function decodeStarted(raw, expected) {
1094
1121
  return payment && { payment, storeProductId: raw.storeProductId, appAccountToken: raw.appAccountToken };
1095
1122
  }
1096
1123
  function decodeStartedItem(raw, expected) {
1097
- if (!isObject3(raw) || !isUUID(raw.ecomOrderId)) return null;
1124
+ if (!isObject3(raw)) return null;
1125
+ const ecomOrderId = optionalId(raw.ecomOrderId);
1126
+ const joinApplicationId = optionalId(raw.joinApplicationId);
1127
+ if (ecomOrderId === null || joinApplicationId === null || !ecomOrderId && !joinApplicationId) return null;
1098
1128
  const started = decodeStarted(raw, expected);
1099
1129
  if (!started || started.payment.appProductId !== expected.catalogItemId) return null;
1100
- return { ...started, ecomOrderId: raw.ecomOrderId };
1130
+ return { ...started, ...ecomOrderId ? { ecomOrderId } : {}, ...joinApplicationId ? { joinApplicationId } : {} };
1131
+ }
1132
+ function optionalId(value) {
1133
+ if (value === void 0 || value === "") return void 0;
1134
+ return isUUID(value) ? value : null;
1101
1135
  }
1102
1136
  function decodePaymentAnswer(raw, expected) {
1103
1137
  return isObject3(raw) ? decodePayment(raw.payment, expected) : null;
@@ -1223,11 +1257,12 @@ function createWixIapClient(deps) {
1223
1257
  }
1224
1258
  function startItemPayment(input) {
1225
1259
  const item = catalogItemOf(input.item);
1226
- if (!item) return Promise.resolve(failure("startItemPayment", "invalidArgument"));
1260
+ const country = input.storeCountryCode;
1261
+ if (!item || country !== void 0 && !isStoreCountryCode(country)) return Promise.resolve(failure("startItemPayment", "invalidArgument"));
1227
1262
  return runUnrepeatable({
1228
1263
  operation: "startItemPayment",
1229
1264
  codes: START_ITEM_PAYMENT_CODES,
1230
- request: (scope) => startItemPaymentCall(scope, item),
1265
+ request: (scope) => startItemPaymentCall(scope, item, country),
1231
1266
  decode: (raw, scope) => {
1232
1267
  const started = decodeStartedItem(raw, { ...expectationOf2(scope), catalogItemId: item.catalogItemId });
1233
1268
  return started && { status: "started", ...started };
@@ -1259,6 +1294,18 @@ function createWixIapClient(deps) {
1259
1294
  }
1260
1295
  });
1261
1296
  }
1297
+ function cancelPayment(input) {
1298
+ if (!isUUID(input.paymentId)) return Promise.resolve(failure("cancelPayment", "invalidArgument"));
1299
+ return run({
1300
+ operation: "cancelPayment",
1301
+ codes: CANCEL_PAYMENT_CODES,
1302
+ request: (scope) => cancelPaymentCall(scope, input.paymentId),
1303
+ decode: (raw, scope) => {
1304
+ const payment = decodePaymentAnswer(raw, { ...expectationOf2(scope), paymentId: input.paymentId });
1305
+ return payment && { status: "answered", payment };
1306
+ }
1307
+ });
1308
+ }
1262
1309
  async function run(spec) {
1263
1310
  return (await execute(spec)).result;
1264
1311
  }
@@ -1308,7 +1355,7 @@ function createWixIapClient(deps) {
1308
1355
  function isCurrent(session) {
1309
1356
  return deps.session.current().generation === session.generation;
1310
1357
  }
1311
- return { startPayment, startItemPayment, completePayment, getPayment };
1358
+ return { startPayment, startItemPayment, completePayment, getPayment, cancelPayment };
1312
1359
  }
1313
1360
  async function attempt(transport, call, spec, expectation) {
1314
1361
  try {
@@ -1372,8 +1419,18 @@ var START_ITEM_PAYMENT_CODES = [
1372
1419
  "ALREADY_OWNED",
1373
1420
  "ITEM_NOT_AVAILABLE",
1374
1421
  "SITE_NOT_ACCEPTING_PAYMENTS",
1375
- "UNSUPPORTED_ORDER"
1422
+ "UNSUPPORTED_ORDER",
1423
+ "CATALOG_NOT_SUPPORTED",
1424
+ "VERTICAL_ACCESS_DENIED",
1425
+ "EVENT_CHECKOUT_NOT_ECOM",
1426
+ "ALREADY_SUBSCRIBED",
1427
+ "SUBSCRIPTION_NOT_IN_APP",
1428
+ "BILLING_COUNTRY_REQUIRED",
1429
+ "APP_NOT_CONFIGURED",
1430
+ "NOT_BOOKING_OWNER",
1431
+ "BOOKING_PAYMENT_PENDING"
1376
1432
  ];
1433
+ var CANCEL_PAYMENT_CODES = ["NOT_PENDING", "APP_NOT_CONFIGURED", "NOT_FOUND"];
1377
1434
  var UNDECIDED = /* @__PURE__ */ new Set(["unavailable", "sessionChanged", "invalidResponse"]);
1378
1435
  var COMPLETE_PAYMENT_CODES = [
1379
1436
  "INVALID_PURCHASE",