Shopify to NetSuite Customer Sync: Map/Reduce Script Integration Guide

Integrating Shopify with NetSuite helps automate the synchronization of customer data between both platforms. This ensures customer information, such as contact details and order history, is consistent and up-to-date across both systems, reducing manual effort and errors. With this integration, businesses can improve operational efficiency and gain real-time visibility into their customer data. In this guide, we’ll explore how to set up a NetSuite Map/Reduce script to sync customers from Shopify to NetSuite. This integration also helps in maintaining data accuracy, reducing the risk of discrepancies between the two systems.

Key Script Functions

1) Fetch Updated Shopify Customers

The process starts by fetching updated customers from Shopify. The script uses Shopify’s Admin API to retrieve customer data that has been modified since the last sync. The getInputData function fetches these updated records by calling the fetchUpdatedShopifyCustomers function, which handles the API call to Shopify and returns the updated customer list.

const getInputData = (inputContext) => {
    try {
        let scriptObj = runtime.getCurrentScript();
        let lastSyncDate = scriptObj.getParameter({ name: 'custentity_jj_shopify_last_sync' }) || '2025-01-01T00:00:00Z';
        let customers = fetchUpdatedShopifyCustomers(SHOPIFY_URL, SHOPIFY_TOKEN, lastSyncDate);
        return customers;
    } catch (e) {
        log.error('error@getinputdata', e);
        return [];
    }
};

2) Sync Customers to NetSuite

Once the updated customer data is retrieved, the script enters the map stage, where it processes each Shopify customer. It either creates a new NetSuite customer record or updates an existing one based on the customer’s Shopify ID or email address. The `upsertCustomerInNetSuite` function is responsible for this, ensuring fields like name, email, and phone are updated correctly.

const map = (mapContext) => {
    let shopifyCust = JSON.parse(mapContext.value);
    try {
        let savedId = upsertCustomerInNetSuite(shopifyCust);
        log.audit('Customer Synced', `Shopify ID: ${shopifyCust.id} → NetSuite ID: ${savedId}`);
    } catch (err) {
        log.error(`error@map ${shopifyCust.id}`, err);
    }
};

Here’s how the `upsertCustomerInNetSuite` function works:

const upsertCustomerInNetSuite = (shopifyCust) => {
    let shopifyId = String(shopifyCust.id);
    let email = (shopifyCust.email || '').trim().toLowerCase();
    let existingId = findCustomerByShopifyId(shopifyId);
    if (!existingId && email) {
        existingId = findCustomerByEmail(email);
    }
    let custRec = existingId
        ? record.load({ type: record.Type.CUSTOMER, id: existingId, isDynamic: true })
        : record.create({ type: record.Type.CUSTOMER, isDynamic: true });


    custRec.setValue({ fieldId: 'firstname', value: shopifyCust.first_name || '' });
    custRec.setValue({ fieldId: 'lastname', value: shopifyCust.last_name || '' });
    custRec.setValue({ fieldId: 'email', value: email });
    return custRec.save({ enableSourcing: true, ignoreMandatoryFields: false });
};

3) Summarizing Script Execution

After processing all customer data, the script summarizes the execution. It logs the total usage, time taken, and any errors encountered during the Map/Reduce execution. This summary helps monitor the script’s performance and troubleshoot issues.

const summarize = (summaryContext) => {
    log.audit('Map/Reduce Summary', {
        Total_Usage: summaryContext.usage,
        Total_Seconds: summaryContext.seconds
    });
};

Conclusion

This integration script automates the syncing of customer data from Shopify to NetSuite, ensuring that customer records are consistently updated across both platforms. By using NetSuite’s Map/Reduce architecture, the script efficiently handles large data sets while reducing manual data entry. With proper error handling and logging, this solution ensures data accuracy and minimizes potential issues.

Leave a comment

Your email address will not be published. Required fields are marked *