Liquid-Variablen in Shopify Flow verwenden

Liquid-Variablen sind in Liquid definierte Platzhalter, die beim Durchlauf eines Workflows durch Werte aus der GraphQL Admin API ersetzt werden. Variablen können die Attribute der Kund:innen, Bestellungen und Produkte beschreiben, die in deinen Workflows involviert sind, wie etwa die Bestellnummer, den Bestellpreis oder den Kundennamen. Variablen können in Bedingungen verwendet werden, um die Logik in deinem Workflow zu steuern, oder um Daten aus einer Aktion auszugeben.

Variablen in Workflows mit Liquid hinzufügen

Du kannst Liquid-Variablen zu jedem Textfeld hinzufügen, das den Link Variable hinzufügen enthält. Klicke auf den Link Variable hinzufügen unter dem entsprechenden Feld und wähle dann eine Variable aus der Liste aus.

Bild des Konfigurationsfensters der Aktion „Interne E-Mail senden“, wobei die Option „Variable hinzufügen“ unter dem Feld „Betreff“ hervorgehoben ist.

Die Variablen in der Liste Variable hinzufügen sind gefiltert, sodass du nur Variablen verwendest, die von Schritten vor dem aktuellen Schritt – z. B. von Triggern – zurückgegeben werden. Der Trigger Bestellung erstellt stellt beispielsweise Bestell- und Shop-Ressourcen aus der Admin API bereit, die als Variablen eingefügt werden können. Nachdem du eine Variable aus der Liste ausgewählt hast, wird sie dem Textfeld als korrekt formatiertes Liquid hinzugefügt.

Du kannst Liquid auch direkt in das Textfeld schreiben. Beispielsweise kannst du die Variable {{ order.name }} verwenden, um den Bestell-String aus dem Shopify-Adminbereich anzuzeigen, z. B. order-123.

Da Flow die Admin API verwendet, um die für Liquid genutzten Daten abzurufen, verwendet die Variablensyntax Camel-Case. Bei Camel-Case-Variablen beginnt das erste Wort mit einem Kleinbuchstaben und die nachfolgenden Wörter beginnen mit einem Großbuchstaben, wie z. B. bei firstName oder canMarkAsPaid. Um beispielsweise auf das Erstellungsdatum eines Produkts zuzugreifen, gib {{ product.createdAt }} ein. Wenn du die Liquid-Syntax in einem Shopify-Theme verwendest, das kein Camel-Case nutzt, würdest du {{ product.created_at }} eingeben.

Bedingte und iterative Liquid-Tags

Liquid-Tags können zusammen mit Variablen verwendet werden, um die folgenden Funktionen auszuführen:

  • Bedingte Anweisungen schreiben, z. B. um festzustellen, ob eine Bestellsumme größer als 100 USD ist.
  • Eine Liste von Objekten durchlaufen, z. B. um Daten für jede Position in einer Bestellung auszugeben.

Du kannst Liquid-Tags verwenden, um diese Anweisungen zu schreiben und Objekte zu durchlaufen.

Das folgende Liquid zeigt beispielsweise die Bestellnummer an, wenn die Bestellsumme größer als 100 USD ist:

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

Du kannst auch eine For-Schleife verwenden, um eine Liste von Objekten, wie z. B. Positionen einer Bestellung, zu durchlaufen. Das folgende Liquid zeigt beispielsweise den Namen jeder Position in einer Bestellung an:

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

Flow unterstützt die folgenden bedingten (oder Kontrollfluss-)Liquid-Tags:

Flow unterstützt außerdem die folgenden iterativen Liquid-Tags:

Filter auf Variablen anwenden

Du kannst Variablendaten in Liquid mithilfe von Filtern umwandeln. Flow unterstützt alle Open-Source-Liquid-Filter.

Das folgende Liquid entfernt beispielsweise ein Präfix aus einem Bestellnamen und gibt den Rest aus: {{ order.name | remove: "Order-" }}

Überlegungen zur Verwendung von Liquid-Variablen in Filtern

Bevor du Variablen mit Filtern umwandelst, beachte die folgenden Überlegungen:

  • Flow unterstützt keine Punktnotation, die für einige Filter verfügbar ist. Flow unterstützt beispielsweise {{ order.lineItems | size }}, aber nicht {{ order.lineItems.size }}.
  • Flow unterstützt keine Punktnotation für Metafelder. Du kannst beispielsweise nicht {{ order.metafields.custom.hold_note }} verwenden. Stattdessen musst du die Metafelder wie in den Beispielen beschrieben durchlaufen.
  • Flow unterstützt nicht die Verwendung von Indizes für den Zugriff auf Artikel in einer Liste. Du kannst beispielsweise nicht {{ order.lineItems[0].title }} verwenden. Stattdessen musst du die Positionen wie in den Beispielen beschrieben durchlaufen.

Datumsfilter

Zusätzlich zu den standardmäßigen Liquid-Filtern stellt Flow Datumsfilter bereit, um ein Datum relativ zu einem anderen Datum zu erhalten und so die Trigger-Funktionen Geplante Zeit und Daten abrufen zu unterstützen. Diese Filter sind: date_minus und date_plus. Zum Beispiel:

  • So gibst du ein Datum einen Tag in der Zukunft zurück: {{ "now" | date_plus: "1 day" }}
  • So gibst du ein Datum einen Tag in der Vergangenheit zurück: {{ "now" | date_minus: "1 day" }}

Diese Filter akzeptieren second, minute, day, week, month und year als Zeiteinheit, sowohl im Singular (z. B. second) als auch im Plural (z. B. seconds). Du kannst auch die folgenden Arten von anpassbaren Einheiten angeben:

  • Eine Ganzzahl, die die Anzahl der Sekunden darstellt: {{ "now" | date_minus: 3600 }}, wobei 3600 einer Stunde entspricht.
  • Ein ISO 8601-Dauerstring: {{ "now" | date_minus: "P1Y2D" }}, wobei P1Y2D für 1 Jahr und 2 Tage steht.

Kryptografische Filter

Flow bietet kryptografische Filter für das Hashing und die Erstellung von Hash-basierten Nachrichtenauthentifizierungscodes (HMACs). Diese Filter sind nützlich, um eindeutige IDs, Prüfsummen oder Integrationen mit externen Systemen zu erstellen, die bestimmte Hash-Formate erfordern.

Hashing-Filter

Shopify Flow unterstützt die folgenden Arten von Hashing-Filtern:

  • blake3 – Erstellt einen BLAKE3-Hash (empfohlen für die allgemeine Verwendung).
  • sha256 – Erstellt einen SHA-256-Hash.
  • sha1 – Erstellt einen SHA-1-Hash.
  • md5 – Erstellt einen MD5-Hash.

Für allgemeine Hashing-Zwecke und neue Implementierungen solltest du `blake3` verwenden, da es im Vergleich zu älteren Algorithmen eine höhere Leistung und Sicherheit bietet. `sha256`, `sha1` und `md5` sind jedoch zur Kompatibilität mit externen Systemen verfügbar.

Anwendungsbeispiel: {{ "hello world" | blake3 }} gibt den BLAKE3-Hash von „hello world“ zurück.

HMAC-Filter

Um einen HMAC mit einem geheimen Schlüssel zu erstellen, verwende einen der folgenden unterstützten Filter:

Anwendungsbeispiel:

  • Einfach: {{ "message" | hmac_sha256: "secret_key" }}
  • Mit Secrets (empfohlen): {{ "message" | hmac_sha256: secrets.api_key }}

Beispiele für die Verwendung von Variablen mit Liquid in Shopify Flow

Die folgenden Beispiele vermitteln dir ein besseres Gefühl dafür, wie du Liquid-Variablen verwenden kannst:

URLs für Ressourcen ausgeben

Du möchtest die URLs für Kund:in, Bestellung und Produkt ausgeben, die an einem Workflow beteiligt sind.

# 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>

Eine Liste von Tags in ein Metafeld umwandeln

Du möchtest eine Reihe von Tags in ein Metafeld umwandeln, das eine Liste einzeiliger Textfelder ist. Du erstellst einen Workflow mit dem Trigger Produkt zum Shop hinzugefügt und verwendest die Aktion Produktmetafeld aktualisieren. Im Abschnitt Wert der Aktion Produktmetafeld aktualisieren fügst du den folgenden Liquid-Code hinzu. Dieses Beispiel geht davon aus, dass du die Werte nur einmal beim Erstellen des Produkts festlegen musst und dass das Produkt zwei relevante Tags hat: color:red und color:orange.

Beispiel für Liquid, um die Liste eines einzeiligen Textfelds festzulegen.
EingabeAusgabe
{% 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"]

Eine dynamische E-Mail-Nachricht für eine Bestellung verfassen

Du möchtest einen Workflow erstellen, um eine E-Mail an eine:n Mitarbeiter:in zu senden, wenn ein:e Kund:in mehr als 500 $ für eine Bestellung ausgibt. Du erstellst einen Workflow mit dem Trigger Bestellung erstellt, legst eine Bedingung fest, die zutrifft, wenn die Gesamtsumme der Bestellung über 500 $ liegt, und verwendest die Aktion Interne E-Mail senden. Im Abschnitt Nachricht der Aktion Interne E-Mail senden verwendest du die folgenden Variablen.

Beispiel für die Verwendung von Variablen zur Bereitstellung von Kund:innendetails.
EingabeAusgabe
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 }}.
Bitte sende eine persönliche Dankesnachricht an Jeanne Dupont (jeanne@example.com), weil sie eine Bestellung über 763,42 $ aufgegeben hat.

Eine dynamische E-Mail-Nachricht für ein Produkt mit geringem Lagerbestand verfassen

Du entscheidest, dass du eine:n Mitarbeiter:in informieren musst, wenn der Lagerbestand eines Produkts zur Neige geht und Nachschub bestellt werden muss. Du erstellst einen Workflow, der mit dem Trigger Inventarmenge geändert beginnt, und legst eine Bedingung fest, die zutrifft, wenn die vorherige Inventarmenge kleiner oder gleich 10 ist. Im Abschnitt Nachricht der Aktion Interne E-Mail senden verwendest du die folgenden Variablen.

Beispiel für die Verwendung von Variablen zur Bereitstellung von Artikeldetails.
EingabeAusgabe
Please reorder {{ product.title }}. Email owner@store.com to verify that they've received the purchase order.
Bitte bestelle High Waist Leggings – Schwarz erneut. Sende eine E-Mail an owner@example.com, um zu überprüfen, ob sie die Bestellung erhalten haben.

Eine dynamische E-Mail-Nachricht schreiben, um Mitarbeiter:innen über eine betrügerische Bestellung zu benachrichtigen

Du möchtest Bestellungen mit hoher Risikostufe stornieren, bevorzugst es aber, dass deine Mitarbeiter:innen die Bestellung manuell stornieren. Du erstellst einen Workflow, der mit dem Trigger Bestellung erstellt beginnt, und legst eine Bedingung fest, die zutrifft, wenn die Risikostufe der Bestellung „hoch“ ist. Im Abschnitt Nachricht der Aktion Interne E-Mail senden verwendest du die folgenden Variablen.

Beispiel für die Verwendung von Variablen zur Bereitstellung von Informationen zu einer betrügerischen Bestellung.
EingabeAusgabe
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!
Unser Shopify-Shop hat eine Bestellung mit hohem Betrugsrisiko erhalten. Wir möchten diese Bestellung stornieren, bevor sie in die Produktion geht:

#1001
Dupont, Jeanne
jeanne@example.com

Bitte bestätige den neuen Bestellstatus. Vielen Dank!

Die Positionen einer Bestellung mithilfe einer for-Schleife ausgeben

Wenn eine Bestellung eingeht, kann es nützlich sein, eine Nachricht mit den bestellten Produkten zu senden. Das kannst du mit einer for-Schleife tun, die einen Code-Block wiederholt ausführt. Textfelder, die Variablen unterstützen, unterstützen auch for-Schleifen und das forloop-Objekt.

Du möchtest beispielsweise einen Workflow erstellen, der eine Liste aller SKUs und Mengen in einer Bestellung zurückgibt. Im Abschnitt Nachricht der Aktion Interne E-Mail senden verwendest du die folgenden Variablen.

Beispiel für die Verwendung einer for-Schleife zur Bereitstellung von Bestellinformationen.
EingabeAusgabe
Order summary:
{% for a in order.lineItems %}
  {{a.sku}} ( {{a.quantity}} )
{% endfor %}
Bestellübersicht:
8987097979 (50)
8877778887 (3)
888998898B (1)

Positionen für eine Bestellung mithilfe einer for-Schleife mit zusätzlichen Informationen ausgeben

Du möchtest der E-Mail weitere Informationen hinzufügen, einschließlich Produktname, SKUs, Preis pro Artikel und Versandinformationen der Kundschaft. Im Abschnitt Nachricht der Aktion Interne E-Mail senden verwendest du die folgenden Variablen.

Beispiel für die Verwendung einer for-Schleife zur Bereitstellung umfangreicherer Bestellinformationen.
EingabeAusgabe
Order summary:
{% for a in order.lineItems %}
  Product: {{a.title}}
  SKU: {{a.sku}}
  Price (per unit): ${{a.originalUnitPriceSet.shopMoney.amount}}
  Quantity: {{a.quantity}}
{% endfor %}
Bestellübersicht:
Produkt: High Waist Leggings – Schwarz
SKU: 8987097979
Preis (pro Stück): 8,49 $
Menge: 5
Produkt: Athletic Socks – Blau
SKU: 888998898B
Preis (pro Stück): 5,61 $
Menge: 2

Einige Positionen durch die Kombination einer for-Schleife mit einer if-Anweisung ausgeben

Du musst verkaufte Artikel nachverfolgen, die von einem bestimmten Anbieter geliefert werden. Im Abschnitt Nachricht der Aktion Interne E-Mail senden verwendest du die folgenden Variablen und fügst eine if-Anweisung in deine for-Schleife ein.

Beispiel für die Verwendung einer for-Schleife und einer if-Anweisung zur Bereitstellung von Bestellinformationen für bestimmte Anbieter.
EingabeAusgabe
Acme product sold:
{% for x in order.lineItems %}
  {% if x.vendor == 'acme-vendor' %}
    Product name: {{x.title}}
    SKU: {{x.sku}}
  {% endif %}
{% endfor %}
Acme-Produkt verkauft:
Produktname: High Waist Leggings – Schwarz
SKU: 8987097979

Komplexe Datenobjekte in Shopify Flow

Mit Flow kannst du auf fast alle Daten zugreifen, die in der GraphQL Admin API enthalten sind. Dazu gehören komplexe Datenobjekte wie Listen und Objekte. Es gibt jedoch einige Einschränkungen, was du mit diesen Objekten tun kannst. Dieser Abschnitt beschreibt diese Einschränkungen und enthält Beispiele für die Arbeit mit ihnen.

Anstatt Listen und Objekte direkt aufzurufen, solltest du die Liste in einer Schleife durchlaufen und nur die Felder einbeziehen, die du verwenden möchtest.

Anstatt beispielsweise {{ order.lineItems }} direkt aufzurufen, verwende das folgende Format, um bestimmte Felder aufzurufen. Diese Beispiele enthalten alle Felder, die durch den direkten Aufruf der Liste oder des Objekts eingeschlossen würden. Kopiere die Felder, die du benötigst, und füge sie ein.

Text
{% 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 %}
]

}