️バックアップ

テンプレートのバックアップを必ず取り、検証した上で適用させる様にご注意ください。

SDK

いよいよproteger統合の最終段階です! :congratulations:
テーマにproteger SDKを組み込み顧客にリーチします。


StoreIdを管理画面で確認

proteger管理画面の設定(右上歯車アイコン) → 店舗設定 → StoreID(店舗ID)を確認します。


テンプレートを開く

新管理画面と旧管理画面でデザイン編集画面への遷移方法は異なりますが、SDKの設定方法に差異はありません。
旧管理画面で設定済の場合、新たに新管理画面での設定は不要です。

新管理画面をご利用の方

  1. 「メインメニュー」 > 「ショップデザイン」 > 「テンプレート選択・編集」に移動します。
  2. 右上の「(旧デザイン)ベーシックモード編集画面へ」をクリックします。

旧管理画面をご利用の方

  1. makeshop管理画面のデザイン編集画面から「独自デザイン」をクリックします。

商品詳細画面の設定

makeshop管理画面から「商品詳細画面」をクリックします。

「商品詳細ページ選択」からテンプレートを選択します。

デフォルトだと「カテゴリ共通デザイン」に記述すると全ての商品に反映させる事ができます。
カテゴリによってテンプレートを変更している場合は他にも記述が必要になる事があります。


シンボルエレメント追加

保証プランを表示する「カートに入れる」の上に以下のHTMLを追加します。

<div id="proteger-offer"></div>


SDK初期化

次にテンプレートの最下部にSDKを初期化する記述を追加します。

<script src="https://sdk.helloproteger.com/v4/makeshop-plan.min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script>
  Proteger.config({
    storeId: 'StoreId', // proteger管理画面から確認できるStoreId
    logoUrl: 'https://proteger.com/logo.png', // ロゴURL
    protegerEnv: "prd",
  });
  ProtegerMakeshop.config({
    makeshopId: 'proteger', // makeshopのid
    isSP: false, // SPテンプレートか @optional
    isCreatorMode: false, // クリエイターモード利用か
  });
</script>

保証プラン表示

次に保証プランを表示するためのAPIを実行します。

<script src="https://sdk.helloproteger.com/v4/makeshop-plan.min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script>
  Proteger.config({
    storeId: 'StoreId',
    logoUrl: 'https://proteger.com/logo.png',
    protegerEnv: "prd",
  });
  ProtegerMakeshop.config({
    makeshopId: 'proteger',
    isSP: false,
    isCreatorMode: false,
  });
</script>
<script>
  if (window.Proteger || window.ProtegerMakeshop) {

    // 商品Idを取得
    var productId  =  "[SYSTEM_CODE]";

    // 保証プランをレンダリング
    // 'proteger-offer'は先ほど追加したシンボルエレメントのid
    Proteger.buttons.render('proteger-offer', {
      productId: productId,
    });
  }
</script>

ここまででプレビューを確認すると保証プランが表示されているはずです。


商品をカートに追加する関数を追加

商品を追加する為の関数を追加します。

PCとSPで記述が異なります。

*デフォルトのテンプレートの場合の記述なので適宜記述を変更して下さい。


PCの場合

<script src="https://sdk.helloproteger.com/v4/makeshop-plan.min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script>
  Proteger.config({
    storeId: 'StoreId',
    logoUrl: 'https://proteger.com/logo.png',
    protegerEnv: "prd",
  });
  ProtegerMakeshop.config({
    makeshopId: 'proteger',
    isSP: false,
    isCreatorMode: false,
  });
</script>
<script>
  if (window.Proteger || window.ProtegerMakeshop) {

    // 商品Idを取得
    var productId  =  "[SYSTEM_CODE]";

    // 保証プランをレンダリング
    Proteger.buttons.render('proteger-offer', {
      productId: productId,
    });
    
    // 「カートに入れる」ボタンを取得
    // * aタグを取得する様に記述
    var addToCartButton = document.querySelector("#addCartBtn");
    // デフォルトの関数
    var addProductToCartFunStr = [GETBASKET];
    
    // 商品をカートに追加する関数
    // EX.)
    function addProductToCart() {
      addToCartButton.removeEventListener('click', submitBtnHandler);
      addToCartButton.click();
      addToCartButton.addEventListener('click', submitBtnHandler);
    }
  }
</script>

SPの場合

<script src="https://sdk.helloproteger.com/v4/makeshop-plan.min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script>
  Proteger.config({
    storeId: 'StoreId',
    logoUrl: 'https://proteger.com/logo.png',
    protegerEnv: "prd",
  });
  ProtegerMakeshop.config({
    makeshopId: 'proteger',
    isSP: true, // SPテンプレート
    isCreatorMode: false,
  });
</script>
<script>
  if (window.Proteger || window.ProtegerMakeshop) {

    // 商品Idを取得
    var productId  =  "<{$system_code}>";

    // 保証プランをレンダリング
    Proteger.buttons.render('proteger-offer', {
      productId: productId,
    });
    
    // 「カートに入れる」ボタンを取得
    var addToCartButton = document.querySelector('[value="カートに入れる"]');
    
    // 商品をカートに追加する関数
    // EX.)
    function addProductToCart() {
      addToCartButton.removeEventListener('click', submitBtnHandler);
      addToCartButton.setAttribute('onclick', "<{$get_basket_url}>");
      addToCartButton.click();
      addToCartButton.removeAttribute('onclick');
      addToCartButton.addEventListener('click', submitBtnHandler);
    }
  }
</script>

※新規にSDKを導入する際は以下の対応は不要です。

️ WARN

2024/02月以前にSDKを導入された場合は、以下の変更箇所があるはずですので、SDKを解除する際はご留意お願いいたします。

SPモードではデフォルトの挙動を止める為に以下の変更を行います。

<input onclick="<{$get_basket_url}>" type="submit" class="btn btnCart" value="カートに入れる">

からonclick="<{$get_basket_url}>"を削除

<input type="submit" class="btn btnCart" value="カートに入れる">

️ WARN

この記述を削除すると、protegerのSDK無しでは商品がカートに入らなくなります。
protegerを非表示にする時は、必ずこの記述を元に戻して下さい。


ボタンハンドラーを定義

「カートに入れる」ボタンのハンドラーを定義します。

*デフォルトのテンプレートの場合の記述なので適宜記述を変更して下さい。

<script src="https://sdk.helloproteger.com/v4/makeshop-plan.min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script>
  Proteger.config({
    storeId: 'StoreId',
    logoUrl: 'https://proteger.com/logo.png',
    protegerEnv: "prd",
  });
  ProtegerMakeshop.config({
    makeshopId: 'proteger',
    isSP: false,
    isCreatorMode: false,
  });
</script>
<script>
  if (window.Proteger || window.ProtegerMakeshop) {

    // 商品Idを取得
    var productId  =  "[SYSTEM_CODE]";

    // 保証プランをレンダリング
    Proteger.buttons.render('proteger-offer', {
      productId: productId,
    });
    
    // 「カートに入れる」ボタンを取得
    // * aタグを取得する様に記述
    var addToCartButton = document.querySelector("#addCartBtn");
    
    // 商品をカートに追加する関数
    function addProductToCart() {
      addToCartButton.removeEventListener('click', submitBtnHandler);
      addToCartButton.click();
      addToCartButton.addEventListener('click', submitBtnHandler);
    }
    
    function submitBtnHandler(e) {
      // デフォルトの挙動を停止
      e.preventDefault();
      e.stopImmediatePropagation();
      
      // 数量を取得
      var quantityEl = document.querySelector('[name="amount"]');
      quantity = quantityEl && quantityEl.value

      // コンポーネント取得
      const component = Proteger.buttons.instance('proteger-offer');
      // 選択中の保証プラン取得
      const plan = component.getPlanSelection();
      // 保証プランをカートに追加
      ProtegerMakeshop.addPlanToCart({productId: productId, plan: plan, quantity: quantity, productHandler: addProductToCart, modal: true});
    }
    
    // イベントリスナーに登録
    addToCartButton.addEventListener('click', submitBtnHandler);
    // SP板の場合は以下を追加
    // addToCartButton.removeAttribute('onclick');
  }
</script>

完了

保証プランが表示されカートに追加される事を確認して下さい。


カートページで保証プランを追加(β版)

カートページを編集します。

🚧

WARN

シンボルエレメントは間違った箇所に記述をしてしまうと、正しく動作しない恐れがあります。
記述をした後にMakeshopタグ(data-num='[BASKET_NUM]'等)が正しく動作してる事を確認して下さい。


PCの場合

「保証を追加」のボタンを表示をする為に、1つ目のシンボルエレメントを記述します。

<div class="proteger-cart-offer" data-num='[BASKET_NUM]' data-product='[BASKET_BRANDNAME]' data-quantity='[BASKET_QUANTITY]' data-update=[BASKET_UPDATE]></div>

1つ目の記述箇所の例です。

2つ目のシンボルエレメントは下記です。

<div class="proteger-cart-opt" data-num='[BASKET_NUM]'>

2つ目の記述箇所の例です。

3つ目のシンボルエレメントは下記です。

この記述は数量を囲む要素にアトリビュートとして追加します。

data-num='[BASKET_NUM]'

3つ目の記述箇所の例です。


SPの場合

「保証を追加」のボタンを表示をする為に、1つ目のシンボルエレメントを記述します。

<div class="proteger-cart-offer" data-num='<{$basket.num}>' data-product='<{$basket.name}>' data-quantity='<{$basket.qut}>' data-update="<{$basket.qut_chg}>" data-product-id="<{$basket.detail_url}>"></div>

1つ目の記述箇所の例です。

2つ目のシンボルエレメントは下記です。

<{$basket.option}>を囲む様に記述します。

<div class="proteger-cart-opt" data-num='<{$basket.num}>'>
  <{$basket.option}>
</div>

2つ目の記述箇所の例です。

3つ目のシンボルエレメントは下記です。

この記述は数量を囲む要素にアトリビュートとして追加します。

data-num='<{$basket.num}>'

3つ目の記述箇所の例です。

次に実際にprotegerのソースコードを追加していきます。


PCの場合

<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/v4/makeshop-cart.min.js" charset="utf-8"></script>
<script>
window.addEventListener('DOMContentLoaded', function(){
  Proteger.config({
    storeId: 'StoreID',
    logoUrl: 'ロゴURL',
    protegerEnv: "prd",
  });

  ProtegerMakeshop.config({
    makeshopId: 'MakeshopのID',
    isSP: false,
  });
  
  var slice = Array.prototype.slice;
  
  /**
   * elementを全て取得する関数を定義
   * @param {string} element クエリ
   *
   */
  function findAll(element) {
    var items = document.querySelectorAll(element);
    return items ? slice.call(items, 0) : [];
  }
  
  /**
   * 文字列からelementを作成
   * @param {string} html html文字列
   *
   */
  function createElementFromHTML(html) {
    const tempEl = document.createElement('div');
    tempEl.innerHTML = html;
    return tempEl.firstElementChild;
  }

  /**
   * 商品削除する関数
   * @param {item} item 削除するitem
   */
  function deleteItem({item}) {
    var f = document.getElementById("forms" + item.num);
    f.type.value = 'del';
    f.submit();
  }

  ProtegerMakeshop.setOnDelete({onDelete: deleteItem});
  
  findAll(".proteger-cart-opt").forEach((el) => {
    (el.firstElementChild) ? optionEl = el.firstElementChild : optionEl = null;
    (optionEl) ? options = optionEl.firstElementChild : options = null
    ProtegerMakeshop.addItemOption({num: el.getAttribute('data-num'), options: options});
  });
  
  findAll(".proteger-cart-offer").forEach((el) => {
    var num = el.getAttribute('data-num');
    var productEl = createElementFromHTML(el.getAttribute('data-product'));
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: productEl.title, id: productEl.getAttribute('href').split('/')[2], quantity: quantityEl.value, onUpdate: onUpdate};
    ProtegerMakeshop.addItem(item);
  });

  // 3つ目のアトリビュートを追加したクラス
  findAll(".quantityInput").forEach((el) => {
    var num = el.getAttribute('data-num');
    var quantityEl = el.firstElementChild;
    ProtegerMakeshop.addItemQuantity({num: num, quantityEl: quantityEl});
  });
  
  findAll('.proteger-cart-offer').forEach(function(el){
    var num = el.getAttribute('data-num');
    var productEl = createElementFromHTML(el.getAttribute('data-product'));
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: productEl.title, id: productEl.getAttribute('href').split('/')[2], quantity: quantityEl.value, onUpdate: onUpdate};
    if (ProtegerMakeshop.warrantyAlreadyInCart(item)) {
      return;
    }
  
    ProtegerMakeshop.renderSimplePlan(el, {
      item: item,
    });
  });
},false);
</script>

SPの場合

<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/v4/makeshop-cart.min.js" charset="utf-8"></script>
<script>
window.addEventListener('DOMContentLoaded', function(){
  Proteger.config({
    storeId: 'StoreID',
    logoUrl: 'ロゴURL',
    protegerEnv: "prd",
  });
  ProtegerMakeshop.config({
    makeshopId: 'MakeshopのID',
    isSP: true,
  });
  
  var slice = Array.prototype.slice;
  
  /**
   * elementを全て取得する関数を定義
   * @param {string} element クエリ
   *
   */
  function findAll(element) {
    var items = document.querySelectorAll(element);
    return items ? slice.call(items, 0) : [];
  }
  
  /**
   * 文字列からelementを作成
   * @param {string} html html文字列
   *
   */
  function createElementFromHTML(html) {
    const tempEl = document.createElement('div');
    tempEl.innerHTML = html;
    return tempEl.firstElementChild;
  }

  /**
   * 商品削除する関数
   * @param {item} item 削除するitem
   */
  function deleteItem({item}) {
    window.document.basket_form.action = "./basket.html";
    window.document.basket_form.selected_item.value=item.id;
    window.document.basket_form.selected_item_spcode.value=ProtegerMakeshop.getSpcode(item);
    window.document.basket_form.selected_item_spcode2.value="0";
    window.document.basket_form.selected_item_optcode.value="0";
    window.document.basket_form.type.value="delete_item";
 
    window.document.basket_form.submit();
  }
  
  ProtegerMakeshop.setOnDelete({onDelete: deleteItem});
  
  findAll(".proteger-cart-opt").forEach((el) => {
    var options = el.querySelectorAll(".option")[1];
    ProtegerMakeshop.addItemOption({num: el.getAttribute('data-num'), options: options});
  });
    
  findAll(".proteger-cart-offer").forEach((el) => {
    var id = el.getAttribute('data-product-id').split("=")[1];
    var num = el.getAttribute('data-num');
    var name = el.getAttribute('data-product');
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: name, id: id, quantity: quantityEl.value, onUpdate: onUpdate};
    ProtegerMakeshop.addItem(item);
  });
  
  // 3つ目のアトリビュートを追加したクラス
  findAll(".amount").forEach((el) => {
    var num = el.getAttribute('data-num');
    var quantityEl = el.firstElementChild;
    ProtegerMakeshop.addItemQuantity({num: num, quantityEl: quantityEl});
  });
    
  findAll('.proteger-cart-offer').forEach(function(el){
    var id = el.getAttribute('data-product-id').split("=")[1];
    var num = el.getAttribute('data-num');
    var name = el.getAttribute('data-product');
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: name, id: id, quantity: quantityEl.value, onUpdate: onUpdate};
    if (ProtegerMakeshop.warrantyAlreadyInCart(item)) {
      return;
    }
    
    ProtegerMakeshop.renderSimplePlan(el, {
      item: item,
    });
  });
},false);
</script>

ここまでで以下の様に表示されているのを確認して下さい。
ボタンを押すとモーダルが表示され、カートページで保証を追加する事ができます。

次に、カート内の商品と保証の数を合わせる処理を追加します。
これにより、保証単体での購入や商品数以上の保証の購入等を避ける事ができます。


ProtegerCart.normalizeCart 関数を実行します。

balancefalse を記述するとprotegerは商品と保証の数を合わせません

ProtegerMakeshop.normalizeCart({balance: true});

ここまでの記述をまとめると以下のような記述になります。


PCの場合

<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/v4/makeshop-cart.min.js" charset="utf-8"></script>
<script>
window.addEventListener('DOMContentLoaded', function(){
  Proteger.config({
    storeId: 'StoreID',
    logoUrl: 'ロゴURL',
    protegerEnv: "prd",
  });

  ProtegerMakeshop.config({
    makeshopId: 'MakeshopのID',
    isSP: false,
  });
  
  var slice = Array.prototype.slice;
  
  /**
   * elementを全て取得する関数を定義
   * @param {string} element クエリ
   *
   */
  function findAll(element) {
    var items = document.querySelectorAll(element);
    return items ? slice.call(items, 0) : [];
  }
  
  /**
   * 文字列からelementを作成
   * @param {string} html html文字列
   *
   */
  function createElementFromHTML(html) {
    const tempEl = document.createElement('div');
    tempEl.innerHTML = html;
    return tempEl.firstElementChild;
  }

  /**
   * 商品削除する関数
   * @param {item} item 削除するitem
   */
  function deleteItem({item}) {
    var f = document.getElementById("forms" + item.num);
    f.type.value = 'del';
    f.submit();
  }

  ProtegerMakeshop.setOnDelete({onDelete: deleteItem});
  
  findAll(".proteger-cart-opt").forEach((el) => {
    (el.firstElementChild) ? optionEl = el.firstElementChild : optionEl = null;
    (optionEl) ? options = optionEl.firstElementChild : options = null
    ProtegerMakeshop.addItemOption({num: el.getAttribute('data-num'), options: options});
  });
  
  findAll(".proteger-cart-offer").forEach((el) => {
    var num = el.getAttribute('data-num');
    var productEl = createElementFromHTML(el.getAttribute('data-product'));
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: productEl.title, id: productEl.getAttribute('href').split('/')[2], quantity: quantityEl.value, onUpdate: onUpdate};
    ProtegerMakeshop.addItem(item);
  });

  findAll(".quantityInput").forEach((el) => {
    var num = el.getAttribute('data-num');
    var quantityEl = el.firstElementChild;
    ProtegerMakeshop.addItemQuantity({num: num, quantityEl: quantityEl});
  });
  
  findAll('.proteger-cart-offer').forEach(function(el){
    var num = el.getAttribute('data-num');
    var productEl = createElementFromHTML(el.getAttribute('data-product'));
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: productEl.title, id: productEl.getAttribute('href').split('/')[2], quantity: quantityEl.value, onUpdate: onUpdate};
    if (ProtegerMakeshop.warrantyAlreadyInCart(item)) {
      return;
    }
  
    ProtegerMakeshop.renderSimplePlan(el, {
      item: item,
    });
  });

  ProtegerMakeshop.normalizeCart({balance: true});
},false);
</script>

SPの場合

<script src="https://sdk.helloproteger.com/proteger-sdk-min.js" charset="utf-8"></script>
<script src="https://sdk.helloproteger.com/v4/makeshop-cart.min.js" charset="utf-8"></script>
<script>
window.addEventListener('DOMContentLoaded', function(){
  Proteger.config({
    storeId: 'StoreID',
    logoUrl: 'ロゴURL',
    protegerEnv: "prd",
  });
  ProtegerMakeshop.config({
    makeshopId: 'MakeshopのID',
    isSP: true,
  });
  
  var slice = Array.prototype.slice;
  
  /**
   * elementを全て取得する関数を定義
   * @param {string} element クエリ
   *
   */
  function findAll(element) {
    var items = document.querySelectorAll(element);
    return items ? slice.call(items, 0) : [];
  }
  
  /**
   * 文字列からelementを作成
   * @param {string} html html文字列
   *
   */
  function createElementFromHTML(html) {
    const tempEl = document.createElement('div');
    tempEl.innerHTML = html;
    return tempEl.firstElementChild;
  }

  /**
   * 商品削除する関数
   * @param {item} item 削除するitem
   */
  function deleteItem({item}) {
    window.document.basket_form.action = "./basket.html";
    window.document.basket_form.selected_item.value=item.id;
    window.document.basket_form.selected_item_spcode.value=ProtegerMakeshop.getSpcode(item);
    window.document.basket_form.selected_item_spcode2.value="0";
    window.document.basket_form.selected_item_optcode.value="0";
    window.document.basket_form.type.value="delete_item";
 
    window.document.basket_form.submit();
  }
  
  ProtegerMakeshop.setOnDelete({onDelete: deleteItem});
  
  findAll(".proteger-cart-opt").forEach((el) => {
    var options = el.querySelectorAll(".option")[1];
    ProtegerMakeshop.addItemOption({num: el.getAttribute('data-num'), options: options});
  });
    
  findAll(".proteger-cart-offer").forEach((el) => {
    var id = el.getAttribute('data-product-id').split("=")[1];
    var num = el.getAttribute('data-num');
    var name = el.getAttribute('data-product');
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: name, id: id, quantity: quantityEl.value, onUpdate: onUpdate};
    ProtegerMakeshop.addItem(item);
  });
  
  findAll(".amount").forEach((el) => {
    var num = el.getAttribute('data-num');
    var quantityEl = el.firstElementChild;
    ProtegerMakeshop.addItemQuantity({num: num, quantityEl: quantityEl});
  });
    
  findAll('.proteger-cart-offer').forEach(function(el){
    var id = el.getAttribute('data-product-id').split("=")[1];
    var num = el.getAttribute('data-num');
    var name = el.getAttribute('data-product');
    var quantityEl = createElementFromHTML(el.getAttribute('data-quantity'));
    var onUpdate = el.getAttribute('data-update');
    var item = {num: num, name: name, id: id, quantity: quantityEl.value, onUpdate: onUpdate};
    if (ProtegerMakeshop.warrantyAlreadyInCart(item)) {
      return;
    }
    
    ProtegerMakeshop.renderSimplePlan(el, {
      item: item,
    });
  });

  ProtegerMakeshop.normalizeCart({balance: true});
},false);
</script>

完了です。

お疲れ様でした。

📘

NOTE

お困りの際は担当者または下記のメールアドレスにいつでもご連絡下さい。
[email protected]