0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pay.jp 3dセキュア導入

Last updated at Posted at 2025-02-06

ポップアップ型だとカゴ落ちしそう

"ポップアップをブロックしているブラウザだとエラーになる"
とのこと。まずいので 3Dセキュアを リダイレクト型で使う

まず、payjpのphpライブラリを最新にしないと$token->tdsFinish();が動かないので注意する。

流れ

kigengire2 で 決済

tokenCheck で tokenのチェック

comp で 3D認証を完了させる

まずは、payjp-phpを最新版に

vim composer.json
"require": {
        "payjp/payjp-php": "1.*",
    },
composer update payjp/payjp-php

1.7にアップデートされる

注意点

・サーバー側、view側のそれぞれAPIKEYが必要。テストと、本番用を揃えること

じゃないとtokenエラーになる

kigengire2.ctp
<script type="text/javascript">
    function onCreatedToken(response) {
        console.log(response);
        document.querySelector('#created-token').textContent = response.id;
    }
</script>

<h1>支払いフォーム例</h1>

<p>
    payjp_test_key: <?=PAY_JP_TEST_KEY;?><br>
</p>

<form action="/payjp3ds/tokenCheck" method="post">
    <p>おにぎり 100円</p>

    <div style="display: flex; gap: 1rem; align-items: center;">
        <div>
            <script
                    type="text/javascript"
                    src="https://checkout.pay.jp"
                    class="payjp-button"
                    data-payjp-key="<?php echo htmlspecialchars(PAY_JP_TEST_KEY); // `pk_` から始まる公開鍵を設定してください。 ?>"
                    data-payjp-three-d-secure="true"
                    data-payjp-three-d-secure-workflow="redirect"
                    data-payjp-extra-attribute-email="<?=u('email');?>"
                    data-payjp-partial="true"
                    data-payjp-on-created="onCreatedToken"
            ></script>
        </div>
        <div>
            <small> <?php echo htmlspecialchars('<input type="hidden" name="payjp-token">'); ?> の value に token が自動的にセットされます。</small><br />
            <small>※ 生成されたトークン: <span id="created-token"></span></small>
        </div>
    </div>
    <br />
    <input type="hidden" name="csrf_token" value="<?php echo bin2hex(random_bytes(16)); ?>" />
    <button type="submit">支払う</button>
</form>
tokenCheck.php

    public function tokenCheck()
    {
        $secretKey = PAY_JP_TEST_SECRET;
        $publicKey = PAY_JP_TEST_KEY;
        $back_url = 'https://your.com/payjp3ds/comp/';

// トークンを取得
        $payjpToken = $_POST['payjp-token'] ?? '';

// セッションに保存
        $_SESSION['tds_input_data'] = [
            'payjp_token' => $payjpToken,
        ];

        $header = [
            'alg' => 'HS256',
            'typ' => 'JWT'
        ];

        $payload = [
            'url' => $back_url,
        ];

        function base64url_encode($data) {
            // 通常のBase64エンコード
            $b64 = base64_encode($data);
            // '+' → '-' , '/' → '_' , '=' を削除
            return rtrim(strtr($b64, '+/', '-_'), '=');
        }

        $base64Header  = base64url_encode(json_encode($header));
        $base64Payload = base64url_encode(json_encode($payload));
        $signature = hash_hmac(
            'sha256',
            $base64Header . '.' . $base64Payload,
            $secretKey,
            true
        );
        $base64Signature = base64url_encode($signature);
        $jws = $base64Header . '.' . $base64Payload . '.' . $base64Signature;
        header("Location: https://api.pay.jp/v1/tds/{$payjpToken}/start?publickey={$publicKey}&back_url={$jws}");

        die();
    }

comp.php

    public function comp()
    {
        //3Dセキュア認証
        \Payjp\Payjp::setApiKey(PAY_JP_TEST_SECRET);
        $token = \Payjp\Token::retrieve($_SESSION['tds_input_data']['payjp_token']);
        // 3Dセキュアフロー完了します。忘れがちなので注意してください。
        $token->tdsFinish();

        pr("3Dセキュア認証完了しました。");

        die();
    }

これで3D認証まではOK。
次は支払いとかやろう。

顧客化

hoge.php
    public function _addCustomer()
    {
        //3Dセキュア認証
        \Payjp\Payjp::setApiKey($this->config['secret']);
        $token = \Payjp\Token::retrieve($_SESSION['tds_input_data']['payjp_token']);
        // 3Dセキュアフロー完了します。忘れがちなので注意してください。
        $token->tdsFinish();

        if($token->used == false){
            $customer = \Payjp\Customer::create(array(
                "card" => $token->id
            ));
        } else {
            echo "トークンは使用済みです";
            die();
        }

        return $customer->id;
    }

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?