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

Webhook

Omiseアカウントで発生した決済イベント、請求更新、その他の重要なアカウント活動について、安全なHTTPコールバックを通じて即座に通知を受け取ります。

概要

Webhookを使用すると、Omiseアカウントでイベントが発生したときに、アプリケーションがリアルタイムで通知を受け取ることができます。APIをポーリングして変更を確認する代わりに、イベントが発生したときにOmiseが指定されたエンドポイントに自動的にHTTP POSTリクエストを送信します。

主な利点:

  • リアルタイム更新 - イベント発生時の即座の通知
  • API呼び出しの削減 - ステータス更新のためのポーリング不要
  • 信頼性の高い配信 - 失敗時の自動リトライ
  • 安全 - HMAC-SHA256署名検証
  • 包括的 - 30以上のイベントタイプをサポート

Webhookの仕組み

Webhookの設定

ダッシュボード設定

  1. Omiseダッシュボードにログイン
  2. 設定 → Webhookに移動
  3. **「Webhookエンドポイントを作成」**をクリック
  4. エンドポイントURL(HTTPSが必須)を入力
  5. 受信するイベントを選択(または「すべてのイベント」を選択)
  6. 保存して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エンドポイントを設定できます。各エンドポイントは異なるイベントをサブスクライブできます。これは次の場合に便利です:

  • 異なるサービス用の個別のエンドポイント
  • 開発/ステージング/本番環境
  • 冗長性のためのバックアップエンドポイント

関連リソース

次のステップ

  1. Webhookエンドポイントを設定
  2. 署名検証を実装
  3. 主要イベントを処理
  4. ngrokでテスト
  5. 本番環境へ