PHP集成Stripe时无法获取表单隐藏价格值的问题
Stripe多商品支付价格传递问题解决
核心问题分析
- 后端参数获取方式错误:前端所有请求都以JSON格式发送(请求头
Content-Type: application/json),但后端用$_POST['prix']获取参数,这种方式仅适用于form-data格式请求,自然拿不到值。 - 创建PaymentIntent时未传价格:前端
initialize函数调用create_payment_intent接口时,没把隐藏输入框的价格传过去,导致后端无法生成对应金额的PaymentIntent。 - 数据库插入依赖变量未正确初始化:后端
$itemPrice仅通过错误的$_POST方式赋值,后续数据库插入时变量值不可靠。
具体修复步骤
1. 修复后端参数获取逻辑
打开payment_init.php,删除开头的$itemPrice = $_POST['prix'];,在对应请求分支从JSON对象取参数:
- 在
create_payment_intent分支添加价格参数获取:
if($jsonObj->request_type == 'create_payment_intent'){ // 从JSON对象获取商品价格 $itemPrice = !empty($jsonObj->prix) ? $jsonObj->prix : 0; if($itemPrice <= 0){ http_response_code(400); echo json_encode(['error' => '无效的商品价格']); exit; } // 转换为分(Stripe要求金额单位为最小货币单位) $itemPriceCents = round($itemPrice*100); // ... 后续原有代码保持不变 }
- 在
payment_insert分支,直接从Stripe返回的PaymentIntent取实际支付金额(避免前端篡改风险):
}elseif($jsonObj->request_type == 'payment_insert'){ $payment_intent = !empty($jsonObj->payment_intent)?$jsonObj->payment_intent:''; $customer_id = !empty($jsonObj->customer_id)?$jsonObj->customer_id:''; // 获取客户信息 try { $customer = \Stripe\Customer::retrieve($customer_id); }catch(Exception $e) { $api_error = $e->getMessage(); } if(!empty($payment_intent) && $payment_intent->status == 'succeeded'){ $transaction_id = $payment_intent->id; $paid_amount = $payment_intent->amount / 100; $paid_currency = $payment_intent->currency; $payment_status = $payment_intent->status; $customer_name = $customer->name ?? ''; $customer_email = $customer->email ?? ''; // 从PaymentIntent取实际价格和商品名称 $itemPrice = $paid_amount; $itemName = $payment_intent->description; // ... 后续原有代码保持不变 } }
2. 修改前端initialize函数,传递价格参数
打开checkout.js,在initialize的fetch请求中加入隐藏输入框的价格值:
async function initialize() { // 获取隐藏输入框的价格 const prix = document.getElementById("prix").value; const { id, clientSecret } = await fetch("payment_init.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ request_type:'create_payment_intent', prix: prix // 新增传递价格参数 }), }).then((r) => r.json()); // ... 后续原有代码保持不变 }
3. 可选:优化价格传递安全性
如果支持多商品,建议页面加载时从后端获取对应商品价格(比如通过URL参数或后端渲染),避免依赖前端隐藏输入框(易被篡改):
- URL传递商品ID:
your-page.php?product_id=1 - 后端根据ID从数据库取价格,渲染到页面:
<input type="hidden" id="prix" value="<?php echo $productPrice; ?>">
验证修复效果
- 打开支付页面,确认隐藏输入框价格值正确
- 发起支付,查看
create_payment_intent接口是否能正确生成对应金额的PaymentIntent - 支付完成后,检查数据库
transactions表的item_price字段是否正确存储
内容的提问来源于stack exchange,提问作者Fabien
相关产品推荐
相关产品推荐

