Shopifyに無料で希望配送日時指定を追加

# はじめに
shopifyにありそうでない機能の一つが、**商品購入時の希望配送日時指定**。

もちろん、[shopify app store](https://apps.shopify.com/collections/apps-for-japan?locale=ja)には決済画面にて配送日時指定ができるようになるアプリもあるのですが、いつものように無料で追加してみたいと思います。

## 実現したいこと
* 顧客が購入時に希望配送日時が指定ができる
* 管理画面の注文詳細で指定された配送希望日時が確認できる
* 顧客の注文管完了画面（注文状況ページ）や注文確認メールからも確認できる
* 海外からの購入者もいるので国内localeの場合のみ選択できるようにする


# Shopify でのカート〜チェックアウト画面のカスタマイズ

shopifyは通常のプラン（ベーシック、スタンダード、プレミアム）ではチェックアウト画面のカスタマイズができません(制限された範囲に限り可能)。

独自項目を追加するとなると、[shopify plus](https://help.shopify.com/ja/manual/intro-to-shopify/pricing-plans/shopify-plus)に契約してチェックアウト画面のコードの編集をする必要があります。

なので本来であれば配送日時はチェックアウト直前で選択するようにしたいところですが、今回は[Cart Attribute](https://shopify.dev/api/liquid/objects/cart#cart-attributes)というカート画面に入力項目を追加できる属性を使って、カート画面にて指定してもらう形で実装をしたいと思います。


:::note warn
言わずもがなですが、テンプレートをカスタマイズする場合は必ずバックアップをするようにしてください。
:::

## Cart Attributesについて

カート画面に入力項目を追加し、それを顧客の注文完了画面やメール、管理画面から確認することができるカスタム属性です。

[Shopify .dev - Cart Attribute](https://shopify.dev/api/liquid/objects/cart#cart-attributes)

shopifyには他にも商品ページに任意のフィールドを追加できる[Line Item Property](https://shopify.dev/api/liquid/objects/line_item#line_item-properties)、 顧客情報に追加できる　[Customer note](https://shopify.dev/themes/customer-engagement/additional-customer-information)があり、これらを使うことで独自の項目を利用したサービスや機能を実装することができます。

## 配送日指定の実装

カートに配送日を指定する方法についてはshopifyのヘルプセンターの以下のコンテンツを参考にしました。

[Shopify Help Center - Add a delivery date picker to your cart　](https://help.shopify.com/en/manual/online-store/themes/os/customize/add-date-picker)

上記のヘルプではjQuery UIのdatepickerを使っていたので、加えて日本語化と「閉じる」ボタンを追加。
以下のスニペットを新規作成しました。

```Snnipets/delivery-date.liquid
{{ '//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css' | stylesheet_tag }}
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js" defer="defer"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js" type="text/javascript" defer="defer"></script>

<p class="cart-attribute__field">
  <label for="date">お届け希望日:</label>
  <input id="date" type="text" name="attributes[お届け希望日]" value="{{ cart.attributes.date }}"  placeholder="最短で発送"/>
</p>

<script>
  window.onload = function() {
      if (window.jQuery) {
        let $ = window.jQuery;
        $(function() {
          $.datepicker.setDefaults( $.datepicker.regional[ "ja" ] );
          $("#date").datepicker({
          minDate: +3,
          maxDate: '+1M',
          showButtonPanel: true
        });
      });
    }
  }
</script>
```

加えて、カートページに上記スニペットを日本語での表示の場合のみ表示するように修正。

```Templates/cart.liquid
{%- if request.locale.name == "日本語" -%}
  {% render 'delivery-date' %}
{%- endif -%}
```


これでカート画面に配送希望日を設定できるようになりました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/871869/e5a1c487-6393-4fd8-9f08-a72884ad0b24.png" width=60%>


## 配送時間指定の実装

配送時間も同様にCart Attributeを使ってカート画面に入力項目を追加します。
ShopifyのUIを用意する場合は、Shopifyがジェネレータを提供してくれているのでこれを使うのが便利です。

[Shopify UI Elements Generator - Cart Attribute](https://ui-elements-generator.myshopify.com/pages/cart-attribute)

ジェネレータを使って以下のコードを生成しました。内容は日本郵便のゆうパックで指定できる配達希望時間を設定しています。

```
<p class="cart-attribute__field">
  <label>お届け希望時間帯:</label>
  <select id="" name="attributes[お届け希望時間]">
    <option value="指定無し"{% if cart.attributes["お届け希望時間"] == "指定無し" %} selected{% endif %}>指定無し</option>
    <option value="8:00〜12:00"{% if cart.attributes["お届け希望時間"] == "8:00〜12:00" %} selected{% endif %}>8:00〜12:00</option>
    <option value="12:00〜14:00"{% if cart.attributes["お届け希望時間"] == "12:00〜14:00" %} selected{% endif %}>12:00〜14:00</option>
    <option value="14:00〜16:00"{% if cart.attributes["お届け希望時間"] == "14:00〜16:00" %} selected{% endif %}>14:00〜16:00</option>
    <option value="18:00～20:00"{% if cart.attributes["お届け希望時間"] == "18:00～20:00" %} selected{% endif %}>18:00～20:00</option>
    <option value="19:00～21:00"{% if cart.attributes["お届け希望時間"] == "19:00～21:00" %} selected{% endif %}>19:00～21:00</option>
    <option value="20:00～21:00"{% if cart.attributes["お届け希望時間"] == "20:00～21:00" %} selected{% endif %}>20:00～21:00</option>
  </select>
</p>
<br>
```

先程作成したSnipetに上記コードを追加し、カート画面に配送希望日と配送希望時間帯が設定できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/871869/01df3258-f036-171c-09f4-a78fd61c9797.png)



## 受注詳細画面での確認方法

Shopify管理画面の注文詳細では「追加の詳細」という項目で確認ができます。

![order_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/871869/d7565935-06f1-18b9-d502-11563b27cc70.png)


同項目は管理者によって修正することも可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/871869/c40691cd-d1f0-4d09-6e9f-a00c866f9331.png" width=60%>


# 注文完了画面に希望配送日時を表示

Shopifyでは標準のプランでも注文完了画面（注文状況ページ）にスクリプトを追加することができます。
これを使うことでコンバージョントラッキングを設定したり、顧客のロケーションに合わせてメッセージを出すなどといったことができるのですが、この機能を使ってCart Attributesの内容を表示します。

Shopify管理画面から **設定 > チェックアウト > 追加スクリプト**に以下のコードを設定します。

```
<script>
{% if attributes %}
  Shopify.Checkout.OrderStatus.addContentBox(
    {% for attribute in attributes %}
      '<h2>{{ attribute | first }}</h2>',
      '<p>{{ attribute | last }}</p>' 
      {% if forloop.last == false %},{% endif %}
    {% endfor %}
  )
{% endif %}
</script>
```

以下のページを参考にしました。
[注文状況ページをカスタマイズする - Shopify Help Center](https://help.shopify.com/ja/manual/orders/status-tracking/customize-order-status)
[注文状況JavaScriptアセット - Shopify Help Center](https://help.shopify.com/ja/manual/orders/status-tracking/customize-order-status/order-status-javascript-asset)

そうすることで以下のように注文完了画面（注文状況ページ）に設定した内容を表示することができました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/871869/6143ccaa-e913-7b3c-db89-d1f7c767f1e2.png" width=80%>



# 注文確認メールに希望配送日時を表示

ShopifyはメールやSMSの通知テンプレートでもLiquidが使えるのでカスタマイズも簡単です。

Shopify管理画面から **設定 > 通知 > 注文の確認** にて、Cart Attributesの内容を表示するようにテンプレートを修正。
私はメール本文内の**配送先情報**の下に追加しましたが、使用しているテンプレートの構造に応じて適宜調整してください。

```
{% if attributes %}
　　{% for attribute in attributes %}
　　　　<h4>{{ attribute | first }}</h4>
　　　　<p>{{ attribute | last }}</p>
　　{% endfor %}
{% endif %}
```

注文確認メールに配送希望日時が表示されるようになりました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/871869/ee0388ff-10af-7d9c-07ab-66254b12454f.png" width=100%>


# おわりに

途中でも書いたとおり、本来であればチェックアウト直前で入力できるようにしたいところですが、ひとまず無料で実現することができました。

あとは管理画面の注文一覧で配送日時指定がある注文の確認や絞り込みができないので、特定のAttributeがある場合に自動でタグ付け、とかをしたいところですが、どうやらそれはShopify Plusのタスクオートメーション機能である[Shopify ｆlow](https://help.shopify.com/ja/manual/shopify-plus/flow)を導入するか、専用のアプリを購入するしかなさそうです。

そろそろShopify Plusでチェックアウト画面もゴリゴリ修正したい、、と思いつつも月額2,000USDは高い、、まあエンタープライズ向けのプランだからしょうがないんだろうけど。

アプリだけでなくて、店舗の規模ではなく実現したいUXに応じて柔軟にオプションを選択できるようになるといいなあと思う今日このごろ。

おわり