javascript - 首次成功付款后, strip 计费订阅未收取 "subsequent charges"

标签 javascript php stripe-payments recurring-billing

我已关注this实现 Stripe 定期付款的文档,该支付对于非 3d-Secure 卡和启用 3d-Secure 的卡都运行良好。对于初始付款,我从 Stripe 获取 3d-Secure Payment 身份验证模式,以使用 3D-Secure Test 卡验证付款。

订阅是与 Stripe 为我生成的发票一起创建的。一切似乎都正常,但对于启用 3D 安全(Stripe 测试卡)的情况,第一笔付款成功完成,但我设置的 1 天间隔(用于测试)的后续付款被 Stripe “失败”。据我了解,Stripe 需要再次进行客户身份验证才能继续订阅。

<小时/>

this他们说

When 3D Secure is encountered, configure your billing settings to send a hosted link to your customer to complete the flow.

完全没问题,但是为什么如果第一次付款成功并开始订阅,他们甚至需要再次进行身份验证步骤?我已经浏览了所有相关文档,但没有发现任何可以阻止这种情况的方法。

如果客户没有检查他/她的电子邮件以返回我的应用程序来验证付款怎么办? 或

代码有问题吗?我的意思是,Stripe 应该保存付款方式,即卡号,这样每次新的计费周期开始(每月/每半年)时,就不需要对后续费用进行客户身份验证。

我在互联网上搜索并找到并回答说

You are using stripe.createToken which does not support 3ds authentication. You need to migrate your client side code to stripe.createPaymentMethod which does support it

是这样吗?如有任何回应,我们将不胜感激

我的 Payment.js

// set your stripe publishable key
var stripe = Stripe('pk_test_key');
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();

var cardButton = document.getElementById('makePayment');
cardButton.addEventListener('click', function(ev) {
     // alert();
    ev.preventDefault();




    stripe.createToken(cardNumber).then(function(result) {

    if (result.error) {


    } else {
      //$body.addClass("loading");
      fetch('process.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ 
            token_id: result.token.id          
            })
      }).then(function(result) {


        // Handle server response (see Step 3)
        result.json().then(function(json) {
          handleServerResponse(json);
          //alert();
        })
      });
    }
  });
});
function handleServerResponse(response) {
            if (response.error) {
                // Show error from server on payment form
            } else if (response.requires_action) {
                // Use Stripe.js to handle required card action
                var action = response.next_action;
                if (action && action.type == 'redirect_to_url') {
                    window.location = action.redirect_to_url.url;
                }

                handleAction(response);

            } else {
                console.log("3D" + response);
            }
}

        function handleAction(response) {
           var paymentIntentSecret = response.payment_intent_client_secret;
            stripe.handleCardPayment(paymentIntentSecret).then(function(result) {
              if (result.error) {
                // Display error.message in your UI.
              } else {
                // The payment has succeeded. Display a success message.
                alert('Payment succeeded!');
              }
});

}

Process.php

<?php 

require_once('stripe-php/init.php');   
\Stripe\Stripe::setApiKey('sk_test_key');

$json_str = file_get_contents('php://input');

$json_obj = json_decode($json_str);
 //print_r($json_obj->token_id);die;

  //$intent = null;
try {
    if (isset($json_obj->token_id)) {
     //Create Customer   
    $customer = \Stripe\Customer::create([
    "email" => "test@gmail.com",
    "name" => "Haroon",  
    "source" => $json_obj->token_id,
]);
    //create product
    $product = \Stripe\Product::create([
    'name' => 'Water',
    'type' => 'service',
]);
    //create a plan
    $plan = \Stripe\Plan::create([
      'product' => $product->id,
      'nickname' => 'Water',
      'interval' => 'day',
      'currency' => 'eur',
      'amount' => 1200.00,
    ]);   

    //add subscription to stripe
    $subscription = \Stripe\Subscription::create([

        'customer' => $customer->id,
        'items' => [[
        "plan" => $plan->id],],
        'expand' => ['latest_invoice.payment_intent'],
]);    
}

      $intent = \Stripe\PaymentIntent::retrieve($subscription->latest_invoice->payment_intent->id);

      $subscription = \Stripe\Subscription::retrieve($subscription->id);
    //   $intent->confirm();
    // }
    generatePaymentResponse($intent,$subscription);
  }catch (\Stripe\Error\Base $e) {
    # Display error on client
    echo json_encode([
      'error' => $e->getMessage()
    ]);
  }  

   function generatePaymentResponse($intent,$subscription) {
    if ($intent->status == 'requires_action' && $subscription->status == 'incomplete' &&
        $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' && $subscription->status == 'active') {

        # The payment didn’t need any additional actions and completed!
        # Handle post-payment fulfillment
        echo json_encode([
            'success' => true
        ]);
    } else if ($intent->status == 'requires_payment_method' && $subscription->status == 'incomplete') {
        echo "Subscription failed";

    } else {
        # Invalid status
        http_response_code(500);
        echo json_encode(['error' => 'Invalid PaymentIntent status']);
    }
}

最佳答案

如果您正在为已经存在的卡执行此操作,那么我就在前一天完成了此操作。请参阅此文档 https://stripe.com/docs/payments/3d-secure .

这表明您需要创建 paymentIntent 并需要确认此付款意图。并且在3ds中还有测试卡 4242 4242 4242 4242 该卡不需要3ds的任何身份验证。提供以下测试卡链接

https://stripe.com/docs/payments/3d-secure/web#three-ds-cards

关于javascript - 首次成功付款后, strip 计费订阅未收取 "subsequent charges",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57958936/

相关文章:

javascript - 上传时显示预览图片

javascript - Stencil.js 中的自定义属性/指令

php - 多个 PHP IF 语句;寻找一种方法来收紧我的代码

stripe-payments - 以相同价格更改 Stripe 套餐

ruby-on-rails - 集成测试在 Stripe 上创建测试用户,如何停止或 stub

javascript - 显示此元素,而无需每次都重复代码

javascript - 生成轮子- Canvas

python - 如何将 Stripe 支付网关与 Django Oscar 集成?

php - Jquery Datepicker - 从 mysql 数据库启用日期

php - 如何使用 php 验证 Apple IAP 收据?