通貨と金額
Omise APIで金額を正しく指定する方法、通貨単位の理解、マルチ通貨取引の処理方法について解説します。
概要
Omise APIを使用する際、すべての金額は対象通貨の最小単位で指定する必要があります。これにより、小数値を使用した場合に発生する浮動小数点エラーを防ぎ、精度を確保できます。
最小通貨単位
各通貨には最小単位(補助単位とも呼ばれます)があります:
| 通貨 | コード | 最小単位 | 小数桁数 | 例 |
|---|---|---|---|---|
| タイバーツ | THB | サタン | 2 | ฿100.00 = 10000 |
| 日本円 | JPY | 円 | 0 | ¥100 = 100 |
| シンガポールドル | SGD | セント | 2 | S$100.00 = 10000 |
| マレーシアリンギット | MYR | セン | 2 | RM100.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) |
| シンガポール | SGD | S$1 (100) | S$99,999 (9999900) |
| マレーシア | MYR | RM1 (100) | RM30,000 (3000000) |
振込
| 国 | 通貨 | 最小金額 | 最大金額 |
|---|---|---|---|
| タイ | THB | ฿30 (3000) | ฿2,000,000 (200000000) |
| 日本 | JPY | ¥1 (1) | ¥10,000,000 (10000000) |
| シンガポール | SGD | S$1 (100) | S$200,000 (20000000) |
| マレーシア | MYR | RM1 (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/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=1000" \
-d "currency=jpy" \
-d "card=tokn_test_xxx"
これは**¥1,000**(1,000円 - 小数点なし)を課金します。
curl https://api.omise.co/charges \
-u skey_test_YOUR_SECRET_KEY: \
-d "amount=10000" \
-d "currency=sgd" \
-d "card=tokn_test_xxx"
これはS$100.00(10,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桁の小数点を使用します。
関連リソース
- マルチ通貨 - 複数の通貨で支払いを受け付ける
- Charges API - 課金の作成と管理
- Transfers API - 振込の作成と管理
- 返金 - 返金処理