You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js集成Stripe问题:表单数据传递与支付选项添加失败

Stripe支付网关集成问题修复方案

问题1:无法显示sepa_debit、wallets等支付选项

原因

  • 你使用的是已废弃的Stripe Checkout v2,该版本不支持SEPA Debit、数字钱包等现代支付方式,必须升级到新版Checkout(v3)。
  • 支付方式的可用性与货币、用户所在地区强绑定:比如SEPA Debit仅支持欧元(EUR)且用户需位于欧盟/EEA地区;部分钱包支付有严格的地域限制。

修复

替换前端旧版脚本,改用新版Stripe Checkout初始化逻辑(见下文完整代码),并根据目标货币调整支持的支付方式列表。


问题2:用户输入金额无法同步到Stripe支付界面

原因

  • 旧版Checkout的data-amount属性无法动态获取输入值,且原代码data-amount=document.getElementById(amount)存在语法错误(缺少引号和正确取值逻辑)。
  • Stripe要求金额以最小货币单位传入(如INR是paisa,1 INR = 100 paisa),原代码未处理单位转换。

修复

通过JS动态获取输入金额,转换为最小货币单位后传递给后端,再由后端生成Payment Intent同步到Checkout界面。


问题3:前后端用户数据传递异常

原因

  • 后端仍依赖旧版Checkout的stripeToken/stripeEmail参数,新版Checkout通过client_secret完成前后端校验。
  • 后端硬编码了金额、用户信息,未接收前端传递的实际捐赠数据。
  • 后端创建Payment Intent的代码存在语法错误(async函数未执行)。

修复

新增后端接口生成Payment Intent,前端通过异步请求获取client_secret后打开Checkout界面,实现数据同步传递。


修改后的完整代码

前端Home.ejs

<!DOCTYPE html>
<html>
<title>Stripe Payment Demo</title>
<body>
    <h3>Welcome to Payment Gateway</h3>
    
    <form id="donationForm">
        <input type="number" id="amount" placeholder="输入捐赠金额(INR)" required>
        <button type="submit">捐赠</button>
    </form>

    <script src="https://js.stripe.com/v3/"></script>
    <script>
        const stripe = Stripe('<%= key %>');
        const form = document.getElementById('donationForm');

        form.addEventListener('submit', async (e) => {
            e.preventDefault();
            const amountInput = document.getElementById('amount');
            // 转换为最小货币单位(INR → paisa)
            const amount = parseInt(amountInput.value) * 100;

            // 向后端请求生成Payment Intent
            const response = await fetch('/create-payment-intent', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ amount: amount })
            });
            const { clientSecret } = await response.json();

            // 打开Stripe Checkout界面
            const result = await stripe.redirectToCheckout({
                clientSecret: clientSecret,
                lineItems: [
                    {
                        price_data: {
                            currency: 'inr',
                            product_data: {
                                name: 'Sparks Foundation NGO',
                                description: 'Donate Now to Better Someone\'s Life'
                            },
                            unit_amount: amount
                        },
                        quantity: 1
                    }
                ],
                mode: 'payment',
                successUrl: window.location.origin + '/success',
                cancelUrl: window.location.origin + '/cancel',
                // 根据需求调整支持的支付方式(例:INR支持UPI,EUR支持SEPA)
                paymentMethodTypes: ['card', 'upi']
            });

            if (result.error) {
                alert(result.error.message);
            }
        });
    </script>
</body>
</html>

后端index.js

const express = require('express')
const bodyparser = require('body-parser')
const path = require('path')
const app = express()

const Publishable_Key = 'pk_test_51MY8LgSIjyhEAXRbDHDLZUfwFVuxKzUWesWXwQLfnb6vOoAyvelN0KVUGSwXdlez6FhoLgWD6Ngn4DKa6eZnG2c400Dn74v3r2'
const Secret_Key = 'sk_test_51MY8LgSIjyhEAXRbqRP5AWJWYbdXJ0Tj9P1FoYM83U6j0ckHItUTCw8PfAeBKPpP4PJHQ5kzqexK1q6xgsFhxVTB00H7MQtYig'

const stripe = require('stripe')(Secret_Key)

const port = process.env.PORT || 3000

app.use(bodyparser.urlencoded({ extended: false }))
app.use(bodyparser.json())

app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'ejs')

app.get('/', function(req, res){
    res.render('Home', { key: Publishable_Key })
})

// 生成Payment Intent的接口
app.post('/create-payment-intent', async (req, res) => {
    try {
        const { amount } = req.body;

        const paymentIntent = await stripe.paymentIntents.create({
            amount: amount,
            currency: 'inr',
            payment_method_types: ['card', 'upi']
        });

        res.json({ clientSecret: paymentIntent.client_secret });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
})

// 支付成功页面
app.get('/success', (req, res) => {
    res.send('捐赠成功!感谢您的支持!');
})

// 支付取消页面
app.get('/cancel', (req, res) => {
    res.send('支付已取消,您可以重新尝试捐赠。');
})

app.listen(port, function(error){
    if(error) throw error
    console.log("Server created Successfully on port " + port)
})

关键补充说明

  1. 支付方式适配:若需SEPA Debit,需将货币改为eur,并使用欧盟地区的测试账号;钱包支付(如Google Pay)需生产环境HTTPS域名支持。
  2. 金额校验:前端需添加金额合法性校验(如最小值、非负),避免无效请求。
  3. 数据存储:如需记录捐赠信息,建议配置Stripe Webhook,在支付成功后接收官方推送的支付详情,而非依赖前端传递的数据。

内容的提问来源于stack exchange,提问作者Priya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:46:09