php - 如何修复 Stripe Payment Intent 中客户端或服务器端的 3D 安全确认付款?

标签 php jquery codeigniter stripe-payments

我正在集成 Stripe Payment Intent API,它在不需要 3D 安全的情况下运行良好,3D 安全授权正在弹出,但我认为我缺少 return_url确认付款。

我需要在 PaymentIntent 中的哪里提及 3D Secure 的 return_url?

我已尝试多次,但卡在 3D 安全授权上。它返回对象中的错误。

我在下面提到了 View 和 Controller 的代码。

提前致谢

客户端代码:


    form.addEventListener('submit', function(event) {
        event.preventDefault();
    
        $('#card-button').html('<i class="fa fa-circle-o-notch fa-spin" style="font-size:24px"></i>');
        var fname = $('#firstname2').val();
        var lname = $('#lastname2').val();
                    
        var cardholderName = fname + " " + lname;
        var cardButton = document.getElementById('card-button');
        var form_data = $("#payment-form").serialize();
                    
        cardButton.addEventListener('click', function(ev) {
          stripe.createPaymentMethod('card', cardElement, {
            billing_details: {name: cardholderName}
          }).then(function(result) {
            if (result.error) {
             // Show error in payment form
          } else {
             console.log(result);
             // Otherwise send paymentMethod.id to your server (see Step 2)
             fetch('<?php echo base_url(); ?>payment/stripe_test/process_payment', 
             {
               method: 'POST',
               headers: { 'Content-Type': 'application/json' },
               body: JSON.stringify({ payment_method_id: result.paymentMethod.id, customer_detail: form_data})
              }).then(function(result) {
                // Handle server response (see Step 3)
                result.json().then(function(result) {
                console.log("Response" + result);
                handleServerResponse(result);
              });
           });
          }
        });
       });
    }


    function handleServerResponse(response) {
              if (response.error) {
                // Show error from server on payment form
              } else if (response.requires_action) {
                  
                    var action = response.next_action;
                    if (action && action.type === 'redirect_to_url') {
                      window.location = action.redirect_to_url.url;
                    }
                    
                // Use Stripe.js to handle required card action
                stripe.handleCardAction(
                  response.payment_intent_client_secret
                ).then(function(result) {
                  if (result.error) {
                    // Show error in payment form
                  } else {
                    // The card action has been handled
                    // The PaymentIntent can be confirmed again on the server
                    fetch('<?php echo base_url(); ?>payment/stripe_test/process_payment', {
                      method: 'POST',
                      headers: { 'Content-Type': 'application/json' },
                      body: JSON.stringify({ payment_intent_id: result.paymentIntent.id })
                    }).then(function(confirmResult) {
                      return confirmResult.json();
                    }).then(handleServerResponse);
                  }
                });
              } else {
                // Show success message
                console.log("3D" + response);
              }
            }

CodeIgniter Controller :


    //PaymentIntent Function
        function process_payment() {
            require_once (APPPATH."third_party/stripe/init.php");
                
            $key = "STRIPE_KEY_HERE";
            
            header('Content-Type: application/json');
    
            # retrieve json from POST body
            $json_str = file_get_contents('php://input');
            $json_obj = json_decode($json_str);
            
            $intent = null;
            try {
                if (isset($json_obj->payment_method_id)) {
                  # Create the PaymentIntent
                    //STRIPE PAYMENT INTENT
                    \Stripe\Stripe::setApiKey($key);
                    
                    // Create a Customer:
                    $customer = \Stripe\Customer::create([
                        'email' => 'client@gmail.com',
                    ]);
                    
                    // Attach payment method to the customer:
                    
                    $customer_detail = $json_obj->customer_detail;
                    
                  $intent = \Stripe\PaymentIntent::create([
                    'payment_method' => $json_obj->payment_method_id,
                    'amount' => 1099,
                    'currency' => 'GBP',
                    'confirmation_method' => 'manual',
                    "customer" => $customer->id,
                    'confirm' => true,
                  ]);
                }
                if (isset($json_obj->payment_intent_id)) {
                  $intent = \Stripe\PaymentIntent::retrieve(
                    $json_obj->payment_intent_id
                  );
                  $intent->confirm();
                }
                
                $this->generatePaymentResponse($intent);
                
            } catch (\Stripe\Error\Base $e) {
                # Display error on client
                echo json_encode([
                  'error' => $e->getMessage()
                ]);
            }
        }

生成支付响应函数:


    function generatePaymentResponse($intent) {
            if ($intent->status == 'requires_source_action' &&
                $intent->next_action->type == 'use_stripe_sdk') {
              # Tell the client to handle the action
              echo json_encode([
                'requires_action' => true,
                'payment_intent_client_secret' => $intent->client_secret
              ]);
            } else if ($intent->status == 'succeeded') {
              # The payment didn’t need any additional actions and completed!
              # Handle post-payment fulfillment
              echo json_encode([
                "success" => true
              ]);
            } else {
              # Invalid status
              http_response_code(500);
              echo json_encode(['error' => 'Invalid PaymentIntent status']);
            }
        }

最佳答案

正如评论中提到的,您不需要指定return_url,因为在您的情况下,Stripe 将使用 Popup 进行 3DS 确认,而不是重定向。

您在代码中遗漏了两件事:
1. 在函数 generatePaymentResponse 中添加 $intent->status === 'requires_action' 的条件。
2. 在付款意向确认 ($intent->confirm();) 时,您错过了设置 api key (\Stripe\Stripe::setApiKey($key);)

我已经测试了您的代码,经过上述修改后它可以正常工作。

关于php - 如何修复 Stripe Payment Intent 中客户端或服务器端的 3D 安全确认付款?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55858767/

相关文章:

php - Mysql查询有两个表php

php - MySQL - 插入时重复父列值

php - 如何在品牌 exe/dmg 安装程序中打包 chrome 浏览器?

CodeIgniter JQuery $.post

java - Codeigniter 相关下拉列表

php - 如何在 Wordpress 主题中调用 laravel 函数

javascript - 防止用户使用 JS/jQuery 在输入中键入多个字符

javascript - 如何在更改事件上添加 fadeIn Jquery

javascript - 设置由 ng-if 隐藏的文本框的值

codeigniter core/model.php 未定义属性