skip to Main Content

I am struggling to understand how to use the Shopify App Proxy feature.

We have a store using Shopify Pay and multi currency, but have offsite landing pages on Unbounce and the CRO people want to use direct checkout links, ie

https://our-shopify-store.myshopify.com/cart/36485954240671:1

Which is a nice idea, but the product gets added to the cart and then redirected to checkout in the store default currency, and it needs added in an appropriate currency based on the user location.

There seems to be no way to pass currency as a parameter in the direct checkout links so I am trying to create an intermediary app running on an app proxy to intercept this request;

https://my-cunning-proxy.com/36485954240671:1

And use a 3rd party API to get the user geoip before trying to create a checkout in the user currency by posting the variant, quantity and currency to the checkout API and receiving back a checkout url to redirect the visitor to.

What I’ve tried

I’ve got an app working in development.

The app is on https://our-shopify-store.myshopify.com with an app proxy of https://my-cunning-proxy.com/

Shopify App Proxy Settings

I can access the app on https://my-cunning-proxy.com?host=our-shopify-store.myshopify.com but if I try to post to the checkout API in an included .jsx file;

const dataBody = "{"checkout":{"line_items":[{"variant_id":7699511831234,"quantity":5,"presentment_currency": "USD"}]}}";
const authtoken = 'xxxxx';
const shopifyDomain = 'https://our-shopify-store.myshopify.com/admin/api/2022-10/checkouts.json';

const response = await axios({ 
  url: shopifyDomain,
  method: 'POST',
  headers: { 
    "X-Shopify-Access-Token": authtoken,
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin":"*"
  },
  data: { 
    dataBody
  }
});
console.log(response.data);

It rejects the post based on CORS policy. I’m not sure where the Subpath prefix and Subpath even come into things. None of the following urls work, they all 404;

const shopifyDomain = '/admin/api/2022-10/checkouts.json';

const shopifyDomain = 'https://our-shopify-store.myshopify.com/apps/proxy-subpath/admin/api/2022-10/checkouts.json';

const shopifyDomain = 'https://our-shopify-store.myshopify.com/apps/admin/api/2022-10/checkouts.json';

const shopifyDomain = '/apps/proxy-path/admin/api/2022-10/checkouts.json';

Any pointers/suggestions/observations/criticisms much appreciated, it’s my first public Shopify app and it has been something of a struggle to even get to this lowly position.

2

Answers


  1. Chosen as BEST ANSWER

    As mentioned in the comments, I realised the easy solution to the problem (although not necessarily the answer to this question) was to do it using JS and not use an app at all.

    Create a custom page template that includes a div <div id="direct-checkout"></div>. In this example it has the url /pages/direct-checkout

    Assuming there is a currency switcher form template in the theme in this format;

    {%- if localization.available_countries.size > 1 -%}
        <div class="currency-switcher-form">
            <localization-form>
                {% form 'localization' %}
                    <div class="select-country" data-input-name="country2" data-selected-country="{{ localization.country.iso_code }}"></div>
                    <input type="hidden" name="country_code" value="{{ localization.country.iso_code }}">
                {% endform %}
            </localization-form>
        </div>
    {%- endif -%}
    

    You would use the following JS for both general currency switching (rather than using the badly performing and impossible to tweak Shopify Geolocation App) and also to handle the direct-to-checkout links passing product variant and quantity parameters.

    It uses a cookie to reduce the geoip API calls and would redirect users who had previously been on the site to the currency they had previously been assigned/selected.

    /*-----------------------------------------------------------------------------------*/
    /*  GeoIP currency switching
    /*-----------------------------------------------------------------------------------*/
    
    function setCurrencyCookie(countryCode) {
    
        var cookieArguments = {
          expires: 30,
          path: '/',
          domain: 'your-domain.com'
        }
        
        Cookies.set('_your-domain-geoip-currency', countryCode, cookieArguments);
    
    }
    
    var cookieName = '_your-domain-geoip-currency';
    
    if (!Cookies.get(cookieName)) {
      autoCurrencySwitch();
    } else {
      instantBuy();
    }
    
    function autoCurrencySwitch() {
    
      $.ajax( {
        url: 'https://api.ipgeolocation.io/',
        type: 'GET',
        dataType: 'json',
        success: function(location) {
            var currencyCountry= location.country_code2;
    
            $('input[name="country_code"]').val(currencyCountry);
            $(".select-country").attr('data-selected-country', currencyCountry);
            
            var form = $('form#localization_form');
            var actionUrl = form.attr('action');
    
            $.ajax({
              type: "POST",
              url: actionUrl,
              data: form.serialize(),
              success: function(data){ 
                setCurrencyCookie(currencyCountry);
                instantBuy();
              },
              error: function(errorData){
                  console.log('currency switch error', errorData);
              }
            });
            
        }
      });
    
    }
    
    /*-----------------------------------------------------------------------------------*/
    /*  Direct Checkout Redirect
    /*-----------------------------------------------------------------------------------*/                
    
    function instantBuy( ){
    
      var directCheckoutElement = document.getElementById("direct-checkout");
    
      const params = new Proxy(new URLSearchParams(window.location.search), {
        get: (searchParams, prop) => searchParams.get(prop),
      });
    
      // Example URL
      // https://your-domain.com/pages/direct-checkout?variant=417239912345&quantity=1
    
      let variantId = params.variant;
      let qty = params.quantity;
    
      if (directCheckoutElement && variantId && qty) {
    
        $.ajax({
          url: "/cart/add.js",
          type: "POST",
          data : { id: variantId, quantity: qty },
          dataType: 'json',
          success: function(data){ 
            window.location.href = "/checkout";
          },
          error: function(errorData){
              console.log('checkout redirect error', errorData);
          }
        });
    
      } else {
        return false;
      }
    
    }
    
    

    Hopefully this can help someone with the same requirement I had.


  2. I will inform you that you are indeed using App Proxy in a manner that induces head-scratching. But nonetheless, carry on.

    If you wanted to create a checkout with more correctness, you can leverage Storefront API. It is meant to provide you with access to both your products and checkout, without actually forcing your customers to use your Shopify store. You should pivot to trying that out. While it is not perfect, it is far superior to simply hitting a checkout with a variant ID, because as you have indicated, that does not work at all with multi-currency. Or does it?

    Since Shopify hacked on languages and markets recently, have you looked into markets, where you can sell to your "market" in their currency?

    Anyway, long story short, and the answer, you are getting CORS because you are doing App Proxy all wrong, and no, it cannot help you with your checkout issue!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search