Skip to Content

Order mapping

Orders are the heaviest resource. StagingOrder mixes flat fields (addresses split into shipping_address1 etc., a single discount shape) with nested pass-through arrays for line items, transactions, tax lines, and shipping lines.

Quick reference — minimum loadable order

{ "original_id": increment_id, "name": "#" & $string(increment_id), "email": customer_email, "processedAt": created_at, "currency": order_currency, "financialStatus": "PAID", "lineItems": items.{ "title": name, "sku": sku, "quantity": qty_ordered, "priceSet": { "shopMoney": { "amount": $string(price), "currencyCode": $$.order_currency } } } }

processedAt is critical. If you omit it, the order’s “created at” defaults to load time, breaking historical reports. Always emit it from the source’s order timestamp.

Identity & status

namestring

Order display name (e.g. #1042). Customers and merchants see this.

"name": "#" & $string(increment_id)
emailstring

Order contact email — used for notifications. Falls back to the customer’s email if omitted.

phonestring

Order contact phone.

processedAtstring (ISO8601)

When the order was placed on the source platform. Always emit this on historical orders so the timeline is preserved.

"processedAt": created_at
closedAtstring (ISO8601)

When the order was closed (typically equal to processedAt for fully-fulfilled historical orders).

financialStatusstring

One of PENDING, AUTHORIZED, PARTIALLY_PAID, PAID, PARTIALLY_REFUNDED, REFUNDED, VOIDED.

"financialStatus": is_paid ? "PAID" : "PENDING"
fulfillmentStatusstring

One of FULFILLED, PARTIALLY_FULFILLED, RESTOCKED. Omit for unfulfilled orders.

taxesIncludedboolean

true if line item prices already include tax (common in EU merchants), false if tax is added on top (common in US).

buyerAcceptsMarketingboolean
sourceIdentifierstring

The original platform’s order ID — preserves cross-system traceability. Often the same as original_id for orders.

sourceNamestring

Where the order originated (e.g. web, pos, magento).

Currency

currencystring

ISO 4217 currency code for the shop’s base currency on this order. Used inside priceSet.shopMoney.currencyCode of every line item.

"currency": order_currency
presentmentCurrencystring

The currency the customer saw at checkout, if multi-currency. Often equal to currency for single-currency orders.

Customer

The order's customer is composed from these fields. The staging model assembles them into Shopify's customer.toUpsert shape.

firstNamestring

Used on the order’s customer record AND on shipping/billing addresses.

lastNamestring
customerNotestring

Note attached to the customer on this order. Different from note (below), which is the order-level admin note.

customerTagsstring[]

Tags attached to the customer (not the order).

Shipping address (flat)

Shopify nests its address shapes; the staging model flattens them. Setting shipping_address1 is what triggers the shipping address being attached.

shipping_address1string
"shipping_address1": shipping.street
shipping_address2string
shipping_citystring
shipping_provincestring

State / province.

shipping_countrystring

Country code (ISO 3166-1 alpha-2 preferred).

shipping_zipstring

Billing address (flat)

Same shape as shipping, with a billing_ prefix. Setting billing_address1 triggers the billing address.

billing_address1string
billing_address2string
billing_citystring
billing_provincestring
billing_countrystring
billing_zipstring

Line items (nested pass-through)

Each line item is a Shopify-shaped object. The staging model validates each one and rejects malformed entries early.

lineItemsLineItem[]required

Array of order line items. Each entry has the same shape Shopify’s OrderCreateLineItemInput accepts:

FieldNotes
titleProduct name as it was at purchase.
quantityint. Required per line.
skuVariant SKU at purchase.
variantIdShopify variant GID, if known. Omit and Graftport resolves via original_id matching after the products migrate.
priceSet{ shopMoney: { amount: string, currencyCode } } — money is always strings.
taxLinesPer-line-item tax breakdown.
taxable / requiresShippingBooleans.
propertiesArray of { name, value } for line-item customizations.
vendorSnapshotted vendor name.
weightSnapshotted weight.
"lineItems": items.{ "title": name, "sku": sku, "quantity": qty_ordered, "priceSet": { "shopMoney": { "amount": $string(price), "currencyCode": $$.order_currency } } }

Discounts (flat — pick one)

Set exactly one discount field. The staging model wires it into Shopify's discount-code shape with a placeholder code.

itemPercentageDiscountnumber

Percentage off as a number 0-100 (25 = 25%). Applied to qualifying items.

"itemPercentageDiscount": discount_percent
itemFixedDiscountnumber

Fixed money amount off (in the order’s currency). Rounded to 2 decimals.

freeShippingDiscountboolean

true if the order had a free-shipping discount.

Fulfillment (flat)

Setting locationId is what triggers the fulfillment record. Without locationId, no fulfillment is created — even if you set the other fields.

locationIdstring

The Shopify location GID this order ships from. Required to create a fulfillment.

"locationId": $$.config.default_location_gid
notifyCustomerboolean

Whether to send a fulfillment notification email when the load creates the fulfillment. Default behavior is Shopify’s (no email for migrated orders is usually right).

trackingCompanystring

Carrier name (e.g. UPS, DHL).

trackingNumberstring
shipmentStatusstring

One of Shopify’s shipment statuses (e.g. DELIVERED, IN_TRANSIT).

Transactions (nested pass-through)

transactionsTransaction[]

Array of payment transactions. Each entry follows Shopify’s OrderCreateOrderTransactionInput shape:

FieldNotes
kindSALE, AUTHORIZATION, CAPTURE, REFUND, VOID, CHANGE.
statusSUCCESS, FAILURE, PENDING, ERROR.
amountSetMoney bag — { shopMoney: { amount, currencyCode } }.
gatewayPayment processor name.
processedAtISO8601.
"transactions": [{ "kind": "SALE", "status": "SUCCESS", "gateway": payment_method, "processedAt": created_at, "amountSet": { "shopMoney": { "amount": $string(grand_total), "currencyCode": order_currency } } }]

Tax & shipping lines (nested pass-through)

taxLinesTaxLine[]

Order-level tax breakdown. Each entry is { title, rate, priceSet }. Mixing order-level and line-item-level tax lines double-counts the total — pick one consistently per merchant.

shippingLinesShippingLine[]

Shipping methods used on the order. Each entry is { title, priceSet }.

"shippingLines": [{ "title": shipping_method, "priceSet": { "shopMoney": { "amount": $string(shipping_amount), "currencyCode": order_currency } } }]

Custom attributes & notes

dict_customAttributesobject

Free-form { key, value } map of order-level custom attributes (notes from checkout, gift options, custom forms). Each entry becomes one Shopify custom attribute.

"dict_customAttributes": { "gift_message": gift_message, "preferred_delivery": delivery_window }
notestring

Order-level admin note (separate from customerNote).

tagsstring[] | string

Order-level tags.

Patterns

Magento order — minimum viable

{ "original_id": increment_id, "name": "#" & increment_id, "email": customer_email, "phone": billing_address.telephone, "firstName": customer_firstname, "lastName": customer_lastname, "processedAt": created_at, "currency": order_currency_code, "presentmentCurrency": order_currency_code, "financialStatus": "PAID", "taxesIncluded": false, "shipping_address1": shipping_address.street[0], "shipping_city": shipping_address.city, "shipping_province": shipping_address.region_code, "shipping_country": shipping_address.country_id, "shipping_zip": shipping_address.postcode, "billing_address1": billing_address.street[0], "billing_city": billing_address.city, "billing_country": billing_address.country_id, "billing_zip": billing_address.postcode, "lineItems": items.{ "title": name, "sku": sku, "quantity": qty_ordered, "priceSet": { "shopMoney": { "amount": $string(price), "currencyCode": $$.order_currency_code } } }, "transactions": [{ "kind": "SALE", "status": "SUCCESS", "gateway": payment.method, "processedAt": created_at, "amountSet": { "shopMoney": { "amount": $string(grand_total), "currencyCode": order_currency_code } } }] }

Order with a percentage discount

{ "original_id": increment_id, …, "itemPercentageDiscount": discount_percent }

The staging model wires this into a Shopify discount code with a placeholder code (migration_placeholder_percentage_code) — the discount applies to the order, but no real coupon code is created.

Order with shipping fulfillment

{ "original_id": increment_id, …, "locationId": $$.config.default_location_gid, "trackingCompany": shipment.carrier, "trackingNumber": shipment.tracking_number, "shipmentStatus": shipment.status = "delivered" ? "DELIVERED" : "IN_TRANSIT" }

Capture custom checkout fields

"dict_customAttributes": { "gift_message": gift_message, "delivery_instructions": delivery_notes, "purchase_order": po_number }

Gotchas

Money amounts are strings inside priceSet. amount: 19.99 fails; amount: "19.99" works. Wrap with $string().

  • processedAt is critical for historical orders. Without it, the order shows up as created today.
  • Variants must exist before orders. Run the products load before the orders load — otherwise lineItems can’t resolve to Shopify variant IDs and lose their product link.
  • Discount codes are placeholders. Setting itemPercentageDiscount doesn’t create a real reusable code on Shopify — it applies the discount to this single order with a generated placeholder. Use the discount code resource for real reusable codes.
  • Tax lines at order level vs line-item level: don’t mix. Pick one consistent level per merchant.
  • Currency consistency. Top-level currency and the currencyCode inside every priceSet.shopMoney must match for single-currency orders.
  • shipping_address1 is the trigger — without it, no shipping address is created even if you set city/zip/country.
  • Fulfillment requires locationId. Setting trackingNumber alone produces no fulfillment record.
Last updated on