Vue Storefront is now Alokai! Learn More
Order normalizer

Order normalizer

  • normalizeOrder: This function is used to map BigCommerce OrderByCartResponse into SfOrder, which includes order details data.
  • normalizeOrderListItem: This function maps BigCommerce Order into Unified SfOrderListItem which includes only basic order details, used to display data in an order list.

Parameters

normalizeOrder

NameTypeDefault valueDescription
contextNormalizerContextContext which contains e.g. currency
inputOrderByCartResponseBigCommerce OrderByCartResponse

normalizeOrderListItem

NameTypeDefault valueDescription
contextNormalizerContextContext which contains e.g. currency
orderOrderBigCommerce Order

normalizeOrderLineItem

NameTypeDefault valueDescription
contextNormalizerContextContext which contains e.g. currency
lineItemOrderItemBigCommerce Order Item

Extending

The SfOrder is returned from the GetOrders Method. If the SfOrder structure doesn't contain the information you need for your Storefront, you can extend its logic using the addCustomFields API. The following example demonstrates how to extend SfOrder with a staffNotes field.

export const unifiedApiExtension = createUnifiedExtension({
  normalizers: {
    addCustomFields: [
      {
        normalizeOrder: (context, order) => ({
          staffNotes: order.staff_notes,
        }),
      },
    ],
  },
  config: {
    ...
  },
});

You can override the normalizeOrder, but it's also available to override the smaller normalizers such as normalizeAddress, normalizeShippingMethod.

Source

order.ts
import { z } from "zod";

import { defineNormalizer } from "../defineNormalizer";

const orderSchema = z.object({
  billing_address: z.looseObject({}),
  date_created: z.string().min(1, "Order date is required"),
  id: z.number(),
  products: z.array(z.looseObject({})).min(1, "At least one product is required"),
  shipping_addresses: z.tuple([
    z.looseObject({
      shipping_method: z.string().min(1, "Shipping method is required"),
    }),
  ]),
  shipping_cost_inc_tax: z.string(),
  status: z.string().optional(),
  subtotal_ex_tax: z.string(),
  total_inc_tax: z.string(),
  total_tax: z.string(),
});

export const normalizeOrder = defineNormalizer.normalizeOrder((context, input) => {
  let validated;
  try {
    validated = orderSchema.parse(input);
  } catch (error) {
    throw new Error("Missing required order fields", { cause: error });
  }

  const lineItems = validated.products.map((entry) =>
    context.normalizers.normalizeOrderLineItem(entry),
  );

  return {
    billingAddress: context.normalizers.normalizeAddress(validated.billing_address),
    id: validated.id.toString(),
    lineItems,
    orderDate: new Date(validated.date_created).toISOString(),
    paymentMethod: "CARD",
    shippingAddress: context.normalizers.normalizeAddress(validated.shipping_addresses[0]),
    shippingMethod: context.normalizers.normalizeShippingMethod({
      name: validated.shipping_addresses[0].shipping_method,
      price: validated.shipping_cost_inc_tax,
    }),
    status: validated.status ?? "UNKNOWN",
    subtotalPrice: context.normalizers.normalizeMoney(Number.parseFloat(validated.subtotal_ex_tax)),
    totalPrice: context.normalizers.normalizeMoney(Number.parseFloat(validated.total_inc_tax)),
    totalShippingPrice: context.normalizers.normalizeMoney(
      Number.parseFloat(validated.shipping_cost_inc_tax),
    ),
    totalTax: context.normalizers.normalizeMoney(Number.parseFloat(validated.total_tax)),
  };
});