> ## Documentation Index
> Fetch the complete documentation index at: https://docs-stage.bglobale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# International Prices

> Retrieve updated international prices for your products across the territories operated by Global-e — as a ready-calculated price feed (GetCatalogPrices) or as the parameters you apply yourself to calculate prices in the destination currency (GetMerchantPriceDetails).

## Overview

The International Prices APIs provide merchants with the most updated international prices of their products in the territories operated by Global‑e. Two methods are available, depending on how you consume the prices.

### GetCatalogPrices

The **GetCatalogPrices** API provides merchants with the most updated international prices of their products in different territories operated by Global‑e. These prices can be used for marketing needs (for example, in the Google Shopping Feed or in email marketing campaigns).

The recommended frequency of usage of this API call is 1 call per day, as currency rates are updated in the Global-e system once a day.

The maximum number of currency results (i.e. product count multiplied by requested countries count) cannot exceed 10,000. It means that if a merchant wishes to get prices of 10 currencies, the maximum number of products that can be sent via this API is 1000. If the API call exceeds this number, a failure message is sent back as a response, and no international prices are retrieved.

<Note>
  Merchants implementing the Price feeds API (GetCatalogPrices API) to show correct international prices in the Google Shopping feed must ensure that the correct product landing page URL is set to show the price for a country that the feed was generated for.

  For example, for GEM merchants, the URL should have an additional query string parameter: `glCountry`, so that the URL for the UK looks like this:

  `<product_page_url>?glCountry=gb`

  In addition, if the `glCountry` parameter has been specified, make sure to change the Link of Global‑e CSS by adding the same parameter, so that it looks like this:

  `//gepi.global-e.com/proxy/css/<MerchantID>?glCountry=gb`
</Note>

This document is intended for Global-e merchants wishing to retrieve updated international prices for their products, as calculated by the Global-e platform. This document describes relevant API methods and provides implementation examples. For details on the Global-e API, see the General API Reference documentation.

<Note>
  This API endpoint is used to pull the catalogue prices for international markets. If the merchant wishes it to be fully automated for new products, we need to make sure that they also upload catalogues through SFTP, otherwise, some new products may not exist in the Global-e Database.
</Note>

### GetMerchantPriceDetails

This Global-e `GetMerchantPriceDetails` REST API enables merchants to obtain the parameters required to calculate product prices in a destination country currency.

This document provides details about the GetMerchantPriceDetails API, a flow and explanations on how to implement the logic, and a sample implementation in JavaScript.

This document is intended for the developer in charge of evaluating and integrating the solution with the merchant's ecommerce platform and assumes familiarity with the Global-e technology, concepts, and terminology.

## API reference

<div className="api-ref-card">
  <Card title="Get Catalog Prices — full request & response" icon="code" href="/api-reference/get-catalog-prices">
    Parameters, schema, examples for `POST /Browsing/GetCatalogPrices`.
  </Card>
</div>

<div className="api-ref-card">
  <Card title="Get Merchant Price Details — full request & response" icon="code" href="/api-reference/get-merchant-price-details">
    Query parameters, response schema, examples for `GET /externalapi/GetMerchantPriceDetails`.
  </Card>
</div>

## Calculating Prices: Logic and Flow

This section provides the logic and flow required to calculate product prices as they will be displayed to shoppers in their country's local currency on the merchant's website.

The following flow is affected by the various rules, regulations, and specific price factors. Make sure to keep these in consideration when implementing the calculations. The field properties are detailed in Parameters, VAT Settings, and Applying Rounding Rules.

<img src="https://mintcdn.com/globale-enterprise/tw35F3WiyJ8sxtxX/images/pricing/calculate-product-price-flow.svg?fit=max&auto=format&n=tw35F3WiyJ8sxtxX&q=85&s=8058023a1cbdc684391d5b061e554bfa" alt="Calculate product price flow" width="794" height="1123" data-path="images/pricing/calculate-product-price-flow.svg" />

**To implement the Product Price Logic and Flow:**

1. Call the GetMerchantPriceDetails REST API to get the set of price calculation rules for the relevant territory.

2. Fixed prices: Check if at least some of the products have fixes prices.

   If true, these products are configured as fixed prices in the merchant's database.

   Fixed prices do not require additional calculation. Therefore, skip this entire flow. However, make sure to show the fixed prices for the products as set in your database.

   For non-fixed prices, proceed as detailed below.

   **⇾ For each product, perform the following steps:**

3. VAT settings: If you are a merchant from the European Union, proceed as follows. If you are a non-EU merchant, skip to step 4.

   There are two VAT scenarios, depending on how you manage pricing in the e‑commerce platform.

   **Scenario 1** — The price of the product in the merchant's system includes the local VAT.

   1. Get the merchant's product price (including the local VAT).
   2. Deduct the local VAT from the base price of the product if you selected one of the following VAT options:

      `VATTypeId = 0` (hide/deduct the VAT)

      *or*

      `VATTypeID = 6` *and* `useDistanceSellingVAT = true`

      (This means that the product is shipped to a destination country where the distance selling regulation applies (within the EU))

      Formula:

      ```
      [price] = [price before VAT] / (1 + [VAT] / 100)
      ```
   3. Add the destination country VAT to the base price of the product if:

      `VATTypeID = 6` (force VAT).

      Formula:

      ```
      [price] = [price without VAT] * (1 + [VAT]/ 100)
      ```

      Otherwise, if the `VATTypeID` is not 0 or 6 and the rate of the destination country is not applicable, `(useDistanceSellingVAT = False)`, proceed to step 4.

   **Scenario 2** — The price of the product in the merchant's country does not include the local VAT.

   1. Get the merchant's product price (without the local VAT).
   2. Depending on the VAT options you choose, add the destination or local VAT to the base price of the product if the the product is shipped to a destination country where the distance selling regulation applies (within the EU):

      * if `VATTypeId = 0` (hide/deduct the VAT), proceed to step 4.
      * Add the **destination** VAT to the base price of the product if:

        `VATTypeID = 4` (pocket VAT)

        *or*

        `VATTypeID = 6` *and* `useDistanceSellingVAT = true`

        (This means that the product is shipped to a destination country where the distance selling regulation applies (within the EU)).

        Formula:

        ```
        [price] = [price before VAT] * (1 + [destination VAT] / 100)
        ```
      * Add the **local** VAT to the base price of the product if:

        `VATTypeID = 4` (pocket VAT)

        *or*

        `VATTypeID = 6` *and* `useDistanceSellingVAT = false`

        (This means that the product is shipped to a destination country where the distance selling regulation does not apply).

        Formula:

        ```
        [price] = [price before VAT] * (1 + [VAT] / 100)
        ```

   See VAT Settings for field and option descriptions.

4. Apply the `currencyConversionRate`.

5. Apply the the `countryCoefficientRate` or apply the correct rate from the `productClassCoefficients` list, according to the following:

   * If the `countryCoefficientRate` is not defined and the `productClassCoefficient` is not defined, no coefficient is applied.
   * If the `countryCoefficientRate` is not defined and the `productClassCoefficient` is defined, the `productCoefficient` is applied.
   * If the `countryCoefficientRate` is defined and the `productClassCoefficient` is not defined, the `countryCoefficientRate` is applied.
   * If the `countryCoefficientRate` is defined and the `productClassCoefficient` is defined, the `productClassCoefficient` is applied.

6. Perform the arithmetic rounding:

   Round up the currency's decimal places, leaving the same number of decimals defined in `currencyDecimalPlaces`.

   **Example:**

   If `currencyDecimalPlaces` = 2

   And your currency = 223.0234512

   Round up the number after the decimal =223.02

7. Calculate and apply the marketing rounding. See Applying Rounding Rules.

<Tip>
  **Basic rule for arithmetic rounding**

  If the number you are rounding is followed by a decimal and digits containing 5, 6, 7, 8, or 9, round the number up. Example: .29 rounded up to the nearest ten is .30

  If the number you are rounding is followed by a decimal and digits containing 0, 1, 2, 3, or 4, round the number down. Example: .24 rounded down to the nearest ten is .20.
</Tip>

## VAT Settings

This section lists the VAT properties and provides an example on how to calculate the VAT based on the selected VATTypeId option.

**VatTypeID Descriptions**

| VATTypeID | Description                                                                                                                                                                            |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0         | Hide VAT (default)                                                                                                                                                                     |
| 4         | "Pocket" VAT (increase the original price by the value of the respective product's VAT)                                                                                                |
| 6         | Force VAT (used to support trade agreements between the countries such as EEA, when the customer in the destination country must pay VAT; for simplicity assuming UseCountryVAT=false) |

**Example of Price Calculation Based on the VATTypeID**

The following table is the list of VATTypeID values and descriptions and the expected results for a sample product with an original cost in UK = 100 GBP before VAT to be shipped to Germany (with a country coefficient Rate=1 and the user selected currency=GBP, for simplicity).

For this sample product UK VAT=20%, DE Duties Total=17%:

| Include VAT Option Value | Description                                                                                                                                                 | Price in Browsing | Price in Checkout | Price Paid to Merchant (incl. VAT) | Checkout Duties Total | Checkout Total |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ----------------- | ---------------------------------- | --------------------- | -------------- |
| 0                        | Hide VAT(default)                                                                                                                                           | 100               | 100               | 120                                | 17                    | 117            |
| 4                        | "Pocket" VAT (increase the original price by the value of the respective product's VAT)                                                                     | 120               | 120               | 144                                | 20.4 (17%)            | 140.4          |
| 6                        | Force VAT (used to support trade agreements between the countries such as EEA, when end customer must pay VAT; for simplicity assuming UseCountryVAT=false) | 120               | 120               | 120                                | 0                     | 120            |

## Applying Rounding Rules

After calculating the price of the product, you must apply the arithmetic and marketing rounding rules.

The arithmetic rounding rule is detailed in section Calculating Prices: Logic and Flow.

The following tables provide the list of properties required to implement the remaining rounding rules.

**RangeBehaviors Enumeration**

| RangeBehavior Option Value | Name                    | Behavior Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| -------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1                          | Absolute target         | All the values within the specified range (`LowerTarget`, `UpperTarget`, `Threshold` and `RoundingExceptions`) denote the values themselves as is, without the need for additional mathematical operations. To get rounding result (R) for the source number (S): If (S = Exception) then R = Exception; If (S \< Threshold) then R = LowerTarget; If (S >= Threshold) then R = UpperTarget.                                                                                                                               |
| 2                          | Relative Decimal target | All the values within the specified range represent floating point numbers between 0 (inclusive) and 1 (inclusive). Relative to the calculation base (B = whole part of S): LA = B – 1 + LowerTarget; UA = B + UpperTarget; TA = B + Threshold; EA = B + Exception. If (S = EA) then R = EA; If (S \< TA) then R = LA; If (S >= TA) then R = UA.                                                                                                                                                                           |
| 3                          | Relative Whole target   | All the values within the specified range represent non-negative whole numbers. `TargetBehaviorHelperValue` (V) determines the calculation base (B); V must be a power of 10 (10, 100, 1000, etc.). B = S rounded down to the closest multiple of V. LA = B – V + LowerTarget; UA = B + UpperTarget; TA = B + Threshold; EA = B + Exception. If (S = EA) then R = EA; If (S \< TA) then R = LA; If (S >= TA) then R = UA.                                                                                                  |
| 4                          | Nearest target          | `LowerTarget` and `UpperTarget` represent non-negative floating point numbers. `TargetBehaviorHelperValue` (V) must be a whole divisor of any power of 10 (5, 10, 25, 50, 100, 250, 500, 1000, etc.). `Threshold` must be any floating point number between 0 (inclusive) and V (exclusive). B = S rounded down to the closest multiple of V. LA = B – 1 + LowerTarget; UA = B – 1 + V + UpperTarget; TA = B + Threshold; EA = B + Exception. If (S = EA) then R = EA; If (S \< TA) then R = LA; If (S >= TA) then R = UA. |

<Warning>
  **Important.** For any rounding behavior defined in the table above, if the rounding result is a negative number, it must be set to zero.

  If either the `LowerTarget` or `UpperTarget` value violates the `MaxDecimalPlaces` setting for the respective currency, this value must be truncated.

  For example, if `UpperTarget` is set to 0.999 for USD, it must be truncated to 0.99 before performing further calculations.
</Warning>

## Use Cases

### Rounding Rules Samples

The following samples indicate how rounding X to Y (X → Y) is implemented using the respective settings.

| Property                  | 0.25 → 0; 3 → 0; 1.5 → 1.5; 2 → 2 | 22.47 → 21.95; 22.48 → 22.99; 22.50 → 22.50; 33.75 → 33.75 | 2047 → 1995; 2048 → 2100 | 122.26 → 124.99; 122.25 → 119.99; 127.26 → 129.99; 121.50 → 121.50; 127.50 → 127.50; 123 → 123; 128 → 128 | 2047 → 1999; 2048 → 2100 |
| ------------------------- | --------------------------------- | ---------------------------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------- | ------------------------ |
| From                      | 0                                 | 1                                                          | 1000                     | 100                                                                                                       | 1000                     |
| To                        | 3                                 | 250                                                        | 10000                    | 1000                                                                                                      | 10000                    |
| Threshold                 | 3.01                              | 0.48                                                       | 48                       | 2.26                                                                                                      | 48                       |
| LowerTarget               | 0                                 | 0.95                                                       | 95                       | 0.99                                                                                                      | 0                        |
| UpperTarget               | 0                                 | 0.99                                                       | 100                      | 0.99                                                                                                      | 1                        |
| RangeBehavior             | 1 (Absolute)                      | 2 (Relative Decimal)                                       | 3 (Relative Whole)       | 4 (Nearest)                                                                                               | 4 (Nearest)              |
| TargetBehaviorHelperValue |                                   |                                                            | 100                      | 5                                                                                                         | 100                      |
| RoundingExceptions        | 1.5; 2                            | 0.50; 0.75                                                 |                          | 1.50; 2.50; 3                                                                                             |                          |

### Price Conversion and Rounding Rule Implementation in JavaScript

This section shows an example of price conversion and rounding implementation in JavaScript. Use this example to write the APIs required for your specific environment and implement them.

```js theme={null}
function CalculatePrice(value, fxRate, vatRateTypes, productLocalVatRate, isGrossPrices, currencyDecimalPlaces, quantity, productClassCoefficient, priceCoefficient, productCountryVatRate, roundingRules) {
    if (value == 0)
        return (0).toFixed(currencyDecimalPlaces);

    var merchantVatRate = vatRateTypes.LocalVATRateType.Rate / 100;
    if (productLocalVatRate !== null) {
        if (productLocalVatRate == 0) {
            merchantVatRate = 0;
        } else {
            merchantVatRate = productLocalVatRate / 100;
        }
    }

    var countryVatRate = vatRateTypes.VATRateType.Rate / 100;
    if (productCountryVatRate || productCountryVatRate === 0) {
        if (productCountryVatRate == 0) {
            countryVatRate = 0;
        } else {
            countryVatRate = productCountryVatRate / 100;
        }
    }

    if (isGrossPrices) {
        if (vatRateTypes.IncludeVATTypeId == 0 ||
            vatRateTypes.IncludeVATTypeId == 8 ||
            (vatRateTypes.IncludeVATTypeId == 6 && vatRateTypes.UseCountryVAT)) {
            value = value / (1 + merchantVatRate);
            if (vatRateTypes.IncludeVATTypeId == 6) {
                value += value * countryVatRate;
            }
        }
    } else {
        if (vatRateTypes.IncludeVATTypeId == 2 ||
            vatRateTypes.IncludeVATTypeId == 4 ||
            vatRateTypes.IncludeVATTypeId == 6) {
            if (vatRateTypes.UseCountryVAT) {
                value += value * countryVatRate;
            } else {
                value += value * merchantVatRate;
            }
        }
    }

    value = value * fxRate;
    if (productClassCoefficient) {
        value = value / priceCoefficient * productClassCoefficient;
    }

    value = value.toFixed(currencyDecimalPlaces);
    if (skipRounding || roundingRules == null) {
        value = value * quantity;
    } else {
        var ranges = roundingRules.RoundingRanges;
        var range = null;
        for (var r in ranges) {
            var rg = ranges[r];
            if (rg.From < value && value <= rg.To) {
                range = rg;
                break;
            }
        }

        if (range != null) {
            // convert range to form of absolute
            range = ConvertRoundingRangeToAbsolute(value, range);
            // apply logic of absolute range rounding
            value = AbsoluteRounding(value, range) * quantity;

            if (value < 0) {
                value = 0;
            }
        }
    }

    return value;
};


function ConvertRoundingRangeToAbsolute(price, range) {
    var result = null;
    if (range.RangeBehavior == 1) {
        // range already has absolute behavior
        result = range;
    } else {
        result = new Object();
        result.RangeBehavior = range.RangeBehavior;
        result.RoundingExceptions = [];
        result.From = range.From;
        result.To = range.To;

        var int_part = Math.floor(price);

        if (range.RangeBehavior == 2) {
            //Relative Decimal 
            result.LowerTarget = int_part - 1 + range.LowerTarget;
            result.UpperTarget = int_part + range.UpperTarget;
            result.Threshold = int_part + range.Threshold;
            for (var ex in range.RoundingExceptions) {
                range.RoundingExceptions[ex].ExceptionValue += int_part;
                result.RoundingExceptions.push(range.RoundingExceptions[ex]);
            }
        } else if (range.RangeBehavior == 3) {
            // Relative Whole
            if (range.TargetBehaviorHelperValue == 0) {
                range.TargetBehaviorHelperValue = 10;
            }
            var base = Math.floor(price / range.TargetBehaviorHelperValue) * range.TargetBehaviorHelperValue;
            result.LowerTarget = base - range.TargetBehaviorHelperValue + range.LowerTarget;
            result.UpperTarget = base + range.UpperTarget;
            result.Threshold = base + range.Threshold;
            for (var ex in range.RoundingExceptions) {
                range.RoundingExceptions[ex].ExceptionValue += base;
                result.RoundingExceptions.push(range.RoundingExceptions[ex]);
            }
        } else if (range.RangeBehavior == 4) {
            // Nearest target
            if (range.TargetBehaviorHelperValue == 0) {
                range.TargetBehaviorHelperValue = 5;
            }
            var base = Math.floor(price / range.TargetBehaviorHelperValue) * range.TargetBehaviorHelperValue;
            result.LowerTarget = base - 1 + range.LowerTarget;
            result.UpperTarget = base - 1 + range.TargetBehaviorHelperValue + range.UpperTarget;
            result.Threshold = base + range.Threshold;
            for (var ex in range.RoundingExceptions) {
                range.RoundingExceptions[ex].ExceptionValue += base;
                result.RoundingExceptions.push(range.RoundingExceptions[ex]);
            }

        }

    }

    return result;
};

function AbsoluteRounding(price, range) {
    var result = null;
    // check exceptions
    if (range.RoundingExceptions.length > 0) {
        for (var e in range.RoundingExceptions) {
            ex = range.RoundingExceptions[e];
            if (price == ex.ExceptionValue) {
                result = price;
            }
        }
    }
    // no exception was found 
    if (!result) {
        // check threshold
        if (price < range.Threshold) {
            result = range.LowerTarget;
        } else {
            result = range.UpperTarget;
        }
    }

    return result;
};
```
