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

时间:2019-04-25 23:13:07

标签: php jquery codeigniter stripe-payments

我正在集成Stripe Payment Intent API,并且在不需要3D安全的情况下可以很好地工作,3D安全授权正在弹出,但我认为我缺少return_url来确认付款。

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

我已经尝试了多次,但是在3D安全授权上遇到了麻烦。返回对象错误。

我在下面提到了视图和控制器的代码。

预先感谢

客户端代码:


    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()
            ]);
        }
    }

generatePaymentResponse Function:

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']);
        }
    }

1 个答案:

答案 0 :(得分:2)

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

您错过了代码中的两件事:
1.在功能generatePaymentResponse中为$intent->status === 'requires_action'添加条件。
2.在确认付款意图($intent->confirm();)后,您未设置api键(\Stripe\Stripe::setApiKey($key);

我已经测试了您的代码,并且可以进行上述修改。