分かりづらいので、リダイレクト型で入れてみる
3Dセキュア導入してって
EMV3Dセキュアにつきましては、
2025年3月末までに、必須項目の追加および義務化
取引の安全性を高めらしい
参考
うーん複雑。超複雑。
2025/01/10 追記
スケジュールは?
https://pay.jp/info/2024/10/29/140000
ようは、2月4日から4月1日までは両方使えるから、
その期間に切り替えてね。
不安なら3Dセキュアのプレリリース版でテストしてね
ということか。
わかりづらすぎだろ。
自分の場合のデバッグ時の注意
デバッグする際は、2回目以降の同じカードの決済は tok エラーが出るので、
customer_idを使うようにする。
自分の場合は payjpテーブルからデータを抹消しないこと。
退会処理するときも、そもそもpayjpテーブルからデータを消していない。
既存から変更するには?
・エンドポイントは2月4日以降なら4月1日まで、そのままで利用できるよ
・メールアドレス必須だから追加してね
・checkout利用時は、一度 3d認証してからtokenを取得する手間が増える
・tokenを取得したらサーバーに送る
php側は、今までと同じだよ。
という流れにする。
たったこれだけのことをよくまーわかりづらく延々と・・・
自分の場合は rental-ojisan の kigengire2.ctp を参考に。。。
動くようになったのでphpのサンプル
流れ
・クレジットカード番号を入力
・ポップアップが開いて3D認証画面へ
・成功すると自動的にポップアップは閉じて、フォームを送信
スマホの場合はポップアップせずに画面が勝手に3dセキュアに切り替わる
親切設計。
だったら、リダイレクトなんて作らず、サブウィンドウだけでいいだろ。。。
<script type="text/javascript">
// トークン生成直後のコールバック
function onCreatedToken(response) {
console.log('onCreatedToken:', response);
// 画面表示用など。ここではsubmitしない
document.querySelector('#created-token').textContent = response.id;
}
// 一定間隔で監視して、トークンが入ったらフォーム送信
setInterval(function() {
const tokenSpan = document.querySelector('#created-token');
if (tokenSpan && tokenSpan.textContent.trim() !== '') {
// すでに値があれば、自動的にフォームを送信して終了
const form = document.getElementById('payjp-form');
if (form) {
form.submit();
}
}
}, 1000);
</script>
<form id="payjp-form" action="/payjp3ds/keizoku2/" method="post">
<div>
<div>
<script
type="text/javascript"
src="https://checkout.pay.jp/prerelease"
data-payjp-key="<?=$config['key'];?>"
data-payjp-three-d-secure="true"
data-payjp-three-d-secure-workflow="subwindow"
data-payjp-partial="true"
data-payjp-extra-attribute-email="your@email.com"
data-payjp-on-created="onCreatedToken"
></script>
</div>
<div>
<small>
<span id="created-token"></span>
</small>
</div>
</div>
<br>
<!-- value は何でも良いみたい -->
<input type="hidden" name="csrf_token" value="csrf">
<button type="submit">支払う</button>
</form>
サブウィンドウではなく、リダイレクトでもできたけど、
シンプルにしといたほうが後々楽なのでシンプルで行こう。
ちなみに、リダイレクト方式は以下
public function tokenCheck()
{
$secretKey = PAY_JP_TEST_SECRET;
$publicKey = PAY_JP_TEST_KEY;
// トークンを取得
$payjpToken = $_POST['payjp-token'] ?? '';
// セッションに保存
$_SESSION['tds_input_data'] = [
'payjp_token' => $payjpToken,
];
// ================================================
// 1) JWTの要素を準備
// ================================================
// ヘッダー部
$header = [
'alg' => 'HS256',
'typ' => 'JWT'
];
// ペイロード部(今回は back_url 用の 'url' を設定)
$payload = [
'url' => 'https://your.com/payjp3ds/comp/',
];
// ================================================
// 2) Base64URLエンコード関数を用意
// ================================================
function base64url_encode($data) {
// 通常のBase64エンコード
$b64 = base64_encode($data);
// '+' → '-' , '/' → '_' , '=' を削除
return rtrim(strtr($b64, '+/', '-_'), '=');
}
// ================================================
// 3) header と payload をBase64URL化
// ================================================
$base64Header = base64url_encode(json_encode($header));
$base64Payload = base64url_encode(json_encode($payload));
// ================================================
// 4) 署名を作成 (HS256)
// ================================================
$signature = hash_hmac(
'sha256',
$base64Header . '.' . $base64Payload,
$secretKey,
true
);
// Base64URLエンコード
$base64Signature = base64url_encode($signature);
// ================================================
// 5) JWT(=JWS)文字列を生成 (header.payload.signature)
// ================================================
$jws = $base64Header . '.' . $base64Payload . '.' . $base64Signature;
// ================================================
// 6) リダイレクト
// ================================================
header("Location: https://api.pay.jp/v1/tds/{$payjpToken}/start?publickey={$publicKey}&back_url={$jws}");
die();
}
3dsセキュア認証画面
本番
成功したら、自動的にポップアップが閉じられる
テストのときは、ポップアップ後に
成功かエラーかを選ぶ必要がある
2024/11/01 追記
以下では、駄目。
2025年2月4日に3Dセキュア版にするから、エンドポイントを変更して3Dセキュア版を試してね。とのこと。
以下のように変更してみた。
<form action="/pays/teiki/" method="post">
<input type="hidden" id="selected-plan" name="plan" value="1000">
<input type="hidden" id="user_id" name="user_id" value="<?=u('id');?>">
<script src="https://checkout.pay.jp/prerelease/" class="payjp-button" data-key="<?=$key;?>" data-text="申し込み"></script>
</form>
んーテストしてみたけど
今までと何も変わらない。
まぁ、これでいいんでしょうね。
checkout と payjp.js の 2種類
僕はすべてのサイトにchecktoutを使っている
ただ、なんかバグってたから3Dセキュア導入はもう少し待ってとのこと。
問題が発生したため、リリースを延期いたしました。
https://pay.jp/info/2024/07/31/110000
改めて、10月中旬〜下旬にプレリリース方式での先行配布を実施予定です。
https://pay.jp/info/2024/10/04/151500
導入方法?
