Can Your Exchange-Rate API Explain a Customer Dispute? A 2026 Buyer Checklist
The hard part of an FX dispute is rarely the multiplication. It is proving which rate was used, when it was observed, which business rule applied, and whether the final customer amount also included payment, settlement, refund, tax, or billing logic.
A customer sees one EUR amount at checkout, another amount on a card statement, and a third number on a refund. Support opens a ticket. Finance asks whether the order used the checkout date or refund date. Payments asks whether the processor converted the final charge. Engineering asks whether a cached display price was confused with a committed quote.
This is a bottom-funnel buying question. If an exchange-rate provider cannot give your team support-ready evidence, a cheap plan can become expensive through manual investigations, reopened invoices, slow refunds, and weak chargeback notes.
Currency-Exchange.app verifies the useful building blocks in its public product surface: conversion responses with exchangeRate, rateTime, original and converted amounts; historical lookup via a date parameter; currency metadata; API-key management; usage lookup and export; and documented rate-limit headers. The site also uses live or real-time wording in some places, but this workflow should preserve the exact response timestamp instead of turning every rate into a vague freshness claim.
The buyer checklist
| Criterion | Why it matters | Verified product fit |
|---|---|---|
| Response-level rate evidence | Support needs the exact exchangeRate, rateTime, originalAmount, and convertedAmount used in the customer event. | The public conversion response exposes exchangeRate, rateTime, originalAmount, convertedAmount, and convertedText. |
| Historical replay | Refunds, chargebacks, and invoice questions often reference the order date, settlement date, or policy date. | The documented conversion and pair-rate endpoints accept a date parameter for historical lookup. |
| Freshness controls | A live checkout question is different from a closed-period replay. The workflow should show which rule applied. | The OpenAPI reference includes skipCache, cacheTimeSeconds on the rate endpoint, and rateTime in responses. |
| Usage and API-key ownership | A dispute review is weaker when support traffic, BI refreshes, and production checkout share one anonymous key. | The public API includes API-key management, daily usage lookup, and usage download endpoints. |
| Rate-limit context | Support should know whether a failed lookup was a data question, a retry issue, or a quota issue. | The API integration docs call out X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. |
Build the dispute evidence workflow
1. Classify the disputed money event
Tag the ticket as display price, checkout conversion, refund, settlement, payout, invoice, or report variance. The category decides whether the reviewer needs the current rate, a historical date, or the rate already stored on the transaction.
2. Pull the stored transaction evidence first
Collect source amount, source currency, target currency, committed amount, policy date, checkout time, refund time, processor reference, and internal order or invoice ID before calling the rate API again.
3. Replay the rate only with the same business rule
Use the documented date parameter for historical replay when the disputed event belongs to a past policy date. Use a fresh lookup only when the question is about a live display or a new quote.
4. Attach the evidence bundle to the ticket
Store the response fields, request timestamp, API key owner, rate-limit headers when relevant, and a short explanation of why the rate was current or historical for that workflow.
5. Route exceptions to the right owner
Unsupported currency codes go to product or operations. Processor fee questions go to payments. Stale-rate or cache-policy questions go to engineering. Closed-period differences go to finance.
The workflow is intentionally API-based. No native Zendesk, Intercom, payment-processor, spreadsheet, ERP, or MCP integration was verified on the public site. If your support desk receives an evidence packet from a worker, Zapier or n8n step, spreadsheet script, internal admin panel, or AI agent, label it as that workflow. Do not market it as a native integration unless the integration exists.
API examples for support evidence
For a live checkout or quote question, retrieve the conversion evidence and store the response beside the business event.
curl "https://api.currency-exchange.app/v1-convert-currency?from=USD&to=EUR&amount=249.99&skipCache=true&getPerformanceData=true" \
-H "x-api-key: YOUR_API_KEY"For a past invoice, refund, or chargeback question, replay the documented historical date used by the business policy.
curl "https://api.currency-exchange.app/v1-get-currency-exchange-rate?from=USD&to=EUR&date=2026-03-31&cacheTimeSeconds=3600" \
-H "x-api-key: YOUR_API_KEY"A representative response contains the fields support and finance need to explain.
{
"exchangeRate": 0.92,
"rateTime": "2026-03-31T00:00:00.000Z",
"originalAmount": 249.99,
"convertedAmount": 229.99,
"convertedText": "249.99 USD equal to 229.99 EUR",
"cached": false
}In production, wrap the call with response-shape validation and rate-limit capture before attaching the bundle to a ticket.
type DisputeInput = {
from: string;
to: string;
amount: number;
policyDate?: string;
orderId: string;
};
type ConversionEvidence = {
exchangeRate: number;
rateTime: string;
originalAmount: number;
convertedAmount: number;
convertedText?: string;
cached?: boolean;
};
type SupportEvidence = ConversionEvidence & {
orderId: string;
requestedAt: string;
rateLimit: {
limit: string | null;
remaining: string | null;
reset: string | null;
};
};
function isConversionEvidence(value: unknown): value is ConversionEvidence {
if (!value || typeof value !== 'object') return false;
const record = value as Record<string, unknown>;
return (
typeof record.exchangeRate === 'number' &&
typeof record.rateTime === 'string' &&
typeof record.originalAmount === 'number' &&
typeof record.convertedAmount === 'number'
);
}
export async function buildSupportEvidence(input: DisputeInput): Promise<SupportEvidence> {
const url = new URL('https://api.currency-exchange.app/v1-convert-currency');
url.searchParams.set('from', input.from);
url.searchParams.set('to', input.to);
url.searchParams.set('amount', String(input.amount));
url.searchParams.set('skipCache', 'true');
url.searchParams.set('getPerformanceData', 'true');
if (input.policyDate) {
url.searchParams.set('date', input.policyDate);
}
const requestedAt = new Date().toISOString();
const response = await fetch(url, {
headers: { 'x-api-key': process.env.FX_API_KEY ?? '' },
});
const payload: unknown = await response.json();
if (!isConversionEvidence(payload)) {
throw new Error('Unexpected conversion response shape');
}
return {
...payload,
orderId: input.orderId,
requestedAt,
rateLimit: {
limit: response.headers.get('X-RateLimit-Limit'),
remaining: response.headers.get('X-RateLimit-Remaining'),
reset: response.headers.get('X-RateLimit-Reset'),
},
};
}Which evidence answers which dispute?
| Dispute type | Evidence to collect | Avoid this shortcut |
|---|---|---|
| Checkout amount differs from product page | Display cache policy, checkout conversion response, rateTime, and committed order amount. | Do not explain the difference with a new live rate unless that is the same rule the checkout used. |
| Refund amount differs from original charge | Original charge evidence, refund policy date, historical replay, processor refund record, and support note. | Do not present API rate movement as the only cause if processor fees or card-network conversion may also apply. |
| Invoice variance after month end | Invoice currency, functional currency, accounting policy date, historical rate response, and usage export. | Do not let a dashboard refresh silently call a current rate for a closed accounting period. |
| International payment or payout question | Payment amount, target currency, timestamp, rate response, processor line items, and settlement reference. | Do not collapse FX rate evidence and payment settlement evidence into one unsupported claim. |
| Bulk repricing or backfill complaint | Batch job ID, source file, per-row rate evidence, API-key owner, and usage export for the job window. | Do not call a loop, worker, spreadsheet import, or no-code run a native bulk endpoint unless the endpoint is actually verified. |
Rate language matters
Do not treat live, real-time, updated every second, historical, cached, market data, or instant settlement as interchangeable phrases. The support note should say what the product returned: the observed rateTime, the requested date when used, the converted amount, and the workflow rule.
Historical does not mean retroactive
A historical lookup helps explain what a policy date would return. It should not rewrite the order record. Keep the original committed amount, replay result, and reviewer decision separate so audits do not blur operational evidence.
Internal links for the implementation path
- review the documented conversion, rate, currency, key, and usage endpoints
- validate currencies and rate evidence before the exception becomes a ticket
- build refund reconciliation workflows with rate evidence
- separate FX evidence from payment settlement evidence
- monitor freshness, rate limits, and cache behavior
FAQ
Does Currency-Exchange.app publish a native Zendesk, Intercom, or help-desk integration?
No native support-desk integration was verified in the public site, docs, or repo. Treat this as an API-based workflow: your app, worker, no-code step, or agent retrieves the evidence and attaches it to the ticket.
Should support agents quote a current rate when a customer asks about an old order?
Usually no. A past order, refund, invoice, or settlement question should use the rate policy for that event, often a historical date. A current rate is useful for a new quote or a live display check.
Can an AI agent draft the customer response?
Yes as a workflow pattern, not as a verified native product feature. The safer pattern is for the agent to read stored order data, call documented API endpoints, cite the returned fields, and send uncertain cases to a human queue.
What should not be blamed on the exchange-rate API?
Card-network conversion, processor markup, payout timing, tax, shipping, discounts, and refund policy can all affect the final amount. Keep FX rate evidence separate from payment and billing evidence.
Make FX evidence boring on purpose
The best support workflow does not make agents interpret rate markets. It gives them a clean evidence packet: amount, pair, timestamp, historical date when applicable, usage context, and a route for exceptions.