← back to Dw Vendor Microsites

vendors/gracie/viewer/public/buybutton.js

71 lines

/* Shopify sample checkout for the DW vendor microsites.
 *
 * These vendor lines are OFF Shopify (no per-product Shopify variant), so "Request
 * Sample" cannot add a per-product variant. Instead it uses ONE generic "Memo Sample"
 * Shopify product/variant and adds it to a real Shopify cart once per requested swatch,
 * carrying each swatch's pattern/color/SKU/vendor as line-item custom properties, then
 * opens Shopify's secure hosted checkout. The order line-items tell fulfillment which
 * swatches to pull.
 *
 * Config is injected by the server at /config.js as window.DWV_CFG = {
 *   domain: '<store>.myshopify.com', storefrontToken: '<token>', sampleVariantId: '<gid or numeric>'
 * }. Until storefrontToken + sampleVariantId are set, this falls back to the no-payment
 * JSONL sample-request endpoint (POST /api/sample-request) so the button always works.
 */
(function () {
  var CFG = window.DWV_CFG || {};
  var ready = CFG.storefrontToken && CFG.sampleVariantId && CFG.domain;
  var client = null, checkoutId = null;

  function loadSDK(cb) {
    if (window.ShopifyBuy && window.ShopifyBuy.buildClient) return cb();
    var s = document.createElement('script');
    s.src = 'https://sdks.shopifycdn.com/js-buy-sdk/latest/index.umd.min.js';
    s.onload = cb; s.onerror = function () { ready = false; cb(); };
    document.head.appendChild(s);
  }

  function ensureClient(cb) {
    if (client) return cb();
    loadSDK(function () {
      if (!window.ShopifyBuy || !ready) { ready = false; return cb(); }
      client = window.ShopifyBuy.buildClient({ domain: CFG.domain, storefrontAccessToken: CFG.storefrontToken });
      client.checkout.create().then(function (co) { checkoutId = co.id; cb(); }).catch(function () { ready = false; cb(); });
    });
  }

  // items: [{sku, mfr_sku, pattern_name, color_name, line}]  -> Shopify checkout
  function shopifyCheckout(items, contact) {
    return new Promise(function (resolve, reject) {
      ensureClient(function () {
        if (!ready || !client || !checkoutId) return reject(new Error('shopify-unavailable'));
        var lines = items.slice(0, 250).map(function (it) {
          return {
            variantId: CFG.sampleVariantId,
            quantity: 1,
            customAttributes: [
              { key: 'Pattern', value: String(it.pattern_name || it.sku || '') },
              { key: 'Color', value: String(it.color_name || '') },
              { key: 'SKU', value: String(it.mfr_sku || it.sku || '') },
              { key: 'Line', value: String(it.line || '') }
            ]
          };
        });
        var attrs = [];
        if (contact && contact.name) attrs.push({ key: 'Requested by', value: contact.name });
        var p = client.checkout.addLineItems(checkoutId, lines);
        p.then(function (co) {
          if (attrs.length) return client.checkout.updateAttributes(checkoutId, { customAttributes: attrs }).then(function () { return co; });
          return co;
        }).then(function (co) { window.location.href = co.webUrl; resolve(co); }).catch(reject);
      });
    });
  }

  // Expose for the viewer's sample modal. Returns true if Shopify path is wired.
  window.DWV_SAMPLE = {
    available: function () { return !!ready; },
    checkout: shopifyCheckout
  };
})();