3D Secure
3D Secure 2.0認証を実装して、不正を削減し、責任を転嫁し、ヨーロッパなどでのStrong Customer Authentication (SCA)要件に準拠します。
概要
3D Secure (3DS)は、オンラインカード取引にセキュリティレイヤーを追加する認証プロトコルです。有効にすると、顧客は決済を完了する前にカード発行者で本人確認を行います。
主な利点:
- 🔒 不正の削減 - 追加の認証ステップ
- 🛡️ 責任の転嫁 - 不正の責任がカード発行者に転嫁されます
- ✅ SCA準拠 - ヨーロッパの決済に必要
- 📈 承認率の向上 - 発行者は認証さ れた取引を信頼します
- 💳 すべてのカードをサポート - Visa、Mastercard、JCB
3D Secureブランド:
- Visa: Visa Secure (旧Verified by Visa)
- Mastercard: Mastercard Identity Check (旧Mastercard SecureCode)
- JCB: J/Secure
3D Secure 1 vs 3D Secure 2
| 機能 | 3DS 1.0 (レガシー) | 3DS 2.0 (現在) |
|---|---|---|
| ユーザー体験 | ポップアップ、扱いにくい | アプリ内、シームレス |
| モバイルサポート | 貧弱 | 優秀 |
| 共有データ | 限定的 | リッチなコンテキスト |
| 摩擦 | 高い | 低い (多くの場合摩擦なし) |
| 認証 | パスワード | 生体認証、PIN、OTP |
| 成功率 | 低い | 高い |
備考
Omiseはデフォルトで3D Secure 2.0をサポートしており、最高のユーザー体験と最高の承認率を提供します 。
3D Secureの仕組み
顧客体験:
- 顧客がチェックアウト時にカード情報を入力
- 3DSが必要な場合、発行者の認証ページにリダイレクト
- 顧客が以下で認証:
- 生体認証 (指紋、Face ID)
- PINまたはパスワード
- ワンタイムパスワード (SMS/アプリ)
- マーチャントサイトに戻る
- 認証に基づいて決済が完了または失敗
完了時間: 10-30秒 (生体認証でシームレス)
実装
自動3DS (推奨)
Omiseは必要に応じて自動的に3DSをトリガーします:
- Node.js
- PHP
- Python
const omise = require('omise')({
publicKey: 'pkey_test_YOUR_PUBLIC_KEY',
secretKey: 'skey_test_YOUR_SECRET_KEY'
});
// カードトークンで課金を作成
const charge = await omise.charges.create({
amount: 100000,
currency: 'THB',
card: cardToken, // Omise.jsから
return_uri: 'https://yourdomain.com/payment/callback'
});
// 3DSが必要かどうかを確認
if (charge.authorize_uri) {
// 顧客を3DS認証にリダイレクト
res.redirect(charge.authorize_uri);
} else if (charge.status === 'successful') {
// 3DSなしで決済成功
res.redirect('/success');
}
<?php
$charge = OmiseCharge::create(array(
'amount' => 100000,
'currency' => 'THB',
'card' => $cardToken,
'return_uri' => 'https://yourdomain.com/payment/callback'
));
if ($charge['authorize_uri']) {
// 3DSにリダイレクト
header('Location: ' . $charge['authorize_uri']);
} else if ($charge['status'] === 'successful') {
// 3DSなしで成功
header('Location: /success');
}
?>
import omise
charge = omise.Charge.create(
amount=100000,
currency='THB',
card=card_token,
return_uri='https://yourdomain.com/payment/callback'
)
if charge.authorize_uri:
# 3DSにリダイレクト
return redirect(charge.authorize_uri)
elif charge.status == 'successful':
# 3DSなしで成功
return redirect('/success')
3DSからの復帰を処理
app.get('/payment/callback', async (req, res) => {
try {
const chargeId = req.query.charge_id;
const charge = await omise.charges.retrieve(chargeId);
if (charge.status === 'successful') {
// 3DS認証成功
await processOrder(charge.metadata.order_id);
res.redirect('/payment-success');
} else if (charge.status === 'failed') {
// 認証または決済失敗
res.redirect(`/payment-failed?reason=${charge.failure_message}`);
} else {
// 保留中 (まれ)
res.redirect('/payment-pending');
}
} catch (error) {
res.redirect('/payment-error');
}
});
3DSが必要な場合
必須 (常に必要)
欧州経済領域 (EEA):
- すべての消費者決済にはStrong Customer Authentication (SCA)が必要
- EU + アイスランド、リヒテンシュタイン、ノルウェーをカバー
- マーチャントは3DSを実装する必要があります。そうしないとカードが拒否されます
一部の銀行/地域:
- インド (RBI義務)
- アジア太平洋の一部
- 発行者のポリシーによって異なります
オプション (リスクベース)
カード発行者が3DSを要求する可能性がある場合:
- 高額取引
- 高リスクマーチャント
- 疑わしいパターン
- マーチャントでの顧客の初回取引
- 国境を越えた決済
摩擦なし vs チャレンジ:
- 摩擦なし: 発行者が顧客のアクションなしで承認 (3DS 2.0の80%以上)
- チャレンジ: 顧客が認証する必要がある (20%)
完全な実装例
const express = require('express');
const omise = require('omise')({
publicKey: process.env.OMISE_PUBLIC_KEY,
secretKey: process.env.OMISE_SECRET_KEY
});
const app = express();
app.use(express.json());
// ステップ1: 課金を作成
app.post('/checkout', async (req, res) => {
try {
const { token, amount, currency, order_id } = req.body;
const charge = await omise.charges.create({
amount: amount,
currency: currency,
card: token, // Omise.jsから
return_uri: `${process.env.BASE_URL}/payment/callback`,
metadata: {
order_id: order_id
}
});
if (charge.authorize_uri) {
// 3DS必要 - リダイレクトURLを返す
res.json({
requires_authentication: true,
authorize_uri: charge.authorize_uri,
charge_id: charge.id
});
} else if (charge.status === 'successful') {
// 3DSなしで成功
await processOrder(order_id);
res.json({
requires_authentication: false,
status: 'successful',
charge_id: charge.id
});
} else {
// 失敗
res.status(400).json({
error: charge.failure_message
});
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// ステップ2: 3DS復帰を処理
app.get('/payment/callback', async (req, res) => {
try {
const charge = await omise.charges.retrieve(req.query.charge_id);
if (charge.status === 'successful') {
await processOrder(charge.metadata.order_id);
res.redirect(`/order-confirmation?order=${charge.metadata.order_id}`);
} else {
res.redirect(`/payment-failed?error=${charge.failure_code}`);
}
} catch (error) {
res.redirect('/payment-error');
}
});
// ステップ3: Webhook (推奨)
app.post('/webhooks/omise', async (req, res) => {
const event = req.body;
if (event.key === 'charge.complete') {
const charge = event.data;
if (charge.status === 'successful') {
await processOrder(charge.metadata.order_id);
}
}
res.sendStatus(200);
});
app.listen(3000);
テスト3D Secure
テストカード
| カード番号 | 3DS動作 | 結果 |
|---|---|---|
| 4242424242424242 | 3DSなし | 成功 |
| 4000000000003220 | 3DS必要、成功 | 成功 |
| 4000000000009235 | 3DS必要、失敗 | 拒否 |
| 4000008260003178 | 3DS、残高不足 | 拒否 |
テストフロー
- 3DSテストカードを使用
- テスト3DSページにリダ イレクト
- "成功"または"失敗"ボタンをクリック
- 結果とともにreturn_uriに戻る
完全なリストについてはテストガイドをご覧ください。
ベストプラクティス
1. 常にreturn_uriを提供
// 3DSリダイレクトに必要
const charge = await omise.charges.create({
// ... その他のパラメータ
return_uri: 'https://yourdomain.com/payment/callback' // HTTPSである必要があります
});
2. すべての課金ステータスを処理
switch (charge.status) {
case 'successful':
// 決済完了
break;
case 'failed':
// エラーを表示、再試行を許可
break;
case 'pending':
// Webhookを待つ (まれ)
break;
case 'expired':
// 顧客が3DSを完了しなかった
break;
}
3. HTTPSを使用
3DSはreturn_uriにHTTPSが必要です:
✅ https://yourdomain.com/callback
❌ http://yourdomain.com/callback
4. Webhookを実装
return_uriのみに依存しないでください:
// Webhook は信頼できる情報源です
app.post('/webhooks/omise', handleWebhook);
// Return URIは顧客UXのみ
app.get('/payment/callback', showCustomerResult);
よくある質問
3D Secureは必須ですか?
必須の場合:
- 欧州経済領域 (EEA)の決済 - SCA要件
- インド - RBI義務
- 一部のアジア太平洋地域
オプションの場合:
- その他の地域 (ただし不正保護のために推奨)
- 高リスク取引 (発行者が要求する場合があります)
3DSはコンバージョンを下げますか?
3DS 1.0: はい、大幅な低下 (10-20%) 3DS 2.0: 最小限の影響 (1-5%) 理由:
- 摩擦なし認証 (80%以上のケース)
- 生体認証 (高速で簡単)
- より良いモバイル体験
責任転嫁とは何ですか?
3DS認証が成功すると、不正の責任はマーチャントからカード発行者に転嫁されます。3DSがない場合、マーチャントが不正の責任を負います。
顧客は3DSをスキップできますか?
いいえ。3DSが必要な場合(規制または発行者による)、スキップできません。顧客が認証を完了しない場合、決済は失敗します。
関連リソース
次のステップ
- 統合に自動3DSを実装
- すべてのカード課金にreturn_uriを追加
- 3DSリダイレクトと復帰フローを処理
- 3DSテストカードでテスト
- Webhook処理を設定
- 3DS成功率を監視
- 本番環境に移行