在 Laravel 收银台中处理新 PaymentIntent 的最佳方式是什么

What is the best way of handling a new PaymentIntent in Laravel Cashier

除非我遗漏了什么,否则我看不到任何提供 PaymentIntent 创建的 Cashier 包装器,这是否存在?

虽然 Cashier v10 添加了一些内容来处理 SCA,但它对我不起作用,因为我通过 font-end 元素处理付款细节,因此重定向到新的 route 很麻烦。

我需要按照本指南进行处理https://stripe.com/docs/payments/payment-intents/migration

这需要像这样创建一个 PaymentIntent:

$intent = \Stripe\PaymentIntent::create([
    'payment_method' => $json_obj->payment_method_id,
    'amount' => 1099,
    'currency' => 'gbp',
    'confirmation_method' => 'manual',
    'confirm' => true,
]);

我当然可以直接从 Stripe sdk 执行此操作,如此处所示,但考虑到我可能会添加更多功能,这些功能可能会利用 Cashier 的其他功能,这将使一切通过 Cashier 变得更清晰。

我可以通过 Cashier 创建 PaymentIntent 还是错过了?如果是这样,如何?或者我应该以不同的方式处理这个问题?

我不是 Cashier 用户,但它看起来像是 Stripe Billing 的接口,因此它主要处理与 Billing 相关的原语。 据我所知,它确实在幕后使用了 PaymentIntents(用于验证需要身份验证的发票付款)但不直接公开 PaymentIntent 创建。

Cashier 文档建议您在需要身份验证时将集成重定向到 "payment page":https://laravel.com/docs/5.8/billing#payments-requiring-additional-confirmation(对于 PaymentIntents 处于状态 requires_action 的情况)

要直接创建 PaymentIntents,stripe-php API 库将是正确的方法。

进一步调查后,答案是

Laravel\Cashier\Billable->charge($amount,$method,$options)

方法在幕后执行 \Stripe\PaymentIntent::create($options)

有几点需要注意:

  • 默认情况下,选项 confirmation_method 将设置为 automaticconfirm 将设置为 true
  • 将设置 currency 选项并将使用收银台默认货币
  • amount选项将根据传入的$amount设置,payment_method选项将根据传入的$method设置。
  • 这些值都可以通过在 $options 参数
  • 中传递等效值来替换掉

最后,如果您需要 SCA(我这样做了),那么您必须捕获 \Laravel\Cashier\Exceptions\PaymentActionRequired 异常并为此重定向到内置的 Cashier 页面,或者通过您的 API 请求在您的前端处理它。

扩展Laravel\Cashier\Billable特征; 和 Laravel\Cashier\Concerns\PerformsCharges; 并使用它代替用户模型中的默认 Billable 特征

<?php

namespace App\Traits\Stripe;

use Laravel\Cashier\Concerns\ManagesCustomer;
use Laravel\Cashier\Concerns\ManagesInvoices;
use Laravel\Cashier\Concerns\ManagesPaymentMethods;
use Laravel\Cashier\Concerns\ManagesSubscriptions;
use App\Traits\Stripe\CustomPerformCharges as PerformsCharges;

trait CustomBillable
{
    use ManagesCustomer;
    use ManagesInvoices;
    use ManagesPaymentMethods;
    use ManagesSubscriptions;
    use PerformsCharges;
}
trait CustomPerformCharges
{
    use PerformsCharges;
  
    public function authorize(int $amount): Payment
    {
        if (!$this->hasStripeId()) {
            throw new BadRequestException(__('User is not a stripe customer'));
        }
        
        $paymentMethod = $this->defaultPaymentMethod();

        $options = [
            'capture_method' => 'manual'
        ];

        return $this->charge($amount, $paymentMethod, $options);
    }


    public function capture(int $amount, string $paymentIntent): void
    {
        $intent = StripePaymentIntent::retrieve($paymentIntent, $this->stripeOptions());
        $intent->capture(['amount_to_capture' => $amount]);
    }
}