基于Stripe API实现ERC20代币售卖提现的技术咨询
ERC20代币售卖功能的Stripe集成问题及解决方案
背景
我开发了一款支持用户用USD买卖ERC20代币的应用,已通过Stripe Checkout完成代币购买功能,现需实现代币售卖功能——用户卖出代币后可收取USD,计划使用Stripe Payout API实现。流程为:用户售卖代币时,可提供自身Stripe账户ID;若用户无Stripe账户,则收集其银行路由号、银行账号及邮箱,通过stripe.accounts.create为其创建账户。目前处于测试模式,有以下疑问:
- 测试用的Stripe账户ID如何获取?
- 使用测试银行账户信息创建新账户时,提示需注册Stripe Connect,该如何操作?
- 是否有更适配此需求的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选项,跟着引导完成注册:
- 选择你的平台业务类型,填写基础业务信息。
- 完成身份验证,绑定测试银行账户(用Stripe提供的测试信息即可,比如路由号
110000000、账号000123456789)。 - 配置平台展示信息(名称、图标等),完成后就能在测试模式下创建和管理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
相关产品推荐
相关产品推荐

