Skip to content
On this page

Checkout · Home > Payments > Payske Checkout

Present local currencies

Present prices and charge payments in your customer’s local currency using Checkout or Payment Links.

Prospective customers might abandon the checkout flow when prices aren’t presented in their local currency, and some payment methods might also require local currency. For businesses in the US and Canada, present local currency prices for one-time payments by turning on automatic currency conversion using Checkout and Payment Links, without the need to update your integration.

Before you begin

Depending on the user selected currency, the CheckoutSession and the underlying PaymentIntent objects update automatically to reflect the selected currency and amount. Because presenting in a customer’s local currency changes both the underlying CheckoutSession object and the PaymentIntent’s currency, make sure that your custom integrations are set up for handling the new localized currencies.

Automatic currency conversion | Multi-currency prices

Automatic currency conversion is a Checkout and Payment Links feature available to businesses in the US and Canada that converts prices based on location. Customers see prices converted to the local currency, along with the exchange rate and supported payment methods. They still have the option to pay in the original currency you set for your prices. Prices convert using the latest Payske-provided exchange rate, which we lock for the lifetime of the Checkout Session (up to 24 hours) through settlement. The lock stays in place as long as the exchange rate doesn’t change by more than 2%. Specify the currency of your Checkout Session or set multi-currency prices to override automatically converted prices.

Supported currencies and integrations

Automatic currency conversion supports conversion from CAD and USD to AUD, CAD, CHF, EUR, GBP, JPY, MXN, NOK, SEK, SGD, and USD.

Automatic currency conversion requires the currency for your prices to be the same as your default settlement currency in USD or CAD. Checkout Sessions won’t convert automatically if the currency value is set on creation. Any standard prices you create on a product and inline prices defined on line_items that use price_data automatically convert during checkout. Automatic currency conversion doesn’t apply for any Sessions with multi-currency prices, subscriptions, or the following integrations:

  • Checkout Sessions using Connect
  • Checkout Sessions using client-only integration
  • Checkout Sessions using manual capture

For Sessions that aren’t supported by automatic currency conversion, customers are presented prices in the original currency that you’ve set your prices in.

Enable automatic currency conversion

Enable automatic currency conversion in test mode or live mode in your Automatic currency conversion settings. Disabling automatic currency conversion doesn’t affect Checkout Sessions that have already been converted. Learn more about the fees associated with automatic currency conversion.

Test currency presentment

In the Checkout Session creation method, pass in a customer_email that includes a suffix in a +location_XX format in the local part of the email. XX must be a valid two-letter ISO country code.

console
curl https://api.payske.com/v1/checkout/sessions \
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
  -d "line_items[0][price]"="{{PRICE_ID}}" \
  -d "line_items[0][quantity]"=1 \
  -d mode=payment \
  -d success_url="https://example.com/success" \
  -d cancel_url="https://example.com/cancel" \
  --data-urlencode customer_email="test+location_FR@example.com"
console
payske checkout sessions create  \
  -d "line_items[0][price]"="{{PRICE_ID}}" \
  -d "line_items[0][quantity]"=1 \
  --mode=payment \
  --success-url="https://example.com/success" \
  --cancel-url="https://example.com/cancel" \
  --customer-email="test+location_FR@example.com"
ruby
# Set your secret key. Remember to switch to your live secret key in production.
# See your keys here: https://account.payske.com/api/key
Payske.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'

Payske::Checkout::Session.create(
  {
    line_items: [{price: '{{PRICE_ID}}', quantity: 1}],
    mode: 'payment',
    success_url: 'https://example.com/success',
    cancel_url: 'https://example.com/cancel',
    customer_email: 'test+location_FR@example.com',
  },
)
python
# Set your secret key. Remember to switch to your live secret key in production.
# See your keys here: https://account.payske.com/api/key
import payske
payske.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"

payske.checkout.Session.create(
  line_items=[{"price": "{{PRICE_ID}}", "quantity": 1}],
  mode="payment",
  success_url="https://example.com/success",
  cancel_url="https://example.com/cancel",
  customer_email="test+location_FR@example.com",
)
php
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
$payske = new \Payske\PayskeClient('sk_test_4eC39HqLyjWDarjtT1zdp7dc');

$payske->checkout->sessions->create(
  [
    'line_items' => [['price' => '{{PRICE_ID}}', 'quantity' => 1]],
    'mode' => 'payment',
    'success_url' => 'https://example.com/success',
    'cancel_url' => 'https://example.com/cancel',
    'customer_email' => 'test+location_FR@example.com',
  ]
);
java
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
Payske.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";

SessionCreateParams params =
  SessionCreateParams
    .builder()
    .addLineItem(
      SessionCreateParams.LineItem
        .builder()
        .setPrice("{{PRICE_ID}}")
        .setQuantity(1L)
        .build()
    )
    .setMode(SessionCreateParams.Mode.PAYMENT)
    .setSuccessUrl("https://example.com/success")
    .setCancelUrl("https://example.com/cancel")
    .setCustomerEmail("test+location_FR@example.com")
    .build();

Session session = Session.create(params);
typescript
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
const payske = require('payske')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');

const session = await payske.checkout.sessions.create({
  line_items: [{price: '{{PRICE_ID}}', quantity: 1}],
  mode: 'payment',
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  customer_email: 'test+location_FR@example.com',
});
go
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
payske.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"

params := &payske.CheckoutSessionParams{
  LineItems: []*payske.CheckoutSessionLineItemParams{
    &payske.CheckoutSessionLineItemParams{
      Price: payske.String("{{PRICE_ID}}"),
      Quantity: payske.Int64(1),
    },
  },
  Mode: payske.String(string(payske.CheckoutSessionModePayment)),
  SuccessURL: payske.String("https://example.com/success"),
  CancelURL: payske.String("https://example.com/cancel"),
  CustomerEmail: payske.String("test+location_FR@example.com"),
};
result, _ := session.New(params);
csharp
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
PayskeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";

var options = new SessionCreateOptions
{
    LineItems = new List<SessionLineItemOptions>
    {
        new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1 },
    },
    Mode = "payment",
    SuccessUrl = "https://example.com/success",
    CancelUrl = "https://example.com/cancel",
    CustomerEmail = "test+location_FR@example.com",
};
var service = new SessionService();
service.Create(options);

When you visit the URL for the Session created with customer_email, you see the same currency as your customer when they’re in the specified country.

As an alternative to customer_email, you can also create a Customer and specify their email that contains the +location_XX suffix.

When it’s possible to present the customer’s local currency in Checkout, the Checkout Session object changes. Fields like currency, payment_method_types, and amount_total reflect the local currency and price.

For Payment Links, you can use the prefilled_email URL parameter to test currency presentment for customers in different countries. Pass in an email address that includes a suffix in a +location_XX format in the local part of the email where XX is a valid two-letter ISO country code.

Exchange rate

We lock the exchange rate for the duration of the Checkout Session (up to 24 hours) and guarantee the same rate for settlement if the rate doesn’t change by more than 2%. If the exchange rate changes by more than 2% from the Checkout locked rate or if you change your default settlement currency, we might use an updated exchange rate when calculating your payout.

Refunds

We issue refunds in the currency that your customer pays in using latest Payske-provided exchange rate to calculate the refund amount. You might pay more or less to cover the refund depending on how rates change. For example, if your settlement currency is CAD and you process a 60 USD payment with a Payske-provided rate of 1.37 CAD per 1 USD, the converted amount is 82.12 CAD (excluding Payske fees). If the Payske-provided rate is 1.35 CAD per 1 USD at the time of refund, the amount deducted from your account balance would be 81 CAD.

If you’re using the Dashboard to refund, we display the currency that you use for payments.

If you have a custom refund integration using the API, make sure the refund amount is in the correct currency.

API and webhooks

Depending on the user selected currency, both the CheckoutSession and the underlying PaymentIntent objects update automatically to reflect the selected currency and amount. After a user pays in local currency, the CheckoutSession object’s currency and total amount is in local currency and contains a currency_conversion hash to reflect what the user would have paid in the default currency. Learn more about what’s deposited in your account after fees.

The CheckoutSession completed event webhook contains the currency_conversion hash that includes the amount_total and amount_subtotal in the source_currency. The amounts reflect what your customer would have paid in the source currency.

json
{
  "id": "evt_123456789",
  "object": "event",
  "type": "checkout.session.completed",
  // ...other webhook attributes
  "data": {
    "object": {
      "id": "cs_12356789",
      "object": "checkout.session",
      "currency": "cad",
      "amount_total": 2055,
      "amount_subtotal": 2055,
      // ...other Checkout Session attributes,
      "currency_conversion": {
       "amount_subtotal": 1500,
       "amount_total": 1500,
       "source_currency": "usd",
       "fx_rate": 1.37,
      }
     }
   }
}

Reporting

Review your reporting and other integrations to make sure that they can handle the Webhooks and PaymentIntent objects in the local currency. To determine what your customer would have paid in the default currency, use the currency_conversion hash on the CheckoutSession object. Use the BalanceTransactions API to determine how much you pay after fees.

Multi-currency prices

You can create multi-currency Prices in the API or the Dashboard. Checkout displays prices that you set in the relevant currency based on your customer’s location. If you have automatic currency conversion enabled, sessions with multi-currency prices for the customer’s local currency don’t convert automatically.

From the Product details page for a product in your Dashboard, click +Add another price to create a new price. The first currency on your Price is the default currency. Make sure that all your Prices have the same default currency. After you select the default currency, click +Add more currencies to add currency options to your Price. You can search and select from supported currencies. Payske suggests an exchange rate based on currency values at 12:00 PM EST, but you can pick your own. After you fill in the details, click Add price to save it. Use the multi-currency Price IDs that you create by passing them into the line items when you create a Checkout Session.

Supported integrations

When a customer loads a Checkout Session, Checkout tries to automatically present the customer’s local currency as determined by their IP address. Checkout automatically presents the local currency if all of the following are true:

  • The Session’s Prices, Shipping Rates, and Coupons with amount_off have the relevant currency in their currency_options.
  • If a Price on the Session has an upsell, the upsell’s Price has the relevant currency in its currency_options.
  • You didn’t specify a currency during Checkout Session creation.

Price localization isn’t available for:

  • Checkout Sessions that use payment_intent_data.application_fee_amount or payment_intent_data.transfer_data.amount.

Test currency presentment

Use the API to test what your Checkout Sessions look like for customers in different countries.

In the Checkout Session creation method, pass in a customer_email that includes a suffix in a +location_XX format in the local part of the email. XX must be a valid two-letter ISO country code.

console
curl https://api.payske.com/v1/checkout/sessions \
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
  -d "line_items[0][price]"="{{PRICE_ID}}" \
  -d "line_items[0][quantity]"=1 \
  -d mode=payment \
  -d success_url="https://example.com/success" \
  -d cancel_url="https://example.com/cancel" \
  --data-urlencode customer_email="test+location_FR@example.com"
console
payske checkout sessions create  \
  -d "line_items[0][price]"="{{PRICE_ID}}" \
  -d "line_items[0][quantity]"=1 \
  --mode=payment \
  --success-url="https://example.com/success" \
  --cancel-url="https://example.com/cancel" \
  --customer-email="test+location_FR@example.com"
ruby
# Set your secret key. Remember to switch to your live secret key in production.
# See your keys here: https://account.payske.com/api/key
Payske.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'

Payske::Checkout::Session.create(
  {
    line_items: [{price: '{{PRICE_ID}}', quantity: 1}],
    mode: 'payment',
    success_url: 'https://example.com/success',
    cancel_url: 'https://example.com/cancel',
    customer_email: 'test+location_FR@example.com',
  },
)
python
# Set your secret key. Remember to switch to your live secret key in production.
# See your keys here: https://account.payske.com/api/key
import payske
payske.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"

payske.checkout.Session.create(
  line_items=[{"price": "{{PRICE_ID}}", "quantity": 1}],
  mode="payment",
  success_url="https://example.com/success",
  cancel_url="https://example.com/cancel",
  customer_email="test+location_FR@example.com",
)
php
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
$payske = new \Payske\PayskeClient('sk_test_4eC39HqLyjWDarjtT1zdp7dc');

$payske->checkout->sessions->create(
  [
    'line_items' => [['price' => '{{PRICE_ID}}', 'quantity' => 1]],
    'mode' => 'payment',
    'success_url' => 'https://example.com/success',
    'cancel_url' => 'https://example.com/cancel',
    'customer_email' => 'test+location_FR@example.com',
  ]
);
java
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
Payske.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";

SessionCreateParams params =
  SessionCreateParams
    .builder()
    .addLineItem(
      SessionCreateParams.LineItem
        .builder()
        .setPrice("{{PRICE_ID}}")
        .setQuantity(1L)
        .build()
    )
    .setMode(SessionCreateParams.Mode.PAYMENT)
    .setSuccessUrl("https://example.com/success")
    .setCancelUrl("https://example.com/cancel")
    .setCustomerEmail("test+location_FR@example.com")
    .build();

Session session = Session.create(params);
typescript
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
const payske = require('payske')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');

const session = await payske.checkout.sessions.create({
  line_items: [{price: '{{PRICE_ID}}', quantity: 1}],
  mode: 'payment',
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  customer_email: 'test+location_FR@example.com',
});
go
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
payske.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"

params := &payske.CheckoutSessionParams{
  LineItems: []*payske.CheckoutSessionLineItemParams{
    &payske.CheckoutSessionLineItemParams{
      Price: payske.String("{{PRICE_ID}}"),
      Quantity: payske.Int64(1),
    },
  },
  Mode: payske.String(string(payske.CheckoutSessionModePayment)),
  SuccessURL: payske.String("https://example.com/success"),
  CancelURL: payske.String("https://example.com/cancel"),
  CustomerEmail: payske.String("test+location_FR@example.com"),
};
result, _ := session.New(params);
csharp
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
PayskeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";

var options = new SessionCreateOptions
{
    LineItems = new List<SessionLineItemOptions>
    {
        new SessionLineItemOptions { Price = "{{PRICE_ID}}", Quantity = 1 },
    },
    Mode = "payment",
    SuccessUrl = "https://example.com/success",
    CancelUrl = "https://example.com/cancel",
    CustomerEmail = "test+location_FR@example.com",
};
var service = new SessionService();
service.Create(options);

When you visit the URL for the Session created with customer_email, you see the same currency as your customer when they’re in the specified country.

As an alternative to customer_email, you can also create a Customer and specify their email that contains the +location_XX suffix.

When it’s possible to present the customer’s local currency in Checkout, the Checkout Session object changes. Fields like currency, payment_method_types, and amount_total reflect the local currency and price.

For Payment Links, you can use the prefilled_email URL parameter to test currency presentment for customers in different countries. Pass in an email address that includes a suffix in a +location_XX format in the local part of the email where XX is a valid two-letter ISO country code.

Specify a currency

When you use multi-currency Prices in a Session, Checkout automatically handles currency localization for your customers. However, you can override this behavior by specifying a currency during Checkout Session creation.

console
curl https://api.payske.com/v1/checkout/sessions \
  -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
  -d "line_items[0][price]"="{{PRICE_ID}}" \
  -d "line_items[0][quantity]"=1 \
  -d mode=payment \
  -d success_url="https://example.com/success" \
  -d cancel_url="https://example.com/cancel" \
  --data-urlencode customer_email="test+location_FR@example.com"
console
payske checkout sessions create  \
  --mode=payment \
  --success-url="https://example.com/success" \
  --cancel-url="https://example.com/cancel" \
  --customer-email="test+location_FR@example.com"
ruby
# Set your secret key. Remember to switch to your live secret key in production.
# See your keys here: https://account.payske.com/api/key
Payske.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'

Payske::Checkout::Session.create(
  {
    mode: 'payment',
    success_url: 'https://example.com/success',
    cancel_url: 'https://example.com/cancel',
    customer_email: 'test+location_FR@example.com',
  },
)
python
# Set your secret key. Remember to switch to your live secret key in production.
# See your keys here: https://account.payske.com/api/key
import payske
payske.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"

payske.checkout.Session.create(
  mode="payment",
  success_url="https://example.com/success",
  cancel_url="https://example.com/cancel",
  customer_email="test+location_FR@example.com",
)
php
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
$payske = new \Payske\PayskeClient('sk_test_4eC39HqLyjWDarjtT1zdp7dc');

$payske->checkout->sessions->create(
  [
    'mode' => 'payment',
    'success_url' => 'https://example.com/success',
    'cancel_url' => 'https://example.com/cancel',
    'customer_email' => 'test+location_FR@example.com',
  ]
);
java
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
Payske.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";

SessionCreateParams params =
  SessionCreateParams
    .builder()
    .setMode(SessionCreateParams.Mode.PAYMENT)
    .setSuccessUrl("https://example.com/success")
    .setCancelUrl("https://example.com/cancel")
    .setCustomerEmail("test+location_FR@example.com")
    .build();

Session session = Session.create(params);
typescript
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
const payske = require('payske')('sk_test_4eC39HqLyjWDarjtT1zdp7dc');

const session = await payske.checkout.sessions.create({
  mode: 'payment',
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  customer_email: 'test+location_FR@example.com',
});
go
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
payske.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"

params := &payske.CheckoutSessionParams{
  Mode: payske.String(string(payske.CheckoutSessionModePayment)),
  SuccessURL: payske.String("https://example.com/success"),
  CancelURL: payske.String("https://example.com/cancel"),
  CustomerEmail: payske.String("test+location_FR@example.com"),
};
result, _ := session.New(params);
csharp
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://account.payske.com/api/key
PayskeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";

var options = new SessionCreateOptions
{
    Mode = "payment",
    SuccessUrl = "https://example.com/success",
    CancelUrl = "https://example.com/cancel",
    CustomerEmail = "test+location_FR@example.com",
};
var service = new SessionService();
service.Create(options);

In the example above, the Checkout Session’s currency is always EUR (eur) regardless of a user’s location.