@salla.sa/twilight-components 2.14.533 → 2.14.535

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 (350) hide show
  1. package/dist/cjs/{Helper-B2B-kxAI.js → Helper-6RI07gZo.js} +10 -0
  2. package/dist/cjs/{filepond-CTU0puJK.js → filepond-DMiqAXY6.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-poster-e2j_qdEq.js → filepond-plugin-file-poster-BVSRV0B1.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-size-CJ2bdUHS.js → filepond-plugin-file-validate-size-pCvjseUb.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-file-validate-type-BAPOnkKm.js → filepond-plugin-file-validate-type-D092neDg.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-edit-Qg5TvRQk.js → filepond-plugin-image-edit-XbqlePV3.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-exif-orientation-CDWu2nuZ.js → filepond-plugin-image-exif-orientation-BX82zMyc.js} +1 -1
  8. package/dist/cjs/{filepond-plugin-image-preview-D7tinAVs.js → filepond-plugin-image-preview-CD9tScCD.js} +1 -1
  9. package/dist/cjs/{functions-9UoEMgE8.js → functions-Df0Ggsup.js} +1 -1
  10. package/dist/cjs/{index-Bzkj4Mih.js → index-C5ZvHCin.js} +2 -2
  11. package/dist/cjs/{intlTelInput-B-ymxxq7.js → intlTelInput-CI7qauwd.js} +1 -1
  12. package/dist/cjs/loader.cjs.js +1 -1
  13. package/dist/cjs/salla-accordion-body_2.cjs.entry.js +1 -1
  14. package/dist/cjs/salla-accordion_6.cjs.entry.js +2 -2
  15. package/dist/cjs/salla-add-product-button_5.cjs.entry.js +605 -48
  16. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  17. package/dist/cjs/salla-alert_2.cjs.entry.js +1 -1
  18. package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
  19. package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
  20. package/dist/cjs/salla-badge.cjs.entry.js +1 -1
  21. package/dist/cjs/salla-basket-gap.cjs.entry.js +1 -1
  22. package/dist/cjs/salla-booking-field_7.cjs.entry.js +11 -11
  23. package/dist/cjs/salla-bullet-delivery_2.cjs.entry.js +1 -1
  24. package/dist/cjs/salla-cart-coupons.cjs.entry.js +1 -1
  25. package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +1 -1
  26. package/dist/cjs/salla-cart-summary-card.cjs.entry.js +1 -1
  27. package/dist/cjs/salla-cashback-banner.cjs.entry.js +1 -1
  28. package/dist/cjs/salla-comment-factors.cjs.entry.js +1 -1
  29. package/dist/cjs/salla-comment-form_8.cjs.entry.js +2 -2
  30. package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
  31. package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
  32. package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
  33. package/dist/cjs/salla-count-down_2.cjs.entry.js +1 -1
  34. package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
  35. package/dist/cjs/salla-delivery-promise.cjs.entry.js +1 -1
  36. package/dist/cjs/salla-edit-order-button.cjs.entry.js +1 -1
  37. package/dist/cjs/salla-filters-widget.cjs.entry.js +2 -2
  38. package/dist/cjs/salla-filters.cjs.entry.js +2 -2
  39. package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
  40. package/dist/cjs/salla-gifting.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-hook.cjs.entry.js +1 -1
  42. package/dist/cjs/salla-infinite-scroll.cjs.entry.js +2 -2
  43. package/dist/cjs/salla-installment.cjs.entry.js +1 -1
  44. package/dist/cjs/salla-list-tile.cjs.entry.js +1 -1
  45. package/dist/cjs/salla-localization-modal.cjs.entry.js +1 -1
  46. package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
  47. package/dist/cjs/salla-loyalty-banner.cjs.entry.js +2 -2
  48. package/dist/cjs/salla-loyalty-exchange-product-card_5.cjs.entry.js +3 -3
  49. package/dist/cjs/salla-loyalty-hero_2.cjs.entry.js +2 -2
  50. package/dist/cjs/salla-loyalty-panel.cjs.entry.js +3 -3
  51. package/dist/cjs/salla-loyalty-points-banner.cjs.entry.js +1 -1
  52. package/dist/cjs/salla-loyalty-points-history.cjs.entry.js +1 -1
  53. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
  54. package/dist/cjs/salla-loyalty-program.cjs.entry.js +3 -3
  55. package/dist/cjs/salla-loyalty-reward.cjs.entry.js +2 -2
  56. package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
  57. package/dist/cjs/salla-maintenance-alert.cjs.entry.js +1 -1
  58. package/dist/cjs/salla-map_2.cjs.entry.js +1 -1
  59. package/dist/cjs/salla-menu.cjs.entry.js +1 -1
  60. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  61. package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +1 -1
  62. package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +1 -1
  63. package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +1 -1
  64. package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
  65. package/dist/cjs/salla-notification-item.cjs.entry.js +1 -1
  66. package/dist/cjs/salla-notifications.cjs.entry.js +2 -2
  67. package/dist/cjs/salla-offer-modal.cjs.entry.js +1 -1
  68. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  69. package/dist/cjs/salla-order-branch.cjs.entry.js +1 -1
  70. package/dist/cjs/salla-order-cancel.cjs.entry.js +1 -1
  71. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  72. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  73. package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
  74. package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
  75. package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +1 -1
  76. package/dist/cjs/salla-order-edit.cjs.entry.js +1 -1
  77. package/dist/cjs/salla-order-shipments.cjs.entry.js +1 -1
  78. package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
  79. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  80. package/dist/cjs/salla-orders.cjs.entry.js +2 -2
  81. package/dist/cjs/salla-payments.cjs.entry.js +1 -1
  82. package/dist/cjs/salla-placeholder.cjs.entry.js +1 -1
  83. package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
  84. package/dist/cjs/salla-product-card-embed.cjs.entry.js +1 -1
  85. package/dist/cjs/salla-product-card_2.cjs.entry.js +3 -2
  86. package/dist/cjs/salla-product-size-guide.cjs.entry.js +1 -1
  87. package/dist/cjs/salla-products-list.cjs.entry.js +8 -2
  88. package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
  89. package/dist/cjs/salla-rating-modal-v2.cjs.entry.js +2 -2
  90. package/dist/cjs/salla-rating-modal.cjs.entry.js +2 -2
  91. package/dist/cjs/salla-review-factors-tags.cjs.entry.js +1 -1
  92. package/dist/cjs/salla-scopes.cjs.entry.js +1 -1
  93. package/dist/cjs/salla-search.cjs.entry.js +2 -2
  94. package/dist/cjs/salla-skeleton.cjs.entry.js +1 -1
  95. package/dist/cjs/salla-slider.cjs.entry.js +1 -1
  96. package/dist/cjs/salla-social-share.cjs.entry.js +1 -1
  97. package/dist/cjs/salla-social.cjs.entry.js +1 -1
  98. package/dist/cjs/salla-tab-content_3.cjs.entry.js +1 -1
  99. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  100. package/dist/cjs/salla-tooltip.cjs.entry.js +1 -1
  101. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  102. package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
  103. package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
  104. package/dist/cjs/salla-user-settings.cjs.entry.js +1 -1
  105. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  106. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  107. package/dist/cjs/salla-wishlist-actions.cjs.entry.js +1 -1
  108. package/dist/cjs/{tracked-promise-B0bluwtb.js → tracked-promise-6lFHNFpe.js} +1 -1
  109. package/dist/cjs/twilight.cjs.js +1 -1
  110. package/dist/cjs/{vanilla-picker-b_58j2ys.js → vanilla-picker-DzOJP2_X.js} +1 -1
  111. package/dist/collection/Helpers/Helper.js +10 -0
  112. package/dist/collection/components/salla-add-product-button/salla-add-product-button.js +7 -4
  113. package/dist/collection/components/salla-products-list/salla-products-list.js +6 -0
  114. package/dist/collection/components/salla-products-slider/salla-products-slider.js +1 -0
  115. package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +18 -36
  116. package/dist/components/Helper.js +10 -0
  117. package/dist/components/index.js +2 -2
  118. package/dist/components/salla-add-product-button2.js +7 -5
  119. package/dist/components/salla-products-list2.js +6 -0
  120. package/dist/components/salla-products-slider2.js +1 -0
  121. package/dist/components/salla-quick-buy2.js +597 -42
  122. package/dist/esm/{Helper-BQ9mvrt9.js → Helper-CBmYxrzX.js} +10 -0
  123. package/dist/esm/{filepond-cbwmiCMW.js → filepond-C4OniETR.js} +1 -1
  124. package/dist/esm/{filepond-plugin-file-poster-CnPkPMW8.js → filepond-plugin-file-poster-DoLmPZN0.js} +1 -1
  125. package/dist/esm/{filepond-plugin-file-validate-size-DvbfP3XU.js → filepond-plugin-file-validate-size-GSTJAVro.js} +1 -1
  126. package/dist/esm/{filepond-plugin-file-validate-type-BmKx6JGC.js → filepond-plugin-file-validate-type-BgosaXBw.js} +1 -1
  127. package/dist/esm/{filepond-plugin-image-edit-Bs6ewOpy.js → filepond-plugin-image-edit-CKH9ms-8.js} +1 -1
  128. package/dist/esm/{filepond-plugin-image-exif-orientation-BHCRYCoF.js → filepond-plugin-image-exif-orientation-Dm1m6o6h.js} +1 -1
  129. package/dist/esm/{filepond-plugin-image-preview-BcBXsocw.js → filepond-plugin-image-preview-Clw-ajQg.js} +1 -1
  130. package/dist/esm/{functions-BDNgBQjQ.js → functions-_bjecsq1.js} +1 -1
  131. package/dist/esm/{index-_4UMswuA.js → index-DBZ1mmdE.js} +2 -2
  132. package/dist/esm/{intlTelInput-BqsfLR9B.js → intlTelInput-C8TBhLMB.js} +1 -1
  133. package/dist/esm/loader.js +2 -2
  134. package/dist/esm/salla-accordion-body_2.entry.js +1 -1
  135. package/dist/esm/salla-accordion_6.entry.js +2 -2
  136. package/dist/esm/salla-add-product-button_5.entry.js +605 -48
  137. package/dist/esm/salla-advertisement.entry.js +1 -1
  138. package/dist/esm/salla-alert_2.entry.js +1 -1
  139. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  140. package/dist/esm/salla-apps-icons.entry.js +1 -1
  141. package/dist/esm/salla-badge.entry.js +1 -1
  142. package/dist/esm/salla-basket-gap.entry.js +1 -1
  143. package/dist/esm/salla-booking-field_7.entry.js +11 -11
  144. package/dist/esm/salla-bullet-delivery_2.entry.js +1 -1
  145. package/dist/esm/salla-cart-coupons.entry.js +1 -1
  146. package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
  147. package/dist/esm/salla-cart-summary-card.entry.js +1 -1
  148. package/dist/esm/salla-cashback-banner.entry.js +1 -1
  149. package/dist/esm/salla-comment-factors.entry.js +1 -1
  150. package/dist/esm/salla-comment-form_8.entry.js +2 -2
  151. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  152. package/dist/esm/salla-contacts.entry.js +1 -1
  153. package/dist/esm/salla-cookies-bar.entry.js +1 -1
  154. package/dist/esm/salla-count-down_2.entry.js +1 -1
  155. package/dist/esm/salla-custom-fields.entry.js +1 -1
  156. package/dist/esm/salla-delivery-promise.entry.js +1 -1
  157. package/dist/esm/salla-edit-order-button.entry.js +1 -1
  158. package/dist/esm/salla-filters-widget.entry.js +2 -2
  159. package/dist/esm/salla-filters.entry.js +2 -2
  160. package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
  161. package/dist/esm/salla-gifting.entry.js +1 -1
  162. package/dist/esm/salla-hook.entry.js +1 -1
  163. package/dist/esm/salla-infinite-scroll.entry.js +2 -2
  164. package/dist/esm/salla-installment.entry.js +1 -1
  165. package/dist/esm/salla-list-tile.entry.js +1 -1
  166. package/dist/esm/salla-localization-modal.entry.js +1 -1
  167. package/dist/esm/salla-login-modal.entry.js +1 -1
  168. package/dist/esm/salla-loyalty-banner.entry.js +2 -2
  169. package/dist/esm/salla-loyalty-exchange-product-card_5.entry.js +3 -3
  170. package/dist/esm/salla-loyalty-hero_2.entry.js +2 -2
  171. package/dist/esm/salla-loyalty-panel.entry.js +3 -3
  172. package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
  173. package/dist/esm/salla-loyalty-points-history.entry.js +1 -1
  174. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  175. package/dist/esm/salla-loyalty-program.entry.js +3 -3
  176. package/dist/esm/salla-loyalty-reward.entry.js +2 -2
  177. package/dist/esm/salla-loyalty.entry.js +1 -1
  178. package/dist/esm/salla-maintenance-alert.entry.js +1 -1
  179. package/dist/esm/salla-map_2.entry.js +1 -1
  180. package/dist/esm/salla-menu.entry.js +1 -1
  181. package/dist/esm/salla-metadata.entry.js +1 -1
  182. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +1 -1
  183. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +1 -1
  184. package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
  185. package/dist/esm/salla-next-order-coupon.entry.js +1 -1
  186. package/dist/esm/salla-notification-item.entry.js +1 -1
  187. package/dist/esm/salla-notifications.entry.js +2 -2
  188. package/dist/esm/salla-offer-modal.entry.js +1 -1
  189. package/dist/esm/salla-offer.entry.js +1 -1
  190. package/dist/esm/salla-order-branch.entry.js +1 -1
  191. package/dist/esm/salla-order-cancel.entry.js +1 -1
  192. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  193. package/dist/esm/salla-order-details-options.entry.js +1 -1
  194. package/dist/esm/salla-order-details.entry.js +1 -1
  195. package/dist/esm/salla-order-edit-item.entry.js +1 -1
  196. package/dist/esm/salla-order-edit-product-card.entry.js +1 -1
  197. package/dist/esm/salla-order-edit.entry.js +1 -1
  198. package/dist/esm/salla-order-shipments.entry.js +1 -1
  199. package/dist/esm/salla-order-summary.entry.js +1 -1
  200. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  201. package/dist/esm/salla-orders.entry.js +2 -2
  202. package/dist/esm/salla-payments.entry.js +1 -1
  203. package/dist/esm/salla-placeholder.entry.js +1 -1
  204. package/dist/esm/salla-price-range.entry.js +1 -1
  205. package/dist/esm/salla-product-card-embed.entry.js +1 -1
  206. package/dist/esm/salla-product-card_2.entry.js +3 -2
  207. package/dist/esm/salla-product-size-guide.entry.js +1 -1
  208. package/dist/esm/salla-products-list.entry.js +8 -2
  209. package/dist/esm/salla-quick-order.entry.js +1 -1
  210. package/dist/esm/salla-rating-modal-v2.entry.js +2 -2
  211. package/dist/esm/salla-rating-modal.entry.js +2 -2
  212. package/dist/esm/salla-review-factors-tags.entry.js +1 -1
  213. package/dist/esm/salla-scopes.entry.js +1 -1
  214. package/dist/esm/salla-search.entry.js +2 -2
  215. package/dist/esm/salla-skeleton.entry.js +1 -1
  216. package/dist/esm/salla-slider.entry.js +1 -1
  217. package/dist/esm/salla-social-share.entry.js +1 -1
  218. package/dist/esm/salla-social.entry.js +1 -1
  219. package/dist/esm/salla-tab-content_3.entry.js +1 -1
  220. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  221. package/dist/esm/salla-tooltip.entry.js +1 -1
  222. package/dist/esm/salla-trust-badges.entry.js +1 -1
  223. package/dist/esm/salla-user-menu.entry.js +1 -1
  224. package/dist/esm/salla-user-profile.entry.js +1 -1
  225. package/dist/esm/salla-user-settings.entry.js +1 -1
  226. package/dist/esm/salla-verify.entry.js +1 -1
  227. package/dist/esm/salla-wallet.entry.js +1 -1
  228. package/dist/esm/salla-wishlist-actions.entry.js +1 -1
  229. package/dist/esm/{tracked-promise-t43zESfb.js → tracked-promise-Ds3IkuGS.js} +1 -1
  230. package/dist/esm/twilight.js +2 -2
  231. package/dist/esm/{vanilla-picker-Cqv-m1pV.js → vanilla-picker-7f106Jxq.js} +1 -1
  232. package/dist/twilight/p-024b399a.entry.js +4 -0
  233. package/dist/twilight/{p-3b536684.entry.js → p-0339162a.entry.js} +1 -1
  234. package/dist/twilight/{p-d3f13515.entry.js → p-0351e1e0.entry.js} +1 -1
  235. package/dist/twilight/{p-61cba9b5.entry.js → p-047ae479.entry.js} +1 -1
  236. package/dist/twilight/{p-853bcd69.entry.js → p-0560c569.entry.js} +1 -1
  237. package/dist/twilight/{p-8db35b36.entry.js → p-05d79cef.entry.js} +1 -1
  238. package/dist/twilight/{p-0652db81.entry.js → p-06a3fd91.entry.js} +1 -1
  239. package/dist/twilight/{p-a5907a8a.entry.js → p-072da339.entry.js} +1 -1
  240. package/dist/twilight/{p-fcdac58f.entry.js → p-0fb71700.entry.js} +1 -1
  241. package/dist/twilight/{p-9645a657.entry.js → p-10270922.entry.js} +1 -1
  242. package/dist/twilight/{p-518fd323.entry.js → p-139940cd.entry.js} +1 -1
  243. package/dist/twilight/{p-877ef36d.entry.js → p-15adae5b.entry.js} +1 -1
  244. package/dist/twilight/{p-431ddda2.entry.js → p-1acccf4f.entry.js} +1 -1
  245. package/dist/twilight/{p-230dbdb0.entry.js → p-1d3377c7.entry.js} +1 -1
  246. package/dist/twilight/{p-2a5ed2b8.entry.js → p-1e09ccf2.entry.js} +1 -1
  247. package/dist/twilight/{p-a89c3af1.entry.js → p-227f91cf.entry.js} +1 -1
  248. package/dist/twilight/{p-98e4b302.entry.js → p-31abf85b.entry.js} +1 -1
  249. package/dist/twilight/{p-a9d7afd4.entry.js → p-335130d7.entry.js} +1 -1
  250. package/dist/twilight/{p-e242ca31.entry.js → p-35c8e1fa.entry.js} +1 -1
  251. package/dist/twilight/{p-f020c70a.entry.js → p-37b6d115.entry.js} +1 -1
  252. package/dist/twilight/{p-3c5dabea.entry.js → p-3c19023a.entry.js} +1 -1
  253. package/dist/twilight/{p-ebab9397.entry.js → p-42abcb14.entry.js} +1 -1
  254. package/dist/twilight/p-433a09b4.entry.js +4 -0
  255. package/dist/twilight/{p-414b8e8b.entry.js → p-45931d37.entry.js} +1 -1
  256. package/dist/twilight/p-45b4ecd7.entry.js +4 -0
  257. package/dist/twilight/{p-83ec7e8a.entry.js → p-45cf57f0.entry.js} +1 -1
  258. package/dist/twilight/{p-a7353a2c.entry.js → p-47ab940f.entry.js} +1 -1
  259. package/dist/twilight/{p-fbcb213b.entry.js → p-493ed5ac.entry.js} +1 -1
  260. package/dist/twilight/{p-7480f7ea.entry.js → p-4bbee9fd.entry.js} +1 -1
  261. package/dist/twilight/{p-6a7f0db4.entry.js → p-4c4249a8.entry.js} +1 -1
  262. package/dist/twilight/{p-9817c793.entry.js → p-4fc6b87e.entry.js} +1 -1
  263. package/dist/twilight/{p-380c1d1f.entry.js → p-50233de9.entry.js} +1 -1
  264. package/dist/twilight/{p-CrgJZliu.js → p-510IBmXt.js} +1 -1
  265. package/dist/twilight/{p-4cac0554.entry.js → p-551fdbe4.entry.js} +1 -1
  266. package/dist/twilight/{p-8a26d45f.entry.js → p-58c14e13.entry.js} +1 -1
  267. package/dist/twilight/{p-b92c5be6.entry.js → p-5e19c7cb.entry.js} +1 -1
  268. package/dist/twilight/{p-5aa2673e.entry.js → p-6371cddf.entry.js} +1 -1
  269. package/dist/twilight/{p-0eb8b68f.entry.js → p-63746eed.entry.js} +1 -1
  270. package/dist/twilight/{p-a30a0d74.entry.js → p-6445f756.entry.js} +1 -1
  271. package/dist/twilight/p-67ae044e.entry.js +4 -0
  272. package/dist/twilight/{p-0bb747c4.entry.js → p-6c4f0341.entry.js} +1 -1
  273. package/dist/twilight/{p-041337bf.entry.js → p-6f667196.entry.js} +1 -1
  274. package/dist/twilight/{p-2fca58b7.entry.js → p-6f82c607.entry.js} +1 -1
  275. package/dist/twilight/{p-dcf83d8d.entry.js → p-6f843c0a.entry.js} +1 -1
  276. package/dist/twilight/{p-cc4694eb.entry.js → p-71d477ae.entry.js} +1 -1
  277. package/dist/twilight/p-73a0207a.entry.js +4 -0
  278. package/dist/twilight/{p-e4c11c19.entry.js → p-77013986.entry.js} +1 -1
  279. package/dist/twilight/{p-73865fc4.entry.js → p-782feccb.entry.js} +1 -1
  280. package/dist/twilight/{p-646a753d.entry.js → p-7f33ee37.entry.js} +1 -1
  281. package/dist/twilight/{p-a2579e15.entry.js → p-8030cbc2.entry.js} +1 -1
  282. package/dist/twilight/{p-cfec1c83.entry.js → p-821b09ef.entry.js} +1 -1
  283. package/dist/twilight/{p-7f2d5291.entry.js → p-83c8591a.entry.js} +1 -1
  284. package/dist/twilight/{p-aad1a140.entry.js → p-85920b90.entry.js} +1 -1
  285. package/dist/twilight/{p-9bdabb1a.entry.js → p-87d19251.entry.js} +1 -1
  286. package/dist/twilight/{p-eac49193.entry.js → p-886c7171.entry.js} +1 -1
  287. package/dist/twilight/{p-3d81a00f.entry.js → p-8be52c77.entry.js} +1 -1
  288. package/dist/twilight/{p-45db790d.entry.js → p-914696e3.entry.js} +1 -1
  289. package/dist/twilight/{p-731c71ae.entry.js → p-9190b2d9.entry.js} +1 -1
  290. package/dist/twilight/{p-56daec16.entry.js → p-9553d9df.entry.js} +1 -1
  291. package/dist/twilight/{p-c1fb3330.entry.js → p-9abb2fe1.entry.js} +1 -1
  292. package/dist/twilight/p-BLPhrBVT.js +9 -0
  293. package/dist/twilight/{p-NVUJ-yak.js → p-CCQS3wWC.js} +1 -1
  294. package/dist/twilight/{p-1DFQh6fF.js → p-CIQ6L-lP.js} +1 -1
  295. package/dist/twilight/{p-fBq3tL2U.js → p-CM1WZMCK.js} +1 -1
  296. package/dist/twilight/{p-DTy2I02l.js → p-CuQ7RhgX.js} +1 -1
  297. package/dist/twilight/{p-_4UMswuA.js → p-DBZ1mmdE.js} +1 -1
  298. package/dist/twilight/p-DOBDDG4K.js +4 -0
  299. package/dist/twilight/{p-6QnQGXyw.js → p-DvWr5QCU.js} +2 -2
  300. package/dist/twilight/{p-BbGG982X.js → p-WIBA-EsX.js} +1 -1
  301. package/dist/twilight/{p-0103aab1.entry.js → p-a20587d9.entry.js} +1 -1
  302. package/dist/twilight/{p-ed84e84a.entry.js → p-a4f499b4.entry.js} +1 -1
  303. package/dist/twilight/{p-64b3ec8e.entry.js → p-a7bfcc4f.entry.js} +1 -1
  304. package/dist/twilight/{p-7a6c2a19.entry.js → p-aacb850d.entry.js} +1 -1
  305. package/dist/twilight/{p-533b4ad3.entry.js → p-b03ba2e5.entry.js} +1 -1
  306. package/dist/twilight/{p-a5313de1.entry.js → p-b5396661.entry.js} +1 -1
  307. package/dist/twilight/{p-46610835.entry.js → p-ba6f546f.entry.js} +1 -1
  308. package/dist/twilight/{p-34a836bc.entry.js → p-bb0f2f84.entry.js} +1 -1
  309. package/dist/twilight/{p-8dd69b86.entry.js → p-bb5dc688.entry.js} +1 -1
  310. package/dist/twilight/{p-fe21d16a.entry.js → p-bcda4b49.entry.js} +1 -1
  311. package/dist/twilight/{p-0b18a6dd.entry.js → p-be80e8ef.entry.js} +1 -1
  312. package/dist/twilight/{p-012ab001.entry.js → p-bea87502.entry.js} +1 -1
  313. package/dist/twilight/{p-60e976c3.entry.js → p-bf75e341.entry.js} +1 -1
  314. package/dist/twilight/{p-1cf132f6.entry.js → p-c552412f.entry.js} +1 -1
  315. package/dist/twilight/{p-5dd628bf.entry.js → p-c78b079c.entry.js} +1 -1
  316. package/dist/twilight/{p-5e4c6345.entry.js → p-c92a44f2.entry.js} +1 -1
  317. package/dist/twilight/{p-8bdca313.entry.js → p-cc6013ec.entry.js} +1 -1
  318. package/dist/twilight/{p-8ecfb854.entry.js → p-cc896aa3.entry.js} +1 -1
  319. package/dist/twilight/{p-4c645ee5.entry.js → p-da20420b.entry.js} +1 -1
  320. package/dist/twilight/{p-8522445b.entry.js → p-db02654a.entry.js} +1 -1
  321. package/dist/twilight/{p-da371fb5.entry.js → p-db4d8f03.entry.js} +1 -1
  322. package/dist/twilight/{p-3b3d778b.entry.js → p-def672b6.entry.js} +1 -1
  323. package/dist/twilight/{p-0a76c201.entry.js → p-df56e678.entry.js} +1 -1
  324. package/dist/twilight/{p-ef02ff89.entry.js → p-e24649dd.entry.js} +1 -1
  325. package/dist/twilight/{p-8be62ddd.entry.js → p-e2ff9857.entry.js} +1 -1
  326. package/dist/twilight/{p-146bb40b.entry.js → p-e8c48ba0.entry.js} +1 -1
  327. package/dist/twilight/{p-452ccc3e.entry.js → p-e99e59be.entry.js} +1 -1
  328. package/dist/twilight/{p-941c3ffa.entry.js → p-ebc967f4.entry.js} +1 -1
  329. package/dist/twilight/{p-e47a4b60.entry.js → p-f167ec3e.entry.js} +1 -1
  330. package/dist/twilight/{p-b60c13a0.entry.js → p-f3846a26.entry.js} +1 -1
  331. package/dist/twilight/{p-fb52bc60.entry.js → p-f63c9b65.entry.js} +1 -1
  332. package/dist/twilight/{p-4c6e6aa9.entry.js → p-f8b4e119.entry.js} +1 -1
  333. package/dist/twilight/{p-527caf04.entry.js → p-fa54137b.entry.js} +1 -1
  334. package/dist/twilight/{p-85650252.entry.js → p-fa85edfd.entry.js} +1 -1
  335. package/dist/twilight/{p-ee6eae74.entry.js → p-fd58290a.entry.js} +1 -1
  336. package/dist/twilight/{p-11a92952.entry.js → p-ffc24d3a.entry.js} +1 -1
  337. package/dist/twilight/{p-Cukniya-.js → p-jMJhY6yy.js} +1 -1
  338. package/dist/twilight/{p-BYBXGGPY.js → p-uowEa6Zu.js} +1 -1
  339. package/dist/twilight/{p-mFNP-Qco.js → p-wNiB1gdh.js} +1 -1
  340. package/dist/twilight/twilight.esm.js +1 -1
  341. package/dist/types/Helpers/Helper.d.ts +1 -0
  342. package/dist/types/components/salla-quick-buy/salla-quick-buy.d.ts +0 -4
  343. package/package.json +5 -5
  344. package/dist/twilight/p-30a9ce5f.entry.js +0 -4
  345. package/dist/twilight/p-336bec27.entry.js +0 -4
  346. package/dist/twilight/p-BeurE6_H.js +0 -9
  347. package/dist/twilight/p-XnA1YTjA.js +0 -4
  348. package/dist/twilight/p-b80d0e39.entry.js +0 -4
  349. package/dist/twilight/p-c1dd71f0.entry.js +0 -4
  350. package/dist/twilight/p-f7ab48c1.entry.js +0 -4
@@ -16,9 +16,135 @@ import { d as defineCustomElement$3 } from './salla-order-options-modal2.js';
16
16
  import { d as defineCustomElement$2 } from './salla-product-options2.js';
17
17
  import { d as defineCustomElement$1 } from './salla-progress-bar2.js';
18
18
 
19
- // display currency (these requests use the global axios, not salla's instance). Legacy-BE stores
20
- // (isLegacyBuyNowBE) keep the old behavior no override. Set once on the axios defaults so
21
- // every method inherits it without overriding the rest of the headers.
19
+ /**
20
+ * Shared Apple Pay support helpers: SDK loading, capability detection, merchant
21
+ * identifier resolution, and Payment Request method-data construction.
22
+ *
23
+ * Lives in @salla.sa/applepay (not a theme) because it is Apple Pay domain
24
+ * logic and is consumed by every Apple Pay entry point — the storefront
25
+ * components (salla-quick-buy, salla-add-product-button) and the shared
26
+ * SallaApplePay session in ./index.js.
27
+ *
28
+ * Apple Pay runs through two flows:
29
+ * - Native (Safari / Apple devices) → window.ApplePaySession
30
+ * - Payment Request API (other browsers) → Apple's "Scan Code with iPhone"
31
+ * QR sheet, which requires Apple's JS SDK to be *loaded and registered*
32
+ * before PaymentRequest.canMakePayment() reports the method as available.
33
+ */
34
+
35
+ const APPLE_PAY_METHOD$1 = 'https://apple.com/apple-pay';
36
+ const APPLE_PAY_SDK_ID = 'apple-pay-sdk';
37
+ const APPLE_PAY_SDK_SRC = 'https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js';
38
+
39
+ let sdkPromise = null;
40
+
41
+ /**
42
+ * Salla-native Apple merchant identifier, sourced from store settings. Returns
43
+ * null when the store has no Apple Pay merchant configured — callers treat that
44
+ * absence as the guard and skip Apple Pay entirely (no hardcoded fallback).
45
+ * @returns {string|null}
46
+ */
47
+ function applePayMerchantId() {
48
+ return salla?.config?.get?.('store.settings.buy_now.merchant_identifier') || null;
49
+ }
50
+
51
+ /**
52
+ * Build the W3C Payment Request `methodData` for the Apple Pay method. Callers
53
+ * supply the values (the probe reads them from config; the live session reads
54
+ * them from the transaction detail), this owns the constant scaffold so the two
55
+ * can't drift apart.
56
+ * @param {{ version: number, merchantIdentifier: string, supportedNetworks: string[], countryCode: string }} opts
57
+ * @returns {PaymentMethodData[]}
58
+ */
59
+ function buildApplePayMethodData({ version, merchantIdentifier, supportedNetworks, countryCode }) {
60
+ return [{
61
+ supportedMethods: APPLE_PAY_METHOD$1,
62
+ data: {
63
+ version,
64
+ merchantIdentifier,
65
+ merchantCapabilities: ['supports3DS'],
66
+ supportedNetworks,
67
+ countryCode,
68
+ },
69
+ }];
70
+ }
71
+
72
+ /**
73
+ * Inject Apple's Pay JS SDK (`1.latest` ships the cross-browser / QR support)
74
+ * and resolve once it has loaded. Idempotent: a second call reuses the same
75
+ * in-flight promise and never appends a second <script>. Resolves (rather than
76
+ * rejects) on load error so a failed CDN fetch simply falls back to "no QR".
77
+ * @returns {Promise<void>}
78
+ */
79
+ function ensureApplePaySdk() {
80
+ if (typeof document === 'undefined') return Promise.resolve();
81
+
82
+ if (sdkPromise) return sdkPromise;
83
+
84
+ const existing = document.getElementById(APPLE_PAY_SDK_ID);
85
+ if (existing) {
86
+ // Script already in the DOM (e.g. added before this refactor). We can't know
87
+ // if it finished loading, so resolve immediately — the native/PaymentRequest
88
+ // probe will just report unavailable until the browser registers the method.
89
+ sdkPromise = Promise.resolve();
90
+ return sdkPromise;
91
+ }
92
+
93
+ sdkPromise = new Promise((resolve) => {
94
+ const script = document.createElement('script');
95
+ script.src = APPLE_PAY_SDK_SRC;
96
+ script.setAttribute('id', APPLE_PAY_SDK_ID);
97
+ script.async = true;
98
+ script.onload = () => resolve();
99
+ script.onerror = () => resolve();
100
+ document.body.appendChild(script);
101
+ });
102
+
103
+ return sdkPromise;
104
+ }
105
+
106
+ /**
107
+ * Whether Apple Pay can be completed in the current browser: natively
108
+ * (Safari / Apple devices) or via the Payment Request API (non-Safari browsers
109
+ * / non-Apple devices → QR-code fallback).
110
+ *
111
+ * For the QR path this awaits the SDK before probing, so callers get a stable
112
+ * answer on first load instead of racing the async script fetch.
113
+ * @param {string} [currency]
114
+ * @returns {Promise<boolean>}
115
+ */
116
+ async function canCompleteApplePay(currency = 'SAR') {
117
+ try {
118
+ if (window.ApplePaySession?.canMakePayments?.()) return true;
119
+ } catch (e) { /* not supported natively */ }
120
+
121
+ if (typeof window === 'undefined' || !window.PaymentRequest) return false;
122
+
123
+ // QR path only: it can't validate the merchant without a merchant identifier,
124
+ // so treat a missing config key as the guard. Native (above) is unaffected —
125
+ // it never uses the client-side merchant id.
126
+ if (!applePayMerchantId()) return false;
127
+
128
+ await ensureApplePaySdk();
129
+
130
+ try {
131
+ const request = new PaymentRequest(
132
+ buildApplePayMethodData({
133
+ version: 3,
134
+ merchantIdentifier: applePayMerchantId(),
135
+ supportedNetworks: salla?.config?.get?.('store.settings.buy_now.supportedNetworks')
136
+ || salla?.config?.get?.('store.settings.buy_now.networks')
137
+ || ['masterCard', 'visa'],
138
+ countryCode: salla?.config?.get?.('store.store_country') || 'SA',
139
+ }),
140
+ { total: { label: 'Salla', amount: { currency: currency || 'SAR', value: '0.00' } } },
141
+ );
142
+ return await request.canMakePayment();
143
+ } catch (e) {
144
+ return false;
145
+ }
146
+ }
147
+
22
148
  function setBaseCurrencyHeader() {
23
149
  axios.defaults.headers.common.currency = salla?.config?.get?.('user.currency_code');
24
150
  }
@@ -404,6 +530,14 @@ if (typeof window !== 'undefined') {
404
530
  window.Salla.Payments = window.Salla.Payments || {};
405
531
  }
406
532
 
533
+ // Apple Pay method identifier for the W3C Payment Request API.
534
+ const APPLE_PAY_METHOD = 'https://apple.com/apple-pay';
535
+
536
+ // Captured at module load, before the Apple Pay SDK is injected: real Safari /
537
+ // Apple devices expose `ApplePaySession` natively, whereas non-Safari browsers
538
+ // only get it once the SDK loads. Keeps native-vs-PaymentRequest routing stable.
539
+ const HAS_NATIVE_APPLE_PAY = typeof window !== 'undefined' && !!window.ApplePaySession;
540
+
407
541
  /**
408
542
  * Full Example
409
543
  *
@@ -447,6 +581,11 @@ const SallaApplePay = typeof window !== 'undefined' ? {
447
581
  countryCode: null,
448
582
  totals: [],
449
583
  shippingCompany: null,
584
+ // Set true once onCancel has fired for the current transaction, so the
585
+ // QR (PaymentRequest) dismissal catch can notify on a plain sheet-close
586
+ // without double-firing when a prior handler (e.g. merchant validation)
587
+ // already routed through onCancel. Reset at the start of each transaction.
588
+ canceled: false,
450
589
  init: function () {
451
590
  document.removeEventListener('payments::apple-pay.start-transaction', SallaApplePay.startSession);
452
591
  Salla.event.addEventListener('payments::apple-pay.start-transaction', SallaApplePay.startSession);
@@ -509,14 +648,52 @@ const SallaApplePay = typeof window !== 'undefined' ? {
509
648
  return SallaApplePay.detail?.requiredShippingContactFields?.includes('postalAddress');
510
649
  },
511
650
 
651
+ /**
652
+ * Whether the native Apple Pay flow (Safari / Apple devices) can run. Gated
653
+ * on the module-load capture so the SDK loading later can't flip a
654
+ * non-Safari browser into the native path.
655
+ */
656
+ canUseNative: function () {
657
+ if (!HAS_NATIVE_APPLE_PAY) {
658
+ return false;
659
+ }
660
+ try {
661
+ return ApplePaySession.canMakePayments();
662
+ } catch (e) {
663
+ return false;
664
+ }
665
+ },
666
+
667
+ // Sourced from config (via the transaction detail). No fallback: a missing
668
+ // identifier means Apple Pay isn't configured for this store, and callers
669
+ // treat that null as the guard to skip Apple Pay.
670
+ getMerchantIdentifier: function () {
671
+ return (SallaApplePay.detail && SallaApplePay.detail.merchantIdentifier) || null;
672
+ },
673
+
512
674
  startSession: async function (event) {
513
675
 
514
676
  SallaApplePay.detail = event.detail || event;
515
677
 
678
+ // Fresh transaction → clear any cancel flag from a previous attempt.
679
+ SallaApplePay.canceled = false;
680
+
516
681
  salla.log('🍏 Pay: payments::apple-pay.start-transaction', SallaApplePay.detail);
517
682
 
518
683
  SallaApplePay.initDefault();
519
684
 
685
+ // Native (Safari / Apple devices) → classic ApplePaySession. Otherwise
686
+ // (non-Safari / non-Apple device) → Payment Request API, which renders
687
+ // Apple's "Scan Code with iPhone" QR sheet.
688
+ if (!SallaApplePay.canUseNative()) {
689
+ return SallaApplePay.startPaymentRequestSession(event);
690
+ }
691
+
692
+ return SallaApplePay.startNativeSession(event);
693
+ },
694
+
695
+ startNativeSession: async function (event) {
696
+
520
697
  let version = SallaApplePay.getApplePaySessionVersion();
521
698
  // Normalize to an array: the backend can serialize the networks list as a JSON object
522
699
  // (non-sequential PHP array keys). Copy it so we never mutate the shared `detail` reference.
@@ -650,6 +827,7 @@ const SallaApplePay = typeof window !== 'undefined' ? {
650
827
  },
651
828
 
652
829
  onCancel: (event = {}, message = null) => {
830
+ SallaApplePay.canceled = true;
653
831
  SallaApplePay.detail.onError(message || salla.lang.get('pages.checkout.payment_failed'));
654
832
  Salla.event.createAndDispatch('payments::apple-pay.canceled', event);
655
833
  },
@@ -866,6 +1044,400 @@ const SallaApplePay = typeof window !== 'undefined' ? {
866
1044
  }
867
1045
  },
868
1046
 
1047
+ /* -------------------------------------------------------------------------
1048
+ * Payment Request API flow (non-Safari browsers / non-Apple devices).
1049
+ * Apple renders the "Scan Code with iPhone" QR sheet. Reuses the same
1050
+ * backend endpoints (validate / address / shipping / recalculate / submit)
1051
+ * as the native flow; only the sheet-completion model differs
1052
+ * (event.updateWith / response.complete instead of session.completeXxx).
1053
+ * ---------------------------------------------------------------------- */
1054
+
1055
+ paymentRequest: null,
1056
+ paymentResponse: null,
1057
+
1058
+ getCurrency: () => SallaApplePay.detail.currency || 'SAR',
1059
+
1060
+ prAmount: (value) => ({ currency: SallaApplePay.getCurrency(), value: String(value) }),
1061
+
1062
+ prTotal: () => {
1063
+ const total = SallaApplePay.prepareTotal();
1064
+ return { label: total.label, amount: SallaApplePay.prAmount(total.amount) };
1065
+ },
1066
+
1067
+ prDisplayItems: () => SallaApplePay.prepareLineItems().map(item => ({
1068
+ label: item.label,
1069
+ amount: SallaApplePay.prAmount(item.amount),
1070
+ })),
1071
+
1072
+ prShippingOptions: (selectedId = null) => {
1073
+ const options = SallaApplePay.mappingShippingMethods(SallaApplePay.shipping_methods || []);
1074
+ return options.map((option, index) => ({
1075
+ id: option.identifier,
1076
+ label: option.label,
1077
+ amount: SallaApplePay.prAmount(option.amount),
1078
+ selected: selectedId ? option.identifier === selectedId : index === 0,
1079
+ }));
1080
+ },
1081
+
1082
+ prContactOptions: () => {
1083
+ const fields = SallaApplePay.detail.requiredShippingContactFields || [];
1084
+ return {
1085
+ requestPayerName: fields.includes('name'),
1086
+ requestPayerEmail: fields.includes('email'),
1087
+ requestPayerPhone: fields.includes('phone'),
1088
+ requestShipping: fields.includes('postalAddress'),
1089
+ shippingType: 'shipping',
1090
+ };
1091
+ },
1092
+
1093
+ startPaymentRequestSession: async function () {
1094
+ // No merchant identifier in config → Apple Pay isn't set up for this
1095
+ // store; bail rather than open a QR sheet that can't be validated.
1096
+ const merchantIdentifier = SallaApplePay.getMerchantIdentifier();
1097
+ if (!merchantIdentifier) {
1098
+ salla.logger.error('🍏 Pay: missing merchant identifier — skipping QR Apple Pay');
1099
+ return;
1100
+ }
1101
+
1102
+ const version = SallaApplePay.getApplePaySessionVersion();
1103
+ const supportedNetworks = [...(SallaApplePay.detail.supportedNetworks || ['masterCard', 'visa'])];
1104
+ if (version === 5 && !supportedNetworks.includes('mada')) {
1105
+ supportedNetworks.push('mada');
1106
+ }
1107
+
1108
+ const methodData = [{
1109
+ supportedMethods: APPLE_PAY_METHOD,
1110
+ data: {
1111
+ version,
1112
+ merchantIdentifier,
1113
+ merchantCapabilities: ['supports3DS'],
1114
+ supportedNetworks,
1115
+ countryCode: SallaApplePay.detail.countryCode || 'SA',
1116
+ },
1117
+ }];
1118
+
1119
+ const requiresShipping = SallaApplePay.isPhysical();
1120
+
1121
+ const details = {
1122
+ total: SallaApplePay.prTotal(),
1123
+ displayItems: SallaApplePay.prDisplayItems(),
1124
+ };
1125
+ if (requiresShipping) {
1126
+ details.shippingOptions = SallaApplePay.prShippingOptions();
1127
+ }
1128
+
1129
+ let request;
1130
+ try {
1131
+ request = new PaymentRequest(methodData, details, SallaApplePay.prContactOptions());
1132
+ } catch (error) {
1133
+ salla.logger.error('🍏 Pay: Failed to create PaymentRequest', error);
1134
+ SallaApplePay.detail.onError(salla.lang.get('pages.checkout.payment_failed'));
1135
+ return;
1136
+ }
1137
+
1138
+ SallaApplePay.paymentRequest = request;
1139
+
1140
+ request.onmerchantvalidation = (event) => {
1141
+ event.complete(SallaApplePay.prValidateMerchant(event));
1142
+ };
1143
+
1144
+ if (requiresShipping) {
1145
+ request.onshippingaddresschange = (event) => {
1146
+ event.updateWith(SallaApplePay.prShippingAddressChange(request));
1147
+ };
1148
+ request.onshippingoptionchange = (event) => {
1149
+ event.updateWith(SallaApplePay.prShippingOptionChange(request));
1150
+ };
1151
+ }
1152
+
1153
+ // Showing the sheet is the QR equivalent of ApplePaySession.begin(): it
1154
+ // must run inside the user gesture (transient activation). Wrapped so the
1155
+ // order-options deferral can drive it — the caller either calls begin()
1156
+ // itself (no options → open the QR sheet now) or discards this request
1157
+ // and the modal's own Apple Pay button starts a fresh one (options found).
1158
+ const beginShow = async () => {
1159
+ // The QR sheet is browser chrome (fixed, top layer) that overlays the
1160
+ // page. Signal open/closed so hosts embedding Apple Pay (e.g. the
1161
+ // mini-checkout modal in an iframe) can hide UI — like their own close
1162
+ // button — that would otherwise collide with the sheet.
1163
+ Salla.event.dispatch('payments::apple-pay.sheet-opened');
1164
+ try {
1165
+ const response = await request.show();
1166
+ SallaApplePay.paymentResponse = response;
1167
+ await SallaApplePay.prPaymentAuthorized(response);
1168
+ } catch (error) {
1169
+ // AbortError → the shopper dismissed the sheet / QR, or merchant
1170
+ // validation rejected. Mirror the native oncancel path so hosts
1171
+ // listening for payments::apple-pay.canceled (to reset checkout UI)
1172
+ // still get notified on a plain dismissal. The `canceled` guard
1173
+ // skips the double-fire when validation already routed through
1174
+ // onCancel via validateMerchant.onFailed.
1175
+ salla.logger.log('🍏 Pay: PaymentRequest closed', error);
1176
+ if (error?.name === 'AbortError' && !SallaApplePay.canceled) {
1177
+ SallaApplePay.onCancel({});
1178
+ }
1179
+ } finally {
1180
+ SallaApplePay.paymentRequest = null;
1181
+ SallaApplePay.paymentResponse = null;
1182
+ Salla.event.dispatch('payments::apple-pay.sheet-closed');
1183
+ }
1184
+ };
1185
+
1186
+ // Mirror the native path (startNativeSession): expose a hook between
1187
+ // request creation and show(). Returning truthy skips the immediate
1188
+ // show() so the order-options modal can open first. Same shim contract
1189
+ // as native — the caller only needs `.begin()`.
1190
+ let skipBegin;
1191
+ if (typeof SallaApplePay.detail.onStartedSession === 'function') {
1192
+ skipBegin = SallaApplePay.detail.onStartedSession({ begin: beginShow });
1193
+ }
1194
+ if (!skipBegin) {
1195
+ await beginShow();
1196
+ }
1197
+ },
1198
+
1199
+ /** Merchant validation — resolves the promise passed to event.complete(). */
1200
+ prValidateMerchant: async function (event) {
1201
+ Salla.event.dispatch('payments::apple-pay.validate-merchant.init', event);
1202
+ try {
1203
+ const { data } = await http.post(
1204
+ SallaApplePay.detail.validateMerchant.url.replace('{id}', SallaApplePay.id),
1205
+ { validation_url: event.validationURL }
1206
+ );
1207
+
1208
+ // The BE can return HTTP 200 while Apple actually rejected the session
1209
+ // (e.g. statusCode 417 "not a registered merchant in WWDR"), with the
1210
+ // real session under data.data. A valid Apple session always carries a
1211
+ // merchantSessionIdentifier; its absence means validation failed. Without
1212
+ // this the QR sheet just closes silently — notify the shopper and abort.
1213
+ if (!data?.data?.merchantSessionIdentifier) {
1214
+ salla.logger.error('🍏 Pay: merchant validation failed', data?.statusMessage || data);
1215
+ Salla.event.dispatch('payments::apple-pay.validate-merchant.failed', { data });
1216
+ SallaApplePay.onCancel({});
1217
+ // Dismiss the sheet + paired device immediately. Rejecting
1218
+ // event.complete() alone leaves them spinning until Apple's own
1219
+ // timeout; abort() forces an instant close. Deferred a tick so it
1220
+ // runs after this validation update settles (abort() throws if
1221
+ // called while an update is still in flight).
1222
+ setTimeout(() => {
1223
+ try { SallaApplePay.paymentRequest?.abort(); } catch (e) { /* already closing */ }
1224
+ }, 0);
1225
+ const validationError = new Error('Apple Pay merchant validation failed');
1226
+ validationError.handled = true;
1227
+ throw validationError;
1228
+ }
1229
+
1230
+ Salla.event.dispatch('payments::apple-pay.validate-merchant.success', data);
1231
+
1232
+ if (typeof SallaApplePay.detail.validateMerchant.onSuccess === 'function') {
1233
+ const response = await SallaApplePay.detail.validateMerchant.onSuccess(data);
1234
+ if (response?.redirect) {
1235
+ window.location = response.redirect;
1236
+ }
1237
+ }
1238
+
1239
+ return data.data;
1240
+ } catch (error) {
1241
+ // Skip when the invalid-session branch above already notified via onCancel.
1242
+ if (!error?.handled) {
1243
+ const response = error?.response;
1244
+ Salla.event.dispatch('payments::apple-pay.validate-merchant.failed', response);
1245
+ if (typeof SallaApplePay.detail.validateMerchant.onFailed === 'function') {
1246
+ SallaApplePay.detail.validateMerchant.onFailed(response);
1247
+ }
1248
+ }
1249
+ // Rethrow so PaymentRequest aborts the sheet.
1250
+ throw error;
1251
+ }
1252
+ },
1253
+
1254
+ /**
1255
+ * ISO 3166 alpha-2 code → localized country name. The native path sends the
1256
+ * country *name* in `country` (from ApplePayPaymentContact.country) and the
1257
+ * ISO code in `country_code`; W3C PaymentAddress only exposes the ISO code,
1258
+ * so we derive the name the backend expects. Falls back to the code if
1259
+ * Intl.DisplayNames is unavailable or the code is unknown.
1260
+ */
1261
+ prCountryName: (isoCode) => {
1262
+ if (!isoCode) {
1263
+ return isoCode;
1264
+ }
1265
+ try {
1266
+ const locale = (salla?.config?.get?.('user.language_code')) || 'en';
1267
+ return new Intl.DisplayNames([locale], { type: 'region' }).of(isoCode) || isoCode;
1268
+ } catch (e) {
1269
+ return isoCode;
1270
+ }
1271
+ },
1272
+
1273
+ /** Shipping address selected in the sheet → returns a PaymentDetailsUpdate. */
1274
+ prShippingAddressChange: async function (request) {
1275
+ const address = request.shippingAddress;
1276
+ const fallback = {
1277
+ total: SallaApplePay.prTotal(),
1278
+ displayItems: SallaApplePay.prDisplayItems(),
1279
+ shippingOptions: [],
1280
+ };
1281
+
1282
+ if (!address) {
1283
+ return fallback;
1284
+ }
1285
+
1286
+ try {
1287
+ const { data } = await http.post(
1288
+ SallaApplePay.detail.shippingContactSelected.url.replace('{id}', SallaApplePay.id),
1289
+ {
1290
+ country: SallaApplePay.prCountryName(address.country),
1291
+ city: address.city,
1292
+ local: address.dependentLocality || address.region || address.city,
1293
+ description: address.region,
1294
+ street: (address.addressLine || []).join(', ') || address.region,
1295
+ country_code: address.country,
1296
+ postal_code: address.postalCode,
1297
+ }
1298
+ );
1299
+
1300
+ SallaApplePay.address_id = data.data.address_id;
1301
+ SallaApplePay.shipping_methods = data.data.shipping_methods;
1302
+
1303
+ if (!SallaApplePay.shipping_methods?.length) {
1304
+ return { ...fallback, error: salla.lang.get('pages.checkout.payment_failed') };
1305
+ }
1306
+
1307
+ await SallaApplePay.selectApplePayShippingMethod(SallaApplePay.shipping_methods[0]);
1308
+ await SallaApplePay.recalculateTotal();
1309
+
1310
+ return {
1311
+ total: SallaApplePay.prTotal(),
1312
+ displayItems: SallaApplePay.prDisplayItems(),
1313
+ shippingOptions: SallaApplePay.prShippingOptions(),
1314
+ };
1315
+ } catch (error) {
1316
+ salla.logger.warn('🍏 Pay: PR shipping address change failed', error);
1317
+ return { ...fallback, error: salla.lang.get('pages.checkout.payment_failed') };
1318
+ }
1319
+ },
1320
+
1321
+ /** Shipping option selected in the sheet → returns a PaymentDetailsUpdate. */
1322
+ prShippingOptionChange: async function (request) {
1323
+ const identifier = request.shippingOption;
1324
+ if (!identifier) {
1325
+ return {
1326
+ total: SallaApplePay.prTotal(),
1327
+ displayItems: SallaApplePay.prDisplayItems(),
1328
+ shippingOptions: SallaApplePay.prShippingOptions(),
1329
+ };
1330
+ }
1331
+
1332
+ const ids = identifier.split(',');
1333
+ const shippingMethod = {
1334
+ ship_id: ids[0],
1335
+ private_ship_id: typeof ids[1] === 'undefined' ? null : ids[1],
1336
+ type: typeof ids[2] === 'undefined' ? null : ids[2],
1337
+ route_id: typeof ids[3] === 'undefined' ? null : ids[3],
1338
+ };
1339
+
1340
+ try {
1341
+ if (SallaApplePay.shouldUpdateShippingCompany(shippingMethod)) {
1342
+ await SallaApplePay.selectApplePayShippingMethod(shippingMethod);
1343
+ await SallaApplePay.recalculateTotal();
1344
+ }
1345
+ return {
1346
+ total: SallaApplePay.prTotal(),
1347
+ displayItems: SallaApplePay.prDisplayItems(),
1348
+ shippingOptions: SallaApplePay.prShippingOptions(identifier),
1349
+ };
1350
+ } catch (error) {
1351
+ salla.logger.warn('🍏 Pay: PR shipping option change failed', error);
1352
+ return {
1353
+ total: SallaApplePay.prTotal(),
1354
+ displayItems: SallaApplePay.prDisplayItems(),
1355
+ shippingOptions: SallaApplePay.prShippingOptions(identifier),
1356
+ error: salla.lang.get('pages.checkout.payment_failed'),
1357
+ };
1358
+ }
1359
+ },
1360
+
1361
+ /** Map the PaymentResponse payer fields to the contact shape the API expects. */
1362
+ prContactFromResponse: (response) => {
1363
+ const name = (response.payerName || '').trim();
1364
+ const spaceIndex = name.indexOf(' ');
1365
+ return {
1366
+ givenName: spaceIndex > -1 ? name.slice(0, spaceIndex) : name,
1367
+ familyName: spaceIndex > -1 ? name.slice(spaceIndex + 1) : '',
1368
+ emailAddress: response.payerEmail || null,
1369
+ phoneNumber: response.payerPhone || null,
1370
+ countryCode: response.shippingAddress?.country || SallaApplePay.detail.countryCode || null,
1371
+ };
1372
+ },
1373
+
1374
+ /** Authorize + submit the payment, then close the sheet. */
1375
+ prPaymentAuthorized: async function (response) {
1376
+ // Guest checkout → persist the payer contact before submitting.
1377
+ if (SallaApplePay.detail.guestContactSelected) {
1378
+ const contact = SallaApplePay.prContactFromResponse(response);
1379
+
1380
+ // Require familyName too, mirroring the native guest guard
1381
+ // (utils.js mutateShippingContact). Keeps the payload the backend
1382
+ // receives identical to the production native flow — it has only
1383
+ // ever been sent a non-empty last_name from Apple Pay guest checkout.
1384
+ if (!contact.emailAddress || !contact.givenName || !contact.familyName || !contact.phoneNumber) {
1385
+ await response.complete('fail');
1386
+ SallaApplePay.detail.onError(salla.lang.get('common.messages.required_fields'));
1387
+ return;
1388
+ }
1389
+
1390
+ try {
1391
+ await http.post(
1392
+ SallaApplePay.detail.guestContactSelected.url.replace('{id}', SallaApplePay.id),
1393
+ {
1394
+ email: contact.emailAddress,
1395
+ first_name: contact.givenName,
1396
+ last_name: contact.familyName,
1397
+ phone_number: contact.phoneNumber,
1398
+ country_code: contact.countryCode,
1399
+ }
1400
+ );
1401
+ } catch (error) {
1402
+ await response.complete('fail');
1403
+ SallaApplePay.detail.onError(
1404
+ error?.response?.data?.error?.message || salla.lang.get('pages.checkout.payment_failed')
1405
+ );
1406
+ return;
1407
+ }
1408
+ }
1409
+
1410
+ Salla.event.dispatch('payments::apple-pay.authorized.init', response);
1411
+
1412
+ let authorizedData;
1413
+ try {
1414
+ const { data } = await http.post(
1415
+ SallaApplePay.detail.authorized.url.replace('{id}', SallaApplePay.id),
1416
+ { payment_method: 'apple_pay', applepay_token: JSON.stringify(response.details) }
1417
+ );
1418
+
1419
+ authorizedData = data;
1420
+ Salla.event.dispatch('payments::apple-pay.authorized.success', data);
1421
+ await response.complete('success');
1422
+ } catch (error) {
1423
+ const errorResponse = error?.response;
1424
+ Salla.event.dispatch('payments::apple-pay.authorized.failed', errorResponse);
1425
+ await response.complete('fail');
1426
+ if (typeof SallaApplePay.detail.authorized.onFailed === 'function') {
1427
+ SallaApplePay.detail.authorized.onFailed(errorResponse);
1428
+ }
1429
+ return;
1430
+ }
1431
+
1432
+ // response.complete() has already run above, and it can only be called
1433
+ // once. Run the merchant onSuccess callback OUTSIDE the try/catch so a
1434
+ // throw here (e.g. redirect handling) can't fall into the catch and fire
1435
+ // a second complete('fail') → InvalidStateError that masks the real error.
1436
+ if (typeof SallaApplePay.detail.authorized.onSuccess === 'function') {
1437
+ SallaApplePay.detail.authorized.onSuccess(authorizedData);
1438
+ }
1439
+ },
1440
+
869
1441
  shouldUpdateShippingCompany(shippingCompany) {
870
1442
  return SallaApplePay.shippingCompany?.ship_id != shippingCompany?.ship_id || SallaApplePay.shippingCompany?.private_ship_id != shippingCompany?.private_ship_id
871
1443
  },
@@ -989,8 +1561,10 @@ if (typeof window !== 'undefined') {
989
1561
  }
990
1562
 
991
1563
  //applePay doesn't allow iframes
992
- // SSR-safe: only initialize in browser
993
- if (typeof window !== 'undefined' && window.ApplePaySession?.canMakePayments()) {
1564
+ // SSR-safe (init only in the browser). Native (Safari) OR any browser with the
1565
+ // Payment Request API (non-Safari / QR-code fallback) can start a transaction;
1566
+ // capability is confirmed per-flow.
1567
+ if (typeof window !== 'undefined' && (SallaApplePay.canUseNative() || window.PaymentRequest)) {
994
1568
  SallaApplePay.init();
995
1569
  } else if (typeof document !== 'undefined') {
996
1570
  // You can hide the Apple Pay button easy with add data-show-if-apple-pay-supported to element like <div data-show-if-apple-pay-supported>
@@ -1206,16 +1780,12 @@ const SallaQuickBuy = /*@__PURE__*/ proxyCustomElement(class SallaQuickBuy exten
1206
1780
  currency: this.currency || salla.config.get('store.settings.buy_now.currency') || 'SAR', // SAR
1207
1781
  requiredShippingContactFields: this.getRequiredShippingContactFields(),
1208
1782
  shippingMethods: this.isRequireShipping ? [] : undefined,
1209
- // Legacy BE
1210
- supportedNetworks: this.isLegacyBuyNowBE()
1211
- ? salla.config.get('store.settings.buy_now.networks')
1212
- : ((Array.isArray(this.supportedNetworks) && this.supportedNetworks.length)
1213
- ? this.supportedNetworks : salla.config.get('store.settings.buy_now.supportedNetworks')),
1214
- supportedCountries: this.isLegacyBuyNowBE()
1215
- ? salla.config.get('store.settings.buy_now.countries')
1216
- : ((Array.isArray(this.supportedCountries) && this.supportedCountries.length)
1217
- ? this.supportedCountries : salla.config.get('store.settings.buy_now.supportedCountries')),
1783
+ supportedNetworks: (Array.isArray(this.supportedNetworks) && this.supportedNetworks.length)
1784
+ ? this.supportedNetworks : salla.config.get('store.settings.buy_now.supportedNetworks'),
1785
+ supportedCountries: (Array.isArray(this.supportedCountries) && this.supportedCountries.length)
1786
+ ? this.supportedCountries : salla.config.get('store.settings.buy_now.supportedCountries'),
1218
1787
  countryCode: salla.config.get('store.store_country') || 'SA',
1788
+ merchantIdentifier: applePayMerchantId(),
1219
1789
  onStartedSession: this.handleApplePaySessionStarted,
1220
1790
  validateMerchant: {
1221
1791
  url: this.validateHost ? `${this.validateHost}/checkout/applepay/validate` : salla.url.get('checkout/applepay/validate'),
@@ -1291,21 +1861,8 @@ const SallaQuickBuy = /*@__PURE__*/ proxyCustomElement(class SallaQuickBuy exten
1291
1861
  }
1292
1862
  return fields;
1293
1863
  }
1294
- /**
1295
- * TEMPORARY for BE Vip sync
1296
- */
1297
- isLegacyBuyNowBE() {
1298
- return salla?.config?.get?.('store.settings.buy_now.multi_currency') != null;
1299
- }
1300
1864
  /** Set Apple Pay amount + currency from a price payload, always keeping the pair in one currency. */
1301
1865
  applyBaseCurrencyPrice(data) {
1302
- // Legacy BE: amount only; currency is set once in runInit.
1303
- if (this.isLegacyBuyNowBE()) {
1304
- if (data?.price != null) {
1305
- this.amount = data.price;
1306
- }
1307
- return;
1308
- }
1309
1866
  const base = data?.base_currency_price;
1310
1867
  // Unified BE base pair (regular products): charge in base currency.
1311
1868
  if (base?.amount != null) {
@@ -1327,11 +1884,6 @@ const SallaQuickBuy = /*@__PURE__*/ proxyCustomElement(class SallaQuickBuy exten
1327
1884
  const isSallaGateway = salla?.config?.get?.('store.settings.is_salla_gateway', false) ?? true;
1328
1885
  this.isApplePayActive = canMakePayments && storeHasApplePay && isSallaGateway;
1329
1886
  const runInit = async () => {
1330
- if (this.isLegacyBuyNowBE() && !this.currency && salla?.config?.get) {
1331
- // Legacy BE (pre-PR): currency from the multi_currency flag. The unified BE instead
1332
- // sources amount + currency from `base_currency_price` (see applyBaseCurrencyPrice).
1333
- this.currency = salla.config.get('store.settings.buy_now.multi_currency') ? salla.config.get('user.currency_code') : (salla.config.get('store.settings.buy_now.currency') || 'SAR');
1334
- }
1335
1887
  if (!this.productId && salla?.config?.get && salla.url?.is_page) {
1336
1888
  this.productId = salla.config.get('page.id');
1337
1889
  }
@@ -1357,16 +1909,19 @@ const SallaQuickBuy = /*@__PURE__*/ proxyCustomElement(class SallaQuickBuy exten
1357
1909
  else if (salla?.url?.is_page?.('product.single') && salla?.product?.event?.onPriceUpdated) {
1358
1910
  salla.product.event.onPriceUpdated(response => { this.applyBaseCurrencyPrice(response?.data); });
1359
1911
  }
1360
- this.isApplePayActive = (salla?.helpers?.hasApplePay?.() ?? canMakePayments)
1361
- && (salla?.config?.get?.('store.settings.payments')?.includes?.('apple_pay') ?? storeHasApplePay)
1912
+ const storeAllowsApplePay = (salla?.config?.get?.('store.settings.payments')?.includes?.('apple_pay') ?? storeHasApplePay)
1362
1913
  && (salla?.config?.get?.('store.settings.is_salla_gateway', false) ?? isSallaGateway);
1363
- if (!document.getElementById('apple-pay-sdk') && this.isApplePayActive) {
1364
- const script = document.createElement('script');
1365
- script.src = 'https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js';
1366
- script.setAttribute('id', 'apple-pay-sdk');
1367
- script.async = true;
1368
- document.body.appendChild(script);
1914
+ // Preload Apple's JS SDK so the rendered <apple-pay-button> upgrades on
1915
+ // every flow (native Safari + QR). Fire-and-forget: the element upgrades
1916
+ // retroactively once the script defines it.
1917
+ if (storeAllowsApplePay) {
1918
+ ensureApplePaySdk();
1369
1919
  }
1920
+ // Cross-browser capability: native (Safari) OR the Payment Request API
1921
+ // (non-Safari browsers / non-Apple devices via the QR-code fallback). The
1922
+ // helper loads Apple's JS SDK and awaits it before probing, so this is a
1923
+ // stable answer on first load (no race against the async script fetch).
1924
+ this.isApplePayActive = storeAllowsApplePay && await canCompleteApplePay(this.currency);
1370
1925
  };
1371
1926
  return new Promise((resolve) => {
1372
1927
  if (typeof salla?.onReady === 'function') {
@@ -1378,7 +1933,7 @@ const SallaQuickBuy = /*@__PURE__*/ proxyCustomElement(class SallaQuickBuy exten
1378
1933
  });
1379
1934
  }
1380
1935
  render() {
1381
- return h(Host, { key: 'c2ba63eb4fad49f80977d6f1adc836f655524933' }, this.quickBuyButton());
1936
+ return h(Host, { key: '100f3cd501d568084f3596f5cef7c9b744f7ec82' }, this.quickBuyButton());
1382
1937
  }
1383
1938
  quickBuyButton() {
1384
1939
  return h("apple-pay-button", { locale: salla?.config?.get?.('user.language_code') || 'ar', onClick: () => this.quickBuyHandler(), "data-quick-purchase": "applepay", class: "s-quick-buy-apple-pay", "data-is-applepay": "1", buttonstyle: "black", type: this.type });
@@ -1480,4 +2035,4 @@ function defineCustomElement() {
1480
2035
  }
1481
2036
  defineCustomElement();
1482
2037
 
1483
- export { SallaQuickBuy as S, defineCustomElement as d };
2038
+ export { SallaQuickBuy as S, canCompleteApplePay as c, defineCustomElement as d };