如何向Stripe自定义支付流程的感谢页传递用户邮箱与Stripe客户ID参数
如何向Stripe自定义支付流程的感谢页传递用户邮箱与Stripe客户ID参数
作为搞过Stripe支付流程的开发者,我给你两个实用方案,你可以根据自己的需求选:
方案一:通过Stripe API安全获取(推荐)
这个方案不会在URL里暴露任何敏感信息,完全依赖Stripe的官方API获取真实数据,准确性和安全性都有保障。
步骤1:修改后端prepare接口,返回客户ID
你的prepare.php目前只返回了clientSecret,现在把创建好的Stripe客户ID也加进去,方便后续使用:
$productID = $request['items'][0]['id']; $customer = \Stripe\Customer::create(); $paymentIntent = \Stripe\PaymentIntent::create([ 'customer' => $customer->id, 'setup_future_usage' => 'off_session', 'amount' => config('app.PRICE_TNT6WEEK') * 100, 'currency' => 'usd', 'automatic_payment_methods' => ['enabled' => true], 'description' => $productID, ]); // 新增返回customerId $output = [ 'clientSecret' => $paymentIntent->client_secret, 'customerId' => $customer->id ]; \Log::debug(['<pre>'.print_r($request->toArray(), true).'</pre>', $productID, $output]); return response()->json($output);
步骤2:在感谢页通过ClientSecret拉取数据
你已经有checkStatus函数用来验证支付状态,现在扩展它,拿到支付意图后再拉取客户的邮箱信息:
// 初始化时先把customerId存到全局变量 let customerId; async function initialize() { const response = await fetch("{{route('prepare.product', [$slug, $slugVersion])}}", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items }), }); const data = await response.json(); const clientSecret = data.clientSecret; customerId = data.customerId; // 存储客户ID elements = stripe.elements({ clientSecret }); // 剩下的元素初始化代码... } async function checkStatus() { const clientSecret = new URLSearchParams(window.location.search).get( "payment_intent_client_secret" ); if (!clientSecret) return; // 获取支付意图 const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret); // 通过客户ID拉取客户详情,拿到邮箱 const { customer } = await stripe.retrieveCustomer(paymentIntent.customer); const userEmail = customer.email; const stripeCustomerId = paymentIntent.customer; // 这里可以把数据传给你的后端存储,或者在页面直接使用 console.log('用户邮箱:', userEmail); console.log('Stripe客户ID:', stripeCustomerId); // 原有的支付状态处理逻辑... switch (paymentIntent.status) { case "succeeded": showMessage(`支付成功!你的邮箱:${userEmail}`); // 可选:发送AJAX把数据存到自己的数据库 fetch('/save-thank-you-data', { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: userEmail, stripeCustomerId }) }); break; // 其他状态处理... } }
可选:提前给Stripe客户绑定邮箱
如果你想确保客户邮箱准确存在Stripe的客户对象里,可以在用户提交表单时,先调用一个后端接口更新客户邮箱:
async function handleSubmit(e) { e.preventDefault(); setLoading(true); const userEmail = document.getElementById("email").value; // 先更新客户邮箱 await fetch("/update-customer-email", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ customerId, email: userEmail }) }); // 原有的确认支付代码... const { error } = await stripe.confirmPayment({/* ... */}); setLoading(false); }
对应的后端接口代码:
public function updateCustomerEmail(Request $request) { \Stripe\Customer::update( $request->customerId, ['email' => $request->email] ); return response()->json(['success' => true]); }
方案二:直接在返回URL里拼接参数(快速实现)
如果只是临时快速上线,不介意参数在URL里暴露,可以直接把邮箱和客户ID拼在return_url后面:
步骤1:前端拼接参数到返回URL
let customerId; async function initialize() { // 同方案一,先拿到customerId并存储 const response = await fetch("{{route('prepare.product', [$slug, $slugVersion])}}", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ items }), }); const data = await response.json(); customerId = data.customerId; // 其他初始化代码... } async function handleSubmit(e) { e.preventDefault(); setLoading(true); const userEmail = document.getElementById("email").value; // 构造带参数的返回URL const returnUrl = new URL("{{route('upsell.show', [$slug, $slugVersion])}}"); returnUrl.searchParams.append('email', userEmail); returnUrl.searchParams.append('stripe_customer_id', customerId); const { error } = await stripe.confirmPayment({ elements, confirmParams: { return_url: returnUrl.toString(), // 使用拼接好的URL payment_method_data: { billing_details: { name: document.getElementById("full_name").value, email: userEmail, phone: document.getElementById("phone").value, } }, }, }); // 错误处理代码... setLoading(false); }
步骤2:感谢页控制器获取参数
在你的upsell.show对应的Laravel控制器里,直接从请求中拿参数:
public function showUpsell(Request $request) { $userEmail = $request->get('email'); $stripeCustomerId = $request->get('stripe_customer_id'); // 可以把参数传给视图,或者存储到数据库 return view('upsell.show', compact('userEmail', 'stripeCustomerId')); }
⚠️ 注意:这种方式参数会暴露在URL中,用户可以手动修改,所以如果需要确保数据绝对准确,还是优先用方案一。
备注:内容来源于stack exchange,提问作者Linas Lg
相关产品推荐
相关产品推荐

