【问题标题】:stripe payment method is returning null when I submit form当我提交表单时,条纹支付方式返回 null
【发布时间】:2021-02-27 22:18:10
【问题描述】:

当我尝试创建新订阅时,我收到此错误(此客户没有附加的付款来源或默认付款方式。)所以我使用 dd($paymentMethod) 检查了 PaymentController,它返回 null

所以我不知道为什么 store 方法中的变量 $paymentMethod 从 $request 中返回 NULL,但是请求中返回的是 price_id。请任何帮助表示赞赏

但是当console.log() setupIntent.payment_method 它返回了控制台中的payment_method

这是我的 PaymentController

         public function index()
{
    $availablePlans = [
        'price_1HnIiLLzAo4pwMcyh2aGaznB'  => 'Monthly',
        'price_1HnJ2vLzAo4pwMcygQT66juk'  => 'Yearly',
        'price_1HnIhILzAo4pwMcy9iH3j30L'  => 'Free Membership'
    ];

    $user = auth()->user();
    $data = [
        'intent' => $user->createSetupIntent(),
        'plans' =>  $availablePlans

    ];
    
    return view('payments.checkout')->with($data);
}
     

       public function store(Request $request)
    {

  


             $user = auth()->user();

              $paymentMethod = $request->payment_method;
             //  dd($paymentMethod);
    
    
             $planId = $request->plan;

             $user->newSubscription('premium', $planId)->create($paymentMethod);

             return response(['status' => 'success']);
       }

这是 Javascript

 window.addEventListener('load', function (){

// 创建一个 Stripe 客户端。 const stripe = Stripe('pk_test_51H2OqqLzAo4pwMcyT4h405wpFRAn3FWhvByfvmVnW6tabrIsDoU1dBXJ0UaWexUJeacCJ9uKpb5OBmmA2KaCg4sd00ZZ5tj2q8');

// Create an instance of Elements.
const elements = stripe.elements();

// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
 
 // const cardElement = elements.create('card', {style: style});

// Create an instance of the card Element.
const cardElement = elements.create('card');

// Add an instance of the card Element into the `card-element` <div>.
cardElement.mount('#card-element');

    const cardHolderName = document.getElementById('card-holder-name');
    const cardButton = document.getElementById('card-button');
    const clientSecret = cardButton.dataset.secret;

    const plan = document.getElementById('subscription-plan').value;

    cardButton.addEventListener('click', async (e) => {
        const { setupIntent, error } = await stripe.handleCardSetup(
            clientSecret, cardElement, {
                payment_method_data: { 
                billing_details: { name: cardHolderName.value }
                }
            }
        );

        if (error) {
            // Display "error.message" to the user...
        } else {
            // The card has been verified successfully...
           // console.log('handling success', setupIntent.payment_method);

            axios.post('/subscribe', {
              payment_method: setupIntent.payment_method,
              plan: plan
            })
        }
    });

 });

              

这是表格

         <form action="{{ route('subscribe')}}" method="POST" id="">
@csrf
  <div class="form-content">

      <div class="field">
        <select class="form-control" name="plan" id="subscription-plan">
          @foreach ($plans as $key=>$plan )
            <option value="{{$key}}">{{$plan}}</option>
          @endforeach
        </select>
      </div>

    <div class="field">
      <input type="text" autocorrect="off" spellcheck="false" id="card-holder-name" maxlength="25" />
      <span class="focus-bar"></span>
      <label for="cardholder">Card holder (Name on card)</label>
    </div>
        
        <div  class="field mb-5" id="card-element">
        <!-- Stripe Elements Placeholder -->
        </div>

    <button id="card-button" data-secret="{{ $intent->client_secret }}"><span>Pay</span></button>
    
  </div>
</form>

路线

   Route::resource('payments', 'PaymentsController', [
         'names'=> [
              'index'     => 'checkout',
               'store'     => 'subscribe',
   
          ]
      ]);

【问题讨论】:

    标签: laravel stripe-payments subscription laravel-cashier payment-method


    【解决方案1】:

    看来您使用 axios 的方式有问题。你有没有试过看看laravel simple axios with argument

    【讨论】:

    • 谢谢,我刚试过,但它没有发出任何帖子请求,只得到请求
    • 嗯,$user-&gt;newSubscription('premium', $planId)-&gt;create($paymentMethod); 行在做什么?
    • 使用 auth 用户为产品溢价创建一个新订阅,$planId 这是产品的价格计划,它可以每年或每月根据表格中选择的计划,选择的计划已通过请求中成功的只是不是来自表单的 payment_plan,我可以从 console.log 访问它,但不会传递给 Paymentcontroller。为了创建新订阅,您必须提供从 Stripe API 生成的付款方式。
    • Gotcha - 更新了我的答案,因为我最初说的是错误的。我没有使用过 axios,但我认为我链接到的答案应该让你走上正轨
    • 谢谢你的帮助我真的很感激
    【解决方案2】:

    在表单中添加隐藏输入字段并将值设置为 setupIntent.payment_method 将 payment_method id 传递给用于创建订阅的控制器,从而解决问题。

    一些修改并在 JS 中添加一个隐藏的输入字段

    // Handle form submission.
                var form = document.getElementById('payment-form');
                form.addEventListener('submit', async (e) => {
                  e.preventDefault();
                    //cardButton.addEventListener('click', async (e) => {
                           //e.preventDefault()
                        const { setupIntent, error } = await stripe.handleCardSetup(
                            clientSecret, cardElement, {
                                payment_method_data: { 
                                billing_details: { name: cardHolderName.value }
                                }
                            }
                        );
                       
                        if (error) {
                            // Display "error.message" to the user...
                        } else {
                            // The card has been verified successfully...
                           //console.log('handling success', setupIntent.payment_method);
                             axios.post('/subscribe',{
                             plan : plan
                        })
                           var paymentMethod  = setupIntent.payment_method;
    
                            var form = document.getElementById('payment-form');
                            var hiddenInput = document.createElement('input');
                            hiddenInput.setAttribute('type', 'hidden');
                            hiddenInput.setAttribute('name', 'payment_method');
                            hiddenInput.setAttribute('value', paymentMethod);
                            form.appendChild(hiddenInput);
    
                            // Submit the form
                            form.submit();
    
              
                        }
    

    【讨论】:

      猜你喜欢
      • 2020-12-09
      • 2020-04-19
      • 1970-01-01
      • 2020-10-15
      • 2016-08-25
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      相关资源
      最近更新 更多