Shopify Flow'da Liquid değişkenlerini kullanma

Liquid değişkenleri, Liquid'de tanımlanan ve bir iş akışı çalıştığında GraphQL Admin API'sinden alınan değerlerle değiştirilen yer tutuculardır. Değişkenler; iş akışlarınızda yer alan müşteriler, siparişler ve ürünler ile ilgili sipariş numarası, sipariş fiyatı veya müşteri adı gibi özellikleri açıklayabilir. Değişkenler, iş akışınızdaki mantığı kontrol etmek için koşullarda veya bir eylemden veri çıkışı almak için kullanılabilir.

Liquid kullanarak iş akışlarına değişken ekleme

Değişken ekle bağlantısını içeren herhangi bir metin alanına Liquid kullanarak değişkenler ekleyebilirsiniz. İlgili alanın altındaki Değişken ekle bağlantısına tıklayın ve ardından listeden bir değişken seçin.

Dahili e-posta gönder eyleminin yapılandırma panelinde, Konu alanının altındaki 'Değişken ekle' seçeneğini vurgulayan resim.

Değişken ekle listesindeki değişkenler filtrelenir. Böylece yalnızca tetikleyiciler gibi, geçerli adımdan önceki adımlar tarafından döndürülen değişkenleri kullanırsınız. Örneğin, Sipariş Oluşturuldu tetikleyicisi, Admin API'dan değişken olarak eklenebilecek sipariş ve mağaza kaynakları sağlar. Listeden bir değişken seçtikten sonra bu değişken, metin kutusuna düzgün biçimlendirilmiş Liquid olarak eklenir.

Metin alanına doğrudan Liquid de yazabilirsiniz. Örneğin, Shopify yöneticisinden order-123 gibi bir sipariş dizesi görüntülemek için {{ order.name }} değişkenini kullanabilirsiniz.

Flow, Liquid için kullanılan verileri almak üzere Admin API'yi kullandığından, değişken söz diziminde camel case kullanılır. Camel case değişkenlerinde ilk kelime küçük harfle, sonraki kelimeler ise büyük harfle başlar (ör. firstName veya canMarkAsPaid). Örneğin, bir ürünün oluşturulma tarihine erişmek için {{ product.createdAt }} girin. Camel case kullanmayan bir Shopify temasında Liquid söz dizimini kullanırsanız {{ product.created_at }} girmeniz gerekir.

Koşullu ve yinelemeli Liquid etiketleri

Liquid etiketleri, değişkenlerle birlikte aşağıdaki işlevleri yerine getirmek için kullanılabilir:

  • Sipariş toplamının 100 $'dan büyük olup olmadığını belirleme gibi koşullu ifadeler yazma.
  • Bir siparişteki her satır öğesi için veri çıktısı alma gibi bir nesne listesinde yineleme yapma.

Bu ifadeleri yazmak ve nesneler arasında yineleme yapmak için Liquid etiketlerini kullanabilirsiniz.

Örneğin aşağıdaki Liquid, sipariş toplamı 100 $'dan büyükse sipariş numarasını görüntüler:

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

Siparişteki satır öğeleri gibi bir nesne listesinde yineleme yapmak için for döngüsü de kullanabilirsiniz. Örneğin aşağıdaki Liquid, bir siparişteki her satır öğesinin adını görüntüler:

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

Flow, aşağıdaki Liquid koşullu (veya kontrol akışı) etiketlerini destekler:

Flow ayrıca aşağıdaki Liquid yineleme etiketlerini de destekler:

Değişkenlere filtre uygulama

Filtreleri kullanarak Liquid'deki değişken verilerini dönüştürebilirsiniz. Flow, tüm açık kaynak Liquid filtrelerini destekler.

Örneğin aşağıdaki Liquid, sipariş adından bir ön eki kaldırır ve kalanı verir: {{ order.name | remove: "Order-" }}

Filtrelerde Liquid değişkenlerini kullanmayla ilgili dikkat edilmesi gerekenler

Filtreleri kullanarak değişkenleri dönüştürmeden önce aşağıdaki hususları gözden geçirin:

  • Flow, bazı filtrelerde kullanılabilen nokta gösterimini desteklemez. Örneğin Flow, {{ order.lineItems | size }} kodunu destekler ancak {{ order.lineItems.size }} kodunu desteklemez.
  • Flow, meta alanlar için nokta gösterimini desteklemez. Örneğin, {{ order.metafields.custom.hold_note }} kodunu kullanamazsınız. Bunun yerine, örneklerde belirtildiği gibi meta alanlar üzerinde döngü yapmanız gerekir.
  • Flow, bir listedeki öğelere erişmek için dizin kullanmayı desteklemez. Örneğin, {{ order.lineItems[0].title }} kodunu kullanamazsınız. Bunun yerine, örneklerde belirtildiği gibi satır öğeleri üzerinde döngü yapmanız gerekir.

Tarih filtreleri

Standart Liquid filtrelerine ek olarak Flow, Zamanlanmış zaman tetikleyicisini ve Veri al özelliklerini desteklemek için başka bir tarihe göre bir tarih elde etmenizi sağlayan tarih filtreleri sunar. Bu filtreler şunlardır: date_minus ve date_plus. Örneğin:

  • Gelecekte bir gün sonraki tarihi döndürmek için: {{ "now" | date_plus: "1 day" }}
  • Geçmişte bir gün önceki tarihi döndürmek için: {{ "now" | date_minus: "1 day" }}

Bu filtreler, süre birimi olarak hem tekil (second gibi) hem de çoğul (seconds gibi) olmak üzere second, minute, day, week, month ve year ifadelerini kabul eder. Ayrıca aşağıdaki özelleştirilebilir birim türlerini de sağlayabilirsiniz:

  • Saniye sayısını temsil eden bir tam sayı: {{ "now" | date_minus: 3600 }} (burada 3600, 1 saate eş değerdir).
  • Bir ISO8601 süre dizesi: {{ "now" | date_minus: "P1Y2D" }} (burada P1Y2D, 1 yıl 2 gün anlamına gelir).

Kriptografik filtreler

Flow, karma oluşturma ve Karma Tabanlı Mesaj Doğrulama Kodları (HMAC'ler) oluşturma için kriptografik filtreler sağlar. Bu filtreler; benzersiz tanımlayıcılar veya sağlama toplamları oluşturmak ya da belirli karma biçimleri gerektiren üçüncü taraf sistemlerle entegre olmak için kullanışlıdır.

Karma oluşturma filtreleri

Shopify Flow, aşağıdaki karma oluşturma filtresi türlerini destekler:

  • blake3: Bir BLAKE3 karması oluşturur (genel kullanım için önerilir).
  • sha256: Bir SHA-256 karması oluşturur.
  • sha1: Bir SHA-1 karması oluşturur.
  • md5: Bir MD5 karması oluşturur.

Genel karma oluşturma amaçları ve yeni uygulamalar için eski algoritmalara kıyasla üstün performans ve güvenlik sunduğundan blake3 kullanmanız gerekir. Ancak sha256, sha1 ve md5, üçüncü taraf sistemlerle uyumluluk için kullanılabilir.

Örnek kullanım: {{ "hello world" | blake3 }}, "hello world" dizesinin BLAKE3 karmasını döndürür.

HMAC filtreleri

Gizli anahtarla HMAC oluşturmak için aşağıdaki desteklenen filtrelerden birini kullanın:

Örnek kullanım:

  • Temel: {{ "message" | hmac_sha256: "secret_key" }}
  • Gizli anahtarlar ile (önerilen): {{ "message" | hmac_sha256: secrets.api_key }}

Shopify Flow'da Liquid ile değişken kullanma örnekleri

Liquid değişkenlerinin nasıl kullanılacağını daha iyi anlamak için aşağıdaki örnekleri inceleyin:

Kaynaklar için URL'ler çıkarma

Bir iş akışında yer alan müşteri, sipariş ve ürün için URL'leri çıkarmak istiyorsunuz.

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

Etiket listesini meta alana dönüştürme

Bir etiket grubunu, tek satırlı metin alanları listesi olan bir meta alana dönüştürmek istiyorsunuz. Mağazaya ürün eklendi tetikleyicisini kullanarak bir iş akışı oluşturuyor ve Ürün meta alanını güncelle eylemini kullanıyorsunuz. Ürün meta alanını güncelle eyleminin Değer bölümüne aşağıdaki liquid kodunu ekliyorsunuz. Bu örnekte, değerleri yalnızca ürün oluşturulduğunda bir kez ayarlamanız gerektiği ve ürünün ilgili iki etiketi (color:red ve color:orange) olduğu varsayılmaktadır.

Tek satırlı bir metin alanı listesini ayarlamaya yönelik örnek liquid.
GirdiÇıktı
{% 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"]

Sipariş için dinamik bir e-posta mesajı yazma

Bir müşteri, bir siparişte 500 $'dan fazla harcama yaptığında bir çalışana e-posta göndermek için iş akışı oluşturmak istiyorsunuz. Sipariş oluşturuldu tetikleyicisini kullanarak bir iş akışı oluşturuyor, sipariş toplamı 500 $'ın üzerindeyse doğru (true) olan bir koşul ayarlıyor ve Dahili e-posta gönder eylemini kullanıyorsunuz. Dahili e-posta gönder eyleminin Mesaj bölümünde aşağıdaki değişkenleri kullanıyorsunuz.

Müşteri bilgilerini sağlamak için değişken kullanımına örnek.
GirdiÇıktı
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 }}.
Lütfen 763,42 $ tutarında sipariş verdiği için Jeanne Dupont'a (jeanne@example.com) kişisel bir teşekkür notu gönderin.

Stoku azalan bir ürün için dinamik e-posta mesajı yazma

Ürün envanteri azaldığında bir personeli bilgilendirmeniz ve daha fazla stok için sipariş verilmesi gerektiğine karar veriyorsunuz. Envanter adedi değişti tetikleyicisiyle başlayan bir iş akışı oluşturuyor ve önceki envanter adedi 10 veya daha az ise doğru (true) olan bir koşul ayarlıyorsunuz. Dahili e-posta gönder eyleminin Mesaj bölümünde aşağıdaki değişkenleri kullanıyorsunuz.

Ürün ayrıntılarını sağlamak için değişken kullanımına örnek.
GirdiÇıktı
Please reorder {{ product.title }}. Email owner@store.com to verify that they've received the purchase order.
Lütfen Yüksek Bel Tayt - Siyah ürününü yeniden sipariş edin. Satın alma emrini aldıklarını doğrulamak için owner@example.com adresine e-posta gönderin.

Personele hileli bir sipariş hakkında bildirim göndermek için dinamik e-posta mesajı yazma

Yüksek risk seviyesine sahip siparişleri iptal etmek, ancak personelinizin siparişi manuel olarak iptal etmesini tercih etmek istiyorsunuz. Sipariş oluşturuldu tetikleyicisiyle başlayan bir iş akışı oluşturuyor ve siparişin risk seviyesi yüksek ise doğru (true) olan bir koşul ayarlıyorsunuz. Dahili e-posta gönder eyleminin Mesaj bölümünde aşağıdaki değişkenleri kullanıyorsunuz.

Hileli bir sipariş hakkında bilgi sağlamak için değişken kullanımına örnek.
GirdiÇıktı
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 mağazamıza sahtekarlık riski yüksek bir sipariş geldi. Bu siparişi üretime gönderilmeden önce, hemen iptal etmek istiyoruz:

#1001
Dupont, Jeanne
jeanne@example.com

Lütfen yeni sipariş durumunu teyit edin. Teşekkürler!

For döngüsü kullanarak bir siparişin satır öğelerini çıkarma

Bir sipariş alındığında, sipariş edilen ürünleri içeren bir mesaj göndermek faydalı olabilir. Bunu, bir kod bloğunu tekrar tekrar yürüten for döngüsü kullanarak yapabilirsiniz. Değişkenleri destekleyen metin alanları for döngülerini ve forloop nesnesini de destekler.

Örneğin, bir siparişteki tüm SKU'ların ve adetlerin listesini döndüren bir iş akışı oluşturmak istediğinizi varsayalım. Dahili e-posta gönder eyleminin Mesaj bölümünde aşağıdaki değişkenleri kullanırsınız.

Sipariş bilgilerini sağlamak için "for" döngüsü kullanımına bir örnek.
GirdiÇıktı
Order summary:
{% for a in order.lineItems %}
  {{a.sku}} ( {{a.quantity}} )
{% endfor %}
Sipariş özeti:
8987097979 (50)
8877778887 (3)
888998898B (1)

Ek bilgiler içeren bir "for" döngüsü kullanarak siparişin satır öğelerini çıktı olarak alma

E-postaya ürün adı, SKU'lar, ürün başına fiyat ve müşterinin kargo bilgileri dahil olmak üzere daha fazla bilgi eklemeye karar verdiğinizi varsayalım. Dahili e-posta gönder eyleminin Mesaj bölümünde aşağıdaki değişkenleri kullanırsınız.

Daha kapsamlı sipariş bilgileri sağlamak için "for" döngüsü kullanımına bir örnek.
GirdiÇıktı
Order summary:
{% for a in order.lineItems %}
  Product: {{a.title}}
  SKU: {{a.sku}}
  Price (per unit): ${{a.originalUnitPriceSet.shopMoney.amount}}
  Quantity: {{a.quantity}}
{% endfor %}
Sipariş özeti:
Ürün: Yüksek Belli Tayt - Siyah
SKU: 8987097979
Fiyat (birim başına): 8,49 $
Adet: 5
Ürün: Spor Çorabı - Mavi
SKU: 888998898B
Fiyat (birim başına): 5,61 $
Adet: 2

Bir "for" döngüsünü "if" ifadesiyle birleştirerek bazı satır öğelerini çıktı olarak alma

Belirli bir satıcı tarafından tedarik edilen satılmış ürünleri takip etmeniz gerektiğini varsayalım. Dahili e-posta gönder eyleminin Mesaj bölümünde aşağıdaki değişkenleri kullanır ve for döngünüze bir if ifadesi eklersiniz.

Belirli satıcılara yönelik sipariş bilgilerini sağlamak için "for" döngüsü ve "if" ifadesi kullanımına bir örnek.
GirdiÇıktı
Acme product sold:
{% for x in order.lineItems %}
  {% if x.vendor == 'acme-vendor' %}
    Product name: {{x.title}}
    SKU: {{x.sku}}
  {% endif %}
{% endfor %}
Acme ürünü satıldı:
Ürün adı: Yüksek Belli Tayt - Siyah
SKU: 8987097979

Shopify Flow'da karmaşık veri nesneleri

Flow, GraphQL Admin API içindeki neredeyse tüm verilere erişmenize olanak tanır. Buna, listeler ve nesneler gibi karmaşık veri nesneleri de dahildir. Ancak bu nesnelerle yapabilecekleriniz konusunda bazı sınırlamalar vardır. Bu bölümde bu sınırlamalar özetlenmekte ve bunlarla nasıl çalışılacağına dair örnekler sunulmaktadır.

Listeleri ve nesneleri doğrudan çağırmak yerine, liste üzerinde döngü oluşturmalı ve yalnızca istediğiniz alanları dahil etmelisiniz.

Örneğin, {{ order.lineItems }} öğesini doğrudan çağırmak yerine, belirli alanları çağırmak için aşağıdaki biçimi kullanın. Bu örnekler, listeyi veya nesneyi doğrudan çağırarak dahil edilecek tüm alanları içerir. İhtiyaç duyduğunuz alanları kopyalayıp yapıştırın.

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

}