寻找所需的信息真的很累,希望能对您有所帮助。 另外,我已经写信给Stripe支持人员,但目前与他们的沟通非常困难。
让我们从头开始。
我与Laravel Cashier一起使用Stripe订阅。
我已经用信用卡/借记卡完成了付款。它具有这样的工作流程: -用户填写表格; -Stripe.js将填充的数据发送到Stripe服务器并返回paymentMethod; -然后,我将PaymentMethod发送到我的服务器,并为有/无试用日期的用户进行订阅。
我需要添加Google Pay和Apple Pay按钮。 根据有关Google pay和Apple pay的Stripe文档,我必须创建Payment Request Button。 据我了解有关“付款请求按钮”的文档,它通过这种方式工作: -服务器端创建payingIntent并将其发送到客户端; -用户按下“付款请求”按钮; -浏览器打开一个带有已保存用户卡的弹出窗口; -用户选择一张卡,stripe.js立即向用户收费。
我不知道在哪个步骤中,条纹知道用于为用户订阅的计划ID。
我不需要立即向用户收费,我只需要获取paymentMethod即可将其发送到服务器端。 有没有人有使用“付款请求”按钮进行条纹订阅的经验?
我将非常感谢您的帮助。
答案 0 :(得分:6)
这就是我的做法。 我在客户端和服务器上使用JS ,但是在大多数情况下,即使语法不同,步骤也是相同的。 关于它的文档很少,我想我可以帮忙。 即使两者完全不同,大多数逻辑也应该相同。特别地:
Frontend returns paymentRequest -> Server-takes-paymentRequest -> customer -> subscription -> Done
首先,您无需对前端的付款意图进行任何操作。我挂了一段时间了。
接下来,使用stripe.paymentRequest()
开始所有操作,该操作将获取一些付款细节,并返回一个“ PaymentRequest”对象。
在此您根据PaymentRequest.canMakePayment()处理按钮的呈现
接下来是他们单击“付款”按钮时的处理方式。
paymentRequest具有一个“ on”方法,该方法基本上是一个订户。我认为这被称为网络挂钩。 它需要两个参数,一个字符串“ 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
});
调用服务器时-由于具有付款方式,因此可以像卡付款一样进行处理。
1:使用付款方式从条带创建“客户”对象。我使用了
const customer = await stripe.customers.create({
payment_method: paymentMethod.id,
email: paymentMethod.billing_details.email,
invoice_settings: {
default_payment_method: paymentMethod.id,
},
});
2:您使用客户从数据条创建一个“订阅”对象,我就是这样
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: [{ plan: "plan_HereIsYourPlanID" }], // <--
trial_period_days: 7,
expand: ["latest_invoice.payment_intent"],
});
3:上一步应该可以完成Stripe所需的一切。此时,我有一些自己的用户管理代码来跟踪我的用户是否订阅。然后,是否返回成功-在前端调用的函数,现在调用event.complete('success')
完成我希望能有所帮助。抱歉,它不是PHP,但希望这是一个开始。
答案 1 :(得分:4)
SeanMC,非常感谢您的回答-很少有关于将PaymentRequestButton与订阅一起使用的文档。 Stripe在PaymentRequestButton上的指南涉及了PaymentIntents,我误认为这是使用RequestPaymentButton的要求。
我在遵循您的代码时确实遇到了一些麻烦,因此想与其他可能为此苦苦挣扎的人分享我的实现。
我正在客户端使用Stripe Elements(StripeJS)创建一个典型的付款页面,其中包含用于计费信息以及用于输入CC信息的字段。我希望客户能够使用Apple Pay或Google Pay来加快此结帐过程。这是我在下面完成此操作的组件(为清楚起见,我删除了一些import / 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;
希望这可以帮助处于类似情况的任何人。感谢SeanMC,在发现这种方法之前,我迷失了两天的研究工作。