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

如何实现Stripe支付成功后再提交Firebase求职发布表单?

问题分析

当前代码的核心问题是:按钮同时设置了type="submit"和onClick={stripePayment},点击时会同时触发表单提交(handleSubmit直接写入Firebase)和Stripe支付跳转,导致支付未完成就已经发布职位。该逻辑错误与Firebase版本升级无关,是流程设计问题。

解决方案

1. 修复前端按钮触发逻辑

将按钮的type="submit"改为type="button",避免点击时自动触发表单提交,只执行Stripe支付跳转:

修改JobForm.js中的Button部分:

<Button onClick={stripePayment}
        variant="contained" 
        type="button"> {/* 替换原type="submit" */}
  Post Job
</Button>

同时删除无用的handleSubmit函数,职位发布不再通过表单提交触发。

2. 通过Stripe Webhook实现可靠的支付后发布(推荐方案)

前端跳转存在伪造风险,必须依赖Stripe官方Webhook验证支付状态,确保只有支付成功时才写入Firebase:

步骤2.1 修改服务端创建支付会话的逻辑

在创建Checkout Session时,将职位信息存入Stripe会话的metadata中,便于支付成功后读取:

修改Server.js的/create-checkout-session路由:

app.post('/create-checkout-session', async (req, res) => {
  const { price, jobDetails } = req.body;
  const session = await stripe.checkout.sessions.create({
    line_items: [
      {
        price: price,
        quantity: 1,
      },
    ],
    mode: 'payment',
    success_url: `${YOUR_DOMAIN}/`,
    cancel_url: `${YOUR_DOMAIN}/form`,
    metadata: {
      jobDetails: JSON.stringify(jobDetails) // 存入职位信息
    }
  });

  res.send(session);
});

步骤2.2 添加Stripe Webhook处理支付成功事件

安装Firebase Admin SDK(用于服务端操作Firebase):

npm install firebase-admin

初始化Firebase Admin并添加Webhook路由:

const admin = require('firebase-admin');
// 替换为你的Firebase服务账号密钥路径
const serviceAccount = require('./firebase-service-account.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});
const db = admin.firestore();

// Stripe Webhook路由
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  // 替换为Stripe控制台获取的Webhook密钥
  const webhookSecret = 'your-stripe-webhook-secret';

  let event;
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // 处理支付成功事件
  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    const jobDetails = JSON.parse(session.metadata.jobDetails);
    
    // 写入Firebase
    await db.collection('jobs').add({
      ...jobDetails,
      createdAt: admin.firestore.FieldValue.serverTimestamp()
    });
  }

  res.json({received: true});
});

步骤2.3 前端传递职位信息到服务端

修改JobForm.js的stripePayment函数,将职位信息传给后端:

async function stripePayment() {
  try {
    const res = await axios.post(
      "https://backend-server.io/create-checkout-session",
      { price: "test", jobDetails: jobDetails } // 传递职位信息
    );
    window.location.href = res?.data?.url;
  } catch (error) {
    console.error('创建支付会话失败:', error);
  }
}

3. 前端用户体验优化(可选)

在支付成功跳转回首页后,清除临时数据并给用户提示:

在首页组件(如Home.js)中添加:

import { useEffect } from 'react';

const Home = () => {
  useEffect(() => {
    // 清除可能存储的临时职位信息
    localStorage.removeItem('jobDetails');
    // 可在此添加支付成功+职位发布成功的提示弹窗
  }, []);

  return (
    // 首页内容
  );
};

export default Home;
关键说明
  • 必须使用Stripe Webhook验证支付状态,不能仅依赖前端跳转,防止恶意用户伪造支付成功场景。
  • 彻底移除表单自动提交逻辑,确保职位发布操作仅在支付确认后执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:35:24