Exchange rates and currencies
The exchange rates between your currencies, converted-price settings, the currency a report is shown in, and the gateway account behind a payment method.
Everything the Currencies screen and the report currency picker read and write, and the two routes that check and register a payment method's own gateway account. See Currencies and Selling through more than one company.
List the exchange rates
/api/v1/kahunacart/currencies/rates
The exchange rates between the store's base currency and each currency it sells in. Answers the rate source (source, and every source the store knows in sources), the fallback asked for what the source does not answer (null for none), how many working days old a fetched rate may get before it counts as old (max_age_days), whether the store fetches rates at all (fetches: a second currency and a source other than manual), and one row per currency with its rate (a decimal string, how many of that currency one unit of the base buys, or null when there is none), its source, rate_date (the day the source says the rate is for, YYYY-MM-DD, null for a typed rate), how long since it was last checked in seconds, pinned (a person typed it, so a refresh leaves it alone), stale, missing, held (null, or a fetched rate that moved more than the store allows and waits for accept_exchange_rate or keep_old_exchange_rate: old, new, moved_percent, source, date), and on a typed rate market (null, or what the last refresh got for it: rate, source, date, away_percent). last_refresh says how the last fetch went and why, when it failed, which source answered each rate (answered_by), and in note why the source could not answer when the fallback answered for it. A store that sells in one currency answers enabled false and no rows. On a multi-currency store, pricing answers missing_price and each currency's configured mode, effective converts flag, markup and rounding.
Look up today's market exchange rates
/api/v1/kahunacart/currencies/rates/lookup
Ask Frankfurter once for today's market rates between the store's base currency and each currency it sells in, and write nothing. Answers currency code => {rate, date, source}, each rate a decimal string, plus away_percent (a decimal string such as "5.05") for a currency whose rate was typed, saying how far that rate is from the market one. The market answer is kept for an hour, so asking again within the hour makes no request. Use it to compare a typed rate with the market, then set_exchange_rate to type one. Answers 502 with the reason when Frankfurter cannot answer, and 404 on a store that sells in one currency.
Type an exchange rate
/api/v1/kahunacart/currencies/rates/{quote}
Set the rate between the base currency and one of the store's other currencies by hand. It is pinned: a refresh from a rate source never overwrites it, and a typed rate never counts as old. Delete it to hand the pair back to the source. Send the rate as a string with at most twelve decimal places, how many of the currency one unit of the base buys ("0.92" for euros on a dollar store). A JSON number with a fraction is refused. Answers the same document as list_exchange_rates.
Parameters
| Name | Type | Description |
|---|---|---|
| quote required | string | The currency code, one of the store's extra currencies (EUR) |
| rate required | string | How many of that currency one unit of the base buys, a positive decimal string like "0.92" |
Remove an exchange rate
/api/v1/kahunacart/currencies/rates/{quote}
Remove the stored rate for one currency, whether a person typed it or a source fetched it. The next refresh from the rate source fills it in again. Until then the store has no rate for it: nothing converts into that currency and an order in it records no rate. Answers the same document as list_exchange_rates.
Parameters
| Name | Type | Description |
|---|---|---|
| quote required | string | The currency code (EUR) |
Fetch the exchange rates now
/api/v1/kahunacart/currencies/rates/refresh
Fetch the rates from the configured source now, instead of waiting for the daily job. The fallback is asked for whatever the source did not answer, or for everything when the source cannot be reached. A rate that moved more than currencies.rates.hold_move_percent is held instead of written and listed in result.held; the rest are written as usual. The fetch runs inside this request, so it waits for the source. A rate someone typed is left alone, a currency the source does not list keeps its old rate, and a source that cannot answer changes nothing and is answered as result.ok false with the reason in result.error. Answers 422 when the store has nothing to fetch (the manual source, or one currency). Otherwise it answers result (what was written, what changed and how far it moved, what was left alone) beside the same document as list_exchange_rates.
Accept a held exchange rate
/api/v1/kahunacart/currencies/rates/{quote}/accept
Accept a rate a refresh held because it moved more than currencies.rates.hold_move_percent from the rate in use. Send the held rate you saw (held.new from list_exchange_rates) as new. It is written with the source and day it came with and is not pinned, so it keeps updating from the source, and the catalog index is told the way a refresh tells it. Answers 409 when the hold is gone or now holds a different rate, and writes nothing. Answers the same document as list_exchange_rates.
Parameters
| Name | Type | Description |
|---|---|---|
| quote required | string | The currency code of the held rate (EGP) |
| new required | string | The held rate you are accepting, as a decimal string, exactly as list_exchange_rates shows it in held.new |
Keep the old exchange rate
/api/v1/kahunacart/currencies/rates/{quote}/held
Turn down a held rate and keep the one in use. The hold goes; the next refresh holds the rate again if the move is still there. To stop being asked, type a rate with set_exchange_rate. Answers the same document as list_exchange_rates.
Parameters
| Name | Type | Description |
|---|---|---|
| quote required | string | The currency code of the held rate (EGP) |
Set pricing in each currency
/api/v1/kahunacart/currencies/pricing
Save manual or converted pricing per enabled currency, with markup and rounding. Typed amounts always win. missing_price convert makes every enabled currency with a rate convert, keeping its markup and rounding. No rate means no conversion. Answers list_exchange_rates with pricing beside rates and queues the catalog index update. Open carts keep their quoted prices.
Parameters
| Name | Type | Description |
|---|---|---|
| missing_price optional | string |
One of:
unavailable, convert |
| pricing required | object | Currency code to pricing choices; currencies omitted stay as they were. Only enabled extra currencies are accepted. |
Read this admin's report currency
/api/v1/kahunacart/reports/currency
Read the saved currency selection and available completed-order currencies, base first. HTTP also permits customer or order readers. Single-currency stores return an empty currency list.
Remember this admin's report currency
/api/v1/kahunacart/reports/currency
Remember a known currency code or all for exact frozen-rate totals in base currency. Only this calling admin's preference changes. Explicit report queries still name their currency. HTTP also permits customer or order readers.
Parameters
| Name | Type | Description |
|---|---|---|
| currency required | string | A known currency code or all |
Check a payment method account
/api/v1/kahunacart/payment-methods/{id}/check-account
Check the saved credentials for this method’s account without returning secrets.
Parameters
| Name | Type | Description |
|---|---|---|
| id required | integer | Payment method ID |
Set up a payment method webhook
/api/v1/kahunacart/payment-methods/{id}/setup-webhook
Register this method’s own endpoint and store its signing secret encrypted.
Parameters
| Name | Type | Description |
|---|---|---|
| id required | integer | Payment method ID |
| reset optional | boolean | Replace only this account revision’s endpoint |
A rate is a decimal string with at most twelve decimal places, how many of the currency one unit of the base buys, and a JSON number with a fraction is refused because a rate is never a float. A rate you type is pinned, so a refresh leaves it alone. Refresh runs inside the request, because a person pressing the button is waiting for the answer, and it answers 422 when there is nothing to fetch (the manual source). A refresh asks the source first and then the fallback for what it didn't answer. A fetched rate that moved more than currencies.rates.hold_move_percent is held and not written, and accept and held answer it. Look up asks Frankfurter once and writes nothing. See A big move is held for you to check. A single-currency store answers enabled false and no rows. On a converting store the rates read also carries pricing, and product and variant reads carry converted_amounts, which are editor hints and never typed prices.
Saving pricing needs all three of mode, markup_percent and rounding for each currency you send, and a currency you leave out is left alone. The base currency and disabled currencies are refused, and a JSON float markup is refused. See Converted prices.
The report currency is a code the store knows, or all for everything in the base currency. A bad code or a value that isn't a string is a 422. A report call that names a currency always wins, and the API never applies the saved choice on its own. See Reports and totals.
The two payment method routes contact the gateway only when someone runs them on purpose, and neither answers with a secret. See Give each payment method its own Stripe account.