API Kurs untuk Faktur Multi-Mata Uang

Buat faktur dalam satu mata uang dan laporkan dalam mata uang lain tanpa kehilangan jumlah asli atau kurs yang dipakai. Ambil kurs bertanggal, bulatkan uang satu kali, lalu simpan buktinya.

Kunci kurs pada tanggal faktur

Faktur perlu tetap dapat dibaca setelah dikirim. Jika Anda menampilkan nilai referensi dalam mata uang kedua, ambil kurs untuk tanggal faktur dan simpan hasilnya. Jangan menghitung ulang dokumen lama dengan kurs hari ini. Pelanggan, tim dukungan, dan bagian keuangan harus melihat angka yang sama.

Tanggal kurs mengikuti aturan bisnis Anda. Sebagian sistem memakai tanggal penerbitan, sebagian memakai tanggal layanan atau tanggal posting. API menyediakan observasi untuk tanggal yang diminta. Kontrak dan kebijakan perusahaan tetap menentukan tanggal mana yang berlaku.

Simpan jumlah asli dan hasil konversi

Simpan currency dan amount asli sebagai fakta utama. Tambahkan reporting_currency, converted_amount, rate, tanggal yang diminta, data_updated_at, source, dan is_forward_filled. Dengan bentuk ini, Anda dapat membuat ulang PDF, menjawab pertanyaan pelanggan, atau mengekspor data ke sistem akuntansi tanpa menebak kurs yang pernah dipakai.

Bulatkan jumlah hasil konversi sesuai minor unit mata uang tujuan. JPY biasanya tidak memakai angka desimal, sedangkan banyak mata uang memakai dua. Simpan kurs dengan presisi penuh dan jangan membulatkan setiap baris lebih dari sekali. Untuk faktur dengan banyak item, hitung subtotal terlebih dahulu jika kebijakan pembulatan Anda berlaku pada total.

Gunakan aturan yang sama untuk nota kredit

Nota kredit harus menyebut faktur asal dan aturan kurs yang dipakai. Jika nota kredit membatalkan faktur secara penuh, memakai kurs faktur asal biasanya membuat nilai pelaporan terbalik dengan rapi. Jika kebijakan Anda meminta kurs pada tanggal nota kredit, simpan kurs baru sebagai observasi terpisah.

Jangan mengubah catatan faktur untuk menyesuaikan koreksi. Simpan dokumen koreksi, nilai asli, nilai hasil konversi, dan relasinya. Riwayat ini jauh lebih mudah direkonsiliasi daripada satu baris yang terus berubah setiap kali dokumen diperbarui.

Pisahkan nilai faktur dari hasil pembayaran

Kurs pada faktur adalah nilai indikatif untuk tampilan atau pelaporan. Bank dan payment processor menentukan jumlah penyelesaian, biaya, dan kurs yang benar-benar dipakai. Saat pembayaran masuk, simpan record penyelesaian mereka dan bandingkan dengan nilai faktur. Selisihnya dapat dicatat sesuai kebijakan akuntansi Anda.

Batas ini penting untuk faktur lintas negara. exchangerate.dev membantu software membuat tampilan dan laporan yang konsisten, tetapi tidak menjamin jumlah yang akan diterima penjual atau dibayar pelanggan. Gunakan record penyedia pembayaran sebagai sumber fakta untuk penyelesaian.

Membuat faktur JPY dengan kurs bertanggal

Simpan key API di server. Contoh ini menyimpan kurs dan detail sumber bersama nilai yang dihitung aplikasi.

TypeScript · faktur multi-mata uang di server
import Decimal from 'decimal.js';

type HistoricalRates = {
  date: string;
  rates: Record<string, number>;
  source: 'ecb_daily' | 'fred_daily' | 'nbp_daily';
  data_updated_at: string;
  is_forward_filled: boolean;
};

const invoice = {
  id: 'invoice_2207',
  issuedOn: '2026-07-15',
  currency: 'USD',
  total: '2400.00',
  displayCurrency: 'JPY',
} as const;

const response = await fetch(
  `https://api.exchangerate.dev/v1/${invoice.issuedOn}/${invoice.currency}?symbols=${invoice.displayCurrency}`,
  { headers: { Authorization: `Bearer ${process.env.EXR_API_KEY}` } },
);
if (!response.ok) throw new Error('Could not load the invoice-date FX rate');

const fx = (await response.json()) as HistoricalRates;
const rawRate = fx.rates[invoice.displayCurrency];
if (!Number.isFinite(rawRate)) throw new Error('Missing USD/JPY rate');

// JPY is a zero-decimal currency. Keep rate at full precision.
const rate = new Decimal(String(rawRate));
const displayTotal = new Decimal(invoice.total)
  .mul(rate)
  .toDecimalPlaces(0, Decimal.ROUND_HALF_UP)
  .toFixed(0);

await saveInvoiceFx({
  invoice_id: invoice.id,
  original_currency: invoice.currency,
  original_total: invoice.total,
  display_currency: invoice.displayCurrency,
  display_total: displayTotal,
  fx_rate: rate.toString(),
  fx_requested_date: fx.date,
  fx_source: fx.source,
  fx_observed_at: fx.data_updated_at,
  fx_is_forward_filled: fx.is_forward_filled,
});

Siap mencoba API?

Mulai dari quickstart, periksa field respons, lalu lihat harga saat Anda membutuhkan kuota akun.

Paket Free hanya untuk evaluasi dan penggunaan internal nonkomersial. Basic dan Pro mencakup penggunaan komersial.

Buat key evaluasi gratis →