Webhook
Omiseアカウントで発生した決済イベント、請求更新、その他の重要なアカウント活動について、安全なHTTPコールバックを通じて即座に通知を受け取ります。
概要
Webhookを使用すると、Omiseアカウントでイベントが発生したときに、アプリケーションがリアルタイムで通知を受け取ることができます。APIをポーリングして変更を確認する代わりに、イベントが発生したときにOmiseが指定されたエンドポイントに自動的にHTTP POSTリクエストを送信します。
主な利点:
- リアルタイム更新 - イベント発生時の即座の通知
- API呼び出しの削減 - ステータス更新のためのポーリング不要
- 信頼性 の高い配信 - 失敗時の自動リトライ
- 安全 - HMAC-SHA256署名検証
- 包括的 - 30以上のイベントタイプをサポート
Webhookの仕組み
Webhookの設定
ダッシュボード設定
- Omiseダッシュボードにログイン
- 設定 → Webhookに移動
- **「Webhookエンドポイントを作成」**をクリック
- エンドポイントURL(HTTPSが必須)を入力
- 受信するイベントを選択(または「すべてのイベント」を選択)
- 保存してwebhook secretをコピー
HTTPS必須
WebhookエンドポイントはHTTPSを使用し、有効なSSL証明書が必要です。自己署名証明書はサポートされていません。
Webhookエンドポイントの実装
基本的なExpress.jsの例
const express = require('express');
const crypto = require('crypto');
const app = express();
// 重要: 署名検証のために生のボディを使用
app.use(express.json({
verify: (req, res, buf) => {
req.rawBody = buf.toString('utf8');
}
}));
app.post('/webhooks/omise', (req, res) => {
// 1. Webhook署名を検証
if (!verifyWebhookSignature(req)) {
console.error('無効なwebhook署名');
return res.sendStatus(401);
}
// 2. イベントデータを取得
const event = req.body;
console.log('受信したイベント:', event.key);
// 3. 異なるイベントタイプを処理
switch (event.key) {
case 'charge.complete':
handleChargeComplete(event.data);
break;
case 'charge.failed':
handleChargeFailed(event.data);
break;
case 'refund.create':
handleRefundCreate(event.data);
break;
// さらにイベントハンドラーを追加...
default:
console.log('未処理のイベントタイプ:', event.key);
}
// 4. 常に200で応答
res.sendStatus(200);
});
function verifyWebhookSignature(req) {
const signatureHeader = req.headers['x-omise-signature'];
const rawBody = req.rawBody;
if (!signatureHeader || !rawBody) {
return false;
}
const secret = Buffer.from(process.env.OMISE_WEBHOOK_SECRET, 'base64');
const expectedBuffer = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest();
const signatures = signatureHeader.split(',');
for (const sig of signatures) {
const sigBuffer = Buffer.from(sig, 'hex');
if (crypto.timingSafeEqual(sigBuffer, expectedBuffer)) {
return true;
}
}
return false;
}
app.listen(3000);
Webhookイベント
決済イベント
| イベント | 説明 |
|---|---|
charge.create | 決済が作成されました |
charge.complete | 決済が正常に完了しました |
charge.failed | 決済が失敗しました |
charge.expire | 承認が期限切れ(未キャプチャ) |
charge.reverse | 決済が取り消されました |
charge.capture | 事前承認された決済がキャプチャされました |
charge.update | 決済が更新され ました |
顧客イベント
| イベント | 説明 |
|---|---|
customer.create | 顧客が作成されました |
customer.update | 顧客情報が更新されました |
customer.update.card | 顧客のカードが更新されました |
customer.destroy | 顧客が削除されました |
カードイベント
| イベント | 説明 |
|---|---|
card.update | カード情報が更新されました |
card.destroy | 顧客からカードが削除されました |
返金イベント
| イベント | 説明 |
|---|---|
refund.create | 返金が作成され処理されました |
セキュリティのベストプラクティス
1. 常に署名を検証
署名検証を絶対にスキップしないでください! これにより、攻撃者が偽のwebhookを送信することを防ぎます。
2. HTTPSを使用
- すべてのwebhookエンドポイントはHTTPSを使用する必要があります
- 有効なSSL証明書を使用(自己署名ではない)
- SSL Labsでテスト
3. 迅速に応答
app.post('/webhooks/omise', async (req, res) => {
// 署名を検証
if (!verifyWebhookSignature(req)) {
return res.sendStatus(401);
}
// すぐに応答
res.sendStatus(200);
// イベントを非同期で処理
processWebhookAsync(req.body).catch(err => {
console.error('Webhook処理エラー:', err);
});
});
テスト
ngrokを使用したローカルテスト
# ngrokをインストール
npm install -g ngrok
# ローカルサーバーを起動
node server.js # ポート3000で実行
# トンネルを作成
ngrok http 3000
# OmiseダッシュボードでHTTPS URLを使用
# 例: https://abc123.ngrok.io/webhooks/omise
よくある質問
OmiseはwebhookにどのIPアドレスを使用しますか?
Omiseはwebhook用の固定IPアドレスリストを公開していません。代 わりに、署名検証(HMAC-SHA256)を使用してwebhookを検証してください。これはIPホワイトリストよりも安全です。
複数のwebhookエンドポイントを持つことができますか?
はい!ダッシュボードで複数のwebhookエンドポイントを設定できます。各エンドポイントは異なるイベントをサブスクライブできます。これは次の場合に便利です:
- 異なるサービス用の個別のエンドポイント
- 開発/ステージング/本番環境
- 冗長性のためのバックアップエンドポイント
関連リソース
- イベント API - 過去のイベントをクエリ
- Webhookセキュリティ - 署名検証
- テストガイド - Webhook処理をテスト
- ダッシュボード Webhook - エンドポイントを設定