การใช้ตัวแปร Liquid ใน Shopify Flow

ตัวแปร Liquid คือตัวยึดตำแหน่งที่กำหนดใน Liquid ซึ่งจะถูกแทนที่ด้วยค่าจาก GraphQL Admin API เมื่อมีการรันเวิร์กโฟลว์ ตัวแปรสามารถอธิบายคุณลักษณะของลูกค้า คำสั่งซื้อ และสินค้าที่เกี่ยวข้องกับเวิร์กโฟลว์ของคุณได้ เช่น เลขคำสั่งซื้อ ราคาคำสั่งซื้อ หรือชื่อลูกค้า สามารถใช้ตัวแปรในเงื่อนไขเพื่อควบคุมตรรกะในเวิร์กโฟลว์ของคุณ หรือเพื่อส่งออกข้อมูลจากการดำเนินการ

การเพิ่มตัวแปรในเวิร์กโฟลว์โดยใช้ Liquid

คุณสามารถเพิ่มตัวแปรโดยใช้ Liquid ไปยังช่องข้อความใดก็ได้ที่มีลิงก์ เพิ่มตัวแปร คลิกที่ลิงก์ เพิ่มตัวแปร ใต้ช่องที่เกี่ยวข้อง จากนั้นเลือกตัวแปรจากรายการ

รูปภาพแผงการกำหนดค่าของการดำเนินการส่งอีเมลภายใน ที่ไฮไลต์ตัวเลือกเพิ่มตัวแปรใต้ช่องหัวเรื่อง

ตัวแปรในรายการ เพิ่มตัวแปร จะได้รับการกรองเพื่อให้คุณใช้เฉพาะตัวแปรที่ส่งคืนมาจากขั้นตอนก่อนหน้าขั้นตอนปัจจุบัน เช่น ทริกเกอร์ ตัวอย่างเช่น ทริกเกอร์ สร้างคำสั่งซื้อแล้ว จะมีทรัพยากรคำสั่งซื้อและร้านค้าจาก Admin API ที่สามารถแทรกเป็นตัวแปรได้ หลังจากที่คุณเลือกตัวแปรจากรายการแล้ว ตัวแปรดังกล่าวจะถูกเพิ่มลงในกล่องข้อความเป็น Liquid ที่จัดรูปแบบอย่างถูกต้อง

คุณยังสามารถเขียน Liquid ลงในช่องข้อความได้โดยตรง ตัวอย่างเช่น คุณสามารถใช้ตัวแปร {{ order.name }} เพื่อแสดงสตริงคำสั่งซื้อจากส่วนผู้ดูแล Shopify เช่น order-123

เนื่องจาก Flow ใช้ Admin API เพื่อดึงข้อมูลที่ใช้สำหรับ Liquid ไวยากรณ์ของตัวแปรจึงใช้รูปแบบ camel case ตัวแปรแบบ Camel case มีคำแรกที่ขึ้นต้นด้วยตัวพิมพ์เล็ก และคำถัดมาจะขึ้นต้นด้วยตัวพิมพ์ใหญ่ เช่น firstName หรือ canMarkAsPaid ตัวอย่างเช่น หากต้องการเข้าถึงวันที่ที่สร้างสินค้า ให้ป้อน {{ product.createdAt }} หากคุณใช้ไวยากรณ์ Liquid ในธีม Shopify ซึ่งไม่ได้ใช้รูปแบบ camel case คุณจะต้องป้อน {{ product.created_at }}

แท็ก Liquid แบบมีเงื่อนไขและการวนซ้ำ

สามารถใช้แท็ก Liquid กับตัวแปรเพื่อทำหน้าที่ต่อไปนี้ได้

  • เขียนคำสั่งแบบมีเงื่อนไข เช่น การพิจารณาว่ายอดรวมของคำสั่งซื้อมากกว่า $100 หรือไม่
  • วนซ้ำในรายการอ็อบเจกต์ เช่น การแสดงผลข้อมูลสำหรับสินค้าเฉพาะรายการแต่ละรายการในคำสั่งซื้อ

คุณสามารถใช้แท็ก Liquid เพื่อเขียนคำสั่งเหล่านี้และวนซ้ำในอ็อบเจกต์ได้

ตัวอย่างเช่น Liquid ต่อไปนี้จะแสดงเลขคำสั่งซื้อหากยอดรวมของคำสั่งซื้อมากกว่า $100

{% if order.totalPriceSet.shopMoney.amount > 100 %}
  Order number: {{ order.name }}
{% endif %}

คุณยังสามารถใช้ลูป for เพื่อวนซ้ำในรายการอ็อบเจกต์ เช่น สินค้าเฉพาะรายการสำหรับคำสั่งซื้อได้ ตัวอย่างเช่น Liquid ต่อไปนี้จะแสดงชื่อของสินค้าเฉพาะรายการแต่ละรายการในคำสั่งซื้อ

{% for li in order.lineItems %}
  {{ li.title }}
{% endfor %}

Flow รองรับแท็ก Liquid แบบมีเงื่อนไข (หรือการควบคุมโฟลว์) ดังต่อไปนี้

Flow ยังรองรับแท็ก Liquid สำหรับการวนซ้ำดังต่อไปนี้ด้วย

การใช้ตัวกรองกับตัวแปร

คุณสามารถแปลงข้อมูลตัวแปรใน Liquid โดยใช้ตัวกรองได้ Flow รองรับตัวกรอง Liquid แบบโอเพนซอร์สทั้งหมด

ตัวอย่างเช่น Liquid ต่อไปนี้จะลบคำนำหน้าออกจากชื่อคำสั่งซื้อและแสดงผลส่วนที่เหลือ {{ order.name | remove: "Order-" }}

ข้อควรพิจารณาในการใช้ตัวแปร Liquid ในตัวกรอง

ก่อนที่จะแปลงตัวแปรโดยใช้ตัวกรอง โปรดตรวจสอบข้อควรพิจารณาดังต่อไปนี้

  • Flow ไม่รองรับสัญกรณ์จุด (dot notation) ที่มีให้ใช้งานสำหรับตัวกรองบางตัว ตัวอย่างเช่น Flow รองรับ {{ order.lineItems | size }} แต่ไม่รองรับ {{ order.lineItems.size }}
  • Flow ไม่รองรับสัญกรณ์จุดสำหรับเมตาฟิลด์ ตัวอย่างเช่น คุณไม่สามารถใช้ {{ order.metafields.custom.hold_note }} ได้ แต่คุณต้องวนซ้ำในเมตาฟิลด์ตามที่ระบุไว้ในตัวอย่าง
  • Flow ไม่รองรับการใช้ดัชนีเพื่อเข้าถึงรายการในลิสต์ ตัวอย่างเช่น คุณไม่สามารถใช้ {{ order.lineItems[0].title }} ได้ แต่คุณต้องวนซ้ำในสินค้าเฉพาะรายการตามที่ระบุไว้ในตัวอย่าง

ตัวกรองวันที่

นอกเหนือจากตัวกรอง Liquid มาตรฐานแล้ว Flow ยังมีตัวกรองวันที่เพื่อรับวันที่ที่สัมพันธ์กับวันอื่นเพื่อรองรับทริกเกอร์เวลาที่กำหนดและฟีเจอร์รับข้อมูล ตัวกรองเหล่านี้ได้แก่ date_minus และ date_plus ตัวอย่างเช่น

  • เพื่อส่งคืนวันที่ในอนาคตอีกหนึ่งวัน: {{ "now" | date_plus: "1 day" }}
  • เพื่อส่งคืนวันที่ในอดีตอีกหนึ่งวัน: {{ "now" | date_minus: "1 day" }}

ตัวกรองเหล่านี้ยอมรับ second, minute, day, week, month และ year เป็นหน่วยระยะเวลา ทั้งในรูปแบบเอกพจน์ (เช่น second) และพหูพจน์ (เช่น seconds) คุณยังสามารถระบุหน่วยที่ปรับแต่งได้ประเภทต่อไปนี้

  • จำนวนเต็มที่แสดงจำนวนวินาที: {{ "now" | date_minus: 3600 }} โดยที่ 3600 เทียบเท่ากับ 1 ชั่วโมง
  • สตริงระยะเวลา ISO8601: {{ "now" | date_minus: "P1Y2D" }} โดยที่ P1Y2D หมายถึง 1 ปีกับ 2 วัน

ตัวกรองการเข้ารหัสลับ

Flow มีตัวกรองการเข้ารหัสสำหรับการ แฮช และการสร้าง รหัสยืนยันตัวตนข้อความแบบแฮช (HMAC) ตัวกรองเหล่านี้มีประโยชน์ในการสร้างตัวระบุที่ไม่ซ้ำกัน เช็คซัม หรือการผสานการทำงานกับระบบภายนอกที่ต้องใช้รูปแบบแฮชที่เฉพาะเจาะจง

ตัวกรองการแฮช

Shopify Flow รองรับตัวกรองการแฮชประเภทต่อไปนี้

  • blake3 - สร้างแฮช BLAKE3 (แนะนำให้ใช้สำหรับการใช้งานทั่วไป)
  • sha256 - สร้างแฮช SHA-256
  • sha1 - สร้างแฮช SHA-1
  • md5 - สร้างแฮช MD5

สำหรับวัตถุประสงค์การแฮชทั่วไปและการนำไปใช้ใหม่ คุณควรใช้ blake3 เนื่องจากมีประสิทธิภาพและความปลอดภัยที่เหนือกว่าเมื่อเทียบกับอัลกอริทึมรุ่นเก่า อย่างไรก็ตาม sha256 sha1 และ md5 ก็มีให้ใช้งานเพื่อให้เข้ากันได้กับระบบภายนอก

ตัวอย่างการใช้งาน: {{ "hello world" | blake3 }} จะส่งคืนแฮช BLAKE3 ของ "hello world"

ตัวกรอง HMAC

หากต้องการสร้าง HMAC ด้วยรหัสลับ ให้ใช้ตัวกรองที่รองรับต่อไปนี้

ตัวอย่างการใช้งาน

  • พื้นฐาน: {{ "message" | hmac_sha256: "secret_key" }}
  • ด้วยรหัสลับ (แนะนำ): {{ "message" | hmac_sha256: secrets.api_key }}

ตัวอย่างการใช้ตัวแปรด้วย Liquid ใน Shopify Flow

หากต้องการทำความเข้าใจวิธีใช้ตัวแปร Liquid ให้ดียิ่งขึ้น โปรดดูตัวอย่างต่อไปนี้

แสดงผล URL สำหรับแหล่งข้อมูล

คุณต้องการแสดงผล URL สำหรับลูกค้า คำสั่งซื้อ และสินค้าที่เกี่ยวข้องในเวิร์กโฟลว์

# Output the base Admin URL for your store
https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}

# Assign the base Admin url to a variable named base_url:
{%- capture base_url -%}https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}{%- endcapture -%}

# Customer from a Customer trigger:
{{ base_url }}/customers/{{ customer.legacyResourceId }}

# Customer without the base_url:
https://admin.shopify.com/store/{{ shop.myShopifyDomain | replace: ".myshopify.com", "" }}/customers/{{ customer.legacyResourceId }}

# Customer from an Order trigger:
{{ base_url }}/customers/{{ order.customer.legacyResourceId }}

# Order:
{{ base_url }}/orders/{{ order.legacyResourceId }}

# Product:
{{ base_url }}/products/{{ product.legacyResourceId }}

# Product Variant:
{{ base_url }}/products/{{ product.legacyResourceId }}/variants/{{ productVariant.legacyResourceId }}

# Example showing a clickable link in HTML, making use of the URL:
<a href="{{ base_url }}/products/{{ product.legacyResourceId }}">{{ product.title }}</a>

แปลงรายการแท็กเป็นเมตาฟิลด์

คุณต้องการแปลงชุดแท็กเป็นเมตาฟิลด์ที่เป็น รายการช่องข้อความบรรทัดเดียว โดยคุณสามารถสร้างเวิร์กโฟลว์โดยใช้ทริกเกอร์ เพิ่มสินค้าไปยังร้านค้าแล้ว และใช้การดำเนินการ อัปเดตเมตาฟิลด์ของสินค้า จากนั้นในส่วน ค่า ของการดำเนินการ อัปเดตเมตาฟิลด์ของสินค้า ให้เพิ่มโค้ด liquid ต่อไปนี้ ตัวอย่างนี้จะถือว่าคุณต้องกำหนดค่าเพียงครั้งเดียวเมื่อสร้างสินค้า และสินค้านั้นมีแท็กที่เกี่ยวข้องสองแท็ก ได้แก่ color:red และ color:orange

ตัวอย่าง Liquid เพื่อตั้งค่ารายการของช่องข้อความบรรทัดเดียว
อินพุตเอาท์พุต
{% capture mf_value %}
{%- for tags_item in product.tags -%}
  {%- if tags_item contains "color:" -%}
    "{{- tags_item | remove_first: "color:" | strip -}}",
  {%- endif -%}
{%- endfor -%}
{% endcapture -%}
[{{mf_value | remove_last: ","}}]
      
["red","orange"]

เขียนข้อความอีเมลแบบไดนามิกสำหรับคำสั่งซื้อ

คุณต้องการสร้างเวิร์กโฟลว์เพื่อส่งอีเมลถึงพนักงานเมื่อลูกค้าใช้จ่ายมากกว่า $500 ในคำสั่งซื้อ ให้คุณสร้างเวิร์กโฟลว์โดยใช้ทริกเกอร์ สร้างคำสั่งซื้อแล้ว กำหนดเงื่อนไขที่เป็นจริงหากยอดรวมของคำสั่งซื้อสูงกว่า $500 และใช้การดำเนินการ ส่งอีเมลภายใน จากนั้นในส่วน ข้อความ ของการดำเนินการ ส่งอีเมลภายใน ให้ใช้ตัวแปรต่อไปนี้

ตัวอย่างการใช้ตัวแปรเพื่อแสดงรายละเอียดลูกค้า
อินพุตเอาท์พุต
Please send a personal thank you note to {{ order.customer.firstName }} {{ order.customer.lastName }}({{ order.customer.email }}) for placing an order for $ {{ order.totalPriceSet.shopMoney.amount }}.
โปรดส่งข้อความขอบคุณเป็นการส่วนตัวถึง Jeanne Dupont (jeanne@example.com) สำหรับการสั่งซื้อเป็นจำนวน $763.42

เขียนข้อความอีเมลแบบไดนามิกสำหรับสินค้าที่ใกล้จะหมดสต็อก

คุณตัดสินใจว่าคุณต้องแจ้งให้พนักงานทราบเมื่อสินค้าคงคลังใกล้จะหมด และจำเป็นต้องสั่งซื้อเพื่อเพิ่มสต็อกสินค้า โดยคุณสร้างเวิร์กโฟลว์ที่เริ่มต้นด้วยทริกเกอร์ ปริมาณสินค้าคงคลังเปลี่ยนแปลง และตั้งเงื่อนไขที่เป็นจริงหากปริมาณสินค้าคงคลังก่อนหน้านี้น้อยกว่าหรือเท่ากับ 10 จากนั้นในส่วน ข้อความ ของการดำเนินการ ส่งอีเมลภายใน ให้ใช้ตัวแปรต่อไปนี้

ตัวอย่างการใช้ตัวแปรเพื่อแสดงรายละเอียดสินค้าเฉพาะรายการ
อินพุตเอาท์พุต
Please reorder {{ product.title }}. Email owner@store.com to verify that they've received the purchase order.
โปรดสั่งซื้อกางเกงเลกกิ้งเอวสูง - สีดำซ้ำ โปรดส่งอีเมลไปที่ owner@example.com เพื่อยืนยันว่าได้รับคำสั่งซื้อแล้ว

เขียนข้อความอีเมลแบบไดนามิกเพื่อแจ้งเตือนพนักงานเกี่ยวกับคำสั่งซื้อจากการฉ้อโกง

คุณต้องการยกเลิกคำสั่งซื้อที่มีระดับความเสี่ยงสูง แต่ต้องการให้พนักงานของคุณยกเลิกคำสั่งซื้อด้วยตนเอง ให้คุณสร้างเวิร์กโฟลว์ที่เริ่มต้นด้วยทริกเกอร์ สร้างคำสั่งซื้อแล้ว และตั้งเงื่อนไขที่เป็นจริงถ้าระดับความเสี่ยงของคำสั่งซื้อเท่ากับสูง จากนั้นในส่วน ข้อความ ของการดำเนินการ ส่งอีเมลภายใน ให้คุณใช้ตัวแปรต่อไปนี้

ตัวอย่างการใช้ตัวแปรเพื่อให้ข้อมูลเกี่ยวกับคำสั่งซื้อจากการฉ้อโกง
อินพุตเอาท์พุต
Our Shopify store has received an order with a high risk of fraud. We would like to cancel this order right away, before it is sent to production:
{{ order.name }} {{ order.billingAddress.lastName }}, {{ order.billingAddress.firstName }} {{ order.email }}
Please confirm the new order status. Thanks!
ร้านค้า Shopify ของเราได้รับคำสั่งซื้อที่มีความเสี่ยงสูงในการทุจริต เราต้องการยกเลิกคำสั่งซื้อนี้ทันทีก่อนที่จะส่งไปยังฝ่ายผลิต:

#1001
Dupont, Jeanne
jeanne@example.com

โปรดยืนยันสถานะคำสั่งซื้อใหม่ ขอบคุณ

แสดงผลสินค้าเฉพาะรายการของคำสั่งซื้อโดยใช้ for loop

เมื่อได้รับคำสั่งซื้อ การส่งข้อความที่มีรายการสินค้าที่สั่งซื้ออาจเป็นประโยชน์ คุณสามารถทำได้โดยใช้ for loop ซึ่งจะดำเนินการชุดคำสั่งซ้ำๆ ช่องข้อความที่รองรับตัวแปรยังรองรับ for loop และอ็อบเจกต์ forloop อีกด้วย

ตัวอย่างเช่น หากคุณต้องการสร้างขั้นตอนการทำงานที่ส่งคืนรายการ SKU และจำนวนทั้งหมดในคำสั่งซื้อ ให้ใช้ตัวแปรต่อไปนี้ในส่วนข้อความของการดำเนินการส่งอีเมลภายใน

ตัวอย่างการใช้ for loop เพื่อระบุข้อมูลคำสั่งซื้อ
อินพุตเอาท์พุต
Order summary:
{% for a in order.lineItems %}
  {{a.sku}} ( {{a.quantity}} )
{% endfor %}
สรุปคำสั่งซื้อ:
8987097979 (50)
8877778887 (3)
888998898B (1)

การแสดงผลลัพธ์สินค้าเฉพาะรายการสำหรับคำสั่งซื้อโดยใช้ for loop พร้อมข้อมูลเพิ่มเติม

หากคุณต้องการเพิ่มข้อมูลเพิ่มเติมลงในอีเมล เช่น ชื่อสินค้า SKU ราคาต่อรายการ และข้อมูลการจัดส่งของลูกค้า ให้ใช้ตัวแปรต่อไปนี้ในส่วนข้อความของการดำเนินการส่งอีเมลภายใน

ตัวอย่างการใช้ for loop เพื่อระบุข้อมูลคำสั่งซื้อที่ครอบคลุมยิ่งขึ้น
อินพุตเอาท์พุต
Order summary:
{% for a in order.lineItems %}
  Product: {{a.title}}
  SKU: {{a.sku}}
  Price (per unit): ${{a.originalUnitPriceSet.shopMoney.amount}}
  Quantity: {{a.quantity}}
{% endfor %}
สรุปคำสั่งซื้อ:
สินค้า: High Waist Leggings - Black
SKU: 8987097979
ราคา (ต่อหน่วย): $8.49
จำนวน: 5
สินค้า: Athletic Socks - Blue
SKU: 888998898B
ราคา (ต่อหน่วย): $5.61
จำนวน: 2

การแสดงผลลัพธ์สินค้าเฉพาะรายการบางส่วนโดยการรวม for loop เข้ากับคำสั่ง if

หากคุณต้องการติดตามรายการที่ขายซึ่งมาจากผู้ขายรายใดรายหนึ่ง ให้ใช้ตัวแปรต่อไปนี้ในส่วนข้อความของการดำเนินการส่งอีเมลภายใน และใส่คำสั่ง if ไว้ใน for loop ของคุณ

ตัวอย่างการใช้ for loop และคำสั่ง if เพื่อระบุข้อมูลคำสั่งซื้อสำหรับผู้ขายรายที่ระบุ
อินพุตเอาท์พุต
Acme product sold:
{% for x in order.lineItems %}
  {% if x.vendor == 'acme-vendor' %}
    Product name: {{x.title}}
    SKU: {{x.sku}}
  {% endif %}
{% endfor %}
สินค้า Acme ที่ขายได้:
ชื่อสินค้า: High Waist Leggings - Black
SKU: 8987097979

ออบเจ็กต์ข้อมูลที่ซับซ้อนใน Shopify Flow

Flow ช่วยให้คุณสามารถเข้าถึงข้อมูลเกือบทุกอย่างที่อยู่ใน GraphQL Admin API ได้ ซึ่งรวมถึงออบเจ็กต์ข้อมูลที่ซับซ้อน เช่น รายการและออบเจ็กต์ อย่างไรก็ตาม สิ่งที่คุณสามารถทำได้กับออบเจ็กต์เหล่านี้มีข้อจำกัดบางประการ ส่วนนี้จะสรุปข้อจำกัดเหล่านี้และแสดงตัวอย่างวิธีการใช้งาน

แทนที่จะเรียกใช้รายการและออบเจ็กต์โดยตรง คุณควรวนลูปไปตามรายการและระบุเฉพาะช่องข้อมูลที่คุณต้องการ

ตัวอย่างเช่น แทนที่จะเรียกใช้ {{ order.lineItems }} โดยตรง ให้ใช้รูปแบบต่อไปนี้เพื่อเรียกใช้ช่องข้อมูลที่ระบุ ตัวอย่างเหล่านี้ประกอบด้วยช่องข้อมูลทั้งหมดที่จะรวมอยู่ด้วยหากมีการเรียกใช้รายการหรือออบเจ็กต์โดยตรง คัดลอกและวางช่องข้อมูลที่คุณต้องการ

ข้อความ
{% for li in order.lineItems %}
    {% comment %}li.contract - omitted{% endcomment %}

{% for ca in li.customAttributes %}
    {{ ca.key }}
    {{ ca.value }}
{% endfor %}

{% for da in li.discountAllocations %}
    {{ da.allocatedAmountSet.presentmentMoney.amount }}
    {{ da.allocatedAmountSet.presentmentMoney.currencyCode }}
    {{ da.allocatedAmountSet.shopMoney.amount }}
    {{ da.allocatedAmountSet.shopMoney.currencyCode }}
{% endfor %}

{{ li.discountedTotalSet.presentmentMoney.amount }}
{{ li.discountedTotalSet.presentmentMoney.currencyCode }}
{{ li.discountedTotalSet.shopMoney.amount }}
{{ li.discountedTotalSet.shopMoney.currencyCode }}

{{ li.discountedUnitPriceSet.presentmentMoney.amount }}
{{ li.discountedUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.discountedUnitPriceSet.shopMoney.amount }}
{{ li.discountedUnitPriceSet.shopMoney.currencyCode }}

{% comment %}li.duties - omitted {% endcomment %}

{{ li.fulfillableQuantity }}

{{ li.fulfillmentService.callbackUrl }}
{{ li.fulfillmentService.fulfillmentOrdersOptIn }}
{{ li.fulfillmentService.handle }}
{{ li.fulfillmentService.id }}
{{ li.fulfillmentService.inventoryManagement }}
{% comment %}rest of location omitted{% endcomment %}
{{ li.fulfillmentService.location.name }}
{{ li.fulfillmentService.productBased }}
{{ li.fulfillmentService.serviceName }}
{% for sm in li.fulfillmentService.shippingMethods %}
    {{ sm.code }}
    {{ sm.label }}
{% endfor %}
{{ li.fulfillmentService.type }}

{{ li.fulfillmentStatus }}
{{ li.id }}

{{ li.image.altText }}
{{ li.image.height }}
{{ li.image.id }}
{% comment %}li.image.metafield omitted{% endcomment %}
{% comment %}li.image.privateMetafield omitted{% endcomment %}
{{ li.image.width }}

{{ li.merchantEditable }}
{{ li.name }}
{{ li.nonFulfillableQuantity }}

{{ li.originalTotalSet.presentmentMoney.amount }}
{{ li.originalTotalSet.presentmentMoney.currencyCode }}
{{ li.originalTotalSet.shopMoney.amount }}
{{ li.originalTotalSet.shopMoney.currencyCode }}

{{ li.originalUnitPriceSet.presentmentMoney.amount }}
{{ li.originalUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.originalUnitPriceSet.shopMoney.amount }}
{{ li.originalUnitPriceSet.shopMoney.currencyCode }}

{% comment %}rest of product omitted{% endcomment %}
{{ li.product.title }}

{{ li.quantity }}
{{ li.refundableQuantity }}
{{ li.requiresShipping }}
{{ li.restockable }}

{{ li.sellingPlan.name }}

{{ li.sku }}

{% for tl in li.taxLines %}
    {{ tl.priceSet.presentmentMoney.amount | json }}
    {{ tl.priceSet.presentmentMoney.currencyCode | json }}
    {{ tl.priceSet.shopMoney.amount | json }}
    {{ tl.priceSet.shopMoney.currencyCode | json }}
    {{ tl.rate | json }}
    {{ tl.ratePercentage | json }}
    {{ tl.title | json }}
{% endfor %}

{{ li.taxable }}
{{ li.title }}

{{ li.totalDiscountSet.presentmentMoney.amount }}
{{ li.totalDiscountSet.presentmentMoney.currencyCode }}
{{ li.totalDiscountSet.shopMoney.amount }}
{{ li.totalDiscountSet.shopMoney.currencyCode }}

{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode }}

{{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode }}

{{ li.unfulfilledQuantity }}

{% comment %}rest of variant omitted{% endcomment %}
{{ li.variant.title }}

{{ li.variantTitle }}
{{ li.vendor }}

{% endfor %}

json
{
    "lineItems": [
        {% for li in order.lineItems %}
            {% if forloop.first != true %},{% endif %}
        {
            "contract": {
                {% comment %}rest of contract omitted{% endcomment %}
                "id": {{ li.contract.id | json }}
            },
            "customAttributes": [
                {% for ca in li.customAttributes %}
                    {% if forloop.first != true %},{% endif %}
                    {
                        "key":{{ ca.key | json }},
                        "value":{{ ca.value | json }}
                    }
                {% endfor %}
            ],
&#x22;discountAllocations&#x22;: [
            {% for da in li.discountAllocations %}
                {% if forloop.first != true %},{% endif %}
                &#x22;allocatedAmountSet&#x22;: {
                    &#x22;presentmentMoney&#x22; : {
                        &#x22;amount&#x22;: {{ da.allocatedAmountSet.presentmentMoney.amount | json }},
                        &#x22;currencyCode&#x22;: {{ da.allocatedAmountSet.presentmentMoney.currencyCode | json }}
                    },
                    &#x22;shopMoney&#x22;: {
                        &#x22;amount&#x22;: {{ da.allocatedAmountSet.shopMoney.amount | json }},
                        &#x22;currencyCode&#x22;: {{ da.allocatedAmountSet.shopMoney.currencyCode | json }}
                    }
                }
            {% endfor %}
        ],

        &#x22;discountedTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.discountedTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.discountedTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;discountedUnitPriceSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.discountedUnitPriceSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedUnitPriceSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.discountedUnitPriceSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.discountedUnitPriceSet.shopMoney.currencyCode | json }}
            }
        },
        &#x22;duties&#x22;: [
            {% for duty li.duties %}
            {% if forloop.first != true %},{% endif %}
            {
                {% comment %}rest of duties omitted{% endcomment %}
                &#x22;id&#x22;: {{ duty.id | json }}
            }
            {% endfor %}
        ],
        &#x22;fulfillableQuantity&#x22;: {{ li.fulfillableQuantity | json }},

        &#x22;fulfillmentService&#x22;: {
            &#x22;callbackUrl&#x22;:{{ li.fulfillmentService.callbackUrl | json }},
            &#x22;fulfillmentOrdersOptIn&#x22;: {{ li.fulfillmentService.fulfillmentOrdersOptIn | json }},
            &#x22;handle&#x22;: {{ li.fulfillmentService.handle | json }},
            &#x22;id&#x22;: {{ li.fulfillmentService.id | json }},
            &#x22;inventoryManagement&#x22;: {{ li.fulfillmentService.inventoryManagement | json }},
            {% comment %}fulfillmentService.inventoryManagement - omitted {% endcomment %}
            &#x22;productBased&#x22;: {{ li.fulfillmentService.productBased | json }},
            &#x22;serviceName&#x22;: {{ li.fulfillmentService.serviceName | json }},
            &#x22;shippingMethods&#x22;: [
                {% for sm in li.fulfillmentService.shippingMethods %}
                    {% if forloop.first != true %},{% endif %}
                    {
                        &#x22;code&#x22;: {{ sm.code | json }},
                        &#x22;label&#x22;: {{ sm.label | json }}
                    }
                {% endfor %}
            ],
            &#x22;type&#x22;: {{ li.fulfillmentService.type | json }}

        },
        &#x22;fulfillmentStatus&#x22;: {{ li.fulfillmentStatus | json }},
        &#x22;id&#x22;: {{ li.id | json }},
        &#x22;image&#x22;: {
            &#x22;altText&#x22;: {{ li.image.altText | json }},
            &#x22;height&#x22;: {{ li.image.height | json }},
            &#x22;id&#x22;: {{ li.image.id | json }},
            {% comment %}li.image.metafield omitted{% endcomment %}
            {% comment %}li.image.privateMetafield omitted{% endcomment %}
            &#x22;width&#x22;:{{ li.image.width | json }}
        },
        &#x22;merchantEditable&#x22;: {{ li.merchantEditable | json }},
        &#x22;name&#x22;: {{ li.name | json }},
        &#x22;nonFulfillableQuantity&#x22;: {{ li.nonFulfillableQuantity | json }},

        &#x22;originalTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.originalTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.originalTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;originalUnitPriceSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.originalUnitPriceSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalUnitPriceSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.originalUnitPriceSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.originalUnitPriceSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;product&#x22;: {
            {% comment %}rest of Product omitted{% endcomment %}
            &#x22;title&#x22;: {{ li.product.title | json }}
        },

        &#x22;quantity&#x22;: {{ li.quantity | json }},
        &#x22;refundableQuantity&#x22;: {{ li.refundableQuantity | json }},
        &#x22;requiresShipping&#x22;: {{ li.requiresShipping | json }},
        &#x22;restockable&#x22;: {{ li.restockable | json }},

        &#x22;sellingPlan&#x22;: {
            &#x22;name&#x22;: {{ li.sellingPlan.name | json }}
        },

        &#x22;sku&#x22;: {{ li.sku | json }},

        &#x22;taxLines&#x22;: [
            {% for tl in li.taxLines %}
                {% if forloop.first != true %},{% endif %}
                {
                    &#x22;priceSet&#x22;: {
                        &#x22;presentmentMoney&#x22; : {
                            &#x22;amount&#x22;: {{ tl.priceSet.presentmentMoney.amount | json }},
                            &#x22;currencyCode&#x22;: {{ tl.priceSet.presentmentMoney.currencyCode | json }}
                        },
                        &#x22;shopMoney&#x22;: {
                            &#x22;amount&#x22;: {{ tl.priceSet.shopMoney.amount | json }},
                            &#x22;currencyCode&#x22;: {{ tl.priceSet.shopMoney.currencyCode | json }}
                        }
                    },
                    &#x22;rate&#x22;: {{ tl.rate | json }},
                    &#x22;ratePercentage&#x22;: {{ tl.ratePercentage | json }},
                    &#x22;title&#x22;: {{ tl.title | json }}
                }
            {% endfor %}
        ],
        &#x22;taxable&#x22;:{{ li.taxable | json }},
        &#x22;title&#x22;:{{ li.title | json }},

        &#x22;totalDiscountSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.totalDiscountSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.totalDiscountSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.totalDiscountSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.totalDiscountSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;unfulfilledDiscountedTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.unfulfilledDiscountedTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;unfulfilledOriginalTotalSet&#x22;: {
            &#x22;presentmentMoney&#x22; : {
                &#x22;amount&#x22;: {{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode | json }}
            },
            &#x22;shopMoney&#x22;: {
                &#x22;amount&#x22;: {{ li.unfulfilledOriginalTotalSet.shopMoney.amount | json }},
                &#x22;currencyCode&#x22;: {{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode | json }}
            }
        },

        &#x22;unfulfilledQuantity&#x22;: {{ li.unfulfilledQuantity | json }},

        &#x22;variant&#x22;: {
            {% comment %}rest of variant omitted {% endcomment %}
            &#x22;title&#x22;: {{ li.variant.title | json }}
        },

        &#x22;variantTitle&#x22;: {{ li.variantTitle | json }},
        &#x22;vendor&#x22;: {{ li.vendor | json }}
    }
{% endfor %}
]

}