メインコンテンツへスキップ
バージョン: 最新版

エラーハンドリング

Omise APIのエラーを理解し、信頼性の高い決済統合のための堅牢なエラーハンドリングを実装します。HTTPステータスコード、エラーレスポンス形式、デバッグのベストプラクティスについて学びます。

概要

Omise APIは、APIリクエストの成功または失敗を示すために従来のHTTPレスポンスコードを使用します。エラーは、デバッグと失敗の適切な処理に役立つ詳細情報を含むJSON形式のレスポンスを返します。

クイックリファレンス
  • 2xxコード → 成功
  • 4xxコード → クライアントエラー(リクエストが無効)
  • 5xxコード → サーバーエラー(Omise側で問題が発生)
  • すべてのエラーはobject: "error"と説明フィールドを含むJSONを返します

エラーレスポンス形式

すべてのAPIエラーは一貫したJSON構造を返します。

{
"object": "error",
"location": "https://www.omise.co/api-errors#authentication-failure",
"code": "authentication_failure",
"message": "authentication failed"
}

エラーオブジェクトのフィールド

フィールド説明
objectstringエラーレスポンスの場合は常に"error"
locationstringこのエラータイプのドキュメントへのURL
codestring機械可読なエラーコード(アンダースコア付き小文字)
messagestring英語の人間可読なエラーメッセージ
追加フィールド

一部のエラーには、詳細なデバッグのためにcharge_idcustomer_id、またはvalidation_errorsなどのコンテキスト固有の追加フィールドが含まれる場合があります。


HTTPステータスコード

2xx 成功

200 OK

意味: リクエストが成功しました

{
"object": "charge",
"id": "chrg_test_5xuy4w91xqz7d1w9u0t",
"amount": 100000,
"status": "successful"
}

発生する場合:

  • ✅ GETリクエストがデータを正常に返しました
  • ✅ POST/PATCHリクエストが正常に完了しました
  • ✅ DELETEリクエストがリソースを正常に削除しました

201 Created

意味: リソースが正常に作成されました

発生する場合:

  • ✅ POSTリクエストが新しいリソースを作成しました(まれで、通常は200を返します)

4xx クライアントエラー

クライアントエラーは、送信したリクエストに問題があることを示します。リクエストを修正して再試行してください。

400 Bad Request

意味: リクエストが不正な形式であるか、無効なパラメータが含まれています

{
"object": "error",
"location": "https://www.omise.co/api-errors#bad-request",
"code": "bad_request",
"message": "amount must be at least 2000 (in subunits)"
}

一般的な原因:

  • ❌ 必須パラメータの欠落
  • ❌ 無効なパラメータ値
  • ❌ 最小しきい値を下回る金額
  • ❌ サポートされていない通貨
  • ❌ 不正な形式のJSONペイロード
  • ❌ 無効なパラメータ型

シナリオ例:

# 必須パラメータの欠落
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "currency=thb"
# Error: amount is required

# 金額が小さすぎる
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100" \
-d "currency=thb"
# Error: amount must be at least 2000 (20 THB)

修正方法:

  1. ✅ 必須パラメータについてAPIドキュメントを確認してください
  2. ✅ 送信前にパラメータ値を検証してください
  3. ✅ 適切なデータ型を確保してください(数値は文字列ではなく数値として)
  4. ✅ 通貨固有の最小金額を確認してください

401 Unauthorized

意味: 認証に失敗しました - 無効または欠落したAPIキー

{
"object": "error",
"location": "https://www.omise.co/api-errors#authentication-failure",
"code": "authentication_failure",
"message": "authentication failed"
}

一般的な原因:

  • ❌ APIキーが提供されていません
  • ❌ 無効なAPIキー形式
  • ❌ 取り消されたまたは期限切れのAPIキー
  • ❌ 環境に対して間違ったキー(本番環境でテストキー)
  • ❌ AuthorizationヘッダーでAPIキーが適切にエンコードされていません

シナリオ例:

# APIキーの欠落
curl https://api.omise.co/account
# Error: authentication failed

# 無効なAPIキー
curl https://api.omise.co/account \
-u invalid_key:
# Error: authentication failed

# 秘密鍵操作に公開鍵を使用
curl https://api.omise.co/charges \
-X POST \
-u pkey_test_...: \
-d "amount=100000" \
-d "currency=thb"
# Error: authentication failed

修正方法:

  1. ✅ APIキーが正しいことを確認してください(ダッシュボードからコピー)
  2. ✅ 余分なスペースや文字がないか確認してください
  3. ✅ サーバー側の操作には秘密鍵を使用してください
  4. ✅ トークン/ソースには公開鍵のみを使用してください
  5. ✅ キーが取り消されていないことを確認してください
  6. ✅ テストキーとライブキーが環境と一致することを確認してください

認証について詳しく →


402 Payment Required

意味: カードまたは支払い方法が拒否されました

{
"object": "error",
"location": "https://www.omise.co/api-errors#payment-declined",
"code": "payment_declined",
"message": "Your card was declined",
"charge_id": "chrg_test_5xuy4w91xqz7d1w9u0t"
}

一般的な原因:

  • ❌ 残高不足
  • ❌ カードの有効期限切れ
  • ❌ 誤ったカード詳細(CVV、有効期限)
  • ❌ カード発行者が拒否(詐欺の疑い)
  • ❌ オンライン決済が有効になっていないカード
  • ❌ 取引限度額超過

支払い固有のエラーコード:

コード意味アクション
insufficient_fundカードに十分な残高がありません顧客に別のカードを使用するよう依頼してください
invalid_cardカード番号が無効ですカード番号を確認してください
stolen_or_lost_cardカードが盗難/紛失として報告されています顧客に銀行に連絡するよう依頼してください
failed_processing処理に失敗しました再試行するか、別のカードを使用してください
payment_cancelled顧客が支払いをキャンセルしました顧客のアクション、修正は不要です
payment_expired支払いウィンドウが期限切れになりました新しいchargeを作成してください

シナリオ例:

# 残高不足でのcharge試行
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=1000000" \
-d "currency=thb" \
-d "card=tokn_test_..."
# Error: insufficient_fund

修正方法:

  1. ✅ 顧客に明確なエラーメッセージを表示してください
  2. ✅ 顧客に別の支払い方法を試すよう依頼してください
  3. ✅ 同じカードを複数回再試行しないでください(カードのブロックを回避)
  4. ✅ 顧客に銀行に連絡するよう提案してください
  5. ✅ 分析のために拒否理由を記録してください
支払い失敗を再試行しないでください

拒否されたカードを繰り返し試行すると、詐欺アラートがトリガーされ、カードがブロックされる可能性があります。代わりに、顧客に支払い詳細を確認するか、別の支払い方法を使用するよう依頼してください。


404 Not Found

意味: 要求されたリソースが存在しません

{
"object": "error",
"location": "https://www.omise.co/api-errors#not-found",
"code": "not_found",
"message": "charge chrg_test_invalid was not found"
}

一般的な原因:

  • ❌ 無効なリソースID
  • ❌ リソースが削除されました
  • ❌ 間違ったAPIエンドポイントURL
  • ❌ リソースIDのタイプミス
  • ❌ ライブモードでテストIDを使用(またはその逆)

シナリオ例:

# 無効なcharge ID
curl https://api.omise.co/charges/chrg_invalid \
-u skey_test_...:
# Error: not found

# 間違ったエンドポイント
curl https://api.omise.co/charge/chrg_test_... \
-u skey_test_...:
# Error: not found (should be /charges not /charge)

修正方法:

  1. ✅ リソースIDが正しいことを確認してください
  2. ✅ リソースが削除されていないか確認してください
  3. ✅ テスト/ライブモードがキーと一致することを確認してください
  4. ✅ エンドポイントURLのスペルを確認してください
  5. ✅ リストエンドポイントを使用してリソースを検索してください

422 Unprocessable Entity

意味: リクエストは適切な形式ですが、セマンティックエラーが含まれています

{
"object": "error",
"location": "https://www.omise.co/api-errors#invalid-charge",
"code": "invalid_charge",
"message": "charge has already been captured"
}

一般的な原因:

  • ❌ 無効な状態遷移の試行
  • ❌ ビジネスロジック違反
  • ❌ リソースがすでに処理されています
  • ❌ 無効なパラメータの組み合わせ

シナリオ例:

# すでにキャプチャされたchargeのキャプチャ
curl https://api.omise.co/charges/chrg_test_.../capture \
-X POST \
-u skey_test_...:
# Error: charge has already been captured

# charge金額を超える払い戻し
curl https://api.omise.co/charges/chrg_test_.../refunds \
-X POST \
-u skey_test_...: \
-d "amount=200000"
# Error: refund amount exceeds available amount

修正方法:

  1. ✅ 操作前にリソースの状態を確認してください
  2. ✅ ビジネスロジックの制約を確認してください
  3. ✅ 同じ操作を再試行しないでください(成功している可能性があります)
  4. ✅ リソースを取得して現在の状態を確認してください

429 Too Many Requests

意味: レート制限を超えました

{
"object": "error",
"location": "https://www.omise.co/api-errors#rate-limit-exceeded",
"code": "rate_limit_exceeded",
"message": "too many requests, please try again later"
}

レスポンスヘッダー:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1612137600
Retry-After: 60

修正方法:

  1. ✅ 指数バックオフを実装してください
  2. Retry-Afterヘッダーを確認してください
  3. ✅ リクエスト頻度を減らしてください
  4. ✅ 可能な場合は操作をバッチ処理してください
  5. ✅ 適切な場合はレスポンスをキャッシュしてください

レート制限について詳しく →


5xx サーバーエラー

サーバーエラーは、Omise側の問題を示します。これらはまれですが、適切に処理する必要があります。

500 Internal Server Error

意味: Omiseのサーバーで問題が発生しました

{
"object": "error",
"location": "https://www.omise.co/api-errors#internal-server-error",
"code": "internal_server_error",
"message": "An internal server error occurred"
}

発生する場合:

  • ⚠️ 予期しないサーバー側エラー
  • ⚠️ 一時的なサービス中断
  • ⚠️ データベース接続の問題

処理方法:

  1. ✅ 指数バックオフでリクエストを再試行してください
  2. ✅ インシデントについてstatus.omise.coを確認してください
  3. ✅ 持続する場合はサポートに連絡してください
  4. ✅ デバッグのためにエラーの詳細を記録してください

503 Service Unavailable

意味: サービスが一時的に利用できません

{
"object": "error",
"location": "https://www.omise.co/api-errors#service-unavailable",
"code": "service_unavailable",
"message": "Service temporarily unavailable"
}

発生する場合:

  • ⚠️ スケジュールされたメンテナンス
  • ⚠️ サービスの過負荷
  • ⚠️ アップストリームプロバイダーの問題

処理方法:

  1. ✅ 遅延後に再試行してください(Retry-Afterヘッダーを確認)
  2. ✅ ユーザーにメンテナンスメッセージを表示してください
  3. ✅ 後で処理するためにリクエストをキューに入れてください
  4. ✅ ステータスページを確認してください

一般的なエラーコード

認証エラー

コードHTTPステータス説明解決策
authentication_failure401無効または欠落したAPIキーAPIキーが正しいことを確認してください
forbidden403キーに必要な権限がありませんこの操作には秘密鍵を使用してください

リクエストエラー

コードHTTPステータス説明解決策
bad_request400無効なリクエストパラメータ必須パラメータと形式を確認してください
invalid_charge422chargeの状態が操作を許可しません最初にchargeのステータスを確認してください
invalid_customer422顧客操作が許可されていません顧客の状態を確認してください
not_found404リソースが存在しませんリソースIDを確認してください

支払いエラー

コードHTTPステータス説明解決策
payment_declined402支払いが拒否されました顧客に別のカードを使用するよう依頼してください
insufficient_fund402残高不足別の支払い方法をリクエストしてください
invalid_card402カードの詳細が無効ですカード番号とCVVを確認してください
stolen_or_lost_card402カードが盗難/紛失として報告されています顧客は銀行に連絡する必要があります
failed_processing402支払い処理に失敗しました再試行するか、別のカードを使用してください
payment_cancelled402顧客が支払いをキャンセルしました顧客のアクション
payment_expired402支払いウィンドウが期限切れになりました新しいchargeを作成してください

システムエラー

コードHTTPステータス説明解決策
internal_server_error500サーバー側エラーバックオフで再試行してください
service_unavailable503サービスが一時的にダウンしています待機して再試行してください
rate_limit_exceeded429リクエストが多すぎますレート制限を実装してください

エラーハンドリングのベストプラクティス

1. 常に最初にHTTPステータスを確認する

# ✅ 良い - ステータスコードを確認
require 'omise'

begin
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: params[:token]
})

# 成功
render json: charge

rescue Omise::Error => e
# タイプに基づいてエラーを処理
case e.http_status
when 400
render json: { error: 'Invalid request' }, status: 400
when 401
render json: { error: 'Authentication failed' }, status: 401
when 402
render json: { error: 'Payment declined', code: e.code }, status: 402
when 404
render json: { error: 'Resource not found' }, status: 404
when 422
render json: { error: 'Invalid operation', message: e.message }, status: 422
when 429
render json: { error: 'Rate limit exceeded' }, status: 429
when 500, 503
render json: { error: 'Service temporarily unavailable' }, status: 503
else
render json: { error: 'An error occurred' }, status: 500
end
end

2. エラーの詳細を解析する

# ✅ 良い - エラーの詳細を抽出
import omise

try:
charge = omise.Charge.create(
amount=100000,
currency='thb',
card=token
)
return charge

except omise.errors.BaseError as e:
error_code = e.code
error_message = e.message

# デバッグのためにログを記録
logger.error(f"Charge failed: {error_code} - {error_message}")

# ユーザーフレンドリーなメッセージを返す
if error_code == 'insufficient_fund':
return {'error': 'Insufficient funds. Please try a different card.'}
elif error_code == 'invalid_card':
return {'error': 'Invalid card details. Please check and try again.'}
else:
return {'error': 'Payment failed. Please try again.'}

3. サーバーエラーの再試行ロジックを実装する

// ✅ 良い - 指数バックオフで再試行
const omise = require('omise')({ secretKey: process.env.OMISE_SECRET_KEY });

async function createChargeWithRetry(chargeData, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const charge = await omise.charges.create(chargeData);
return { success: true, charge };

} catch (error) {
const isServerError = error.statusCode >= 500;
const isLastAttempt = attempt === maxRetries - 1;

if (isServerError && !isLastAttempt) {
// 指数バックオフ: 1s, 2s, 4s
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}

// クライアントエラーまたは最後の試行は再試行しない
return {
success: false,
error: {
code: error.code,
message: error.message,
statusCode: error.statusCode
}
};
}
}
}

4. リクエストを送信する前に検証する

<?php
// ✅ 良い - API呼び出し前に検証
function createCharge($amount, $currency, $token) {
// 金額を検証
$minAmounts = [
'thb' => 2000, // 20 THB
'jpy' => 50, // 50 JPY
'sgd' => 100, // 1 SGD
];

if ($amount < $minAmounts[$currency]) {
return [
'error' => 'Amount below minimum for ' . strtoupper($currency),
'min_amount' => $minAmounts[$currency]
];
}

// 通貨を検証
$supportedCurrencies = ['thb', 'jpy', 'sgd', 'myr', 'usd'];
if (!in_array($currency, $supportedCurrencies)) {
return [
'error' => 'Unsupported currency',
'supported' => $supportedCurrencies
];
}

// トークン形式を検証
if (!preg_match('/^tokn_test_[a-z0-9]+$/', $token) &&
!preg_match('/^tokn_[a-z0-9]+$/', $token)) {
return ['error' => 'Invalid token format'];
}

try {
$charge = OmiseCharge::create([
'amount' => $amount,
'currency' => $currency,
'card' => $token
]);

return ['success' => true, 'charge' => $charge];

} catch (Exception $e) {
return [
'error' => $e->getMessage(),
'code' => $e->getCode()
];
}
}

5. ユーザーフレンドリーなメッセージを表示する

// ✅ 良い - エラーコードをユーザーメッセージに変換
package main

import (
"github.com/omise/omise-go"
)

func getUserMessage(err error) string {
if omiseErr, ok := err.(*omise.Error); ok {
switch omiseErr.Code {
case "authentication_failure":
return "A system error occurred. Please try again later."
case "insufficient_fund":
return "Your card has insufficient funds. Please use a different card."
case "invalid_card":
return "The card details are invalid. Please check and try again."
case "stolen_or_lost_card":
return "This card cannot be used. Please contact your bank."
case "payment_cancelled":
return "Payment was cancelled. You can try again when ready."
case "payment_expired":
return "Payment session expired. Please start a new payment."
case "rate_limit_exceeded":
return "Too many attempts. Please wait a moment and try again."
case "service_unavailable":
return "Payment service is temporarily unavailable. Please try again later."
default:
return "Payment failed. Please try again or use a different payment method."
}
}
return "An unexpected error occurred. Please try again."
}

func createCharge(amount int64, currency string, token string) (string, error) {
client, _ := omise.NewClient(
os.Getenv("OMISE_PUBLIC_KEY"),
os.Getenv("OMISE_SECRET_KEY"),
)

charge, err := client.CreateCharge(&omise.ChargeParams{
Amount: amount,
Currency: currency,
Card: token,
})

if err != nil {
userMessage := getUserMessage(err)
return userMessage, err
}

return "Payment successful!", nil
}

6. デバッグのためにエラーをログに記録する

# ✅ 良い - 包括的なエラーログ
require 'logger'

logger = Logger.new('omise_errors.log')

begin
charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: token
})

rescue Omise::Error => e
# 詳細なエラー情報をログに記録
logger.error({
timestamp: Time.now.iso8601,
error_type: 'omise_api_error',
http_status: e.http_status,
error_code: e.code,
error_message: e.message,
request_id: e.request_id,
charge_params: {
amount: 100000,
currency: 'thb',
token: token[0..10] + '...' # セキュリティのための部分的なトークン
},
backtrace: e.backtrace.first(5)
}.to_json)

# 再発生または処理
raise
end

7. 機密性の高いエラーの詳細を公開しない

// ❌ 悪い - 内部の詳細を公開
app.post('/charge', async (req, res) => {
try {
const charge = await omise.charges.create(req.body);
res.json(charge);
} catch (error) {
// これをしないでください - APIキー、内部パスなどを公開します
res.status(500).json({ error: error.toString() });
}
});

// ✅ 良い - 安全なエラーメッセージ
app.post('/charge', async (req, res) => {
try {
const charge = await omise.charges.create({
amount: req.body.amount,
currency: req.body.currency,
card: req.body.token
});
res.json({ success: true, charge_id: charge.id });

} catch (error) {
// サーバー側で完全なエラーをログに記録
console.error('Charge failed:', error);

// クライアントに安全なメッセージを返す
const safeMessage = {
success: false,
error: {
code: error.code || 'unknown',
message: getUserFriendlyMessage(error.code)
}
};

res.status(error.statusCode || 500).json(safeMessage);
}
});

エラーのデバッグ

1. 開発にテストモードを使用する

開発中は常にテストAPIキーを使用してください。

# ✅ テストモード - デバッグに安全
export OMISE_SECRET_KEY=skey_test_5xuy4w91xqz7d1w9u0t

# テストモードのエラーはライブモードと同じです
curl https://api.omise.co/charges \
-X POST \
-u $OMISE_SECRET_KEY: \
-d "amount=100000" \
-d "currency=thb" \
-d "card=tokn_test_no1t4tnemucod0e51mo"

2. ダッシュボードでリクエスト/レスポンスを確認する

  1. ダッシュボードログに移動します
  2. すべてのAPIリクエストとレスポンスを表示します
  3. 正確なエラーの詳細を確認します
  4. リクエストパラメータを確認します

3. デバッグログを有効にする

# Ruby - デバッグログを有効にする
require 'omise'

Omise.api_key = ENV['OMISE_SECRET_KEY']
Omise.debug = true # HTTPリクエスト/レスポンスを出力

charge = Omise::Charge.create({
amount: 100000,
currency: 'thb',
card: token
})
# Python - デバッグログを有効にする
import omise
import logging

# HTTPデバッグを有効にする
logging.basicConfig(level=logging.DEBUG)

omise.api_secret = os.environ['OMISE_SECRET_KEY']
// Node.js - リクエストインターセプションを使用
const omise = require('omise')({
secretKey: process.env.OMISE_SECRET_KEY
});

// すべてのリクエスト/レスポンスをログに記録
omise.interceptor = {
request: (config) => {
console.log('Request:', config);
return config;
},
response: (response) => {
console.log('Response:', response);
return response;
},
responseError: (error) => {
console.error('Error:', error);
throw error;
}
};

4. Curlでテストする

# 詳細出力は完全なHTTP交換を表示します
curl -v https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100000" \
-d "currency=thb" \
-d "card=tokn_test_..."

# 表示内容:
# > POST /charges HTTP/1.1
# > Authorization: Basic ...
# > Content-Type: application/x-www-form-urlencoded
# < HTTP/1.1 200 OK
# < Content-Type: application/json

5. 一般的なデバッグ手順

認証エラーの場合:

  1. ✅ ダッシュボードからAPIキーをコピーしてください(手動で入力しないでください)
  2. ✅ 余分なスペースや改行がないか確認してください
  3. ✅ テストキーとライブキーが環境と一致することを確認してください
  4. ✅ Authorizationヘッダー形式を確認してください: Basic base64(key:)

支払いエラーの場合:

  1. ✅ 最初にテストカード番号で試してください
  2. ✅ カードの詳細が正しいことを確認してください
  3. ✅ カードがオンライン決済をサポートしているか確認してください
  4. ✅ 問題を特定するために異なるカードでテストしてください

検証エラーの場合:

  1. ✅ エラーメッセージを注意深く読んでください
  2. ✅ パラメータ要件についてAPIドキュメントを確認してください
  3. ✅ データ型を確認してください(数値 vs 文字列)
  4. ✅ 最小値/最大値を確認してください

サーバーエラーの場合:

  1. status.omise.coを確認してください
  2. ✅ 遅延後に再試行してください
  3. ✅ 持続する場合はサポートに連絡してください
  4. ✅ デバッグのためにリクエスト/レスポンスを保存してください

エラーハンドリングのチェックリスト

本番環境に移行する前に、エラーハンドリングが以下を満たしていることを確認してください。

  • すべてのAPI例外/エラーをキャッチする
  • HTTPステータスコードを確認する
  • 特定の処理のためにエラーコードを解析する
  • ユーザーフレンドリーなエラーメッセージを表示する
  • 完全なコンテキストでエラーをログに記録する(サーバー側のみ)
  • サーバーエラーの再試行ロジックを実装する
  • 再試行に指数バックオフを使用する
  • 支払い失敗を再試行しない
  • 送信前にリクエストを検証する
  • 機密性の高いエラーの詳細をユーザーに公開しない
  • ネットワークタイムアウトを処理する
  • サービス利用不可の場合のフォールバックを用意する
  • エラー率を監視する
  • 異常なエラーパターンにアラートを出す
  • 開発環境でエラーシナリオをテストする

エラーシナリオのテスト

認証エラーのテスト

# 無効なAPIキー
curl https://api.omise.co/account \
-u invalid_key:
# Returns 401 authentication_failure

# 間違ったキータイプ
curl https://api.omise.co/charges \
-X POST \
-u pkey_test_...: \
-d "amount=100000"
# Returns 401 authentication_failure

検証エラーのテスト

# 金額が小さすぎる
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100" \
-d "currency=thb"
# Returns 400 bad_request

# 無効な通貨
curl https://api.omise.co/charges \
-X POST \
-u skey_test_...: \
-d "amount=100000" \
-d "currency=invalid"
# Returns 400 bad_request

支払いエラーのテスト

特定のエラーをトリガーする特別なテストカードを使用します。

# 残高不足
curl https://vault.omise.co/tokens \
-X POST \
-u pkey_test_...: \
-d "card[number]=4111111111111111" \
-d "card[name]=Test User" \
-d "card[expiration_month]=12" \
-d "card[expiration_year]=2025" \
-d "card[security_code]=123"
# chargeでトークンを使用 - insufficient_fundで拒否されます

# 処理失敗
curl https://vault.omise.co/tokens \
-X POST \
-u pkey_test_...: \
-d "card[number]=4000000000000002" \
-d "card[name]=Test User" \
-d "card[expiration_month]=12" \
-d "card[expiration_year]=2025" \
-d "card[security_code]=123"
# chargeでトークンを使用 - failed_processingで拒否されます

すべてのテストカードを表示 →


FAQ

失敗した支払いを自動的に再試行する必要がありますか?

いいえ、支払い失敗(4xxエラー)を自動的に再試行しないでください。 拒否されたカードを繰り返し試行すると、以下の問題が発生する可能性があります。

  • 詐欺アラートをトリガーする
  • 発行者によってカードがブロックされる
  • 顧客を苛立たせる

代わりに:

  • 明確なエラーメッセージを表示する
  • 顧客に支払い詳細を確認するよう依頼する
  • 別の支払い方法を提案する
  • 顧客が準備できたときに手動で再試行できるようにする

**サーバーエラー(5xx)**は指数バックオフで再試行できます。

chargeが失敗したかどうかを確認するにはどうすればよいですか?

HTTPステータスコードとchargeのステータスを確認してください。

成功:

  • HTTP 200 OK
  • charge.status = "successful" (キャプチャ済み)
  • charge.status = "pending" (承認済み、まだキャプチャされていません)

失敗:

  • HTTP 402 Payment Required
  • payment_declinedのようなコードを含むエラーレスポンス
  • charge.status = "failed" または "expired"
4xxと5xxエラーの違いは何ですか?

4xx = クライアントエラー(あなたの過失)

  • リクエストが無効でした
  • リクエストを修正して再試行してください
  • 例: 不正なパラメータ、拒否された支払い、無効な認証

5xx = サーバーエラー(私たちの過失)

  • Omise側で問題が発生しました
  • リクエストは有効でしたが、処理できませんでした
  • バックオフで再試行してください
  • 例: サービスダウン、内部エラー
再試行する前にどのくらい待つ必要がありますか?

指数バックオフを使用してください。

  1. 最初の再試行: 1秒待機
  2. 2回目の再試行: 2秒待機
  3. 3回目の再試行: 4秒待機
  4. 4回目の再試行: 8秒待機
  5. 3〜5回の試行後にあきらめる
async function retryWithBackoff(fn, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
if (error.statusCode < 500 || attempt === maxAttempts - 1) {
throw error;
}
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
支払い失敗に関する詳細情報を取得できますか?

支払い失敗の理由は、セキュリティのために意図的に制限されています。カード発行者は、詐欺を防ぐために具体的な拒否理由を常に提供するとは限りません。

取得できる情報:

  • ✅ 高レベルのエラーコード(insufficient_fundinvalid_card
  • ✅ 一般的なエラーメッセージ

取得できない情報:

  • ❌ 正確なカード残高
  • ❌ 特定の詐欺フラグ
  • ❌ 内部銀行コード

これは、攻撃者が盗まれたカードをテストすることからカード所有者を保護します。


クイックリファレンス

エラーレスポンス構造

{
"object": "error",
"location": "https://www.omise.co/api-errors#<error-code>",
"code": "<error_code>",
"message": "<human-readable message>"
}

一般的なステータスコード

ステータス意味アクション
200成功レスポンスを処理
400不正なリクエストパラメータを修正
401未承認APIキーを修正
402支払い失敗エラーを表示、再試行しない
404見つかりませんリソースIDを確認
422無効な状態リソースの状態を確認
429レート制限バックオフを実装
500サーバーエラーバックオフで再試行
503サービスダウン後で再試行

エラーハンドリングパターン

1. APIリクエストを試行
2. エラーをキャッチ
3. HTTPステータスを確認
4. エラーコードを解析
5. エラーをログに記録(サーバー側)
6. ユーザーメッセージを表示(安全)
7. 5xxの場合のみ再試行
8. エラー率を監視

関連リソース


次へ: ページネーションを学習して、大きな結果セットを効率的に処理します。