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

基于Stripe API实现ERC20代币售卖提现的技术咨询

ERC20代币售卖功能的Stripe集成问题及解决方案

背景

我开发了一款支持用户用USD买卖ERC20代币的应用,已通过Stripe Checkout完成代币购买功能,现需实现代币售卖功能——用户卖出代币后可收取USD,计划使用Stripe Payout API实现。流程为:用户售卖代币时,可提供自身Stripe账户ID;若用户无Stripe账户,则收集其银行路由号、银行账号及邮箱,通过stripe.accounts.create为其创建账户。目前处于测试模式,有以下疑问:

  1. 测试用的Stripe账户ID如何获取?
  2. 使用测试银行账户信息创建新账户时,提示需注册Stripe Connect,该如何操作?
  3. 是否有更适配此需求的Stripe API方案?

前端代码

import { useState } from 'react';
import { loadStripe } from '@stripe/stripe-js';

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);

export default function PayoutPage() {
  const [recipientId, setRecipientId] = useState('');
  const [routingNumber, setRoutingNumber] = useState('');
  const [accountNumber, setAccountNumber] = useState('');
  const [numberOfTokens, setNumberOfTokens]=useState()
  const [emailId , setEmailId] = useState('')

  const handlePayout = async () => {
    const stripe = await stripePromise;
    const total = await totalCalcualtion()
    const ttl = numberOfTokens * total;
    const totalPayout =Math.round(ttl*100)
    console.log(totalPayout)

    let payoutData = {
      amount: totalPayout,
    };

    if (recipientId) {
      payoutData.recipientId = recipientId;
    } else {
      payoutData.routingNumber = routingNumber;
      payoutData.accountNumber = accountNumber;
      payoutData.emailId = emailId;
    }

    const response = await fetch('/api/blockchain/sell_token_usd', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payoutData)
    });

    const { sessionId } = await response.json();
    console.log("sessionId", sessionId)
    if (sessionId) {
      // Redirect the user to the Stripe Checkout page
      const { error } = await stripe.redirectToCheckout({
        sessionId
      });

      if (error) {
        console.error(error);
      }
    }
  };

  const totalCalcualtion=()=>{
    const pricePerToken = 1.68;
    const tokenfee = 3;
    const total = pricePerToken - (pricePerToken* (tokenfee/100));
    return total
  }

  return (
    <div>
      <h1>Payout Page</h1>

      <div>
        <label>Number of tokens </label>
        <input type='text' onChange={(e)=>setNumberOfTokens(e.target.value)}></input><br/><br/>
        <label>Stripe Account ID:</label>
        <input type="text" value={recipientId} onChange={(e) => setRecipientId(e.target.value)} />
      </div><br/>
        <h3>Don't have a stripe account enter the following details</h3><br/>
      {!recipientId && (
        <div>
          <label>Bank Routing Number:</label>
          <input type="text"  onChange={(e) => setRoutingNumber(e.target.value)} />

          <label>Bank Account Number:</label>
          <input type="text" value={accountNumber} onChange={(e) => setAccountNumber(e.target.value)} />

          <label>Email Id:</label>
          <input type="text" value={emailId} onChange={(e) => setEmailId(e.target.value)} />
        </div>
      )}

      <button onClick={handlePayout}>Initiate Payout</button>
    </div>
  );
}

后端代码

import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2020-08-27'
});

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      const { amount, recipientId, routingNumber, accountNumber,emailId } = req.body;

      let recipientAccountId;

      if (recipientId) {
        recipientAccountId = recipientId;
      } else {
        // Create a Custom account for the recipient
        const customAccount = await stripe.accounts.create({
          type: 'custom',
          country: 'US', 
          email: emailId 
        });

        recipientAccountId = customAccount.id;

        // Add the recipient's bank account details
        await stripe.accounts.createExternalAccount(recipientAccountId, {
          external_account: {
            object: 'bank_account',
            country: 'US', 
            currency: 'usd',
            routing_number: routingNumber,
            account_number: accountNumber
          }
        });
      }

      // Create a payout to the recipient's account
      const payout = await stripe.payouts.create({
        amount,
        currency: 'usd',
        method: 'standard',
        destination: recipientAccountId
      });

      // Create a session ID to pass back to the client
      const sessionId = payout.id;

      res.status(200).json({ sessionId });
    } catch (error) {
      console.error(error);
      res.status(500).json({ error: 'An error occurred while initiating the payout.' });
    }
  } else {
    res.setHeader('Allow', 'POST');
    res.status(405).end('Method Not Allowed');
  }
}

问题解答

1. 测试用的Stripe账户ID如何获取?

  • 登录Stripe测试后台,进入Connect > 账户页面,列表里每个账户的ID都是acct_开头的字符串,直接复制即可。
  • 也可以通过API创建测试账户,调用stripe.accounts.create后,从返回的响应中提取id字段值。
  • Stripe还提供了预定义的测试Connect账户ID,比如acct_1032D82eZvKYlo2C,可以直接在测试环境使用。

2. 注册Stripe Connect的操作步骤

  • 登录Stripe后台,点击左侧菜单栏的Connect选项,跟着引导完成注册:
    1. 选择你的平台业务类型,填写基础业务信息。
    2. 完成身份验证,绑定测试银行账户(用Stripe提供的测试信息即可,比如路由号110000000、账号000123456789)。
    3. 配置平台展示信息(名称、图标等),完成后就能在测试模式下创建和管理Connect账户了。

3. 更适配的Stripe API方案

目前的Custom账户+Payout API方案可行,但有几个优化方向:

  • 改用Express账户:Express账户由Stripe托管注册流程,用户通过Stripe官方界面完成信息填写,你无需自行收集敏感的银行信息,降低合规风险。只需调用stripe.accountLinks.create生成注册链接,引导用户完成账户创建。
  • 使用Transfer API替代Payout API:如果用户卖出代币后,资金先进入你的Stripe账户,再给用户打款,用Transfer API(stripe.transfers.create)更合适——Transfer是平台账户与用户Connect账户之间的内部转账,之后用户可以自行发起提现,或由你定期批量处理提现。
  • 添加Webhooks监听:配置Stripe Webhooks监听账户创建、转账/提现的状态变更,确保流程可靠性,比如账户创建失败、打款成功/失败时及时通知用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:04:56