简体   繁体   English

无法使用条带 PaymentIntent 中的 fetch API 获取 Payment_method_id

[英]Unable to get the Payment_method_id using fetch API in stripe PaymentIntent

I am using the PaymentIntent API to integrate Stripe payments using stripe-php SDK and Stripe.js V3.我正在使用 PaymentIntent API 通过 stripe-php SDK 和 Stripe.js V3 集成 Stripe 支付。 Following This guide https://stripe.com/docs/payments/payment-intents/migration#saving-cards-checkout .遵循本指南https://stripe.com/docs/payments/payment-intents/migration#saving-cards-checkout I am getting what successful payments in my Stripe Dashboard done with test cards which do not require 3d-secure.我使用不需要 3d 安全的测试卡在我的 Stripe Dashboard 中获得了成功的付款。 But The Stripe's new SCA 3d secure Popup(according to their docs.) is not popping up, Which leads payments done with 3dsecure ENABLED cards to "Incomplete Payments" Tab in stripe Dashboard.但是 The Stripe 的新 SCA 3d 安全弹出窗口(根据他们的文档)没有弹出,这导致使用 3dsecure ENABLED 卡完成的付款到条带仪表板中的“未完成付款”选项卡。

I have examine the code thoroughly multiple times and tested.我已经多次彻底检查代码并进行了测试。 I have noticed that my code skips(somtimes) OR throws an error "Unexpected end of JSON input" in the "Fetch Part" on the client side code.. which leads the 3d-secure cards payments to be incomplete.The JavaScript Fetch function is not fetching the "payment_method_id" from the specified file(url).我注意到我的代码跳过(有时)或在客户端代码的“Fetch Part”中抛出错误“Unexpected end of JSON input”..这导致 3d-secure 卡支付不完整。JavaScript Fetch 函数没有从指定的文件(url)中获取“payment_method_id”。

My Payment.js File:我的 Payment.js 文件:

var elements = stripe.elements();
var style = {
    base: {
        color: '#32325d',
        lineHeight: '18px',
        fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
        fontSmoothing: 'antialiased',
        fontSize: '16px',
        '::placeholder': {
            color: '#aab7c4'
        }
    },
    invalid: {
        color: '#fa755a',
        iconColor: '#fa755a'
    }
};

var cardNumber = elements.create('cardNumber', {
    style: style
});
cardNumber.mount('#cardNumber');
var cardExpiry = elements.create('cardExpiry', {
    style: style
});
cardExpiry.mount('#cardExpiry');
var cardCvc = elements.create('cardCvc', {
    style: style
});
cardCvc.mount('#cardCVC');

var cardholderName = $('#custName').val();
var amount = $('#amount').val();

$(document).ready(function () {
    $("#paymentForm").submit(function (event) {
        //event.preventDefault();

        stripe.createPaymentMethod('card', cardNumber, {
            billing_details: {name: cardholderName.value}
        }).then(function (result) {
            console.log(result);

            if (result.error) {
                var errorElement = document.getElementById('card-error');
                errorElement.textContent = result.error.massage;

            } else {
                 stripeTokenHandler(result);

                fetch('example.com/stripe/index.php', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({
                        payment_method_id: result.paymentMethod.id
                    })
                }).then(function (result) {
                    // Handle server response (see Step 3)
                    result.json().then(function (result) {
                        handleServerResponse(result);
                    })
                });
            }
        });   
        //return false;
    });
 function stripeTokenHandler(result) {
            var payForm = $("#paymentForm");
            var paymentMethodID = result.paymentMethod.id;
            //set the token into the form hidden input to make payment
            payForm.append("<input type='hidden' name='payment_method_id' value='" + paymentMethodID + "' />");
            //  payForm.submit();   
             payForm.submit();
        }
}

My Index.php File我的 Index.php 文件

header('Content-Type: application/json');
if(isset($_POST['submit'])){

    //include Stripe PHP library
    require_once('stripe-php/init.php');    
   //set Stripe Secret Key
\Stripe\Stripe::setApiKey('sk_test_key');

    //add customer to stripe
    $customer = \Stripe\Customer::create(array(
        'email' => $custEmail,
    ));    

function generatePaymentResponse($intent) {
    if ($intent->status == 'requires_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']);
    }
}
# retrieve json from POST body
  $json_str = file_get_contents('php://input');
  $json1 = json_encode($_POST);
  $json_obj = json_decode($json1);

  $intent = null;

try {
    if (isset($json_obj->payment_method_id)) {
    $intent = \Stripe\PaymentIntent::create([
    'payment_method' => $json_obj->payment_method_id,
    'customer' => $customer->id,
    'amount' => 1099,
    'currency' => 'gbp',
    'confirmation_method' => 'manual',
    'confirm' => true,

]);
}
    generatePaymentResponse($intent);

  }catch (\Stripe\Error\Base $e) {
    # Display error on client
    echo json_encode([
      'error' => $e->getMessage()
    ]);
  }


}
?>

As it can be seen my stripeTokenHandler is appending the payment_method.id into HTML form and the process goes on.可以看出,我的 stripeTokenHandler 正在将 payment_method.id 附加到 HTML 表单中,然后该过程继续进行。 but the "fetch" section of JS code should get payment_method_id to generate "Response" and to proceed for "next_action" if the payment status is "requires_action".但是JS代码的“fetch”部分应该获取payment_method_id以生成“Response”并在支付状态为“requires_action”时继续执行“next_action”。

So, In order to achieve what i wanted to, what i did was所以,为了实现我想要的,我所做的是

- removed stripeTokenHandler() - 删除了 stripeTokenHandler()

Because i was using it in my previous charges API integration and thought it will work with the new PaymentIntent.因为我在之前的收费 API 集成中使用了它,并认为它可以与新的 PaymentIntent 一起使用。 And i guess many people misunderstood or misguided buy bunch of different methods stripe has in its docs.I saw a lot of questions on internet people complaining that stripe's "poorly managed" Documentation has confused them.而且我猜很多人误解或误导了 Stripe 在其文档中购买的各种不同方法。

- Learned Fetch Api. - 学习了 Fetch Api。

As a newbie i didnt know what it was for.作为一个新手,我不知道它是做什么用的。

- removed isset post submit from my php code - 从我的 php 代码中删除了 isset post submit

reason: payment.js was unable to POST the paymentMethod.id to the server using Fetch Api and get the response body back from the server to proceed the code further.原因:payment.js 无法使用 Fetch Api 将 paymentMethod.id POST 到服务器并从服务器获取响应正文以进一步处理代码。

I MUST say that Stripe needs to improve its Docs about this SCA ready PaymentIntent thing.我必须说,Stripe 需要改进其有关此 SCA 就绪 PaymentIntent 的文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM