Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPから考える クレジットカードにおける3Dセキュア決済

PHPから考える クレジットカードにおける3Dセキュア決済

PHPerKaigi2025
ECサイトでのオンライン決済は当たり前の時代となっています。
オンライン決済の中でもクレジットカードでの決済を利用した方はかなり多いのではないでしょうか。
しかし今、クレジットカードの不正利用が問題となっており、経済産業省は2025年3月31日までに3Dセキュア2.0の導入を義務化しています。
3Dセキュア2.0とは何なのか、何を考慮すればよいのかをLaravelとStripeをサラッと使いながら軽く説明します。

Avatar for Koji Yoshida

Koji Yoshida

March 22, 2025
Tweet

Other Decks in Technology

Transcript

  1. ❏ よしだ ( :@theyoshida3)
 
 ❏ GMOクリエイターズネットワーク株式会社
 ❏ 事業戦略部 /

    新規開発グループ
 
 ❏ PHP界隈に稀に出没
 
 ❏ メガジョッキハイボールが好き
 2
 自己紹介

  2. 3Dセキュアとは
 2025年3月末までに導入義務化
 
 
 
 
 
 
 7
 経済産業省.

    「「クレジットカード・セキュリティガイドライン」が改訂されました」. https://www.meti.go.jp/press/2023/03/20240315002/20240315002.html
  3. メンバー紹介
 9
 イシュア
 (カード発行会社)
 国際ブランド
 決済代行会社
 カード会員
 加盟店
 アクワイアラー
 (加盟店契約会社)


    カード利用契約
 アライアンス契約
 アライアンス契約
 包括加盟店契約
 店子加盟店契約

  4. カード会員
 10
 イシュア
 (カード発行会社) 
 カード会員
 加盟店
 国際ブランド
 アクワイアラー
 (加盟店契約会社)

    
 決済代行会社
 カード会員は私達
 イシュアと契約してクレジットカード を発行してもらう
 クレジットカードを使って加盟店で決 済する
 

  5. イシュア(カード発行会社)
 11
 イシュア
 (カード発行会社) 
 カード会員
 加盟店
 国際ブランド
 アクワイアラー
 (加盟店契約会社)

    
 決済代行会社
 イシュアはカードの審査・発行を行 う
 私達へ利用代金を請求してくれる
 代表的なイシュア
 • 三井住友カード株式会社
 • 三菱UFJニコス株式会社
 • 株式会社クレディセゾン

  6. 加盟店
 12
 イシュア
 (カード発行会社) 
 カード会員
 加盟店
 国際ブランド
 アクワイアラー
 (加盟店契約会社)

    
 決済代行会社
 加盟店は店舗やECサイトなど
 クレジットカード決済で商品やサー ビスを提供
 

  7. 決済代行会社
 13
 イシュア
 (カード発行会社) 
 カード会員
 加盟店
 国際ブランド
 アクワイアラー
 (加盟店契約会社)

    
 決済代行会社
 決済代行会社は、加盟店とアクワイ アラーの間に立ち、便利にしてくれ ている
 代表的な決済代行会社
 • Stripe Japan
 • GMOペイメントゲートウェイ株式 会社

  8. アクワイアラー(加盟店契約会社)
 14
 イシュア
 (カード発行会社) 
 カード会員
 加盟店
 国際ブランド
 アクワイアラー
 (加盟店契約会社)

    
 決済代行会社
 アクワイアラーは、加盟店の審査・ 管理を行う
 加盟店や決済代行会社はアクワイ アラーに料金の請求を行う
 代表的なアクワイアラー
 • 三井住友カード株式会社
 • 三菱UFJニコス株式会社
 • 株式会社クレディセゾン

  9. 国際ブランド
 15
 イシュア
 (カード発行会社) 
 カード会員
 加盟店
 国際ブランド
 アクワイアラー
 (加盟店契約会社)

    
 決済代行会社
 決済システムネットワークを提供
 イシュア・アクワイアラーは国際ブラ ンドを介して繋がる
 5大国際ブランド
 • VISA
 • Mastercard
 • JCB
 • American Express
 • Diners Club

  10. Laravelでの実装例
 Payment Intent + Payment Element 
 LaravelでPayment Intentを作成
 支払画面はPayment

    Elementを使いサイト内に実装
 
 
 stripe DOCS. 「Payment Intents API」. https://docs.stripe.com/payments/payment-intents
 stripe DOCS. 「インテントを作成する前に支払いの詳細を収集する」. https://docs.stripe.com/payments/accept-a-payment-deferred?type=payment
 32

  11. Laravelでの実装例
 Laravel Cashier
 stripeの仕組みを理解すれば簡単に実装可能
 33
 composer require laravel/cashier php artisan

    vendor:publish --tag="cashier-migrations" php artisan migrate Readouble. 「Laravel 11.x Laravel Cashier (Stripe)」. https://readouble.com/laravel/11.x/ja/billing.html

  12. Laravelでの実装例
 PaymentIntentを作成する処理
 34
 public function createPaymentIntent(Request $request) { Stripe::setApiKey(config('stripe.secret')); $paymentIntent

    = PaymentIntent::create([ 'amount' => 5000, 'currency' => 'jpy', 'payment_method_types' => ['card'], ]); return response()->json([ 'clientSecret' => $paymentIntent->client_secret, ]); }
  13. Laravelでの実装例
 認証後の処理
 35
 public function completePayment(Request $request) { $payment_intent_id =

    $request->input('payment_intent'); $redirect_status = $request->input('redirect_status'); // redirect_statusの確認 // paymentIntentの取得 }
  14. Laravelでの実装例
 37
 <script src="https://js.stripe.com/v3/"></script> <script> const stripe = Stripe('{{ config('stripe.public')

    }}'); const elements = stripe.elements({ mode: 'payment', amount: 5000, currency: 'jpy', paymentMethodCreation: 'manual', }); const paymentElement = elements.create('payment', { layout: 'accordion', }); paymentElement.mount('#payment-element');
  15. Laravelでの実装例
 38
 // サーバーにPaymentIntentをリクエスト const response = await fetch('/payment-intent-any', {

    method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken, // CSRFトークンをリクエストヘッダーに追加 }, }); const { clientSecret } = await response.json();
  16. Laravelでの実装例
 39
 document.getElementById('payment-form').addEventListener('submit', async (e) => { e.preventDefault(); const {

    error: submitError } = await elements.submit(); if (submitError) { // エラー処理 } const { error } = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: 'http://localhost:8080/complete-payment', }, }); if (error) { // エラー処理 } }); 認証のフローを代 行してくれる
 • リダイレクト
 • モーダル