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

Flutter Firebase项目如何让用户创建Stripe账户并接收销售货款?

功能实现完整方案

1. 关联Firebase用户与Stripe卖家账户

首先在Stripe后台开通Connect服务,选择Express账户类型(无需卖家自行注册Stripe账号,适合平台型场景),将Stripe密钥存入Firebase环境变量避免硬编码:

firebase functions:config:set stripe.secret_key="你的Stripe私钥"

Firebase Functions代码示例(JS):

const functions = require("firebase-functions");
const Stripe = require("stripe");
const stripe = Stripe(functions.config().stripe.secret_key);
const admin = require("firebase-admin");
admin.initializeApp();

// 前端点击"成为卖家"时调用的可调用云函数
exports.createSellerAccount = functions.https.onCall(async (data, context) => {
  if (!context.auth) throw new functions.https.HttpsError("unauthenticated", "未登录");
  const uid = context.auth.uid;
  const userEmail = context.auth.token.email;

  try {
    // 创建Stripe Express卖家账户
    const account = await stripe.accounts.create({
      type: "express",
      email: userEmail,
      capabilities: {
        card_payments: {requested: true},
        transfers: {requested: true}, // 必须开启转账权限才能接收货款
      },
      business_type: "individual" // 企业卖家可改为company
    });

    // 绑定Stripe账户ID到Firebase用户文档
    await admin.firestore().collection("users").doc(uid).update({
      stripeAccountId: account.id,
      isSeller: true
    });

    // 生成信息补全链接,前端用WebView打开让卖家提交身份、银行卡信息
    const accountLink = await stripe.accountLinks.create({
      account: account.id,
      refresh_url: "你的App卖家页面跳转链接",
      return_url: "你的App卖家页面跳转链接",
      type: "account_onboarding"
    });
    return {onboardingUrl: accountLink.url};
  } catch(e) {
    throw new functions.https.HttpsError("internal", e.message);
  }
});

前端Flutter调用云函数拿到链接后,引导卖家完成Stripe的资质校验,只有校验通过的账户才能正常收款。

2. 货款到账逻辑实现

提供两种常用到账模式,可根据业务需求选择:

模式1:买家支付后自动打款给卖家

支付时直接拆分资金,扣除平台佣金后自动转入卖家账户,云函数代码:

// 买家下单时调用,创建支付Intent
exports.createPaymentIntent = functions.https.onCall(async (data, context) => {
  if (!context.auth) throw new functions.https.HttpsError("unauthenticated", "未登录");
  const { amount, sellerUid, orderId } = data;

  // 读取卖家的Stripe账户ID
  const sellerDoc = await admin.firestore().collection("users").doc(sellerUid).get();
  const sellerStripeId = sellerDoc.data().stripeAccountId;
  if (!sellerStripeId) throw new functions.https.HttpsError("failed-precondition", "卖家未开通收款权限");

  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount: amount, // 单位为最小货币单位,比如人民币为分、美元为美分
      currency: "cny", // 按需更换币种
      transfer_data: {
        destination: sellerStripeId // 指定收款的卖家账户
      },
      application_fee_amount: Math.round(amount * 0.1), // 平台抽佣比例示例为10%,可自行调整
      automatic_payment_methods: {enabled: true}
    });
    return {clientSecret: paymentIntent.client_secret};
  } catch(e) {
    throw new functions.https.HttpsError("internal", e.message);
  }
});

前端Flutter拿到clientSecret后,使用flutter_stripeSDK调起支付即可,支付成功后资金会自动结算到卖家Stripe账户。

模式2:买家确认收货后再打款给卖家

适合需要售后担保的场景,资金先进入平台账户,买家确认收货后再手动转账给卖家:

// 买家确认收货后调用
exports.transferToSeller = functions.https.onCall(async (data, context) => {
  if (!context.auth) throw new functions.https.HttpsError("unauthenticated", "未登录");
  const { orderId, sellerUid, actualAmount } = data;

  const sellerStripeId = (await admin.firestore().collection("users").doc(sellerUid).get()).data().stripeAccountId;
  // 执行转账
  await stripe.transfers.create({
    amount: actualAmount,
    currency: "cny",
    destination: sellerStripeId,
    transfer_group: orderId // 绑定订单号方便对账
  });
  // 更新订单状态为已打款
  await admin.firestore().collection("orders").doc(orderId).update({
    status: "completed",
    transferSuccess: true
  });
  return {success: true};
});

常见收不到款的排错点

  • 卖家未完成Stripe资质校验:Stripe后台Connect面板可查看卖家账户状态,只有已启用状态的账户才能接收转账
  • 未开启transfers权限:创建卖家账户时必须申请该权限,否则转账会被拦截
  • 支付Intent未配置transfer_data参数:未配置的情况下资金只会进入平台账户,不会自动转给卖家
  • 金额单位错误:Stripe金额默认使用最小货币单位,填错会导致转账失败或金额异常
  • 手动转账模式下平台账户余额不足:需要保证平台Stripe账户有足够余额才能完成向卖家的转账

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 22:48:02