メインコンテンツへスキップ

通貨と金額

Omise APIで金額を正しく指定する方法、通貨単位の理解、マルチ通貨取引の処理方法について解説します。

概要

Omise APIを使用する際、すべての金額は対象通貨の最小単位で指定する必要があります。これにより、小数値を使用した場合に発生する浮動小数点エラーを防ぎ、精度を確保できます。

最小通貨単位

各通貨には最小単位(補助単位とも呼ばれます)があります:

通貨コード最小単位小数桁数
タイバーツTHBサタン2฿100.00 = 10000
日本円JPY0¥100 = 100
シンガポールドルSGDセント2S$100.00 = 10000
マレーシアリンギットMYRセン2RM100.00 = 10000
米ドルUSDセント2$100.00 = 10000
ユーロEURセント2€100.00 = 10000

// タイバーツ: ฿1,000.00 = 100,000サタン
const amount = 100000;
const currency = 'thb';

// 日本円: ¥1,000 = 1,000円(補助単位なし)
const amount = 1000;
const currency = 'jpy';

// シンガポールドル: S$50.50 = 5,050セント
const amount = 5050;
const currency = 'sgd';

よくある間違い

// ❌ 間違い - 小数値を使用している
const charge = await omise.charges.create({
amount: 1000.00, // これは฿1,000ではなく฿10.00です!
currency: 'thb'
});

// ✅ 正しい - 最小単位を使用している
const charge = await omise.charges.create({
amount: 100000, // これは฿1,000.00です
currency: 'thb'
});

金額の変換

表示金額から最小単位への変換

function toSmallestUnit(amount, currency) {
const zeroDecimalCurrencies = ['jpy', 'krw', 'vnd'];

if (zeroDecimalCurrencies.includes(currency.toLowerCase())) {
return Math.round(amount);
}

return Math.round(amount * 100);
}

// 使用例
toSmallestUnit(1000.00, 'thb'); // 100000
toSmallestUnit(1000, 'jpy'); // 1000
toSmallestUnit(99.99, 'sgd'); // 9999

最小単位から表示金額への変換

function toDisplayAmount(amount, currency) {
const zeroDecimalCurrencies = ['jpy', 'krw', 'vnd'];

if (zeroDecimalCurrencies.includes(currency.toLowerCase())) {
return amount;
}

return amount / 100;
}

// 使用例
toDisplayAmount(100000, 'thb'); // 1000.00
toDisplayAmount(1000, 'jpy'); // 1000
toDisplayAmount(9999, 'sgd'); // 99.99

表示用フォーマット

function formatCurrency(amount, currency) {
const displayAmount = toDisplayAmount(amount, currency);

return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency.toUpperCase()
}).format(displayAmount);
}

// 使用例
formatCurrency(100000, 'thb'); // "฿1,000.00"
formatCurrency(1000, 'jpy'); // "¥1,000"
formatCurrency(9999, 'sgd'); // "S$99.99"

対応通貨

課金(クレジット/デビットカード)

課金に使用できる通貨は、アカウントの登録国によって異なります:

対応通貨
タイTHB
日本JPY
シンガポールSGD, USD
マレーシアMYR

課金限度額

通貨最小金額最大金額
タイTHB฿20 (2000)฿150,000 (15000000)
日本JPY¥100 (100)¥6,000,000 (6000000)
シンガポールSGDS$1 (100)S$99,999 (9999900)
マレーシアMYRRM1 (100)RM30,000 (3000000)

振込

通貨最小金額最大金額
タイTHB฿30 (3000)฿2,000,000 (200000000)
日本JPY¥1 (1)¥10,000,000 (10000000)
シンガポールSGDS$1 (100)S$200,000 (20000000)
マレーシアMYRRM1 (100)RM500,000 (50000000)

決済通貨

課金は常にアカウントの資金通貨で決済されます。資金通貨はアカウントの登録国によって決まります:

アカウント登録国決済通貨
タイTHB(タイバーツ)
日本JPY(日本円)
シンガポールSGD(シンガポールドル)
マレーシアMYR(マレーシアリンギット)
マルチ通貨課金

決済通貨と異なる通貨で支払いを受け付けた場合、Omiseは現在の為替レートで自動的に金額を変換します。

ゼロデシマル通貨

一部の通貨には補助単位がありません。これらの通貨では、金額の値がそのまま通貨単位を表します:

通貨コード
日本円JPY¥500 = 500
韓国ウォンKRW₩500 = 500
ベトナムドンVND₫500 = 500

APIの例

課金の作成

curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=100000" \
-d "currency=thb" \
-d "card=tokn_test_xxx"

これは**฿1,000.00**(100,000サタン)を課金します。

振込の作成

curl https://api.omise.co/transfers \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=500000" \
-d "recipient=recp_test_xxx"

これは受取人に**฿5,000.00**(500,000サタン)を振り込みます。

返金の作成

curl https://api.omise.co/charges/chrg_test_xxx/refunds \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=50000"

これは課金から**฿500.00**(50,000サタン)を返金します。

丸め処理

最小単位の端数が発生する計算を行う場合は、常に最も近い整数に丸めてください:

// ฿999.00の10%割引を計算
const originalAmount = 99900; // ฿999.00(サタン単位)
const discount = 0.10;
const discountAmount = Math.round(originalAmount * discount); // 9990サタン(฿99.90)
const finalAmount = originalAmount - discountAmount; // 89910サタン(฿899.10)
浮動小数点を避ける

通貨の計算に浮動小数点演算を使用しないでください。常に整数(最小単位)で計算し、適切に丸めてください。

よくある質問

なぜ小数金額ではなく最小通貨単位を使用するのですか?

最小通貨単位(整数)を使用することで、小数計算で発生する浮動小数点の精度エラーを防ぐことができます。例えば:

// 浮動小数点の問題
0.1 + 0.2 === 0.3 // false!(0.30000000000000004になる)

// 整数計算(問題なし)
10 + 20 === 30 // true

整数を使用することで、金融取引の計算が正確になります。

通貨変換はどのように処理されますか?

Omiseはマルチ通貨アカウントの通貨変換を自動的に処理します。決済通貨と異なる通貨で課金が行われた場合、現在の為替レートで変換されます。変換レートは課金レスポンスに含まれます:

{
"object": "charge",
"amount": 10000,
"currency": "usd",
"funding_amount": 350000,
"funding_currency": "thb",
"exchange_rate": 35.0
}
間違った金額形式を送信するとどうなりますか?

APIは整数値を期待しています。小数値を送信すると、切り捨てられます:

  • 1000.50を送信すると1000になる(.50は失われる)
  • これは฿1,000.50ではなく฿10.00が課金されることになります

APIに送信する前に必ず金額を検証してください。

端数金額(例:฿10.25)を課金できますか?

はい、できますが、金額をサタン単位で指定する必要があります:

  • ฿10.25 = 1025サタン
  • ฿99.99 = 9999サタン

課金可能な最小金額は通貨によって異なり、通常は最小課金限度額に相当します。

顧客に金額を表示するにはどうすればよいですか?

最小単位を表示形式に変換します:

const amountInSatangs = 99999;
const displayAmount = (amountInSatangs / 100).toFixed(2); // "999.99"
const formatted = `฿${displayAmount}`; // "฿999.99"

または、ロケールに対応した適切なフォーマットにはIntl.NumberFormatを使用してください。

小数点以下3桁の通貨はありますか?

KWD(クウェートディナール)、BHD(バーレーンディナール)、OMR(オマーンリアル)などの一部の通貨は3桁の小数点(フィルス)を使用します。ただし、これらの通貨は現在Omiseではサポートされていません。サポートされているすべての通貨は、0桁または2桁の小数点を使用します。

関連リソース