Stripe Connect测试模式生成Token未完成交易及调用Charge方法问询
问题分析
你目前的代码只完成了前端生成Stripe Token的环节,但Stripe的Charge(支付扣款)操作必须在后端执行——前端不能直接调用Charge接口,一来会泄露你的Secret Key,二来Connect场景下的资金流向逻辑也需要后端来处理。这就是为什么你在控制台只能看到v1/token请求,却没有实际支付记录的核心原因。
解决方案步骤
下面分前后端两部分帮你完成完整的支付流程:
1. 前端修改:把Token和自定义数据传给后端
当前前端在生成Token后只是展示token,需要改成通过AJAX把token、课程信息、价格等数据发送到你的后端接口,让后端发起扣款请求。
修改前端的setOutcome函数和表单提交逻辑:
function setOutcome(result) { var successElement = document.querySelector('.success'); var errorElement = document.querySelector('.error'); successElement.classList.remove('visible'); errorElement.classList.remove('visible'); if (result.token) { // 收集表单里的自定义数据 var formData = new FormData(document.querySelector('form')); // 把Stripe Token加入表单数据 formData.append('stripeToken', result.token.id); // 可选:把持卡人姓名也传过去(token里也包含这个信息,后端也可以直接取) formData.append('cardholderName', result.token.card.name); // 发送请求到后端的扣款接口 fetch('/create-charge', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { if (data.success) { successElement.textContent = `支付成功!你的订单ID:${data.chargeId}`; successElement.classList.add('visible'); } else { errorElement.textContent = data.error; errorElement.classList.add('visible'); } }) .catch(error => { errorElement.textContent = '网络连接异常,请稍后重试'; errorElement.classList.add('visible'); }); } else if (result.error) { errorElement.textContent = result.error.message; errorElement.classList.add('visible'); } } // 表单提交逻辑保留,只是把后续处理交给setOutcome document.querySelector('form').addEventListener('submit', function(e) { e.preventDefault(); var form = document.querySelector('form'); var extraDetails = { name: form.querySelector('input[name=cardholder-name]').value, }; stripe.createToken(card, extraDetails).then(setOutcome); });
2. 后端实现扣款接口(PHP示例)
你需要用Stripe的Secret Key(测试环境用sk_test_xxx,生产环境用sk_live_xxx)在后端调用Stripe的Charge API,同时根据你的Connect场景选择对应的逻辑:
场景1:平台直接收取费用(资金进入平台账户)
如果是平台自己收取课程费用,直接创建Charge即可:
<?php // 先引入Stripe PHP SDK,你可以通过Composer安装:composer require stripe/stripe-php require_once('vendor/autoload.php'); // 设置你的Stripe Secret Key \Stripe\Stripe::setApiKey('sk_test_你的测试密钥'); try { // 从前端请求中获取数据 $stripeToken = $_POST['stripeToken']; // 注意:Stripe金额是最小货币单位(比如美元是分,人民币是分),所以要乘以100 $amount = (int)($_POST['selectedAppointment'] * 100); $tutorName = $_POST['selectedTutor']; $subject = $_POST['slectedSubject']; $bookingDates = $_POST['selectedAppointment']; // 创建Charge扣款请求 $charge = \Stripe\Charge::create([ 'amount' => $amount, 'currency' => 'usd', // 根据你的业务修改货币代码,比如人民币填cny 'source' => $stripeToken, 'description' => "课程预约:{$tutorName} - {$subject}", 'metadata' => [ // 存储自定义数据,在Stripe控制台可以查看 'tutor_name' => $tutorName, 'subject' => $subject, 'booking_dates' => $bookingDates ] ]); // 向前端返回成功响应 echo json_encode([ 'success' => true, 'chargeId' => $charge->id ]); } catch(\Stripe\Exception\CardException $e) { // 卡片相关错误(比如余额不足、卡片过期) echo json_encode([ 'success' => false, 'error' => $e->getMessage() ]); } catch(\Exception $e) { // 其他未知错误 echo json_encode([ 'success' => false, 'error' => '支付失败,请稍后重试' ]); } ?>
场景2:通过Connect转账给讲师账户(平台代收后分账)
如果需要把钱转到讲师的Stripe Connect账户,需要添加destination参数:
<?php require_once('vendor/autoload.php'); \Stripe\Stripe::setApiKey('sk_test_你的测试密钥'); try { $stripeToken = $_POST['stripeToken']; $amount = (int)($_POST['selectedAppointment'] * 100); // 讲师的Stripe Connect账户ID,你需要提前存储在数据库中 $tutorStripeAccountId = 'acct_xxx'; $tutorName = $_POST['selectedTutor']; $charge = \Stripe\Charge::create([ 'amount' => $amount, 'currency' => 'usd', 'source' => $stripeToken, 'description' => "课程预约:{$tutorName}", 'metadata' => [ 'tutor_name' => $tutorName ], 'destination' => [ 'account' => $tutorStripeAccountId, // 资金会转入这个账户 // 可选:平台收取手续费,比如抽成10%,这里填给讲师的金额(总金额的90%) // 'amount' => (int)($amount * 0.9) ] ]); echo json_encode([ 'success' => true, 'chargeId' => $charge->id ]); } catch(\Stripe\Exception\CardException $e) { echo json_encode([ 'success' => false, 'error' => $e->getMessage() ]); } catch(\Exception $e) { echo json_encode([ 'success' => false, 'error' => '支付失败,请稍后重试' ]); } ?>
3. 测试环境验证
- 使用Stripe提供的测试卡号(比如
4242 4242 4242 4242,过期日期填未来任意月份/年份,CVC随便填3位)进行支付 - 支付成功后,你可以在Stripe控制台的Payments页面看到完整的Charge记录,而不是只有Token
- 如果是Connect场景,讲师的Stripe控制台也会显示入账记录
4. 生产环境注意事项
- 替换Secret Key为
sk_live_xxx - 确保网站使用HTTPS(Stripe强制要求生产环境必须用HTTPS)
- 配置Stripe Webhook(比如监听
charge.succeeded、charge.failed事件),用来同步你的订单状态,避免前端回调失败导致状态不一致 - 绝对不要在前端代码中暴露任何Secret Key,所有敏感操作必须通过后端完成
关键提醒
- 禁止前端直接调用Charge API:前端只能生成Token,核心的扣款逻辑必须放在后端,否则会泄露密钥导致安全风险
- 金额单位转换:Stripe API的金额是最小货币单位,比如人民币要把元转成分,所以必须乘以100
- Connect账户ID:如果要分账给讲师,需要先让讲师完成Stripe Connect的账户注册,获取他们的
account_id并存在你的数据库中
内容的提问来源于stack exchange,提问作者PriyaNegi
相关产品推荐
相关产品推荐

