# Offering local pricing

If you'd like to pair [Prebuilt Checkout](/digital-river-api/integration-options/low-code-checkouts/drop-in-checkout.md) with [local pricing](/digital-river-api/using-our-services/local-pricing.md), this page contains information on:

* [Setting up the shopping experience](#setting-up-the-shopping-experience)
* [How product prices are displayed throughout the shopping experience](#product-prices-during-the-shopping-experience)
* [Accessing price formatting rules](#access-price-formatting-rules)

All of the local pricing functionality exists within [DigitalRiverCheckout.js](/digital-river-api/developer-resources/digitalrivercheckout.js-reference.md).

## Setting up the shopping experience

When building your shopping experience, one possible solution is to wait until the document loads and then, at a minimum, define [`containerId`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/initializing-digitalrivercheckout.js/digitalrivercheckout-configuration-object.md#containerid). Digital River needs this value to determine where to display the [local pricing selector](/digital-river-api/using-our-services/local-pricing.md#local-pricing-selector). Although it's not a hard requirement, you should also populate [`priceElement`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/initializing-digitalrivercheckout.js/digitalrivercheckout-configuration-object.md#priceelement) so we know which of your [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) elements contain product prices.

You also have the option to define how you want to handle various [selector events](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/initializing-digitalrivercheckout.js/digitalrivercheckout-configuration-object.md#local-pricing-selector-events). These events can be useful for testing, analytics, and triggering redirections. For example, you might handle [`onSave`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/initializing-digitalrivercheckout.js/digitalrivercheckout-configuration-object.md#onsave) by checking the value of `country`, and then, if it's `US` or `CA`, redirect to a customized experience or store for shoppers in those countries.

```javascript
document.addEventListener('DOMContentLoaded', () => {
  const config = {
    countrySelector: {
      containerId: 'country-selector',
      priceElement: ['div.price', 'span.price'],
      autoOpen: true,
      onReady: () => {},
      onOpen: () => {},
      onSelect: (data) => {},
      onSave: (data) => {},
      onCancel: () => {}
    }
  };
  ...
```

You can then use this [configuration object](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/initializing-digitalrivercheckout.js/digitalrivercheckout-configuration-object.md) to [initialize DigitalRiverCheckout.js](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/initializing-digitalrivercheckout.js.md).

```javascript
  ...
  const digitalRiverCheckout = new DigitalRiverCheckout('Your public API key', config);
  ...
```

If you want Digital River to create a checkout button, call [`renderButton()`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button.md).

<pre class="language-javascript"><code class="lang-javascript"><strong>  ...
</strong><strong>  digitalRiverCheckout.renderButton(buttonContainer, buttonOptions);
</strong><strong>  ...
</strong></code></pre>

The function's [first parameter](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button.md#button-container) is the element's `id` where you want the button to display.

```javascript
 <div id="button-container"></div>
 ...
 const buttonContainer = '#button-container';
 ...
```

The [second parameter](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button.md#button-options) is a configuration object that, among other things, allows you to (1) [style the button](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button.md#style-the-button), (2) [modify its text](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button.md#customize-the-buttons-text), and (3) [hide your elements](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button.md#hide-elements).

```javascript
  ...
  const buttonOptions = {
    style: {
      backgroundColor: '#B52',
      borderRadius: '100px',
      color: '#5C6',
      fontSize: '2rem',
      fontWeight: '800',
      fontFamily: 'Montserrat,Arial,Helvetica,sans-serif',
      ':hover': {
        color: 'rgb(0, 167, 225)'
      }
    },
    buttonText: 'Proceed to checkout',
    hiddenElement: ['#checkout-btn'],
    afterRender: true,
    onInit: (actions) => {
      console.log('The button has rendered');
    },
    ...
    onCancel: () => {
      console.log('The checkout window has been closed');
    }
  };
  ...
});
```

This object also contains an [`onClick`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button.md#button-click-event) property to assign an [`async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) event-handling procedure. One way to define it is by using a [`try...catch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch) block that first calls [`actions.loading.start()`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button/performing-actions-on-the-checkout-button.md#start-and-stop-a-loading-spinner) and then your own create checkout-session function. Make sure to use [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) with this expression so that the handler pauses until a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) is returned.

```javascript
  ...
  const buttonOptions = {
    ...
    onClick: async (actions) => {
      console.log('The button has been clicked');
      try {
        actions.loading.start();
        const checkoutSessionId = await createCheckoutSession();
        actions.loading.stop();
        if (!checkoutSessionId) {
          return;
        }
        const config = getConfigObj();
        actions.checkout.modal.open(checkoutSessionId, config);
      } catch (error) {
        actions.loading.stop();
      }
    },
    ...
  };
  ...
});
```

On your front-end, in `onClick`, call [`actions.loading.stop()`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button/performing-actions-on-the-checkout-button.md#start-and-stop-a-loading-spinner) and then check the value of the promise. If it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy), your procedure should reject it and halt execution. Otherwise, pass the returned identifier and, optionally, a [configuration object](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/configuring-prebuilt-checkout.md) to [`actions.checkout.modal.open()`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/rendering-a-checkout-button/performing-actions-on-the-checkout-button.md#open-a-checkout-modal).

## Configuring the checkout-session for local pricing

When defining the [checkout-session](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/drop-in-checkout-sessions/checkout-sessions-basics):

* Call [`digitalRiver.getCountry()`](https://docs.digitalriver.com/digital-river-api/integration-options/low-code-checkouts/pages/ZqmFekSL0GwsOtUOpP5s#digitalriverpricing.getcountry) and [`digitalRiver.getCurrency()`](https://docs.digitalriver.com/digital-river-api/integration-options/low-code-checkouts/pages/ZqmFekSL0GwsOtUOpP5s#digitalriverpricing.getcurrency) and then assign the returned values to the [`shoppingCountry` ](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/drop-in-checkout-sessions/checkout-sessions-basics#shopping-country)and [`currency` ](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/drop-in-checkout-sessions/checkout-sessions-basics#currency)parameters, respectively.
* For each product in the customer's cart, retrieve its original, unconverted price and assign it to [`items[].price`](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/drop-in-checkout-sessions/checkout-sessions-basics#product-data).
* If you're discounting an entire transaction or individual line items within that transaction, use `discount.percentOff` or `items[].discount.percentOff`. In both cases, don't define `amountOff`.

On your server side, send a [`POST /drop-in/checkout-sessions`](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/drop-in-checkout-sessions#drop-in-checkout-sessions) request and include your [secret API key](https://docs.digitalriver.com/digital-river-api-reference/digital-river-api-reference-guide/api-structure#confidential-keys).

## Product prices during the shopping experience

Digital River uses the [checkout-session's](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/drop-in-checkout-sessions/checkout-sessions-basics) `shoppingCountry`, `currency`, and `items[].price` to perform another currency conversion, apply the same [rounding](/digital-river-api/using-our-services/local-pricing.md#rounding-logic) and [formatting](#access-price-formatting-rules) rules used to display prices on your site. As a result, the currency-denominated prices customers see on your storefront and in your cart are identical to those in the checkout experience.

{% tabs %}
{% tab title="Storefront " %}

<div align="left"><figure><img src="/files/IYcqUk2dTkBRQJ807BnR" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Cart" %}

<div align="left"><figure><img src="/files/eOyYN8wnrpxfObVn2D9e" alt="" width="375"><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Prebuilt Checkout" %}

<div align="left"><figure><img src="/files/LELvCB5uguBECc9l3xQh" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Components" %}

<div align="left"><figure><img src="/files/NhQsup6ZRMW2ifQUI01T" alt=""><figcaption></figcaption></figure></div>
{% endtab %}
{% endtabs %}

## Access price formatting rules

Once customers provide payment, complete their purchase, and Digital River converts the [checkout-session](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/drop-in-checkout-sessions) to an [order](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/orders), we add `pricingFormat` to the [event ](https://docs.digitalriver.com/digital-river-api-reference/2021-12-13/events)with a [`type`](/digital-river-api/order-management/events-and-webhooks-1/events-1.md#event-types) of [`checkout_session.order.created`](https://docs.digitalriver.com/digital-river-api/integration-options/low-code-checkouts/pages/okHqAQ9d1PaLPLjq6nZF#checkout_session.order.created).

{% code title="checkout\_session.order.created" %}

```json
{
    "id": "dacc88d7-3f88-469b-9764-35a15681e6c9",
    ...
            "pricingFormat": {
                "currencyNumberFormat": "#,###.##",
                "symbol": "₩",
                "decimalPlaces": 0,
                "currencySymbolBeforePrice": true,
                "useCurrencySymbolSpace": false
            },
            "liveMode": false
        }
    },
    ...
}
```

{% endcode %}

This object contains Digital River's rules for formatting prices throughout the [shopping experience](#product-prices-during-the-shopping-experience). To maintain a consistent format, you can apply these rules to the prices in your [customer notifications](/digital-river-api/order-management/customer-notifications.md) and your site's order management pages.

{% hint style="info" %}
You can also access `pricingFormat` by assigning a handler to [`onCheckoutComplete`](/digital-river-api/developer-resources/digitalrivercheckout.js-reference/digitalrivercheckout-object/configuring-prebuilt-checkout.md#oncheckoutcomplete).
{% endhint %}

```json
{
    "id": "764ddbdd-0f7e-448d-b044-196f67dd1781",
    "type": "checkout_session.order.created",
    "data": {
        "object": {
            ...
            "pricingFormat": {
                "currencyNumberFormat": "#,###.##",
                "symbol": "¥",
                "decimalPlaces": 0,
                "currencySymbolBeforePrice": true,
                "useCurrencySymbolSpace": false
            },
            ...
        }
    },
    ...
}
```

{% hint style="success" %}
If you don't want to build your formatter, many server-side languages have pre-built functions that roughly approximate the formatter Digital River uses. Depending on your application, you might find some of the following pages useful:

* [Java: Numbers and currencies](https://docs.oracle.com/javase/tutorial/i18n/format/numberintro.html)
* [PHP: Number and currency formatter](https://www.php.net/manual/en/numberformatter.formatcurrency.php)
* [Python: Internationalization services](https://rubymoney.github.io/money/)
* [Ruby: Money](https://rubymoney.github.io/money/)
  {% endhint %}

The following objects are nested in `pricingFormat`:

* [`currencyNumberFormat`](#currencynumberformat)
* [`symbol`](#symbol)
* [`decimalPlaces`](#decimalplaces)
* [`currencySymbolBeforePrice`](#currencynumberformat)
* [`useCurrencySymbolSpace`](#usecurrencysymbolspace)

#### `currencyNumberFormat`

You can use `currencyNumberFormat` to determine how to display the integer and fractional parts of a price.

Its value indicates whether the character that groups digits in the integer part should be a comma (`,`), a point (`.`), an apostrophe (`'`), a whitespace( ), or some other character. It also dictates the correct spacing of this character.

Additionally, `currencyNumberFormat` allows you to determine whether the character that separates the price's integer part from its fractional part should be a point or a comma.

{% tabs %}
{% tab title="Example 1" %}
In the following example, `currencyNumberFormat` groups the digits in the integer part with a comma placed every third digit to the left of a point, which acts as the separator between the price's integer and fractional parts.

```json
"currencyNumberFormat": "#,###.##"
```

**Target output in UI**

<div align="left"><img src="/files/TKjaHKxMEcuvuOB7amUi" alt=""></div>
{% endtab %}

{% tab title="Example 2" %}
In the following example, `currencyNumberFormat` groups the digits in the integer part by a point placed every third digit to the left of a comma, which acts as the separator between the price's integer and fractional parts.

```json
"currencyNumberFormat": "#.###,##"
```

**Target output in UI**

<div align="left"><img src="/files/oIIljQRWAEtoeScq7wNF" alt=""></div>
{% endtab %}

{% tab title="Example 3" %}
In the following example, `currencyNumberFormat` groups the digits in the integer part first by a comma placed every third digit to the left of a point, which acts as the separator between the price's integer and fractional parts.

After that, digits in the integer part should follow a two-digit grouping pattern.

```json
"currencyNumberFormat": "#,##,###.##"
```

**Target output in UI**

<div align="left"><img src="/files/LrPkdGg9I3B4PcWiapZ1" alt=""></div>
{% endtab %}

{% tab title="Example 4" %}
In the following example, `currencyNumberFormat` groups the digits in the integer part by an apostrophe placed every third digit to the left of a point, which acts as the separator between the price's integer and fractional parts.

```json
"currencyNumberFormat": "#'###.##"
```

**Target output in UI**

<div align="left"><img src="/files/JnSIhsWxEqRWBv0Z4bhd" alt=""></div>
{% endtab %}
{% endtabs %}

#### `symbol`

Use the graphic `symbol` to denote the price's currency.

{% tabs %}
{% tab title="Example 1" %}
The following is the `symbol` for Swiss Francs:

```json
"symbol": "CHF"
```

**Target output in UI**

<div align="left"><img src="/files/1UPm8JEui4yIrPet2yew" alt=""></div>
{% endtab %}

{% tab title="Example 2" %}
The following is the `symbol` for Jordanian Dinars:

```json
"symbol": "د.ا"
```

**Target output in UI**

<div align="left"><img src="/files/YdgshkgwtUZzhziWTVxO" alt=""></div>
{% endtab %}
{% endtabs %}

#### `decimalPlaces`

This attribute stipulates the number of digits that should be displayed to the right of the character (whether it's a point or comma) that divides a price's integer part from its fractional part.

If `decimalPlaces` is `0` and [`currencyNumberFormat`](#currencynumberformat) indicates that a character should be placed between the integer and fractional parts, then that character shouldn't be displayed.

```json
{
    ...
    "pricingFormat": {
        "currencyNumberFormat": "#,###.##",
        ...
        "decimalPlaces": 0,
        ...
    },
    ...
}
```

| decimalPlaces value | Target output in UI                                                 |
| ------------------- | ------------------------------------------------------------------- |
| `0`                 | ![](/files/rvf9ZaFpxiIfqUvkVXR1)                                    |
| `2`                 | <img src="/files/0yvzyuFsktTAQzRq0bg5" alt="" data-size="original"> |
| `3`                 | ![](/files/coHwWE7Yx9WX5Mr1t3vp)                                    |

#### `currencySymbolBeforePrice`

The `currencySymbolBeforePrice` indicates whether [`symbol`](#symbol) should be placed before or after a price's numeric amount.

<table><thead><tr><th width="324.3333333333333">currencySymbolBeforePrice value</th><th>Target output in UI</th></tr></thead><tbody><tr><td><code>true</code></td><td><img src="/files/yZPorfs5Y7BoLusQNFdc" alt=""></td></tr><tr><td><code>false</code></td><td><img src="/files/mGtpQjz8IuMnxqx94xbO" alt=""></td></tr></tbody></table>

#### `useCurrencySymbolSpace`

The `useCurrencySymbolSpace` indicates whether or not to insert a space between [`symbol`](#symbol) and the price's numeric amount.

| useCurrencySymbolSpace value | Target output in UI              |
| ---------------------------- | -------------------------------- |
| `true`                       | ![](/files/Wmbsc18F1HdTXvMrGTjh) |
| `false`                      | ![](/files/e1IgW4cKkTBYtNaA4lgw) |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.digitalriver.com/digital-river-api/integration-options/low-code-checkouts/offering-local-pricing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
