【问题标题】:Laravel Cashier not storing card version 10.1Laravel Cashier 不存卡 10.1 版
【发布时间】:2020-04-09 10:49:10
【问题描述】:

我正在使用 Cashier 10.1 创建一个新应用。过去,在注册用户订阅时,我会从 Stripe 向订阅功能发送一个令牌。现在它说它需要一个付款方式(id)。我正在使用 Stripe 注册一种付款方式并将其传递给我的控制器,但它返回错误“此客户没有附加的付款来源”。我阅读了文档,但它仅提供了一个示例,说明如何通过传递给视图$user->createSetupIntent() 来向当前用户添加订阅。以下是用户注册时的代码:

组件

       pay() {
            this.isLoading = true;

            if (this.form.payment_method == "cc") {
                let that = this;
                this.stripe
                    .createPaymentMethod({
                        type: "card",
                        card: that.card
                    })
                    .then(result => {
                        this.form.stripePayment = result.paymentMethod.id;
                        this.register();
                    })
                    .catch(e => {
                        console.log(e);
                    });
            } else {
                this.register();
            }
        },

        register() {
            this.form
                .post("/register")
                .then(data => {
                    this.isLoading = false;
                    if (data.type == "success") {
                        this.$swal({
                            type: "success",
                            title: "Great...",
                            text: data.message,
                            toast: true,
                            position: "top-end",
                            showConfirmButton: false,
                            timer: 2000
                        });

                        setTimeout(() => {
                            // window.location.replace(data.url);
                        }, 2000);
                    }
                })
                .catch(error => {
                    this.isLoading = false;
                });
        }

注册控制器

protected function create(request $request)
    {
        $request->validate([
            'name' => 'required',
            'email' => 'required|unique:users',
            'username' => 'required|alpha_dash|unique:users',
            'phone' => 'required',
            'city' => 'required',
            'state' => 'required',
            'password' => 'required|confirmed',
            'agree' => 'required',
        ]);

        $user = User::create([
            'username' => $request['username'],
            'name' => $request['name'],
            'email' => $request['email'],
            'phone' => $request['phone'],
            'city' => $request['city'],
            'state' => $request['state'],
            'password' => Hash::make($request['password']),
        ]);

        if ($request['subscription_type'] == 'premier' && $request['payment_method'] == 'cc') {

            $user->newSubscription('default',  env('STRIPE_PLAN_ID'))->create($request->input('stripePayment'), [
                'email' => $request['email'],
            ]);
        }



        if ($user) {
            $user->assignRole('subscriber');



            Auth::login($user);

            return response()->json([
                'type' => 'success',
                'message' => 'you are all set.',
                'url' => '/dashboard'
            ]);
        }

【问题讨论】:

    标签: laravel stripe-payments laravel-cashier


    【解决方案1】:

    我终于找到了一个很好的article 来解释新设置。基本上,当我显示我的注册视图时,我现在创建一个新用户并在那里传递意图。我一直认为用户必须已经被保存,而不仅仅是创建。因此,如果其他人想要这样做:

    显示视图

    注册控制器

    public function show()
        {
            $user = new User;
    
            return view('auth.register', [
                'intent' => $user->createSetupIntent()
            ]);
        }
    

    将意图传递给我的 Vue 组件

    <register-form stripe-key="{{ env('STRIPE_KEY') }}" stripe-intent="{{ $intent->client_secret }}">
                </register-form>
    

    将条带元素添加到 div:

     mounted() {
            // Create a Stripe client.
            this.stripe = Stripe(this.stripeKey);
    
            // Create an instance of Elements.
            var elements = this.stripe.elements();
    
            var style = {
                base: {
                    color: "#32325d",
                    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
                    fontSmoothing: "antialiased",
                    fontSize: "16px",
                    "::placeholder": {
                        color: "#aab7c4"
                    }
                },
                invalid: {
                    color: "#fa755a",
                    iconColor: "#fa755a"
                }
            };
    
            // Create an instance of the card Element.
            this.card = elements.create("card", { style: style });
    
            // Add an instance of the card Element into the `card-element` <div>.
            this.card.mount("#card-element");
        },
    

    处理数据

    pay() {
                this.isLoading = true;
    
                if (this.form.payment_method == "cc") {
                    this.setupCard();
                } else {
                    this.register();
                }
            },
    
            setupCard() {
                this.stripe
                    .handleCardSetup(this.stripeIntent, this.card, {
                        payment_method_data: {
                            billing_details: { name: this.form.name }
                        }
                    })
                    .then(data => {
                        this.form.stripePayment = data.setupIntent.payment_method;
                        if (this.form.stripePayment) this.register();
                    })
                    .catch(error => {
                        this.isLoading = false;
                        console.log(error);
                    });
            },
    
            register(setupIntent) {
                this.form
                    .post("/register")
                    .then(data => {
                        this.isLoading = false;
                        if (data.type == "success") {
                            this.$swal({
                                type: "success",
                                title: "Great...",
                                text: data.message,
                                toast: true,
                                position: "top-end",
                                showConfirmButton: false,
                                timer: 2000
                            });
    
                            setTimeout(() => {
                                window.location.replace(data.url);
                            }, 2000);
                        }
                    })
                    .catch(error => {
                        this.isLoading = false;
                    });
            }
    

    保存用户

    注册控制器

    protected function create(request $request)
        {
            $request->validate([
                'name' => 'required',
                'email' => 'required|unique:users',
                'username' => 'required|alpha_dash|unique:users',
                'phone' => 'required',
                'city' => 'required',
                'state' => 'required',
                'password' => 'required|confirmed',
                'agree' => 'required',
            ]);
    
            $user = User::create([
                'username' => $request['username'],
                'name' => $request['name'],
                'email' => $request['email'],
                'phone' => $request['phone'],
                'city' => $request['city'],
                'state' => $request['state'],
                'password' => Hash::make($request['password']),
            ]);
    
            if ($request['subscription_type'] == 'premier' && $request['payment_method'] == 'cc') {
    
                $user->newSubscription('default',  env('STRIPE_PLAN_ID'))->create($request->input('stripePayment'), [
                    'email' => $request['email'],
                ]);
            }
    
    
    
            if ($user) {
                $user->assignRole('subscriber');
    
    
    
                Auth::login($user);
    
                return response()->json([
                    'type' => 'success',
                    'message' => 'you are all set.',
                    'url' => '/dashboard'
                ]);
            }
        }
    

    【讨论】:

      【解决方案2】:

      由于Strong Customer Authentication (SCA),Cashier 更新了它与 Stripe 交互的方式。这意味着卡支付需要不同的用户体验,即 3D Secure,才能满足 SCA 要求。阅读 Stripe 上的 Payment Intents API 可能会有所帮助,您可以先通过与 Stripe 的直接交互创建付款意图,然后将其附加到您的 Laravel 用户,从而解决这个问题。

      简单的解决方案可能是有一个多步骤的注册过程:

      • 第 1 步:收集客户详细信息并在 Laravel 和 Stripe 上创建用户
      • 第 2 步: 创建付款意图 $user-&gt;createSetupIntent() 并收集付款详细信息并保存给客户。
      • 第 3 步:为用户订阅收银员计划

      【讨论】:

      • 现在真的是这样吗?如果我们必须中断注册过程以首先创建用户,然后通过加载新页面或必须提交新表单来获取账单信息,它总是会为用户在过程完成之前退出提供可能性。因此,如果他们重新加载页面并尝试再次输入他们的电子邮件以注册它,那么他们需要登录才能看到他们还没有付款,然后填写表格。让 CC 参与用户创建会带来更好的体验。
      • @Packy 根据我使用 Cashier 10 的经验,这是我必须遵循的过程。似乎它会促使您在不需要信用卡的情况下提供免费试用。我已经创建了客户。使用 vanilla Stripe PHP 库似乎可以执行您喜欢的用户流程。 Customer::create() 只需要创建描述,然后为注册创建付款意图,并在收集客户详细信息后分配客户。
      • 我实际上有一种不同的工作方式,没有步骤表格。见下文
      猜你喜欢
      • 2014-05-22
      • 2017-05-17
      • 2016-04-15
      • 2020-05-09
      • 2022-06-15
      • 2015-12-19
      • 2018-07-23
      • 2021-11-28
      • 2020-07-25
      相关资源
      最近更新 更多