
现货交易
现货下单流程 用户下单 → 冻结可用余额 → 撮合成交 → 扣除冻结 + 增加买入币种
- 核心业务流程
2.1 现货下单流程 用户下单 → 冻结可用余额 → 撮合成交 → 扣除冻结 + 增加买入币种
操作类型:
-
BUY_ORDER(201) - 买单冻结
-
SELL_ORDER(202) - 卖单冻结
-
BUY_DEAL(203) - 买单成交
-
SELL_DEAL(204) - 卖单成交
-
BUY_CANCEL_ORDER(205) - 买单撤销解冻
-
SELL_CANCEL_ORDER(206) - 卖单撤销解冻
2.2 充币流程
链上确认 → depositSuccess() → 增加可用余额 → 记录流水 → 发送通知
2.3 提币流程
申请提币 → 冻结金额 → 审核通过 → 链上转账 → withdrawCallback() → 扣除冻结
2.4 账户划转
币币 ↔ OTC ↔ 合约 ↔ 跟单(仅USDT)
- 并发控制
乐观锁: 每次更新时检查 version 字段
UPDATE tb_user_coin_account
SET amount = amount - #{amount},
frozen_amount = frozen_amount + #{amount},
version = version + 1
WHERE user_id = #{userId} AND version = #{version}
分布式锁: Redis 锁防止重复处理(充币、提币回调)
- 资金流水
每次余额变动都会记录到 tb_coin_change_recd 表:
-
变动前金额 before_amount
-
变动金额 amount
-
变动后金额 after_amount
-
操作类型 opt_type
-
关联单号 relate_recd_id
这样可以完整追溯每一笔资金变动的来源。
币币交易
⏺ "币币账户"是加密货币交易所的行业术语,指的是币对币交易(Crypto-to-Crypto)的账户。
名称由来:币币交易 = 用一种加密货币兑换另一种加密货币
例如:
-
用 USDT 买 BTC
-
用 ETH 换 USDT
-
用 BTC 换 ETH
这种交易不涉及法定货币(人民币、美元等),纯粹是"币"换"币",所以叫币币交易,对应的账户就叫币币账户。
与其他账户的区别
为什么不直接叫"现货账户"? 其实"币币账户"和"现货账户"是同一个概念。代码中用的是 TRADE 类型,注释写的是"币币账户",这是国内交易所的习惯叫法。国外交易所通常叫 "Spot Account"(现货账户)。
OTC/C2C交易
法币账户,就叫OTC账户?
⏺ 是的,在这个项目中法币账户 = OTC账户。
为什么这样命名?
OTC = Over-The-Counter(场外交易)
由于监管原因,大多数交易所不能直接提供法币与加密货币的撮合交易。所以法币交易通常采用 C2C 模式(用户对用户):
买家(法币) ←→ 卖家(加密货币)
↑
平台撮合,但不经手资金
这种用户之间直接交易的方式就是"场外交易"(OTC),所以法币账户也叫 OTC 账户。
典型流程
-
卖家在 OTC 账户冻结 USDT
-
买家通过银行卡/支付宝付款给卖家
-
卖家确认收款
-
平台将冻结的 USDT 转给买家的 OTC 账户
代码中的体现
// AccountTypeEnum.java
TRADE(1, "TRADE") // 币币账户 - 现货交易
OTC(2, "OTC") // 法币账户 - 场外交易
所以"法币"描述的是交易内容(涉及法定货币),"OTC"描述的是交易方式(场外/C2C)
完整流程
- 卖家挂单:出售 2000 USDT,价格 5 RMB/USDT
→ 平台冻结卖家 OTC 账户的 2000 USDT
- 买家下单:购买 2000 USDT
→ 买家线下转账 10000 RMB 给卖家(支付宝/银行卡)
- 卖家确认收款
→ 平台将冻结的 2000 USDT 转入买家 OTC 账户
- 交易完成
→ 卖家:收到 10000 RMB(线下)
→ 买家:OTC 账户 +2000 USDT
关键点
-
法币不经过平台:RMB 是买家直接打给卖家的,平台只托管加密货币
-
先冻结后放币:卖家的 USDT 在挂单时就被冻结,确保有币可卖
-
确认收款才放币:卖家点击"确认收款"后,平台才执行转账
代码中的体现
// CoinChangeTypeEnum.java
OTC_SELL_FROZEN(9) // 卖家挂单 → 冻结 USDT
ORDER_UNFROZEN(13) // 订单取消 → 解冻 USDT
// UserCoinAccountService.java
sellCoinTransfer() // 卖家确认收款 → USDT 从卖家转给买家
这种模式让平台规避了法币资金流转的合规风险,同时通过托管加密货币保障交易安全。
买家线下转账 10000 RMB 给卖家(支付宝/银行卡),如果卖家此时收到了买家的10000 RMB,但是卖家撒谎,说自己没有收到,怎么办
⏺ 这是 OTC 交易中常见的恶意不放币问题,平台通常有以下机制来处理:
- 申诉机制
买家可以发起申诉,提交付款凭证:
-
支付宝/微信转账截图
-
银行流水记录
-
交易时间、金额、收款方信息
平台客服介入审核,核实后可强制放币。
- 卖家保证金
成为 OTC 商家通常需要缴纳保证金,如果多次恶意不放币:
-
扣除保证金赔偿买家
-
冻结/封禁商家账户
- 信用体系
-
卖家有成交量、好评率等指标
-
恶意行为会影响信用评分
-
低信用卖家会被限制交易或下架
- 自动放币
部分平台支持绑定收款账户,检测到入账后自动确认放币,减少人为操作。
- 法律手段
OTC 交易有聊天记录、转账凭证,买家可以:
-
向平台举报
-
严重情况可报警处理(诈骗)
这个项目中的处理
从代码看,这个项目主要处理资金流转,申诉和风控逻辑可能在其他服务(如 ex-risk 风控服务)中实现。OTC 订单的状态流转和争议处理通常由专门的 OTC 订单服务管理
卖家注册成为 OTC 商家
-
创建 OTC 账户:在 tb_user_coin_account 中生成 type=2 的记录
-
绑定收款方式:卖家需要在平台绑定自己的收款账户
-
支付宝账号/二维码
-
微信账号/二维码
-
银行卡号(开户行、姓名)
- 发布广告:卖家挂单出售 USDT,设置价格、数量、限额等
买家下单流程
-
买家浏览 OTC 广告列表
-
选择卖家的广告下单
-
平台展示卖家的收款信息(支付宝/银行卡)
-
买家线下转账
-
买家点击"已付款"
-
卖家确认收款 → 放币
收款方式存储
收款方式信息通常不在 ex-finance 中,而是在 OTC 服务 或 用户中心 中管理,比如: 
ex-finance 只负责资金的冻结和划转,收款方式的管理属于用户或 OTC 业务模块
案例展示




场内交易
⏺ 场内交易(交易所直接支持法币买币)的流程完全不同:
场内法币交易流程
-
用户充值法币到交易所账户(银行卡/支付宝转账给平台)
-
平台账户余额显示 10000 RMB
-
用户下单:用 10000 RMB 买 2000 USDT
-
交易所撮合引擎直接成交
-
用户账户:RMB -10000,USDT +2000

为什么国内交易所不做场内法币交易?
2017年后国内禁止交易所直接提供法币兑换加密货币服务,所以:
-
合规交易所(如 Coinbase):有金融牌照,可以直接收法币
-
国内/灰色地带交易所:只能用 OTC/C2C 模式,平台不直接经手法币
场内交易的账户模型, 如果支持场内法币,账户表可能是这样:
tb_user_fiat_account(法币余额账户)
-
user_id
-
currency(CNY/USD/EUR)
-
balance(法币余额)
-
frozen_balance
但这个项目的 type=2 OTC账户 存的还是加密货币余额(如 USDT),不是法币余额,说明走的是 C2C 模式。
