import $ from 'jquery'; import { getOrderAttributionData } from '../utils'; /* global awxExpressCheckoutSettings, Airwallex */ /** * Get WC AJAX endpoint URL. * * @param {String} endpoint Endpoint. * @return {String} */ const getAjaxURL = (endpoint: string): string => { return awxExpressCheckoutSettings.ajaxUrl .toString() .replace('%%endpoint%%', 'airwallex_' + endpoint); }; interface PaymentAddress { countryCode?: string; administrativeArea?: string; postalCode?: string; locality?: string; } export const startPaymentSession = (validationURL: string) => { const data = { security: awxExpressCheckoutSettings.nonce.startPaymentSession, validationURL: validationURL, origin: window.location.host, } return $.ajax({ type: 'POST', data: data, url: getAjaxURL('start_payment_session'), }).done((response) => { return response; }).fail((error) => { return { success: false, message: error, } }); }; /** * Get shipping options based on address. * * @param {PaymentAddress} address Shipping address. */ export const updateShippingOptions = (address: PaymentAddress) => { const data = { security: awxExpressCheckoutSettings.nonce.shipping, country: address.countryCode ?? '', state: address.administrativeArea ?? '', postcode: address.postalCode ?? '', city: address.locality ?? '', }; return $.ajax({ type: 'POST', data: data, url: getAjaxURL('get_shipping_options') }).done(function (response) { return response; }).fail(function (error) { return { success: false, message: error, }; });; }; /** * Updates the shipping price and the total based on the shipping option. * * @param {String} selectedShippingMethodId Selected shipping method id. * @param {Array} shippingMethods All the shipping methods. */ export const updateShippingDetails = (selectedShippingMethodId: string, shippingMethods: string[]) => { // for subscription product there could be multiple shipping methods // sync the selected shipping method id to all shipping methods for (const idx in shippingMethods) { shippingMethods[idx] = selectedShippingMethodId; } const data = { security: awxExpressCheckoutSettings.nonce.updateShipping, shippingMethods: shippingMethods, }; return $.ajax({ type: 'POST', data: data, url: getAjaxURL('update_shipping_method') }).done(function (response) { return response; }).fail(function (error) { return { success: false, message: error, }; }); }; /** * Get estimated cart details for product */ export const getEstimatedCartDetails = () => { let product_id = $('.single_add_to_cart_button').val(); // Check if product is a variable product. if ($('.single_variation_wrap').length) { product_id = $('.single_variation_wrap').find('input[name="product_id"]').val(); } // eslint-disable-next-line @typescript-eslint/no-explicit-any const data: Record = { security: awxExpressCheckoutSettings.nonce.estimateCart, product_id: product_id, qty: $('.quantity .qty').val(), attributes: $('.variations_form').length ? getAttributes().data : [] }; // add addons data to the POST body const formData = $('form.cart').serializeArray(); $.each(formData, function (i, field) { if (/^addon-/.test(field.name)) { if (/\[\]$/.test(field.name)) { const fieldName = field.name.substring(0, field.name.length - 2); if (data[fieldName]) { data[fieldName].push(field.value); } else { data[fieldName] = [field.value]; } } else { data[field.name] = field.value; } } }); return $.ajax({ type: 'POST', data: data, url: getAjaxURL('get_estimated_cart_details') }).done(function(response) { return response; }).fail(function(error) { return { success: false, message: error, } }); }; /** * Adds the current item on the page to the cart and return the cart details * * @returns */ export const addToCart = () => { let product_id = $('.single_add_to_cart_button').val(); // Check if product is a variable product. if ($('.single_variation_wrap').length) { product_id = $('.single_variation_wrap').find('input[name="product_id"]').val(); } // eslint-disable-next-line @typescript-eslint/no-explicit-any const data: Record = { security: awxExpressCheckoutSettings.nonce.addToCart, product_id: product_id, qty: $('.quantity .qty').val(), attributes: $('.variations_form').length ? getAttributes().data : [] }; // add addons data to the POST body const formData = $('form.cart').serializeArray(); $.each(formData, function (i, field) { if (/^addon-/.test(field.name)) { if (/\[\]$/.test(field.name)) { const fieldName = field.name.substring(0, field.name.length - 2); if (data[fieldName]) { data[fieldName].push(field.value); } else { data[fieldName] = [field.value]; } } else { data[field.name] = field.value; } } }); return $.ajax({ type: 'POST', data: data, url: getAjaxURL('add_to_cart') }).done(function(response) { return response; }).fail(function(error) { return { success: false, message: error, } }); }; /** * Get cart details * * @returns {Object} Cart details */ export const getCartDetails = () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const data: Record = { security: awxExpressCheckoutSettings.nonce.payment }; data.product_id = $('.single_add_to_cart_button').val(); if ($('.single_variation_wrap').length) { data.product_id = $('.single_variation_wrap').find('input[name="product_id"]').val(); } return $.ajax({ type: 'POST', data: data, url: getAjaxURL('get_cart_details'), }).done(function (response) { return response; }).fail(function (error) { return { success: false, message: error, } }); }; /** * Create new order and process the payment * * @return {Object} Payment intent */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export const createOrder = (paymentData: any, paymentMethodType: 'googlepay' | 'applepay') => { const data = 'googlepay' === paymentMethodType ? getOrderDataForGooglePay(paymentData) : getOrderDataForApplePay(paymentData); return $.ajax({ type: 'POST', data: data, url: getAjaxURL('create_order'), }).done(function (response) { return response; }).fail(function (error) { return error; }); }; interface AttributeAggregator { count: number; chosenCount: number; data: Record; } const getAttributes = (): AttributeAggregator => { const select = $( '.variations_form' ).find( '.variations select' ); const data: Record = {}; let count = 0; let chosen = 0; select.each( function(this: HTMLElement) { const attribute_name = ($( this ).data( 'attribute_name' ) || $( this ).attr( 'name' )) as string; const value: string = ($( this ).val() ?? '').toString(); if ( value.length > 0 ) { chosen ++; } count ++; data[ attribute_name ] = value; }); return { count, chosenCount: chosen, data, }; }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const getOrderDataForGooglePay = (paymentData: any) => { const billing = paymentData.paymentMethodData.info.billingAddress; const shipping = paymentData.shippingAddress; const formattedBilling = { billing_first_name: billing ? billing.name.split( ' ' ).slice( 0, 1 ).join( ' ' ) : '', billing_last_name: billing ? billing.name.split( ' ' ).slice( 1 ).join( ' ' ) : '', billing_company: '', billing_email: paymentData.email ? paymentData.email : '', billing_phone: billing ? billing.phoneNumber : '', billing_country: billing ? billing.countryCode : '', billing_address_1: billing ? billing.address1 : '', billing_address_2: billing ? billing.address2.concat(' ', billing.address3).trim() : '', billing_city: billing ? billing.locality : '', billing_state: billing ? billing.administrativeArea : '', billing_postcode: billing ? billing.postalCode : '', } const formattedShipping = { shipping_first_name: shipping ? shipping.name.split( ' ' ).slice( 0, 1 ).join( ' ' ) : '', shipping_last_name: shipping ? shipping.name.split( ' ' ).slice( 1 ).join( ' ' ) : '', shipping_company: shipping && shipping.organization ? shipping.organization : '', shipping_country: shipping ? shipping.countryCode : '', shipping_address_1: shipping ? shipping.address1 : '', shipping_address_2: shipping ? shipping.address2.concat(' ', shipping.address3).trim() : '', shipping_city: shipping ? shipping.locality : '', shipping_state: shipping ? shipping.administrativeArea : '', shipping_postcode: shipping ? shipping.postalCode : '', shipping_method: [ paymentData.shippingOptionData ? paymentData.shippingOptionData.id : null ], }; const data = Object.assign( { _wpnonce: awxExpressCheckoutSettings.nonce.checkout, order_comments: '', payment_method: 'airwallex_express_checkout', ship_to_different_address: 1, terms: 1, payment_method_type: 'googlepay' }, formattedBilling, formattedShipping, getOrderAttributionData() ); return data; } // eslint-disable-next-line @typescript-eslint/no-explicit-any const getOrderDataForApplePay = (paymentData: any) => { const billing = paymentData.billingContact; const shipping = paymentData.shippingContact; const formattedBilling = { billing_first_name: billing ? billing.givenName : '', billing_last_name: billing ? billing.familyName : '', billing_company: '', billing_email: billing && billing.emailAddress ? billing.emailAddress : (shipping ? shipping.emailAddress : ''), billing_phone: billing && billing.phoneNumber ? billing.phoneNumber : (shipping ? shipping.phoneNumber : ''), billing_country: billing ? billing.countryCode : '', billing_address_1: billing && billing.addressLines && billing.addressLines.length > 0 ? billing.addressLines.shift() : '', billing_address_2: billing && billing.addressLines ? billing.addressLines.join(' ') : '', billing_city: billing ? (billing.locality ? billing.locality : billing.administrativeArea) : '', billing_state: billing ? billing.administrativeArea : '', billing_postcode: billing ? billing.postalCode : '', }; const formattedShipping = { shipping_first_name: shipping ? shipping.givenName : '', shipping_last_name: shipping ? shipping.familyName : '', shipping_company: '', shipping_country: shipping ? shipping.countryCode : '', shipping_address_1: shipping && shipping.addressLines && shipping.addressLines.length > 0 ? shipping.addressLines.shift() : '', shipping_address_2: shipping && shipping.addressLines ? shipping.addressLines.join(' ') : '', shipping_city: shipping ? (shipping.locality ? shipping.locality : shipping.administrativeArea ) : '', shipping_state: shipping ? shipping.administrativeArea : '', shipping_postcode: shipping ? shipping.postalCode : '', shipping_method: paymentData.shippingMethods ? paymentData.shippingMethods : [ null ], }; const data = Object.assign( { _wpnonce: awxExpressCheckoutSettings.nonce.checkout, order_comments: '', payment_method: 'airwallex_express_checkout', ship_to_different_address: 1, terms: 1, payment_method_type: 'applepay' }, formattedBilling, formattedShipping, getOrderAttributionData() ); return data; }