@salla.sa/applepay 3.0.19 → 3.0.20

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 (2) hide show
  1. package/package.json +2 -2
  2. package/src/index.js +71 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salla.sa/applepay",
3
- "version": "3.0.19",
3
+ "version": "3.0.20",
4
4
  "description": "Salla Apple Pay light",
5
5
  "main": "dist/app.js",
6
6
  "scripts": {
@@ -26,5 +26,5 @@
26
26
  "dependencies": {
27
27
  "axios": "^1.10.0"
28
28
  },
29
- "gitHead": "7668f911e50da28e3b118964ad95591db283bf40"
29
+ "gitHead": "87982d444f0f3f162c8a96a5daaa004a0937487d"
30
30
  }
package/src/index.js CHANGED
@@ -178,6 +178,17 @@ const SallaApplePay = typeof window !== 'undefined' ? {
178
178
 
179
179
  SallaApplePay.initDefault();
180
180
 
181
+ // A saved delivery address goes to the checkout directly, so the native sheet doesn't ask
182
+ // Apple for one. The QR (PaymentRequest) sheet always asks, so it keeps the default flow.
183
+ if (SallaApplePay.detail.savedAddress?.address_id) {
184
+ if (SallaApplePay.canUseNative()) {
185
+ SallaApplePay.detail.requiredShippingContactFields = (SallaApplePay.detail.requiredShippingContactFields || [])
186
+ .filter((field) => field !== 'postalAddress');
187
+ } else {
188
+ SallaApplePay.detail.savedAddress = null;
189
+ }
190
+ }
191
+
181
192
  // Native (Safari / Apple devices) → classic ApplePaySession. Otherwise
182
193
  // (non-Safari / non-Apple device) → Payment Request API, which renders
183
194
  // Apple's "Scan Code with iPhone" QR sheet.
@@ -249,9 +260,14 @@ const SallaApplePay = typeof window !== 'undefined' ? {
249
260
  onPaymentMethodSelected: async (event) => {
250
261
  salla.logger.log('🍏 Pay: onPaymentMethodSelected', event);
251
262
 
252
- // perform recalculate here only if digital product
263
+ // A saved address skips Apple's address step (postalAddress is removed), so isPhysical() is
264
+ // false for it even though the product ships: it takes this path to refresh the total and
265
+ // offer the carriers, since there is no shipping-contact step to do it.
266
+ const usesSavedAddress = !!SallaApplePay.detail.savedAddress?.address_id;
267
+
268
+ // perform recalculate here only if digital product or a saved address
253
269
  // if physical recalculate performed with shipping company
254
- if (!SallaApplePay.isPhysical()) {
270
+ if (!SallaApplePay.isPhysical() || usesSavedAddress) {
255
271
  try {
256
272
  await SallaApplePay.recalculateTotal();
257
273
 
@@ -259,7 +275,13 @@ const SallaApplePay = typeof window !== 'undefined' ? {
259
275
  newTotal: SallaApplePay.prepareTotal(),
260
276
  newLineItems: SallaApplePay.prepareLineItems()
261
277
  };
262
-
278
+
279
+ // A saved address skips Apple's address step, which is where the shipping methods
280
+ // are normally offered, so offer them here with the selected one first.
281
+ if (usesSavedAddress && SallaApplePay.shipping_methods?.length) {
282
+ updatedPaymentDetails.newShippingMethods = SallaApplePay.savedAddressShippingMethods();
283
+ }
284
+
263
285
  salla.logger.log('🍏 Pay: completePaymentMethodSelection', updatedPaymentDetails);
264
286
 
265
287
  SallaApplePay.session.completePaymentMethodSelection(updatedPaymentDetails);
@@ -481,6 +503,12 @@ const SallaApplePay = typeof window !== 'undefined' ? {
481
503
  return SallaApplePay.abortValidateMerchant(response);
482
504
  }
483
505
  }
506
+
507
+ // The cart exists now, so the saved address can be set on it before the sheet opens.
508
+ if (SallaApplePay.detail.savedAddress?.address_id) {
509
+ await SallaApplePay.applySavedAddress();
510
+ }
511
+
484
512
  completeMerchantValidation(data.data);
485
513
  } catch (error) {
486
514
  // Handle errors
@@ -1046,6 +1074,16 @@ const SallaApplePay = typeof window !== 'undefined' ? {
1046
1074
  }
1047
1075
  },
1048
1076
 
1077
+ /** Shipping options for the sheet with the currently selected one first, so Apple keeps it selected. */
1078
+ savedAddressShippingMethods() {
1079
+ const methods = SallaApplePay.shipping_methods || [];
1080
+ const current = SallaApplePay.shippingCompany;
1081
+ const selected = methods.find((method) => method.ship_id == current?.ship_id && method.private_ship_id == current?.private_ship_id);
1082
+ const ordered = selected ? [selected, ...methods.filter((method) => method !== selected)] : methods;
1083
+
1084
+ return SallaApplePay.mappingShippingMethods(ordered);
1085
+ },
1086
+
1049
1087
  shouldUpdateShippingCompany(shippingCompany) {
1050
1088
  return SallaApplePay.shippingCompany?.ship_id != shippingCompany?.ship_id || SallaApplePay.shippingCompany?.private_ship_id != shippingCompany?.private_ship_id
1051
1089
  },
@@ -1155,6 +1193,36 @@ const SallaApplePay = typeof window !== 'undefined' ? {
1155
1193
  return response?.data?.message;
1156
1194
  });
1157
1195
  },
1196
+ /**
1197
+ * Sets the saved delivery address on the cart by its address_id (no address from Apple), then
1198
+ * picks its first shipping method, as the Apple address flow does. Throws an axios-shaped error
1199
+ * so onValidateMerchant's catch can show it through validateMerchant.onFailed.
1200
+ */
1201
+ applySavedAddress: async () => {
1202
+ const { address_id, shippingMethods } = SallaApplePay.detail.savedAddress;
1203
+ const fail = (message) => Object.assign(new Error(message), { response: { data: { error: { message } } } });
1204
+ const outOfCoverage = () => salla.lang.get('pages.checkout.address_out_of_coverage');
1205
+
1206
+ let companies;
1207
+ try {
1208
+ const { data } = await http.get(shippingMethods.url.replace('{id}', SallaApplePay.id), null, null, { address_id });
1209
+ companies = data?.data?.companies;
1210
+ } catch (error) {
1211
+ throw fail(error?.response?.data?.error?.message || outOfCoverage());
1212
+ }
1213
+
1214
+ if (!companies?.length) {
1215
+ throw fail(outOfCoverage());
1216
+ }
1217
+
1218
+ SallaApplePay.address_id = address_id;
1219
+ SallaApplePay.shipping_methods = companies;
1220
+
1221
+ const selected = await SallaApplePay.selectApplePayShippingMethod(companies[0]);
1222
+ if (selected !== true) {
1223
+ throw fail((typeof selected === 'string' && selected) || outOfCoverage());
1224
+ }
1225
+ },
1158
1226
  mappingShippingMethods: methods => methods.map(method => ({
1159
1227
  'label': method.shipping_title,
1160
1228
  'amount': method.enable_free_shipping ? 0 : method.ship_cost,