@salla.sa/applepay 2.14.346 → 2.14.348

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 (3) hide show
  1. package/package.json +2 -2
  2. package/src/index.js +180 -59
  3. package/src/utils.js +119 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salla.sa/applepay",
3
- "version": "2.14.346",
3
+ "version": "2.14.348",
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": "a8d1513a6b6e64f21b450dd4d2c61731ac8773a6"
29
+ "gitHead": "2930266232ae16881f28348370be5e700bf34edf"
30
30
  }
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import Http from './http';
1
+ import http from './http';
2
2
  import DetectOS from './DetectOS';
3
- import { mutateShipmentAddress } from './utils';
3
+ import { mutateShippingContact } from './utils';
4
4
 
5
5
  window.Salla = window.Salla || {};
6
6
  window.Salla.Payments = window.Salla.Payments || {};
@@ -44,6 +44,8 @@ window.SallaApplePay = {
44
44
  request: undefined,
45
45
  id: undefined,
46
46
  countryCode: null,
47
+ totals: [],
48
+ shippingCompany: null,
47
49
  init: function () {
48
50
  document.removeEventListener('payments::apple-pay.start-transaction', SallaApplePay.startSession);
49
51
  Salla.event.addEventListener('payments::apple-pay.start-transaction', SallaApplePay.startSession);
@@ -85,7 +87,7 @@ window.SallaApplePay = {
85
87
  SallaApplePay.detail.items = [
86
88
  {
87
89
  label: salla.lang.get('pages.cart.items_total'),
88
- amount: SallaApplePay.detail.amount
90
+ amount: parseFloat(SallaApplePay.detail.amount).toString()
89
91
  }
90
92
  ]
91
93
  }
@@ -98,10 +100,14 @@ window.SallaApplePay = {
98
100
  // apple ask to use business name
99
101
  label: window.location.hostname || 'Salla',
100
102
  //label: salla.lang.get('pages.cart.final_total'),
101
- amount: SallaApplePay.detail.amount
103
+ amount: parseFloat(SallaApplePay.detail.amount).toString()
102
104
  }
103
105
  },
104
106
 
107
+ isPhysical() {
108
+ return SallaApplePay.detail?.requiredShippingContactFields?.includes('postalAddress');
109
+ },
110
+
105
111
  startSession: async function (event) {
106
112
 
107
113
  SallaApplePay.detail = event.detail || event;
@@ -142,30 +148,62 @@ window.SallaApplePay = {
142
148
  SallaApplePay.session.onvalidatemerchant = SallaApplePay.onValidateMerchant;
143
149
  SallaApplePay.session.onpaymentauthorized = SallaApplePay.onPaymentAuthorized;
144
150
  SallaApplePay.session.oncancel = SallaApplePay.onCancel;
145
- SallaApplePay.session.oncouponcodechanged = SallaApplePay.oncouponcodechanged;
146
- SallaApplePay.session.onpaymentmethodselected = SallaApplePay.onpaymentmethodselected;
151
+ SallaApplePay.session.oncouponcodechanged = SallaApplePay.onCouponCodeChanged;
152
+ SallaApplePay.session.onpaymentmethodselected = SallaApplePay.onPaymentMethodSelected;
147
153
 
148
154
  SallaApplePay.session.begin();
149
155
  },
150
- async onpaymentmethodselected(event) {
151
- await SallaApplePay.recalculateTotal();
152
- const updatedPaymentDetails = {
156
+ onPaymentMethodSelected: async (event) => {
157
+ salla.logger.log('🍏 Pay: onPaymentMethodSelected', event);
158
+
159
+ // perform recalculate here only if digital product
160
+ // if physical recalculate performed with shipping company
161
+ if (!SallaApplePay.isPhysical()) {
162
+ try {
163
+ await SallaApplePay.recalculateTotal();
164
+
165
+ const updatedPaymentDetails = {
166
+ newTotal: SallaApplePay.prepareTotal(),
167
+ newLineItems: SallaApplePay.prepareLineItems()
168
+ };
169
+
170
+ salla.logger.log('🍏 Pay: completePaymentMethodSelection', updatedPaymentDetails);
171
+
172
+ SallaApplePay.session.completePaymentMethodSelection(updatedPaymentDetails);
173
+
174
+ } catch (error) {
175
+ salla.logger.warn('🍏 Pay: Failed recalculate total', error);
176
+
177
+ SallaApplePay.session.completePaymentMethodSelection({
178
+ newTotal: SallaApplePay.prepareTotal(),
179
+ newLineItems: SallaApplePay.prepareLineItems(),
180
+ status: SallaApplePay.session.STATUS_FAILURE,
181
+ errors: [new window.ApplePayError("unknown", undefined, error?.response?.data?.error?.message || error?.response?.data?.error?.code || 'Failed to recalculate total')]
182
+ });
183
+ }
184
+ return;
185
+ }
186
+
187
+ salla.logger.log('🍏 Pay: completePaymentMethodSelection', {
153
188
  newTotal: SallaApplePay.prepareTotal(),
154
189
  newLineItems: SallaApplePay.prepareLineItems(),
155
- };
190
+ });
156
191
 
157
- SallaApplePay.session.completePaymentMethodSelection(updatedPaymentDetails);
192
+ SallaApplePay.session.completePaymentMethodSelection({
193
+ newTotal: SallaApplePay.prepareTotal(),
194
+ newLineItems: SallaApplePay.prepareLineItems(),
195
+ });
158
196
  },
159
197
 
160
- oncouponcodechanged(event) {
198
+ onCouponCodeChanged(event) {
161
199
  Salla.event.dispatch('payments::apple-pay.coupon.change', event);
162
200
 
163
- return Http.post(SallaApplePay.detail.oncouponcodechanged.url.replace('{id}', SallaApplePay.id), {
201
+ return http.post(SallaApplePay.detail.onCouponCodeChanged.url.replace('{id}', SallaApplePay.id), {
164
202
  'coupon': event.couponCode,
165
203
  'payment_method': 'apple_pay',
166
204
  }, async ({ data }) => {
167
- if (typeof SallaApplePay.detail.oncouponcodechanged.onSuccess === 'function') {
168
- SallaApplePay.detail.oncouponcodechanged.onSuccess(data);
205
+ if (typeof SallaApplePay.detail.onCouponCodeChanged.onSuccess === 'function') {
206
+ SallaApplePay.detail.onCouponCodeChanged.onSuccess(data);
169
207
  }
170
208
 
171
209
  salla.log('🍏 Pay: Coupon applied success');
@@ -182,8 +220,8 @@ window.SallaApplePay = {
182
220
  Salla.event.dispatch('payments::apple-pay.coupon.failed', response);
183
221
 
184
222
  // SallaApplePay.abortSession();
185
- if (typeof SallaApplePay.detail.oncouponcodechanged.onFailed === 'function') {
186
- SallaApplePay.detail.oncouponcodechanged.onFailed(response);
223
+ if (typeof SallaApplePay.detail.onCouponCodeChanged.onFailed === 'function') {
224
+ SallaApplePay.detail.onCouponCodeChanged.onFailed(response);
187
225
  }
188
226
 
189
227
  await SallaApplePay.recalculateTotal();
@@ -209,35 +247,80 @@ window.SallaApplePay = {
209
247
  onPaymentAuthorized: async (event) => {
210
248
  salla.logger.log('🍏 Pay: onPaymentAuthorized', event.payment);
211
249
 
212
- // Update the payment address
213
- await mutateShipmentAddress(SallaApplePay, event.payment.shippingContact, true);
250
+ // update guest details
251
+ try {
252
+ await mutateShippingContact(SallaApplePay, event.payment.shippingContact, true);
253
+ } catch (error) {
254
+ salla.logger.error('🍏 Pay: Failed to update guest contact details', error);
255
+
256
+ const response = error?.response || error;
257
+
258
+ // Parse backend errors for shipping contact fields
259
+ const fields = response?.data?.error?.fields || {};
260
+ const errors = [];
261
+
262
+ // Map backend field errors to Apple Pay contact field errors
263
+ if (fields?.email && fields.email.length > 0) {
264
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'emailAddress', fields.email[0]));
265
+ }
266
+
267
+ if (fields?.phone && fields.phone.length > 0) {
268
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'phoneNumber', fields.phone[0]));
269
+ }
270
+
271
+ if (fields?.first_name && fields.first_name.length > 0) {
272
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'name', fields.first_name[0]));
273
+ } else if (fields?.last_name && fields.last_name.length > 0) {
274
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'name', fields.last_name[0]));
275
+ }
276
+
277
+ // If no specific field errors, use general error message
278
+ if (errors.length === 0) {
279
+ const errorMessage = response?.data?.error?.message || response?.data?.error?.code || 'Invalid shipping contact details';
280
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'name', errorMessage));
281
+ }
282
+
283
+ Salla.event.dispatch('payments::apple-pay.authorized.failed', response);
284
+
285
+ if (typeof SallaApplePay.detail.authorized.onFailed === 'function') {
286
+ SallaApplePay.detail.authorized.onFailed(response);
287
+ }
288
+
289
+ // Complete shipping contact selection with invalid contact status
290
+ SallaApplePay.session.completePayment({
291
+ status: ApplePaySession.STATUS_INVALID_SHIPPING_CONTACT,
292
+ errors: errors
293
+ });
294
+
295
+ return;
296
+ }
214
297
 
215
298
  Salla.event.dispatch('payments::apple-pay.authorized.init', event);
216
- Http.post(SallaApplePay.detail.authorized.url.replace('{id}', SallaApplePay.id), {
299
+ http.post(SallaApplePay.detail.authorized.url.replace('{id}', SallaApplePay.id), {
217
300
  payment_method: 'apple_pay',
218
301
  applepay_token: JSON.stringify(event.payment)
219
302
  }, ({ data }) => {
220
303
  Salla.event.dispatch('payments::apple-pay.authorized.success', data);
221
304
 
222
- SallaApplePay.session.completePayment(ApplePaySession.STATUS_SUCCESS);
223
-
224
305
  if (typeof SallaApplePay.detail.authorized.onSuccess === 'function') {
225
306
  SallaApplePay.detail.authorized.onSuccess(data);
226
307
  }
308
+
309
+ SallaApplePay.session.completePayment(ApplePaySession.STATUS_SUCCESS);
227
310
  }, (error) => {
228
311
 
229
312
  let response = error?.response;
230
313
 
231
314
  Salla.event.dispatch('payments::apple-pay.authorized.failed', response);
232
315
 
233
- SallaApplePay.session.completePayment({
234
- status: ApplePaySession.STATUS_FAILURE,
235
- errors: [new ApplePayError("unknown", undefined, response?.data?.error?.message || response?.data?.error?.code || 'Failed to parse authorized response')]
236
- })
237
-
238
316
  if (typeof SallaApplePay.detail.authorized.onFailed === 'function') {
239
317
  SallaApplePay.detail.authorized.onFailed(response);
240
318
  }
319
+
320
+ SallaApplePay.session.completePayment({
321
+ status: ApplePaySession.STATUS_FAILURE,
322
+ errors: [new window.ApplePayError("unknown", undefined, response?.data?.error?.message || response?.data?.error?.code || 'Failed to parse authorized response')]
323
+ })
241
324
  });
242
325
  },
243
326
 
@@ -252,7 +335,7 @@ window.SallaApplePay = {
252
335
  Salla.event.dispatch('payments::apple-pay.validate-merchant.init', event);
253
336
 
254
337
  // Post request to validate merchant
255
- const { data } = await Http.post(SallaApplePay.detail.validateMerchant.url.replace('{id}', SallaApplePay.id), {
338
+ const { data } = await http.post(SallaApplePay.detail.validateMerchant.url.replace('{id}', SallaApplePay.id), {
256
339
  validation_url: event.validationURL
257
340
  });
258
341
 
@@ -301,7 +384,7 @@ window.SallaApplePay = {
301
384
  salla.logger.log('🍏 Pay: onShippingContactSelected', event.shippingContact);
302
385
 
303
386
  // create address for shipping calculation
304
- mutateShipmentAddress(SallaApplePay, event.shippingContact);
387
+ await mutateShippingContact(SallaApplePay, event.shippingContact);
305
388
  },
306
389
 
307
390
  /**
@@ -311,25 +394,54 @@ window.SallaApplePay = {
311
394
  *
312
395
  */
313
396
  onShippingMethodSelected: async (event) => {
314
- salla.logger.log(event);
315
397
 
316
398
  let shipping_ids = event.shippingMethod.identifier.split(',');
399
+ let shippingMethod = {
400
+ ship_id: shipping_ids[0],
401
+ private_ship_id: typeof shipping_ids[1] === 'undefined' ? null : shipping_ids[1],
402
+ type: typeof shipping_ids[2] === 'undefined' ? null : shipping_ids[2],
403
+ route_id: typeof shipping_ids[3] === 'undefined' ? null : shipping_ids[3],
404
+ };
317
405
 
318
- try {
319
- await SallaApplePay.selectApplePayShippingMethod(shipping_ids[0], typeof shipping_ids[1] === 'undefined' ? null : shipping_ids[1]);
406
+ salla.logger.log('🍏 Pay: onShippingMethodSelected', {
407
+ event,
408
+ previous: SallaApplePay.shippingCompany,
409
+ current: shippingMethod,
410
+ });
320
411
 
321
- await SallaApplePay.recalculateTotal();
412
+ if (SallaApplePay.shouldUpdateShippingCompany(shippingMethod)) {
413
+ try {
414
+
415
+ await SallaApplePay.selectApplePayShippingMethod(shippingMethod);
416
+
417
+ await SallaApplePay.recalculateTotal();
418
+
419
+ } catch (error) {
420
+ salla.logger.warn('🍏 Pay: Failed set the shipping details to api', error);
421
+
422
+ // todo :: find a better handling for error without abort session
423
+ SallaApplePay.session.completeShippingMethodSelection({
424
+ newTotal: SallaApplePay.prepareTotal(),
425
+ newLineItems: SallaApplePay.prepareLineItems(),
426
+ status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS,
427
+ errors: [
428
+ new window.ApplePayError('addressUnserviceable')
429
+ ]
430
+ });
431
+
432
+ return;
433
+ }
434
+ }
322
435
 
323
- SallaApplePay.session.completeShippingMethodSelection({
324
- newTotal: SallaApplePay.prepareTotal(),
325
- newLineItems: SallaApplePay.prepareLineItems(),
326
- });
327
- } catch (error) {
328
- salla.logger.warn('🍏 Pay: Failed set the shipping details to api', error);
436
+ salla.logger.log('🍏 Pay: completeShippingMethodSelection', {
437
+ newTotal: SallaApplePay.prepareTotal(),
438
+ newLineItems: SallaApplePay.prepareLineItems(),
439
+ });
329
440
 
330
- // todo :: find a better handling for error without abort session
331
- SallaApplePay.abortSession();
332
- }
441
+ SallaApplePay.session.completeShippingMethodSelection({
442
+ newTotal: SallaApplePay.prepareTotal(),
443
+ newLineItems: SallaApplePay.prepareLineItems(),
444
+ });
333
445
  },
334
446
 
335
447
 
@@ -339,6 +451,10 @@ window.SallaApplePay = {
339
451
  }
340
452
  },
341
453
 
454
+ shouldUpdateShippingCompany(shippingCompany) {
455
+ return SallaApplePay.shippingCompany?.ship_id != shippingCompany?.ship_id || SallaApplePay.shippingCompany?.private_ship_id != shippingCompany?.private_ship_id
456
+ },
457
+
342
458
  getApplePaySessionVersion: () => {
343
459
  const userAgent = navigator.userAgent || navigator.vendor || window.opera;
344
460
 
@@ -364,11 +480,17 @@ window.SallaApplePay = {
364
480
  },
365
481
 
366
482
  recalculateTotal: () => {
367
- salla.logger.log('Recalculate Total');
483
+ salla.logger.log('🍏 Pay: recalculate total');
368
484
 
369
- return Http.requestWithSupportAjax(SallaApplePay.detail.recalculateTotal.url.replace('{id}', SallaApplePay.id), {}, 'get').then((data) => {
485
+ return http.get(SallaApplePay.detail.recalculateTotal.url.replace('{id}', SallaApplePay.id), ({ data }) => {
486
+ salla.logger.log('🍏 Pay: recalculate total success', data);
370
487
  let cart = data.data.initial_data?.cart || data.data.cart;
371
- let payments = data.data.initial_data?.payments;
488
+ let payments = data.data.initial_data?.payments || data.data.payments;
489
+
490
+ salla.logger.log('🍏 Pay: recalculate total success', {
491
+ cart,
492
+ payments
493
+ });
372
494
 
373
495
  // todo :: enhance response from backend
374
496
  SallaApplePay.detail.amount = payments?.gateways?.applePay?.supportedMultiCurrency ? cart.total_in_customer_currency : cart.total;
@@ -381,9 +503,9 @@ window.SallaApplePay = {
381
503
 
382
504
  // lets remove last element (final total)
383
505
  SallaApplePay.detail.items.pop();
506
+ SallaApplePay.totals = SallaApplePay.detail.items;
384
507
 
385
- return data;
386
- }).catch((error) => {
508
+ }, (error) => {
387
509
  salla.logger.warn('🍏 Pay: recalculate total failed', error);
388
510
 
389
511
  // general error
@@ -392,27 +514,26 @@ window.SallaApplePay = {
392
514
  },
393
515
 
394
516
 
395
- selectApplePayShippingMethod: (company_id, private_company_id) => {
396
- salla.logger.log('🍏 Pay: select shipping method ', 'company_id : ' + company_id, 'private_company_id: ' + private_company_id);
517
+ selectApplePayShippingMethod: (shippingMethod) => {
518
+ salla.logger.log('🍏 Pay: select shipping method ', shippingMethod);
519
+ SallaApplePay.shippingCompany = shippingMethod;
520
+
397
521
  const payload = {
398
522
  address_id: SallaApplePay.address_id,
399
- company_id: company_id,
400
- private_company_id: private_company_id,
523
+ company_id: shippingMethod.ship_id,
524
+ private_company_id: shippingMethod.private_ship_id,
525
+ type: shippingMethod.type || undefined,
526
+ route_id: shippingMethod.route_id || undefined,
401
527
  payment_method: 'apple_pay'
402
528
  }
403
- const selectedShippingMethod = SallaApplePay.shipping_methods?.find((item)=> item.company == company_id || item.ship_id == company_id);
404
- if (selectedShippingMethod?.route_id){
405
- payload.shipping_route_id = selectedShippingMethod.route_id
406
- payload.type = selectedShippingMethod.type
407
- }
408
- return Http.requestWithSupportAjax(SallaApplePay.detail.shippingMethodSelected.url.replace('{id}', SallaApplePay.id), payload, 'post').then(() => {
529
+ return http.post(SallaApplePay.detail.shippingMethodSelected.url.replace('{id}', SallaApplePay.id), payload, ({ data }) => {
409
530
  if (typeof SallaApplePay.detail.shippingMethodSelected.onSuccess === 'function') {
410
531
  SallaApplePay.detail.shippingMethodSelected.onSuccess(data);
411
532
  }
412
533
 
413
534
  // we don't have any data in this request, lets resolve the promise
414
535
  return true;
415
- }).catch((error) => {
536
+ }, (error) => {
416
537
  salla.logger.warn('🍏 Pay: Set shipping method failed', error);
417
538
 
418
539
  if (typeof SallaApplePay.detail.shippingMethodSelected.onFailed === 'function') {
@@ -435,7 +556,7 @@ window.SallaApplePay = {
435
556
  'label': method.shipping_title,
436
557
  'amount': method.enable_free_shipping ? 0 : method.ship_cost,
437
558
  'detail': '',
438
- 'identifier': method.ship_id.toString() + (method.private_ship_id ? ',' + method.private_ship_id.toString() : '')
559
+ 'identifier': method.ship_id.toString() + (method.private_ship_id ? ',' + method.private_ship_id.toString() : '') + (method.type ? ',' + method.type : '') + (method.route_id ? ',' + method.route_id : '')
439
560
  }))
440
561
  }
441
562
 
package/src/utils.js CHANGED
@@ -26,10 +26,55 @@ import http from "./http";
26
26
  * @param {ApplePayPaymentContact} shippingContact
27
27
  *
28
28
  */
29
- export function mutateShipmentAddress(SallaApplePay, shippingContact, isAuthorized = false) {
30
- console.log('mutateShipmentAddress called', shippingContact, isAuthorized);
29
+ export async function mutateShippingContact(SallaApplePay, shippingContact, isAuthorized = false) {
30
+ salla.logger.log('🍏 Pay: mutateShippingContact called', shippingContact, isAuthorized);
31
31
 
32
- if (!SallaApplePay.detail.requiredShippingContactFields) {
32
+ if (!SallaApplePay.detail.requiredShippingContactFields || SallaApplePay.detail.requiredShippingContactFields.length == 0) {
33
+ return;
34
+ }
35
+
36
+ if (isAuthorized) {
37
+ if (isGuestCheckout()) {
38
+
39
+ if (
40
+ !shippingContact.emailAddress ||
41
+ !shippingContact.givenName ||
42
+ !shippingContact.familyName ||
43
+ !shippingContact.phoneNumber
44
+ ) {
45
+
46
+ salla.logger.warn('🍏 Pay: Guest contact fields are required', shippingContact);
47
+
48
+ const errors = [];
49
+ if (!shippingContact.emailAddress) {
50
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'emailAddress', 'Email address is required'));
51
+ }
52
+
53
+ if (!shippingContact.phoneNumber) {
54
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'phoneNumber', 'Phone number is required'));
55
+ }
56
+
57
+ if (!shippingContact.givenName || !shippingContact.familyName) {
58
+ errors.push(new window.ApplePayError('shippingContactInvalid', 'name', 'Name is required'));
59
+ }
60
+
61
+ SallaApplePay.session.completePayment({
62
+ status: SallaApplePay.session.STATUS_INVALID_SHIPPING_CONTACT,
63
+ errors: errors
64
+ });
65
+
66
+ return;
67
+ }
68
+
69
+ await updateGuestContact(SallaApplePay, shippingContact);
70
+
71
+ }
72
+
73
+ // if authorized and not guest checkout, do nothing address already added
74
+ return;
75
+ }
76
+
77
+ if (!SallaApplePay.detail.requiredShippingContactFields.includes('postalAddress')) {
33
78
  return;
34
79
  }
35
80
 
@@ -38,15 +83,13 @@ export function mutateShipmentAddress(SallaApplePay, shippingContact, isAuthoriz
38
83
  {
39
84
  'country': shippingContact.country,
40
85
  'city': shippingContact.locality,
41
- 'local': shippingContact.subLocality,
86
+ 'local': shippingContact.subLocality || shippingContact.administrativeArea || shippingContact.locality,
42
87
  'description': shippingContact.subAdministrativeArea,
43
88
  'street': shippingContact.addressLines?.join(", ") || shippingContact.administrativeArea,
44
89
  'country_code': shippingContact.countryCode,
45
90
  'postal_code': shippingContact.postalCode,
46
- 'is_authorized': isAuthorized
47
91
  },
48
92
  async ({ data }) => {
49
- if (isAuthorized) { return }
50
93
  if (typeof SallaApplePay.detail.shippingContactSelected.onSuccess === 'function') {
51
94
  SallaApplePay.detail.shippingContactSelected.onSuccess(data);
52
95
  }
@@ -57,25 +100,29 @@ export function mutateShipmentAddress(SallaApplePay, shippingContact, isAuthoriz
57
100
  if (!SallaApplePay.shipping_methods || (SallaApplePay.shipping_methods && !SallaApplePay.shipping_methods.length)) {
58
101
  salla.logger.warn('🍏 Pay: We dont found any supported methods', data);
59
102
 
60
- return SallaApplePay.session.completeShippingContactSelection({
103
+ SallaApplePay.session.completeShippingContactSelection({
61
104
  status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS,
62
105
  errors: [
63
106
  new window.ApplePayError('addressUnserviceable')
64
107
  ]
65
108
  });
109
+
110
+ return
66
111
  }
67
112
 
68
113
  try {
69
- await SallaApplePay.selectApplePayShippingMethod(SallaApplePay.shipping_methods[0]['ship_id'], SallaApplePay.shipping_methods[0]['private_ship_id']);
114
+ await SallaApplePay.selectApplePayShippingMethod(SallaApplePay.shipping_methods[0]);
70
115
  } catch (error) {
71
116
  salla.logger.warn('Failed set the shipping details to api', error);
72
117
 
73
- return SallaApplePay.session.completeShippingContactSelection({
118
+ SallaApplePay.session.completeShippingContactSelection({
74
119
  status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS,
75
120
  errors: [
76
121
  new window.ApplePayError('addressUnserviceable')
77
122
  ]
78
123
  });
124
+
125
+ return;
79
126
  }
80
127
 
81
128
  try {
@@ -83,20 +130,25 @@ export function mutateShipmentAddress(SallaApplePay, shippingContact, isAuthoriz
83
130
  } catch (error) {
84
131
  salla.logger.warn('🍏 Pay: Failed recalculate total', error);
85
132
 
86
- return SallaApplePay.session.completeShippingContactSelection({
133
+ SallaApplePay.session.completeShippingContactSelection({
87
134
  status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS,
88
135
  errors: [
89
136
  new window.ApplePayError('addressUnserviceable')
90
137
  ]
91
138
  });
139
+
140
+ return;
92
141
  }
93
142
 
94
- SallaApplePay.session.completeShippingContactSelection({
143
+ const updatedShippingContactSelection = {
95
144
  newTotal: SallaApplePay.prepareTotal(),
96
145
  newLineItems: SallaApplePay.prepareLineItems(),
97
146
  newShippingMethods: SallaApplePay.mappingShippingMethods(SallaApplePay.shipping_methods)
98
- });
147
+ };
99
148
 
149
+ salla.logger.log('🍏 Pay: completeShippingContactSelection', updatedShippingContactSelection);
150
+
151
+ SallaApplePay.session.completeShippingContactSelection(updatedShippingContactSelection);
100
152
  },
101
153
  ({ response }) => {
102
154
  salla.logger.warn('🍏 Pay: Failed add address via api', response);
@@ -108,19 +160,11 @@ export function mutateShipmentAddress(SallaApplePay, shippingContact, isAuthoriz
108
160
  // parse 422 errors
109
161
  let fields = response?.data?.error?.fields;
110
162
 
111
- let errors = [];
112
-
113
- if (fields?.country_code) {
114
- errors.push(new window.ApplePayError('shippingContactInvalid', 'countryCode', fields?.country_code[0]))
115
- }
116
-
117
- if (fields?.city) {
118
- errors.push(new window.ApplePayError('shippingContactInvalid', 'locality', fields?.city[0]))
119
- }
120
-
121
- if (fields?.country) {
122
- errors.push(new window.ApplePayError('shippingContactInvalid', 'country', fields?.country[0]))
123
- }
163
+ let errors = getApplePayErrors({
164
+ countryCode: fields?.country_code && fields.country_code.length > 0 ? fields.country_code[0] : null,
165
+ locality: fields?.city && fields.city.length > 0 ? fields.city[0] : null,
166
+ country: fields?.country && fields.country.length > 0 ? fields.country[0] : null,
167
+ });
124
168
 
125
169
  if (errors.length === 0 && response?.data?.error?.message) {
126
170
  errors.push(new window.ApplePayError('shippingContactInvalid', 'locality', response?.data?.error?.message))
@@ -135,3 +179,53 @@ export function mutateShipmentAddress(SallaApplePay, shippingContact, isAuthoriz
135
179
  }
136
180
  );
137
181
  }
182
+
183
+ function isGuestCheckout() {
184
+ return salla.config.isGuest() && salla.config.get('store.features').includes('guest-checkout');
185
+ }
186
+
187
+ /**
188
+ * Update guest contact
189
+ *
190
+ * @param {SallaApplePay} SallaApplePay
191
+ * @param {ApplePayPaymentContact} shippingContact
192
+ *
193
+ */
194
+ async function updateGuestContact(SallaApplePay, shippingContact) {
195
+ salla.logger.log('🍏 Pay: Updating guest contact', shippingContact);
196
+
197
+ return new Promise((resolve, reject) => {
198
+ http.post(
199
+ SallaApplePay.detail.guestContactSelected.url.replace('{id}', SallaApplePay.id),
200
+ {
201
+ 'email': shippingContact.emailAddress || null,
202
+ 'first_name': shippingContact.givenName || null,
203
+ 'last_name': shippingContact.familyName || null,
204
+ 'phone_number': shippingContact.phoneNumber || null,
205
+ 'country_code': shippingContact.countryCode || null,
206
+ },
207
+ async ({ data }) => {
208
+ if (typeof SallaApplePay.detail.guestContactSelected?.onSuccess === 'function') {
209
+ SallaApplePay.detail.guestContactSelected.onSuccess(data);
210
+ }
211
+ resolve(data);
212
+ },
213
+ ({ response }) => {
214
+ salla.logger.warn('🍏 Pay: Failed to update guest contact via api', response);
215
+
216
+ if (typeof SallaApplePay.detail.guestContactSelected?.onFailed === 'function') {
217
+ SallaApplePay.detail.guestContactSelected.onFailed(response);
218
+ }
219
+
220
+ // Reject the promise so it can be caught in onPaymentAuthorized
221
+ reject({ response });
222
+ }
223
+ );
224
+ });
225
+ }
226
+
227
+ function getApplePayErrors(fields) {
228
+ return Object.entries(fields)
229
+ .filter(([field, messages]) => messages && messages.length > 0)
230
+ .map(([field, messages]) => new window.ApplePayError('shippingContactInvalid', field, messages[0]));
231
+ }