UNPKG

@salla.sa/applepay

Version:
232 lines (190 loc) 8.06 kB
import http from "./http"; /** * @typedef {Object} ApplePayPaymentContact * @property {string} phoneNumber * @property {string} emailAddress * @property {string} givenName * @property {string} familyName * @property {string} [phoneticGivenName] * @property {string} [phoneticFamilyName] * @property {string[]} addressLines * @property {string} [subLocality] * @property {string} locality * @property {string} postalCode * @property {string} [subAdministrativeArea] * @property {string} administrativeArea * @property {string} country * @property {string} countryCode */ /** * * @param {SallaApplePay} SallaApplePay * @param {boolean} isAuthorized * @param {ApplePayPaymentContact} shippingContact * */ export async function mutateShippingContact(SallaApplePay, shippingContact, isAuthorized = false) { salla.logger.log('🍏 Pay: mutateShippingContact called', shippingContact, isAuthorized); if (!SallaApplePay.detail.requiredShippingContactFields || SallaApplePay.detail.requiredShippingContactFields.length == 0) { return; } if (isAuthorized) { if (isGuestCheckout()) { if ( !shippingContact.emailAddress || !shippingContact.givenName || !shippingContact.familyName || !shippingContact.phoneNumber ) { salla.logger.warn('🍏 Pay: Guest contact fields are required', shippingContact); const errors = []; if (!shippingContact.emailAddress) { errors.push(new window.ApplePayError('shippingContactInvalid', 'emailAddress', 'Email address is required')); } if (!shippingContact.phoneNumber) { errors.push(new window.ApplePayError('shippingContactInvalid', 'phoneNumber', 'Phone number is required')); } if (!shippingContact.givenName || !shippingContact.familyName) { errors.push(new window.ApplePayError('shippingContactInvalid', 'name', 'Name is required')); } SallaApplePay.session.completePayment({ status: SallaApplePay.session.STATUS_INVALID_SHIPPING_CONTACT, errors: errors }); return; } await updateGuestContact(SallaApplePay, shippingContact); } // if authorized and not guest checkout, do nothing address already added return; } if (!SallaApplePay.detail.requiredShippingContactFields.includes('postalAddress')) { return; } return http.post( SallaApplePay.detail.shippingContactSelected.url.replace('{id}', SallaApplePay.id), { 'country': shippingContact.country, 'city': shippingContact.locality, 'local': shippingContact.subLocality || shippingContact.administrativeArea || shippingContact.locality, 'description': shippingContact.subAdministrativeArea, 'street': shippingContact.addressLines?.join(", ") || shippingContact.administrativeArea, 'country_code': shippingContact.countryCode, 'postal_code': shippingContact.postalCode, }, async ({ data }) => { if (typeof SallaApplePay.detail.shippingContactSelected.onSuccess === 'function') { SallaApplePay.detail.shippingContactSelected.onSuccess(data); } SallaApplePay.address_id = data.data.address_id; SallaApplePay.shipping_methods = data.data.shipping_methods; if (!SallaApplePay.shipping_methods || (SallaApplePay.shipping_methods && !SallaApplePay.shipping_methods.length)) { salla.logger.warn('🍏 Pay: We dont found any supported methods', data); SallaApplePay.session.completeShippingContactSelection({ status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS, errors: [ new window.ApplePayError('addressUnserviceable') ] }); return } try { await SallaApplePay.selectApplePayShippingMethod(SallaApplePay.shipping_methods[0]); } catch (error) { salla.logger.warn('Failed set the shipping details to api', error); SallaApplePay.session.completeShippingContactSelection({ status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS, errors: [ new window.ApplePayError('addressUnserviceable') ] }); return; } try { await SallaApplePay.recalculateTotal(); } catch (error) { salla.logger.warn('🍏 Pay: Failed recalculate total', error); SallaApplePay.session.completeShippingContactSelection({ status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS, errors: [ new window.ApplePayError('addressUnserviceable') ] }); return; } const updatedShippingContactSelection = { newTotal: SallaApplePay.prepareTotal(), newLineItems: SallaApplePay.prepareLineItems(), newShippingMethods: SallaApplePay.mappingShippingMethods(SallaApplePay.shipping_methods) }; salla.logger.log('🍏 Pay: completeShippingContactSelection', updatedShippingContactSelection); SallaApplePay.session.completeShippingContactSelection(updatedShippingContactSelection); }, ({ response }) => { salla.logger.warn('🍏 Pay: Failed add address via api', response); if (typeof SallaApplePay.detail.shippingContactSelected.onFailed === 'function') { SallaApplePay.detail.shippingContactSelected.onFailed(response); } // parse 422 errors let fields = response?.data?.error?.fields; let errors = getApplePayErrors({ countryCode: fields?.country_code && fields.country_code.length > 0 ? fields.country_code[0] : null, locality: fields?.city && fields.city.length > 0 ? fields.city[0] : null, country: fields?.country && fields.country.length > 0 ? fields.country[0] : null, }); if (errors.length === 0 && response?.data?.error?.message) { errors.push(new window.ApplePayError('shippingContactInvalid', 'locality', response?.data?.error?.message)) } SallaApplePay.session.completeShippingContactSelection({ newTotal: SallaApplePay.prepareTotal(), newLineItems: SallaApplePay.prepareLineItems(), status: SallaApplePay.session.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS, errors: errors }); } ); } function isGuestCheckout() { return salla.config.isGuest() && salla.config.get('store.features').includes('guest-checkout'); } /** * Update guest contact * * @param {SallaApplePay} SallaApplePay * @param {ApplePayPaymentContact} shippingContact * */ async function updateGuestContact(SallaApplePay, shippingContact) { salla.logger.log('🍏 Pay: Updating guest contact', shippingContact); return new Promise((resolve, reject) => { http.post( SallaApplePay.detail.guestContactSelected.url.replace('{id}', SallaApplePay.id), { 'email': shippingContact.emailAddress || null, 'first_name': shippingContact.givenName || null, 'last_name': shippingContact.familyName || null, 'phone_number': shippingContact.phoneNumber || null, 'country_code': shippingContact.countryCode || null, }, async ({ data }) => { if (typeof SallaApplePay.detail.guestContactSelected?.onSuccess === 'function') { SallaApplePay.detail.guestContactSelected.onSuccess(data); } resolve(data); }, ({ response }) => { salla.logger.warn('🍏 Pay: Failed to update guest contact via api', response); if (typeof SallaApplePay.detail.guestContactSelected?.onFailed === 'function') { SallaApplePay.detail.guestContactSelected.onFailed(response); } // Reject the promise so it can be caught in onPaymentAuthorized reject({ response }); } ); }); } function getApplePayErrors(fields) { return Object.entries(fields) .filter(([field, messages]) => messages && messages.length > 0) .map(([field, messages]) => new window.ApplePayError('shippingContactInvalid', field, messages[0])); }