无需订阅即可使用 Laravel Cashier 一次性付款

Posted

技术标签:

【中文标题】无需订阅即可使用 Laravel Cashier 一次性付款【英文标题】:one-time payment with Laravel Cashier without subscription 【发布时间】:2019-10-22 08:16:51 【问题描述】:

我计划使用 Laravel Cashier 通过 Stripe 进行一次性付款。上面写着documentation:

如果您只执行“一次性”收费并且不提供订阅服务,则不应使用 Cashier。

但是,我可以使用以下代码在不订阅的情况下向用户收费:

$amount = $request['amount];
Stripe::setApiKey(Config::get('stripe.secret_key'));
$token = $input['stripeToken'];
$user = Auth::user();
return $user->charge($amount * 100, ['source' => $token]);

它奏效了!我想知道这种方法有问题吗?为什么他们建议不要使用 Cashier?一路走来会不会出问题?请告诉我你的想法?

【问题讨论】:

这可能最好在GitHub 或Laravel.io 之类的论坛上提出。我无法明确回答,但我的猜测是 Cashier 是用于订阅的,所以如果您只需要单笔费用,请不要使用它。如果您正在使用订阅,并且偶尔也需要单次收费,那应该没问题。 该警告不再出现在 Laravel 6.x 文档中。 “$input['stripeToken']”从何而来?从以前的形式? 【参考方案1】:
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="csrf-token" content=" csrf_token() ">

</head>
<body>

        <script src="https://js.stripe.com/v3/"></script>
        <br><br>
        <h1 align="center">One Time Charge</h1>
        <form method = "post" action = "route('charge')" id="form">
        @csrf

        <div class="form form-cb" align="center"> 

                        Name on Card:    <input type="text" id="card-holder-name" required>  
                        <br>                <br> 
                        <div id="card-element" style="width: 300px;">
                        <!-- A Stripe Element will be inserted here. -->           
                        </div>

                        <!-- Used to display form errors. -->
                        <div id="card-errors" role="alert"></div><br>
                        <button disabled style="background-color:skyblue;color:black">$1.00 USD</button><br><br>  
                        <button id="card-button" style="background-color: green;color:white;font-size:20px;" />Pay
                        </button>   
        </div>

        </form>
<script>

    var stripe = Stripe('Your Stripe-key');
    var elements = stripe.elements();
    var cardElement = elements.create('card');

    cardElement.mount('#card-element');

    // Add an instance of the card UI component into the `card-element` <div>
    var cardHolderName = document.getElementById('card-holder-name');
    var cardButton = document.getElementById('card-button');

    cardButton.addEventListener('click', async (e) => 
    var  paymentMethod, error  = await stripe.createPaymentMethod(
        'card', cardElement, 
            billing_details:  name: cardHolderName.value 
        
    );
    if (error) 
        console.log('error');
         else 
                var payment_id = paymentMethod.id;
                createPayment(payment_id);
           
    );

    var form = document.getElementById('form');
    form.addEventListener('submit', function(event) 
        event.preventDefault();
    );

    // Submit the form with the token ID.
    function createPayment(payment_id) 
    // Insert the token ID into the form so it gets submitted to the server
    var form = document.getElementById('form');
    var hiddenInput = document.createElement('input');
    hiddenInput.setAttribute('type', 'hidden');
    hiddenInput.setAttribute('name', 'payment_id');
    hiddenInput.setAttribute('value',payment_id);
    form.appendChild(hiddenInput);
    // Submit the form

    form.submit();

    

</script>


</body>
</html>

【讨论】:

【参考方案2】:

按照目前的实施,这样做是安全的。您可以在此处查看charge 方法的代码:https://github.com/laravel/cashier/blob/822b6535e755fd36dec8ecceb52cc8909c8a953e/src/Billable.php#L37

也就是说,考虑到 Cashier 的明确警告不打算用于这种用途,如果 charge 函数被修改导致您的应用程序出现故障,那是您自己的错行。

在这种情况下也没有太多理由使用 Cashier。直接使用 SDK 的 Stripe\Charge 类将是更简洁的代码,并且您不会冒滥用不同库的风险。

【讨论】:

你是对的。我实际上也使用 SDK 使它工作。但我想知道使用收银员是否也是一种选择。谢谢

以上是关于无需订阅即可使用 Laravel Cashier 一次性付款的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Cashier - 使用现有客户对象创建新订阅

Laravel Cashier 新订阅 Stripe 抛出“无法确定请求哪个 URL:”错误

Laravel Cashier - 更新订阅的付款方式

Laravel Cashier SCA 订阅返回不完整的订阅

Laravel 7.0 Cashier - 条纹支付异常

在试用 Laravel Cashier Paddle 期间无法交换计划