3D セキュアを実施することで、不正利用によるチャージバックの発生を抑制する効果が見込めます。 3D セキュアの概要については、3Dセキュアガイド の各ドキュメントをご覧ください。
3Dセキュアを開始する
通常の支払い作成と同様のパラメーターで支払いを作成します。その際、追加のパラメーター three_d_secure=true
を指定することで、3D セキュア処理待ち状態の支払いが作成されます。
3D セキュア処理待ち状態の支払いを作成
curl -X POST https://api.pay.jp/v1/charges \
-u sk_test_c62fade9d045b54cd76d7036: \
-d "amount=500" \
-d "currency=jpy" \
-d "card=tok_xxx" \
-d "capture=true" \
-d "three_d_secure=true"
作成された支払いは決済の成否を表す paid
属性が false
になっており、決済処理はまだ行われていない状態になっています。
また、3D セキュアの実施状態を表す three_d_secure_status
属性が unverified
になっており、これによって 3D セキュア処理待ちであることが示されています。
注意: 3D セキュア開始から一定時間以内に支払い完了まで到達しない場合、その支払いの 3D セキュアを進めることができなくなります。 具体的な時間は API ドキュメントをご参照ください。
購入者を3Dセキュアに誘導する
3D セキュア認証を進めるために、購入者をカード会社が提供する 3D セキュア認証画面に誘導します。 誘導の方法は リダイレクト型 と サブウィンドウ型 の2種類があります。
リダイレクト型
サービスから PAY.JP が提供する 3D セキュア開始エンドポイントにリダイレクトさせ、認証完了後にサービスが指定するエンドポイントにリダイレクトで戻す方式です。 支払いを作成し 3D セキュアを実施するタイミングで、利用者を下記のエンドポイントにパラメーター付きでリダイレクトさせます。
https://api.pay.jp/v1/tds/:resource_id/start?publickey=....&back=...
resource_id には作成したオブジェクト(Charge か Token)の ID が入ります。
リダイレクト時のパラメーターとして、完了後の戻り先となる URL を指定します。以下の 2 通りの指定ができます。
back
- PAY.JP の管理画面で事前に登録した戻り先 URL を使用する場合に指定します。登録時に設定した識別子を指定してください。
back_url
- 動的に戻り先 URL を指定する場合に使用します。JWS(JSON Web Signatures)形式のデータで、戻り先 URL を含めて指定します。以下に
back_url
を使用した「3D セキュア開始エンドポイントへのリダイレクト例」のコードを記載しています。
- 動的に戻り先 URL を指定する場合に使用します。JWS(JSON Web Signatures)形式のデータで、戻り先 URL を含めて指定します。以下に
エンドポイントとパラメーターの詳細はAPIリファレンス - 3Dセキュア開始をご覧ください。
処理完了、あるいはエラーとなったタイミングで、利用者は指定した戻り先 URL にリダイレクトされます。戻り先 URL では次項の支払い完了処理を行います。
サブウィンドウ型に比べると少し実装は煩雑になりますが、一部モバイル環境ではサブウィンドウ型が適切に動作しない可能性があるため、より広い環境で動作させたい場合や、サブウィンドウのユーザー体験が望ましくない場合にはリダイレクト型をご利用ください。
3D セキュア開始エンドポイントへのリダイレクト例
サーバー側処理で3D セキュア開始エンドポイントにリダイレクトするNode.jsのサンプルコードです。
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const secretKey = 'sk_test_xxxxx';
const publicKey = 'pk_test_xxxxx'
function generateJwtUrl(baseUrl, params) {
// パラメータのエンコード処理
const encodedParams = Object.keys(params)
.map(key => `${key}=${encodeURIComponent(params[key])}`)
.join('&');
// エンコード済みのクエリパラメータをURLに追加
const encodedUrl = `${baseUrl}?${encodedParams}`;
const payload = {
url: encodedUrl,
};
// JWTを生成
return jwt.sign(payload, secretKey, { algorithm: 'HS256' });
}
// 決済させる加盟店様側のURL
app.get('/charge', (req, res) => {
// 3DSのChargeを作る
const charge = payjp.charge.create({..., three_d_secure: true});
const baseUrl = 'https://example.com/sample'; // 加盟店様の戻り先URL
const queryParams = {
param1: 'ペイ&太郎',
param2: 'test'
};
// JWT付きURLを生成
const jwtUrl = generateJwtUrl(baseUrl, queryParams);
// 加盟店様のユーザーをリダイレクト
const redirectUrl = `https://api.pay.jp/v1/tds/${charge.id}/start?publickey=${publicKey}&back_url=${jwtUrl}`;
res.redirect(redirectUrl);
});
サブウィンドウ型
3D セキュア認証画面を表示するサブウィンドウを表示し、購入者はその内部に表示されるカード発行会社の画面上でパスワード入力等を行います。
誘導には、payjp.js v2 が提供する openThreeDSecureDialog
関数を利用します。支払い ID が必要になるため、誘導ページのレンダリングに支払いパラメーターを含めるなどの方法でクライアントに支払い ID を連携する必要があります。
一部モバイルブラウザではポップアップに対して警告やブロックが働くため、利用者によっては認証画面に辿りつけないこともございますので、利用状況に応じてリダイレクト型もご検討ください。
const payjp = Payjp('pk_test_0383a1b8f91e8a6e3ea0e2a9')
payjp.openThreeDSecureDialog(
'サーバーサイドから渡された支払いID'
).then(() => {
// 3Dセキュア処理が終了したことをサーバーサイドに通知する
})
openThreeDSecureDialog
を呼び出すと、3D セキュア認証画面がサブウィンドウで開かれます。
購入者が 3D セキュア認証を終了させることでサブウィンドウは自動的に閉じられ、Promise が解決されます。
Promise が解決されたことが確認できたら、再度サーバー側に処理を移し、次項の支払い完了処理を行います。
支払いを完了させる
3D セキュアフローの完了を検知したら、サーバーから 3D セキュア完了エンドポイントにリクエストします。
curl -X POST https://api.pay.jp/v1/charges/支払いID/tds_finish \
-u sk_test_c62fade9d045b54cd76d7036:
3D セキュア認証が正しく行われていれば、決済処理が行われ、通常の支払い作成と同様のレスポンスが返却されます。 注意: 3D セキュアが成功だったとしても、通常の支払い作成同様、与信不足やカードの一時的な停止などにより決済が失敗し、失敗レスポンスが返却される可能性もあります。
より細やかな制御をする場合は、3D セキュア完了エンドポイントにリクエストする前に支払いオブジェクトを取得し直してください。
取得されたオブジェクトの three_d_secure_status
が attempted
の場合に購入手続きを中断することで、完全認証となります。それ以外にも、商品や金額をふまえて加盟店独自の基準で制御することも可能です。
unverified
のままであったり、error
であったりする場合は、3D セキュアの手順中に離脱した、パラメーターに異常があった等の問題が考えられます。この状態では 3D セキュア完了エンドポイントへのリクエストもエラーとなるため、支払いの作成から 3D セキュアフローをやり直す必要があります。