> For the complete documentation index, see [llms.txt](https://developer.esw.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.esw.com/pricing-advisor-api/resources/tutorials/calculating-a-localized-price.md).

# Calculating a Localized Price

{% stepper %}
{% step %}

### Calculation Paths

There are two ways to arrive at a localized price using the Pricing Advisor API. They produce equivalent results.

```ruby
Source price (home currency)
        │
        ├──── Path A: Standard Advice ─────────────────────────────────────────┐
        │       1. Fetch fxRates → find the right currency pair                │
        │       2. Fetch categories → find the matching category               │
        │       3. Check merchandisePricingModel.applicableRates               │
        │       4. Sum the non-applicable rates                                │
        │       5. Convert: sourcePrice × fxRate                               │
        │       6. Apply rates: convertedPrice × (1 + totalRate / 100)         │
        │       7. Round per roundingConfigurations                            │
        │                                                                      │
        └──── Path B: Multiplier Advice ───────────────────────────────────────┤
                1. Fetch categories → find the matching category               │
                2. Find the right currency pair in multipliers                 │
                3. Apply: sourcePrice × adjustedValue                          │
                4. Round per roundingConfigurations                            │
                                                                               ▼
                                                              Localised display price
```

**Path A (Standard Advice)** gives you full visibility into each component — useful when you need to show an itemized breakdown or when your system needs to handle rates separately.

**Path B (Multiplier Advice)** reduces the calculation to a single multiplication — useful for high-volume catalogues or simpler integrations.
{% endstep %}

{% step %}

### Worked Example

Throughout this tutorial we use a single product priced in two destination markets.

#### Product

| Field         | Value                  |
| ------------- | ---------------------- |
| Name          | Classic Leather Wallet |
| Category      | `ApparelAccessories`   |
| Home currency | EUR                    |
| Source price  | **€89.95**             |
| Brand         | `my-brand-001`         |

#### Market 1 — United States

| Data point           | Value                               |
| -------------------- | ----------------------------------- |
| Country ISO          | `US`                                |
| Display currency     | USD                                 |
| FX rate (EUR → USD)  | `1.0872`                            |
| `estimatedDuty`      | `12.5%`                             |
| `estimatedTax`       | `0.0%`                              |
| `estimatedFee`       | `0.5%`                              |
| `retailerAdjustment` | `2.3%`                              |
| `applicableRates`    | `["estimatedDuty", "estimatedTax"]` |
| Rounding             | Up, 2 decimal places                |

#### Market 2 — Japan

| Data point           | Value                                        |
| -------------------- | -------------------------------------------- |
| Country ISO          | `JP`                                         |
| Display currency     | JPY                                          |
| FX rate (EUR → JPY)  | `162.50`                                     |
| `estimatedDuty`      | `8.0%`                                       |
| `estimatedTax`       | `10.0%`                                      |
| `estimatedFee`       | `0.5%`                                       |
| `retailerAdjustment` | `1.8%`                                       |
| `applicableRates`    | `[]` (empty — nothing pre-embedded)          |
| Rounding             | Up, 0 decimal places (JPY has no minor unit) |
| {% endstep %}        |                                              |

{% step %}

### Path A: Standard Advice Calculation

#### 3a. Fetch the Advice

```http
GET /api/4.0/StandardAdvice/my-brand-001/US
Authorization: Bearer <token>
```

```http
GET /api/4.0/StandardAdvice/my-brand-001/JP
Authorization: Bearer <token>
```

#### 3b. Identify the FX Rate

Find the `fxRates` entry where `from` matches your source currency (`EUR`) and `to` matches the destination currency.

**US response:**

```json
"fxRates": [
  { "from": "EUR", "to": "USD", "rate": 1.0872 }
]
```

**JP response:**

```json
"fxRates": [
  { "from": "EUR", "to": "JPY", "rate": 162.50 }
]
```

#### 3c. Find the Matching Category

Look through `categories` for the entry whose `id` matches your product's category.

```json
"categories": [
  {
    "id": "ApparelAccessories",
    "estimatedDuty": 12.5,
    "estimatedTax": 0.0,
    "estimatedFee": 0.5,
    "retailerAdjustment": 2.3,
    ...
  }
]
```

#### 3d. Check `applicableRates` and Determine Which Rates to Apply

Inspect `merchandisePricingModel.applicableRates`. Any rate name listed there is already embedded in the source price — skip it.

**United States:**

```json
"merchandisePricingModel": {
  "id": "DutyAndTaxIncluded",
  "applicableRates": ["estimatedDuty", "estimatedTax"]
}
```

| Rate                 | Value | In `applicableRates`? | Apply?  |
| -------------------- | ----- | --------------------- | ------- |
| `estimatedDuty`      | 12.5% | ✅ Yes                 | ❌ Skip  |
| `estimatedTax`       | 0.0%  | ✅ Yes                 | ❌ Skip  |
| `estimatedFee`       | 0.5%  | ❌ No                  | ✅ Apply |
| `retailerAdjustment` | 2.3%  | ❌ No                  | ✅ Apply |

**Total rate to apply (US): 0.5 + 2.3 = 2.8%**

***

**Japan:**

```json
"merchandisePricingModel": {
  "id": "ExcludingAll",
  "applicableRates": []
}
```

| Rate                 | Value | In `applicableRates`? | Apply?  |
| -------------------- | ----- | --------------------- | ------- |
| `estimatedDuty`      | 8.0%  | ❌ No                  | ✅ Apply |
| `estimatedTax`       | 10.0% | ❌ No                  | ✅ Apply |
| `estimatedFee`       | 0.5%  | ❌ No                  | ✅ Apply |
| `retailerAdjustment` | 1.8%  | ❌ No                  | ✅ Apply |

**Total rate to apply (JP): 8.0 + 10.0 + 0.5 + 1.8 = 20.3%**

***

#### 3e. Apply the FX Rate

Convert the source price to the destination currency.

```
convertedPrice = sourcePrice × fxRate
```

**United States:**

```
convertedPrice = €89.95 × 1.0872 = $97.79
```

**Japan:**

```
convertedPrice = €89.95 × 162.50 = ¥14,616.88
```

#### 3f. Apply the Applicable Rates

Add the non-applicable rates as a single combined percentage on top of the FX-converted price.

```
localisedPrice = convertedPrice × (1 + totalRate / 100)
```

**United States (2.8%):**

```
localisedPrice = $97.79 × (1 + 0.028)
              = $97.79 × 1.028
              = $100.53
```

**Japan (20.3%):**

```
localisedPrice = ¥14,616.88 × (1 + 0.203)
              = ¥14,616.88 × 1.203
              = ¥17,583.51
```

#### 3g. Apply Rounding

Round the price using the `roundingConfigurations` for the destination currency. Full rounding logic is covered in Tutorial 5.

**United States — round up to 2 decimal places:**

```
$100.53  →  $100.53  (already at 2dp, no change)
```

**Japan — round up to 0 decimal places:**

```
¥17,583.51  →  ¥17,584
```

#### Path A Results

| Market        | Source price | Final localised price |
| ------------- | ------------ | --------------------- |
| United States | €89.95       | **$100.53**           |
| Japan         | €89.95       | **¥17,584**           |
| {% endstep %} |              |                       |

{% step %}

### Path B: Multiplier Advice Calculation

Path B compresses the multi-step Standard Advice calculation into a single multiplication and a rounding step.

#### 4a. Fetch the Advice

```http
GET /api/4.0/MultiplierAdvice/my-brand-001/US
Authorization: Bearer <token>
```

```http
GET /api/4.0/MultiplierAdvice/my-brand-001/JP
Authorization: Bearer <token>
```

#### 4b. Find the Matching Category and Currency Pair

Look through `categories` for `id: "ApparelAccessories"`, then within its `multipliers` array find the entry where `fromCurrencyIso` matches your source currency and `toCurrencyIso` matches the destination currency.

**United States:**

```json
{
  "id": "ApparelAccessories",
  "multipliers": [
    {
      "fromCurrencyIso": "EUR",
      "toCurrencyIso": "USD",
      "value": 1.1485,
      "adjustedValue": 1.1177
    }
  ]
}
```

**Japan:**

```json
{
  "id": "ApparelAccessories",
  "multipliers": [
    {
      "fromCurrencyIso": "EUR",
      "toCurrencyIso": "JPY",
      "value": 195.49,
      "adjustedValue": 195.49
    }
  ]
}
```

> **Note on Japan:** `value` and `adjustedValue` are identical because `applicableRates` is empty — no rates are pre-embedded in the source price, so the full multiplier and the adjusted multiplier are the same.

#### 4c. Apply `adjustedValue`

```
localisedPrice = sourcePrice × adjustedValue
```

**United States:**

```
localisedPrice = €89.95 × 1.1177 = $100.54
```

**Japan:**

```
localisedPrice = €89.95 × 195.49 = ¥17,583.82
```

#### 4d. Apply Rounding

Apply the same rounding configuration as Path A.

**United States — round up to 2dp:**

```
$100.54  →  $100.54
```

**Japan — round up to 0dp:**

```
¥17,583.82  →  ¥17,584
```

#### Path B Results

| Market        | Source price | Final localised price |
| ------------- | ------------ | --------------------- |
| United States | €89.95       | **$100.54**           |
| Japan         | €89.95       | **¥17,584**           |
| {% endstep %} |              |                       |

{% step %}

### Pseudocode Reference Implementation

#### Path A — Standard Advice

{% code expandable="true" %}

```ruby
function calculateLocalisedPrice_StandardAdvice(sourcePrice, sourceCurrency, advice, productCategory):

    // 1. Guard for zero price
    if sourcePrice == 0:
        return 0

    // 2. Find FX rate
    fxEntry = advice.fxRates.find(r => r.from == sourceCurrency && r.to == advice.countryIso.currency)
    if fxEntry is null:
        throw Error("No FX rate found for " + sourceCurrency + " → " + advice.countryIso)

    // 3. Find category
    category = advice.categories.find(c => c.id == productCategory)
    if category is null:
        throw Error("No category found for " + productCategory + " in " + advice.countryIso)

    // 4. Determine applicable rates
    applicableRates = advice.merchandisePricingModel.applicableRates ?? []

    totalRate = 0
    if "estimatedDuty" not in applicableRates:
        totalRate += category.estimatedDuty ?? 0
    if "estimatedTax" not in applicableRates:
        totalRate += category.estimatedTax ?? 0
    if "estimatedFee" not in applicableRates:
        totalRate += category.estimatedFee ?? 0
    if "retailerAdjustment" not in applicableRates:
        totalRate += category.retailerAdjustment ?? 0

    // 5. Apply FX and rates
    convertedPrice  = sourcePrice × fxEntry.rate
    localisedPrice  = convertedPrice × (1 + totalRate / 100)

    // 6. Round
    roundingConfig  = category.roundingConfigurations.find(r => r.currencyIso == destinationCurrency)
    localisedPrice  = applyRounding(localisedPrice, roundingConfig)

    return localisedPrice
```

{% endcode %}

***

#### Path B — Multiplier Advice

{% code expandable="true" %}

```ruby
function calculateLocalisedPrice_MultiplierAdvice(sourcePrice, sourceCurrency, advice, productCategory):

    // 1. Guard for zero price
    if sourcePrice == 0:
        return 0

    // 2. Find category
    category = advice.categories.find(c => c.id == productCategory)
    if category is null:
        throw Error("No category found for " + productCategory + " in " + advice.countryIso)

    // 3. Find multiplier for currency pair
    multiplier = category.multipliers.find(
        m => m.fromCurrencyIso == sourceCurrency && m.toCurrencyIso == destinationCurrency
    )
    if multiplier is null:
        throw Error("No multiplier found for " + sourceCurrency + " → " + destinationCurrency)

    // 4. Apply adjustedValue
    localisedPrice = sourcePrice × multiplier.adjustedValue

    // 5. Round
    roundingConfig = category.roundingConfigurations.find(r => r.currencyIso == destinationCurrency)
    localisedPrice = applyRounding(localisedPrice, roundingConfig)

    return localisedPrice
```

{% endcode %}
{% endstep %}

{% step %}

### JavaScript Implementation

#### Path A — Standard Advice

{% code expandable="true" %}

```javascript
function calculateLocalisedPrice(sourcePrice, sourceCurrency, advice, productCategory) {
  if (sourcePrice === 0) return 0;

  // Find FX rate
  const fx = advice.fxRates?.find(r => r.from === sourceCurrency);
  if (!fx) throw new Error(`No FX rate found from ${sourceCurrency} in ${advice.countryIso}`);

  // Find category
  const category = advice.categories?.find(c => c.id === productCategory);
  if (!category) throw new Error(`No category '${productCategory}' in ${advice.countryIso}`);

  // Check which rates to skip
  const applicable = advice.merchandisePricingModel?.applicableRates ?? [];

  let totalRate = 0;
  if (!applicable.includes('estimatedDuty'))       totalRate += category.estimatedDuty       ?? 0;
  if (!applicable.includes('estimatedTax'))        totalRate += category.estimatedTax        ?? 0;
  if (!applicable.includes('estimatedFee'))        totalRate += category.estimatedFee        ?? 0;
  if (!applicable.includes('retailerAdjustment'))  totalRate += category.retailerAdjustment  ?? 0;

  // Convert and apply rates
  const converted = sourcePrice * fx.rate;
  const raw       = converted * (1 + totalRate / 100);

  // Round
  const roundingConfig = category.roundingConfigurations
    ?.find(r => r.currencyIso === fx.to);

  return applyRounding(raw, roundingConfig);
}


function applyRounding(price, config) {
  if (!config) return price;

  const factor = Math.pow(10, config.currencyExponent);

  switch (config.direction?.toLowerCase()) {
    case 'up':      return Math.ceil(price  * factor) / factor;
    case 'down':    return Math.floor(price * factor) / factor;
    case 'nearest': return Math.round(price * factor) / factor;
    default:        return Math.round(price * factor) / factor;
  }
}


// Usage
const usPrice = calculateLocalisedPrice(89.95, 'EUR', usAdvice, 'ApparelAccessories');
const jpPrice = calculateLocalisedPrice(89.95, 'EUR', jpAdvice, 'ApparelAccessories');

console.log(`US: $${usPrice}`);    // US: $100.53
console.log(`JP: ¥${jpPrice}`);   // JP: ¥17584
```

{% endcode %}

***

#### Path B — Multiplier Advice

{% code expandable="true" %}

```javascript
function calculateLocalisedPriceMultiplier(
  sourcePrice, sourceCurrency, destinationCurrency, advice, productCategory
) {
  if (sourcePrice === 0) return 0;

  // Find category
  const category = advice.categories?.find(c => c.id === productCategory);
  if (!category) throw new Error(`No category '${productCategory}' in ${advice.countryIso}`);

  // Find multiplier
  const multiplier = category.multipliers?.find(
    m => m.fromCurrencyIso === sourceCurrency && m.toCurrencyIso === destinationCurrency
  );
  if (!multiplier) {
    throw new Error(`No multiplier for ${sourceCurrency}→${destinationCurrency} in ${advice.countryIso}`);
  }

  // Apply adjustedValue
  const raw = sourcePrice * multiplier.adjustedValue;

  // Round
  const roundingConfig = category.roundingConfigurations
    ?.find(r => r.currencyIso === destinationCurrency);

  return applyRounding(raw, roundingConfig);  // same applyRounding() as above
}


// Usage
const usPrice = calculateLocalisedPriceMultiplier(89.95, 'EUR', 'USD', usAdvice, 'ApparelAccessories');
const jpPrice = calculateLocalisedPriceMultiplier(89.95, 'EUR', 'JPY', jpAdvice, 'ApparelAccessories');

console.log(`US: $${usPrice}`);   // US: $100.54
console.log(`JP: ¥${jpPrice}`);  // JP: ¥17584
```

{% endcode %}
{% endstep %}
{% endstepper %}

<details>

<summary>Worked Example Summary</summary>

|                            | United States                            | Japan             |
| -------------------------- | ---------------------------------------- | ----------------- |
| Source price               | €89.95                                   | €89.95            |
| FX rate                    | EUR → USD: 1.0872                        | EUR → JPY: 162.50 |
| `estimatedDuty`            | 12.5% *(skipped — in `applicableRates`)* | 8.0% *(applied)*  |
| `estimatedTax`             | 0.0% *(skipped — in `applicableRates`)*  | 10.0% *(applied)* |
| `estimatedFee`             | 0.5% *(applied)*                         | 0.5% *(applied)*  |
| `retailerAdjustment`       | 2.3% *(applied)*                         | 1.8% *(applied)*  |
| Total rate applied         | 2.8%                                     | 20.3%             |
| Converted price            | $97.79                                   | ¥14,616.88        |
| Pre-rounding price         | $100.53                                  | ¥17,583.51        |
| Rounding rule              | Up, 2dp                                  | Up, 0dp           |
| **Final price (Path A)**   | **$100.53**                              | **¥17,584**       |
| Multiplier `adjustedValue` | 1.1177                                   | 195.49            |
| Pre-rounding price         | $100.54                                  | ¥17,583.82        |
| **Final price (Path B)**   | **$100.54**                              | **¥17,584**       |

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://developer.esw.com/pricing-advisor-api/resources/tutorials/calculating-a-localized-price.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
