Main site

Built-in Modules > enrichCustomerData Function

enrichCustomerData Function

Important: Shopify has recently started including the customer object in carrier service requests for some stores. This behaviour is not yet officially announced or documented by Shopify and may vary between stores or change without notice. The enrichCustomerData function works only when the customer object is present at checkout.

Overview

The enrichCustomerData function is an asynchronous function designed to enrich the customer field within the input DATA JSON object with customer profile information fetched from Shopify Admin GraphQL API. It can also fetch customer metafields from specified namespaces.

Function Signature

async function enrichCustomerData(DATA, metafield_namespaces = [])

Arguments

  • DATA (Object): The initial DATA JSON object provided to the calculateShippingRates function.
  • metafield_namespaces (Array, Optional): An array specifying customer metafield namespaces and the size of metafields to fetch.
    • Each object within the array contains:
      • namespace (String): The customer metafield namespace.
      • size (Number): The count of customer metafield objects to retrieve from the namespace.

Notes

  • This DATA.customer and DATA.customer.id are available when a registered customer is logged in at checkout.
  • The customer object is not present in the test data payload or when the customer is not logged in.
  • Ensure that each entry in metafield_namespaces includes both a namespace and a size.
  • The function adds/updates DATA.customer with Shopify customer fields and a metafields object.
  • Customer metafields are stored under DATA.customer.metafields.<namespace>.
  • Namespace key sanitization is applied: any non a-zA-Z0-9_ characters in a namespace are replaced with _.

Usage Example

import { enrichCustomerData } from "./modules.js"

DATA = await enrichCustomerData(DATA, [{ namespace: "custom", size: 15 }]);

This enriches the customer object of DATA with customer profile fields and the first 15 metafield objects from the custom namespace.

Sample Output

{
  "customer": {
    "id": "number",
    "firstName": "string|null",
    "lastName": "string|null",

    "email": "string|null",
    "verifiedEmail": "boolean",
    "validEmailAddress": "boolean",

    "numberOfOrders": "number",
    "amountSpent": {
      "amount": "string",
      "currencyCode": "string"
    },

    "createdAt": "string",
    "updatedAt": "string",
    "note": "string|null",

    "tags": "array<string>",
    "lifetimeDuration": "string",

    "defaultAddress": {
      "company": "string|null",
      "address1": "string|null",
      "address2": "string|null",
      "city": "string|null",
      "zip": "string|null",
      "province": "string|null",
      "provinceCode": "string|null",
      "country": "string|null",
      "countryCode": "string|null"
    },

    "addresses": [
      {
        "company": "string|null",
        "address1": "string|null",
        "address2": "string|null",
        "city": "string|null",
        "zip": "string|null",
        "province": "string|null",
        "provinceCode": "string|null",
        "country": "string|null",
        "countryCode": "string|null"
      }
    ],

    "companyContactProfiles": [
      {
        "company": {
          "name": "string|null"
        }
      }
    ],

    "metafields": {
      "custom": {
        "date_of_birth": "string"
      }
    }
  }
}

Notes

  • The output above shows the structure and data types of the enriched customer object.
  • addresses is an array of address objects.
  • companyContactProfiles is an array of company profile objects.
  • The metafields object can contain various other namespace objects as per the specified namespaces.
  • Namespace keys may appear sanitized (for example vip-data becomes vip_data).

Sample AI Prompt

I'd like a shipping rate calculator that gives VIP customers free shipping.

Use the built-in module enrichCustomerData to enrich the customer object.
Fetch the first 15 metafields from the "custom" namespace.

If the customer has the tag "VIP", return free shipping.
Otherwise, return a flat $9.95 shipping rate.

If customer data is missing (no customer or no customer id), return the flat $9.95 rate.

Sample AI Output

import { enrichCustomerData } from "./modules.js";

export async function calculateShippingRates(DATA, env) {
  try {
    // Default currency from the request or fallback to USD
    const currency = DATA.currency || "USD";

    // Define the standard flat rate ($9.95 -> 995 cents)
    const standardRate = {
      service_name: "Standard Shipping",
      service_code: "STANDARD",
      total_price: "995",
      description: "Flat rate shipping",
      currency: currency,
      min_delivery_date: "",
      max_delivery_date: ""
    };

    // Check if customer data is present (logged in customer)
    if (DATA.customer && DATA.customer.id) {
      // Enrich customer data with specific metafields requirements
      // Fetch first 15 metafields from the "custom" namespace
      await enrichCustomerData(DATA, [{ namespace: "custom", size: 15 }]);

      // Check if the customer has the "VIP" tag
      // DATA.customer.tags is expected to be an array of strings
      const tags = Array.isArray(DATA.customer.tags) ? DATA.customer.tags : [];
      
      if (tags.includes("VIP")) {
        // Return Free Shipping for VIPs
        return {
          rates: [
            {
              service_name: "VIP Free Shipping",
              service_code: "VIP_FREE",
              total_price: "0",
              description: "Exclusive free shipping for VIP customers",
              currency: currency,
              min_delivery_date: "",
              max_delivery_date: ""
            }
          ]
        };
      }
    }

    // If no customer or not VIP, return the flat rate
    return {
      rates: [standardRate]
    };

  } catch (error) {
    // Log the error for debugging purposes
    console.error("Error calculating shipping rates:", error);
    
    // Return an empty rates array as a fallback to ensure a valid response structure
    return {
      rates: []
    };
  }
}