Shopify/buy-button-js

Markets and currencies

lucalbert opened this issue · 14 comments

Hello,

We now use markets (and Shopify Payments) to allow our customers to pay in their local currency.

We had already integrated the possibility of retrieving the translated content of the store by setting up the client:

const client = ShopifyBuy.buildClient({
  domain: shopify.domain,
  storefrontAccessToken: shopify.token,
  language: shopify.language
})

How is it possible to set the currency (or market country)?

When the customer adds a product to the cart and proceeds to payment, the local currency is displayed correctly only when he has entered his delivery address (step 2).
Is it possible to also force the opening of the cart in a certain currency (other than the base currency of the store)?

(we also had to adapt the script to force the language of the shopping cart because the configuration of the language at the client level was not sufficient:

cart: {
  events: {
    beforeInit(cart) {
      const actualOpen = cart.checkout.open
      cart.checkout.open = function (url) {
        const newUrl = new URL(url)
        newUrl.searchParams.set('locale', shopify.language)

        let finalUrl = newUrl.toString()
        actualOpen.call(this, finalUrl)
      }
    }
  }
}

)

Thanks!

Having the same issue. Would love to know the solution.

Hey all,
I found a workaround to set the market and currencies to the checkout!

The trick is to manually create a checkout with the Shopify SDK who is built-in with the buy button.
With that, you have the control of which market you want by setting the buyerIdentity with the countryCode.
You need to manually set the local storage, so the buy button can find the existing checkout id to update it normally after.

var client = ShopifyBuy.buildClient({
    domain: '',
    storefrontAccessToken: '',
    language: getLanguage()
  });
  
var input = {
    buyerIdentity: {
      countryCode: getCountry(),
    },
};

var localStorageCheckoutKey = `${client.config.storefrontAccessToken}.${client.config.domain}.checkoutId`;

client.checkout.create(input).then((checkout) => {
    localStorage.setItem(localStorageCheckoutKey, checkout.id)
    ShopifyBuy.UI.onReady(client).then(function (ui) {

    [...]

    });
});

Thanks Simon for posting your solution!

jsyk -- I got reply from Shopify.

q: How is it possible to set the currency (or market country) in the buy button code?
a: Currently, the buy button is using your store's default currency which is CZK. The local currencies and international pricing is only available to Shopify Market and your online store. Our Developers are still working on expanding the market features to other sales channels such as the buy button. Rest assured that if in the event the feature will be available you will receive a communication from us.
When you [create a Buy Button](https://help.shopify.com/en/manual/online-sales-channels/buy-button/create-buy-button) you will see the default settings and does not have the option to set up local currencies for other regions/market yet.

q: Do you have any estimates of when we can expect the buy button to support market currencies? It's last thing we need to be able to expand on more markets :-)
a: Currently, we do not have a time frame since our Developers have to make sure that once implemented it will cause any issues across all stores. What we can assure you is that as soon as this is implemented, you will be notified or you will automatically see the changes in the market section. Rest assured that we hear and do something about your feedback and recommendations since we know that these features will benefit the platform and the business owners.


Good luck everyone trying to fix this :-)

In case someone else stumbles upon this issue looking for a solution, I've been able to set the country using a similar method as @simoncrypta and calculating the country from the browser timezone.

const client = await ShopifyBuy.buildClient({
  domain: '',
  storefrontAccessToken: '',
})

const input = {
  buyerIdentity: {
    countryCode: getUserCountryCode() // See blogpost link below
  },
}

const localStorageCheckoutKey = `${client.config.storefrontAccessToken}.${client.config.domain}.checkoutId`

// Prevent creating a checkout if there is already one available
if (!localStorage.getItem(localStorageCheckoutKey)) {
  const checkout = await client.checkout.create(input)
  localStorage.setItem(localStorageCheckoutKey, checkout.id)
}

const ui = await ShopifyBuy.UI.init(client)

Regargind the country calculation, check this blog post: https://www.techighness.com/post/get-user-country-and-region-on-browser-with-javascript-only/

Shopify country codes can be seen here: https://help.shopify.com/en/manual/payments/shopify-payments/multi-currency/international-pricing#country-codes

All the above is helpfull. Is there also a way to pass the buyerIdentity/countryCode to the product UI as well? We have a WordPress site and utilize the Buy Button for our commerce. We are expanding into Canada and will regionalize our WordPress site. Therefore when a user is in the CA region, we want the price to be the Shopify converted price for CA to show instead of USD.

@mocodev
A potential workaround solution is to have the price as a css class based element on your website and then add the Buy Button with adjusted CA price.

If you have the price as a css class based element on your CA site, you can create a js function that checks the domain of the client and changes the price to CA based on that, so it will show the client a CA price.
Then you adjust the buy button with the CA currency and on the backend in Shopify you can add a CA market zone with the CA price.

Example Buy Button

ShopifyBuy.UI.onReady(client).then(function (ui) {
      ui.createComponent('product', {
        id: 'XXXXXXX',
        moneyFormat: 'CA {{amount_no_decimals}}'
  // rest of buy button code
  } }

Hope, that makes sense.

Hey all, I found a workaround to set the market and currencies to the checkout!

The trick is to manually create a checkout with the Shopify SDK who is built-in with the buy button. With that, you have the control of which market you want by setting the buyerIdentity with the countryCode. You need to manually set the local storage, so the buy button can find the existing checkout id to update it normally after.

var client = ShopifyBuy.buildClient({
    domain: '',
    storefrontAccessToken: '',
    language: getLanguage()
  });
  
var input = {
    buyerIdentity: {
      countryCode: getCountry(),
    },
};

var localStorageCheckoutKey = `${client.config.storefrontAccessToken}.${client.config.domain}.checkoutId`;

client.checkout.create(input).then((checkout) => {
    localStorage.setItem(localStorageCheckoutKey, checkout.id)
    ShopifyBuy.UI.onReady(client).then(function (ui) {

    [...]

    });
});

Just wanted to thank @simoncrypta this solution really works!

I will also add that - if you expect it to work well with COD then just don't. It's pain - we ended up creating a second store. Shame on @shopify-admins for not solving this for years. I bet investors are happy to have AI features in the latest "editions" all over the place - now please do what Shopify should do. Sell shit... same goes for manual stuff like wire transfers.

I will also add that - if you expect it to work well with COD then just don't. It's pain - we ended up creating a second store. Shame on @shopify-admins for not solving this for years. I bet investors are happy to have AI features in the latest "editions" all over the place - now please do what Shopify should do. Sell shit... same goes for manual stuff like wire transfers.

@Toooorch btw here is the answer from Shopify support I got yesterday 19.12.2023

> It is not currently possible to configure multiple local currencies in your existing store. However, setting up a new store with the desired currency is indeed a viable option for you to consider. I want to assure you that your feedback has been duly noted and shared with our team. We greatly appreciate your input and suggestions, as they play a crucial role in shaping future updates to the Shopify system.

I will also add that - if you expect it to work well with COD then just don't. It's pain - we ended up creating a second store. Shame on @shopify-admins for not solving this for years. I bet investors are happy to have AI features in the latest "editions" all over the place - now please do what Shopify should do. Sell shit... same goes for manual stuff like wire transfers.

@Toooorch btw here is the answer from Shopify support I got yesterday 19.12.2023

> It is not currently possible to configure multiple local currencies in your existing store. However, setting up a new store with the desired currency is indeed a viable option for you to consider. I want to assure you that your feedback has been duly noted and shared with our team. We greatly appreciate your input and suggestions, as they play a crucial role in shaping future updates to the Shopify system.

Oh my! What are the @shopify-admins thinking? Duplicating all these products just for currency variations seems excessive, especially since I already have a shop with nearly 700 products...

Additionally, while @simoncrypta's solution works for calculating the card sum, it's not accurately retrieving the price in the correct currency.

@sercan-uzun you are right, regarding the pricing a workaround for few products is to duplicate the product and then set the price to the target currencies price so e.g.

Product 600 EUR I 700 CHF
Duplicated Product 700 EUR I 700 CHF

And then pull the duplicated product into the cart with converted currency. This way the user sees the correct price on the front end and when they proceed to the next step the price is either already correct, or gets adjusted to the correct price by Shopify.

But this is not really feasable for 700 products

Hey all, I found a workaround to set the market and currencies to the checkout!

The trick is to manually create a checkout with the Shopify SDK who is built-in with the buy button. With that, you have the control of which market you want by setting the buyerIdentity with the countryCode. You need to manually set the local storage, so the buy button can find the existing checkout id to update it normally after.

var client = ShopifyBuy.buildClient({
    domain: '',
    storefrontAccessToken: '',
    language: getLanguage()
  });
  
var input = {
    buyerIdentity: {
      countryCode: getCountry(),
    },
};

var localStorageCheckoutKey = `${client.config.storefrontAccessToken}.${client.config.domain}.checkoutId`;

client.checkout.create(input).then((checkout) => {
    localStorage.setItem(localStorageCheckoutKey, checkout.id)
    ShopifyBuy.UI.onReady(client).then(function (ui) {

    [...]

    });
});

@simoncrypta hi, would you mind letting me know where to paste this code? i am wanting to fix the same problem...i tried just pasting it at the the top of my embedded buy button, but it disabled it... i don't know anything about js. many thanks.

Hello friends,

I have forked a version of the buybutton that supports customAttributes (thx Innovation-Magic-LLC/buy-button-js-customattributes) and added/hacked support for the new cart graphQL API. This means that this version has support for pricing per market and has also line item displayed in the right language. Hope this helps.

https://github.com/jadetr/buy-button-js