带订阅的条纹付款请求按钮

Rom*_*lov 9 php payment button request stripe-subscriptions

我真的厌倦了寻找我需要的信息,希望得到您的帮助。另外,我已经写信给 Stripe 支持,但目前与他们的沟通非常困难。

让我们从头开始。

我在 Laravel Cashier 中使用 Stripe 订阅。

我已经用信用卡/借记卡完成了付款。它有这样一个工作流程: - 用户填写表单;- Stripe.js 将填充的数据发送到 Stripe 服务器并返回支付方法;- 然后我将支付方法发送到我的服务器,并为有/没有试用日的用户订阅。

我需要添加 Google pay 和 Apple pay 按钮。根据关于Google payApple pay的 Stripe 文档,我必须创建Payment Request Button。据我了解有关付款请求按钮的文档,它是通过这种方式工作的: - 服务器端创建 paymentIntent 并将其发送到客户端;- 用户按下支付请求按钮;- 浏览器打开一个带有保存的用户卡的弹出窗口;- 用户选择一张卡,stripe.js 立即向用户收费。

我无法理解在哪个步骤 Stripe 知道为用户进行订阅的计划 ID。

我不需要立即向用户收费,我只需要获取 paymentMethod 即可将其发送到服务器端。有没有人有使用 Payment Request 按钮进行 Stripe 订阅的经验?

我将非常感谢您的帮助。

Sea*_*nMC 12

这是我如何做到的。我在客户端和服务器上使用了 JS,但在大多数情况下,即使语法不同,步骤也是相同的。关于它的文档太少了 - 我想我会看看我是否可以提供帮助。即使完全不同,大部分逻辑也应该是一样的。具体:

Frontend returns paymentRequest -> Server-takes-paymentRequest -> customer -> subscription -> Done

首先,您不需要对前端的支付意图做任何事情。我被挂了一段时间。

接下来,开始一切使用stripe.paymentRequest()它需要一些付款细节,并返回一个“PaymentRequest”对象..

在这里,您根据 PaymentRequest.canMakePayment() 处理按钮的呈现

接下来是当他们点击支付按钮时我的处理方式。

paymentRequest 有一个paymentmethod事件监听器。该函数on采用 2 个参数,一个字符串 'paymentmethod' 指示您正在收听的内容,以及一个将事件作为参数的函数。很喜欢

    stripePaymentRequest.on('paymentmethod', (event) => {
      const paymentMethod = event.paymentMethod
  
      if (paymentMethod) {
        // call your server and pass it the payment method 
        // for Server side Stripe-API handling of payment
      }

      event.complete('success'); // Completes the transaction and closes Google/Apple pay
    });
Run Code Online (Sandbox Code Playgroud)

当您调用服务器时,您可以像使用信用卡付款一样处理它,因为您拥有付款方式。

1:您使用付款方式从条带创建“客户”对象。我用过类似的东西

        const customer = await stripe.customers.create({
            payment_method: paymentMethod.id,
            email: paymentMethod.billing_details.email,
            invoice_settings: {
                default_payment_method: paymentMethod.id,
            },
        });
Run Code Online (Sandbox Code Playgroud)

2:您使用客户从条带创建“订阅”对象,我是这样做的

        const subscription = await stripe.subscriptions.create({
            customer: customer.id,
            items: [{ plan: "plan_HereIsYourPlanID" }], // <--
            trial_period_days: 7,
            expand: ["latest_invoice.payment_intent"],
        });
Run Code Online (Sandbox Code Playgroud)

3:前面的步骤应该完成您对 Stripe 所需的一切。在这一点上,我有一些我自己的用户管理代码来跟踪我的用户是否订阅。然后,您返回成功与否 - 到您在前端调用的那个函数,现在完成您调用 event.complete('success')

我希望这有帮助。对不起,它不是 PHP,但希望它是一个开始。


jam*_*ail 5

SeanMC,非常感谢您的回答 - 关于使用 PaymentRequestButton 进行订阅的文档很少。Stripe 关于 PaymentRequestButton 的指南涉及到 paymentIntents,我错误地认为这是使用 RequestPaymentButton 的必要条件。

我确实在遵循您的代码时遇到了一些麻烦,因此想与其他可能为此苦苦挣扎的人分享我的实现。

我在客户端使用 Stripe Elements (StripeJS) 作为典型的支付页面,其中包含帐单信息字段以及输入 CC 信息的字段。我希望客户能够使用 Apple Pay 或 Google Pay 来加快结账流程。下面是我的组件,它实现了这一点(为了清楚起见,我删除了一些导入/TypeScript 定义)。

import React, { useEffect, useState } from 'react';
import {
  PaymentRequestButtonElement,
  useStripe,
} from '@stripe/react-stripe-js';
import * as stripeJs from '@stripe/stripe-js';

const AlternativePaymentOption: React.FC = ({
  price, //the price for the subscription being purchased
  priceId, //the priceId for the subscription (I found it easiest to create one 
           //product with multiple priceId for the different subscription tiers
  checkout,
}) => {
  const stripe = useStripe();
  const [paymentRequest, setPaymentRequest] = useState<
    stripeJs.PaymentRequest
  >();

  useEffect(() => {
    //return early if missing dependancies
    if (!stripe || !price) return;
    //create the paymentRequest which is passed down to
    //to the <PaymentRequestButtonElement /> as a prop
    const pr = stripe.paymentRequest({
      country: 'US',
      currency: 'usd',
      total: {
        label: 'Website Subscription',
        amount: price * 100,
      },
      requestPayerName: true,
      requestPayerEmail: true,
      requestPayerPhone: true,
    });
    //check if the browser has a saved card that can be used
    pr.canMakePayment()
      .then((result) => {
        //user has a saved card that can be used - display button
        if (result) {
          //the render method below is conditional based on this state
          setPaymentRequest(pr);
          pr.on('paymentmethod', (ev) => {
            //this event is triggered at the completion of the saved payment 
            //interface
            //we don't care about the actual payment request anymore
            //now that we have a paymentMethod, we can check out as normal
            //the checkout function I am not including here, but is very similar 
            //to the 'create a subscription' stripe guide
            //however it is important to note that I am passing in the event as an 
            //argument.  Once checkout receives a response from my server as to 
            //wether the transaction was successful or not, use 
            //ev.complete('success') and ev.complete('fail') accordingly to close
            //the modal or display an error message (browser specific behavior)
            checkout(ev.paymentMethod.id, ev);
          });
        }
      })
      .catch((err) => {
        //log errors, retry, or abort here depending on your use case
      });
     //stripe, priceId, and price are listed as dependancies so that if they 
     //change, useEffect re-runs.
  }, [stripe, priceId, price]);
  return (
    <>
      {paymentRequest && (
        <PaymentRequestButtonElement
          options={{ paymentRequest }}
          //hacky fix to make force this component to re-render
          //a la https://github.com/stripe/react-stripe-elements/issues/284
          key={Math.random()}
        />
      )}
    </>
  );
};

export default AlternativePaymentOption;
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助任何处于类似情况的人。在我发现这种方法之前,由于 SeanMC,我在杂草中迷失了两天。