土法炼钢兴趣小组的算法知识备份

【金融科技工程】数字人民币、稳定币与 CBDC:双层运营、离线支付、链上/链下清算

文章导航

分类入口
architecturefintech
标签入口
#cbdc#e-cny#digital-yuan#stablecoin#usdc#usdt#mbridge#offline-payment#mica#two-tier

目录

引子:当”钱”被重新定义

过去十年里,支付工程师习惯了一个假设:记账发生在商业银行与清算组织之间,央行只在 RTGS(第 12 篇)的顶层做最终结算。但 2020 年之后,这个假设被三股力量同时撼动:

三者在工程上完全不同:CBDC 是央行直接负债,稳定币是私营或商业银行负债,加密货币是无信用资产。它们共享”数字化、可编程、可跨境”的外壳,但在架构、合规、风险模型上分道扬镳。

本篇面向的读者:做支付网关、钱包、商户收单、清结算的工程师,想要在未来 3 年内对接 e-CNY 或稳定币,但对”双层运营”“双离线支付”“铸造赎回”等术语只有模糊印象。我们的目标是:从系统架构出发,把三类数字货币的数据流、状态机、失败模式讲清楚,再给出落地清单。

一、三类数字货币的工程画像

1.1 分类坐标

用两个维度就能把三类数字货币分清楚:发行方信用账本形态

quadrantChart
    title 数字货币分类坐标
    x-axis "中心化账本" --> "去中心化账本"
    y-axis "无信用背书" --> "主权信用"
    quadrant-1 "CBDC(e-CNY / Digital Euro)"
    quadrant-2 "商业银行代币化存款"
    quadrant-3 "BTC / ETH"
    quadrant-4 "USDT / USDC / DAI"
    "e-CNY": [0.2, 0.95]
    "Sand Dollar": [0.25, 0.9]
    "Digital Euro": [0.3, 0.88]
    "USDC": [0.7, 0.55]
    "USDT": [0.75, 0.5]
    "DAI": [0.85, 0.4]
    "BTC": [0.95, 0.05]
    "ETH": [0.92, 0.08]

三者的核心差异:

维度 CBDC(如 e-CNY) 稳定币(如 USDC) 加密货币(如 BTC)
发行方 中央银行 持牌私营机构 / 银行 无(协议自发)
信用基础 主权信用 储备资产(现金、国债) 算法与共识
账本 混合(账户 + token) 公链(ERC-20、TRC-20 等) 公链(自有)
法偿性 有(法定货币数字形态) 无(合约债权)
赎回权 1:1 兑现金 合约承诺兑 USD
可编程性 有限(受控智能合约) 强(任意合约调用)
典型 TPS 十万级(测试) 单链数千 7(BTC)/ 30(ETH L1)
匿名性 可控匿名 地址级假名 地址级假名
跨境 通过 mBridge 等桥 原生跨链 原生跨链

1.2 为什么工程实现差异巨大

下文聚焦 CBDC(以 e-CNY 为主)与稳定币;加密货币只在与跨境、稳定币相关时出现。

1.3 与既有支付通道的关系

很多工程师最初的疑问是:“e-CNY 到底是 M0 还是 M1?和微信支付、支付宝是竞争关系吗?”

从货币属性看:

从支付链路看,e-CNY 与微信/支付宝不是互斥而是并行:支付宝、微信已经接入 e-CNY 受理(钱包 App 可选择使用 e-CNY 支付),聚合支付网关把 e-CNY 看作一条与银行卡、第三方支付并列的通道。真正的竞争不在终端体验,而在资金沉淀与备付金收益——e-CNY 不付利息、也不产生备付金沉淀收益,这是运营机构的”成本”,但换来了”央行发行权”下的普惠与合规能力。

二、数字人民币 e-CNY 的系统架构

2.1 双层运营模型

人民银行数字货币研究所(DCI)自 2020 年公开的白皮书明确:e-CNY 采用 “一币、两库、三中心”+ 双层运营

flowchart TB
  subgraph L1["第一层:发行层(中央银行)"]
    PBOC["人民银行<br/>发行库 / 认证中心 / 登记中心 / 大数据分析中心"]
  end

  subgraph L2["第二层:流通层(指定运营机构)"]
    ICBC[工商银行]
    ABC[农业银行]
    BOC[中国银行]
    CCB[建设银行]
    BOCOM[交通银行]
    PSBC[邮储银行]
    MYBANK[网商银行]
    WEBANK[微众银行]
  end

  subgraph L3["第三层:受理层"]
    Wallet[软钱包 App / SIM 卡 / 硬钱包]
    Merchant[商户 / POS / 聚合码]
    PSP[支付服务商]
  end

  PBOC -- "发行与回笼(100% 准备金)" --> L2
  L2 -- "兑换、钱包开立、KYC" --> Wallet
  Wallet -- "支付" --> Merchant
  Merchant -- "T+0 结算" --> PSP
  PSP -- "回传至运营机构" --> L2

关键点:

这个结构在”系统可靠性”上的好处:央行不承载 C 端并发。2024 年春节、2026 年冬奥会延展等高峰时段,直面 C 端的仍是六大行的钱包系统,央行只做最终净额结算。

2.2 四类钱包与强弱实名

e-CNY 钱包按实名强度分 4 类,对应不同余额与交易限额。实际限额以当期监管为准,下表为白皮书披露的示例级参考:

钱包类别 实名程度 开立方式 单笔限额 日累计 年累计 余额上限
一类 强实名(柜面核验) 线下面签 不限 不限 不限 不限
二类 强实名(绑定银行卡) App 绑卡 50000 100000 不限 500000
三类 手机号实名 App 内自助 5000 10000 500000 50000
四类 匿名(仅手机号,未与身份关联) App 内自助 2000 5000 50000 10000

工程含义:钱包等级是一段属性,不同等级在同一套接口中体现为不同的 wallet_class 字段。支付网关在受理交易时必须执行如下校验链:

def check_limits(wallet, tx):
    # 核心限额校验——简化伪码
    cls = wallet.class_level          # 1..4
    limits = LIMIT_TABLE[cls]
    if tx.amount > limits.per_txn:
        raise LimitExceeded("per_txn")
    if wallet.day_sum + tx.amount > limits.per_day:
        raise LimitExceeded("per_day")
    if wallet.year_sum + tx.amount > limits.per_year:
        raise LimitExceeded("per_year")
    if wallet.balance + tx.amount > limits.balance_cap and tx.direction == "IN":
        raise LimitExceeded("balance_cap")

注意:限额是 钱包级 而非账户级。同一用户可在不同运营机构开立多个子钱包,但实名强度、KYC 记录在央行认证中心统一。

2.3 账户与 token 的混合形态

白皮书里有一句常被误读的话:“e-CNY 基于广义账户体系,支持银行账户松耦合”。从工程上拆开:

可以把”账户形态”和”token 形态”理解成同一笔 e-CNY 的两种视图:

flowchart LR
  Issue["央行发行<br/>token: {amount, serial, issuer}"]
  Issue --> OpBank["运营机构账户视图<br/>users.balance += amount"]
  Issue --> Offline["硬钱包 token 视图<br/>SE 芯片存 token 串"]
  OpBank -.-> Recon["登记中心对账<br/>sum(token) = sum(account)"]
  Offline -.-> Recon

2.4 智能合约:有限可编程

e-CNY 支持有限智能合约,但设计哲学与以太坊不同:

这与 USDC、USDT 上的”任意合约调用”是本质区别:e-CNY 的可编程性是政策工具而非开发者平台

2.5 双离线支付:工程最硬的骨头

离线支付是 e-CNY 相对于微信/支付宝最显著的差异化能力,也是工程最复杂的部分。

双离线:支付方与收款方同时离线仍可成交,事后再回联清算。这比”单离线”(仅一方离线)难得多。

实现依赖:

关键威胁模型:

威胁 说明 缓解
重放 攻击者复制离线报文再次提交 每笔交易带 nonce + 序列号 + SE 签名,运营机构侧去重
双花 付款方对多个收款方花同一笔 token SE 内部”支付计数器”单调递增;上送后运营机构发现同一 token 多次签名 → 冲正
离线额度透支 付款方离线时无法查账户真实余额 限制离线累计额度(如单钱包 ≤ 10000 元)、离线次数(≤ 10 次),强制定期联网对账
设备被替换 攻击者把 token 从 SE 导出到假 SE SE 做 GlobalPlatform / SESIP 认证,token 封装在 SE 私钥加密层内
拆分攻击 离线时把 token 拆分成多份再各自支付 token 拆分只允许在 SE 内部执行,拆分记录进计数器

冲正:当运营机构事后发现双花或透支,会触发 reversal:

sequenceDiagram
  participant Payer
  participant Payee
  participant Op as 运营机构
  participant PBOC as 央行登记中心

  Payer->>Payee: 离线交易 T1(NFC 碰一碰)
  Payer->>Payee: 离线交易 T2(同 token,双花)
  Note over Payer,Payee: 两笔都完成本地扣减/增加

  Payee->>Op: 上送 T1(先联网)
  Op->>PBOC: 登记 T1
  Payer->>Op: 上送 T2(后联网)
  Op-->>Payer: 检测到同 token 已被花,冲正 T2
  Op->>Payer: 扣回信用额度 / 追偿

这意味着离线支付有”临时信用”的性质:收款方承担”可能被冲正”的风险;为降低此风险,监管要求离线单笔额度较低,且收款方也多为面对面小额场景。

2.6 可控匿名与数据分层

可控匿名(Controllable Anonymity)是 e-CNY 的重要设计原则:小额匿名、大额依法可溯

工程实现:交易报文携带的身份信息在不同系统层级上分层披露

数据层级 可见方 内容
受理层 商户 / PSP 钱包编号(不含身份证)
运营机构 运营行 钱包绑定手机号、KYC 等级
认证中心 PBOC 实名信息(仅一、二类钱包)
大数据中心 PBOC 聚合分析(不向运营机构反向披露)

对支付工程师意味着:不要在日志、风控、BI 系统里沉淀 PBOC 不希望下沉的数据。常见合规红线:

2.7 试点进展(截至 2026 Q2)

2.8 一笔 e-CNY 支付的端到端链路

把前面的元素串起来,看一笔线下扫码支付 100 元是怎么走完的(假设付款方在工行 e-CNY 子钱包,商户结算行为建行):

sequenceDiagram
  participant U as 用户钱包(工行)
  participant M as 商户 POS
  participant PSP as 聚合支付网关
  participant ICBC as 工行 e-CNY 系统
  participant CCB as 建行 e-CNY 系统
  participant PBOC as 央行登记中心

  M->>U: 展示动态收款码
  U->>U: SE 内生成支付指令、签名
  U->>PSP: 上送扫码支付报文
  PSP->>ICBC: 路由:识别付款运营机构
  ICBC->>ICBC: 校验钱包等级、限额、余额
  ICBC->>CCB: 跨机构转账(通过 e-CNY 机构间接口)
  CCB-->>M: 入账(e-CNY 钱包 or T+0 代付到银行账户)
  ICBC-->>PBOC: 异步上送 token 变更明细
  CCB-->>PBOC: 异步上送 token 变更明细
  PBOC-->>PBOC: 登记中心对账:两端 token 变更匹配
  ICBC-->>PSP: 支付结果
  PSP-->>M: 显示支付成功

关键工程观察:

2.9 数据模型示例

在运营机构一侧,一个极简的 e-CNY 账本模型可以是(仅示意,真实系统更复杂、分库分表见第 4 篇):

-- 钱包主表
CREATE TABLE ecny_wallet (
    wallet_id       VARCHAR(32)  PRIMARY KEY,          -- 钱包编号
    user_ref        VARCHAR(64)  NOT NULL,             -- 内部用户引用(脱敏)
    class_level     TINYINT      NOT NULL,             -- 1..4
    operator_code   VARCHAR(8)   NOT NULL,             -- 运营机构
    balance         DECIMAL(20,2) NOT NULL DEFAULT 0,  -- 账户视图余额
    offline_balance DECIMAL(20,2) NOT NULL DEFAULT 0,  -- 离线已预扣
    status          TINYINT      NOT NULL,             -- 0 正常 1 冻结 2 注销
    se_bound_flag   TINYINT      NOT NULL,             -- 是否绑定 SE
    created_at      DATETIME     NOT NULL,
    updated_at      DATETIME     NOT NULL
);

-- 交易流水(线上与离线统一)
CREATE TABLE ecny_txn (
    txn_id          CHAR(32)     PRIMARY KEY,
    out_trade_no    VARCHAR(64)  NOT NULL,             -- 商户订单号
    payer_wallet    VARCHAR(32)  NOT NULL,
    payee_wallet    VARCHAR(32)  NOT NULL,
    amount          DECIMAL(20,2) NOT NULL,
    tx_type         TINYINT      NOT NULL,             -- 1 扫码 2 NFC 3 离线 4 合约
    offline_flag    TINYINT      NOT NULL DEFAULT 0,
    nonce           VARCHAR(64)  NOT NULL,
    se_signature    VARBINARY(256),                    -- 离线交易必填
    status          TINYINT      NOT NULL,             -- 10 已扣 20 已入 30 已登记 90 冲正
    occur_at        DATETIME     NOT NULL,             -- 业务发生时间(可能 <上送时间)
    upload_at       DATETIME     NOT NULL,
    pboc_regist_at  DATETIME,                          -- 登记中心确认时间
    KEY idx_out (out_trade_no),
    KEY idx_payer (payer_wallet, occur_at),
    KEY idx_status (status, occur_at)
);

-- 离线 token 串(仅硬钱包 / 强离线场景)
CREATE TABLE ecny_token (
    token_id        CHAR(32)    PRIMARY KEY,
    serial          VARCHAR(32) NOT NULL UNIQUE,       -- 央行 token 冠字号
    amount          DECIMAL(20,2) NOT NULL,
    holder_wallet   VARCHAR(32) NOT NULL,
    se_id           VARCHAR(64),                       -- 所在安全芯片 ID
    state           TINYINT     NOT NULL,              -- 0 流通 1 已花 2 冻结 3 回笼
    parent_token    CHAR(32),                          -- 拆分来源(若存在)
    last_signed_cnt BIGINT      NOT NULL,              -- SE 内单调计数器快照
    updated_at      DATETIME    NOT NULL
);

三张表对应三个视角:账户视图(balance)、交易视图(txn)、token 视图(token)。日常扫码支付 99% 走前两张表,离线和硬钱包场景才启用第三张。

2.10 冲正与一致性工程

一笔离线交易的完整状态机:

stateDiagram-v2
    [*] --> SE_Debited: 付款 SE 完成本地扣减
    SE_Debited --> SE_Credited: 收款 SE 完成本地增加
    SE_Credited --> Uploading_One: 任一方联网上送
    Uploading_One --> Registered: 运营机构 → 登记中心成功
    Uploading_One --> Reversal_Pending: 发现双花 / 透支
    Reversal_Pending --> Reversed: 冲正完成、信用追偿
    Registered --> [*]
    Reversed --> [*]

这里的一致性保障有两个层面:

三、稳定币的架构与治理

3.1 储备模型:三种范式

稳定币的”稳定”本质是兑付承诺。按储备模型分三类:

类型 代表 储备 工程挑战
法币全额储备 USDC、PYUSD、FDUSD 现金 + 短期美债 储备审计、赎回窗口
加密资产超额抵押 DAI、LUSD ETH、stETH 等,150%+ 抵押 清算引擎、预言机
算法稳定 UST(已崩溃)、USDe 对冲头寸、协议铸销机制 反身性风险、脱锚

Terra/UST 的教训(2022 年 5 月):UST 通过与 LUNA 的 mint/burn 机制维持锚定,当信心崩塌时,LUNA 通胀对冲失效,出现”死亡螺旋”。对工程者而言,核心启示是:没有外部储备的稳定币,在极端行情下任何内生机制都可能失败

USDe(Ethena)的新思路:用”现货多头 + 永续空头”的 delta 中性组合对冲价格风险,资金费率收益作为收益来源。这本质上是把”衍生品对冲”放进稳定币结构,工程上需要实时监控交易所对手方风险与资金费率极端值。

3.2 铸造与赎回流程(以 USDC 为例)

sequenceDiagram
  participant Inst as 机构客户
  participant Circle as Circle Mint API
  participant Bank as 托管银行
  participant Chain as 公链(Ethereum 等)
  participant User as 终端用户

  Inst->>Circle: 发起 mint(含目标链、数量、接收地址)
  Circle->>Circle: KYC / 白名单校验
  Inst->>Bank: 电汇 USD 到 Circle 托管账户
  Bank-->>Circle: 到账通知
  Circle->>Chain: 调用合约 mint(to, amount)
  Chain-->>User: 接收地址收到 USDC
  Note over User,Chain: 链上自由流通

  User->>Inst: 二级市场卖出(获得 USD 或其他资产)
  Inst->>Circle: 赎回(把 USDC 转到 burn 地址)
  Circle->>Chain: burn(amount)
  Circle->>Bank: 从储备账户电汇 USD 给机构
  Bank-->>Inst: 到账

关键工程点:

3.3 跨链与桥接

同一个”USDC”在以太坊、Solana、Base、Arbitrum 上都有实例。早期通过第三方桥(Multichain、Wormhole)实现跨链,事故不断:

Circle 之后推出 CCTP(Cross-Chain Transfer Protocol),原理是”burn-and-mint”:

flowchart LR
  A[源链 USDC] -->|burn| B((Circle Attestation 服务))
  B -->|签名消息| C[目标链 Mint 合约]
  C -->|mint USDC| D[目标链地址]

CCTP 的工程价值:不依赖第三方锁仓池,源链销毁 + Circle 签名证明 + 目标链铸造,攻击面从”桥池”缩小到”Circle 签名密钥”。对接入方:只需在源链调用 depositForBurn()、等待 attestation,再在目标链调用 receiveMessage() 即可。

3.4 稳定币合约的关键接口

以 USDC 合约(EIP-20 扩展)为例,关注几个与合规直接相关的函数:

// 简化后的 USDC 合约关键接口
interface IFiatToken {
    // ERC-20 基础
    function transfer(address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);

    // 铸造 / 销毁(仅 minter 角色)
    function mint(address to, uint256 amount) external returns (bool);
    function burn(uint256 amount) external;

    // 黑名单 / 冻结(仅 blacklister 角色)
    function blacklist(address account) external;
    function unBlacklist(address account) external;
    function isBlacklisted(address account) external view returns (bool);

    // 暂停(仅 pauser 角色)
    function pause() external;
    function unpause() external;
}

工程含义:

3.5 储备证明的几种模式

监管对储备的要求在 2024–2026 之间迅速收紧。常见模式:

模式 代表 可信度 工程难度
定期审计报告(attestation) USDC、PYUSD 低(外包审计)
实时链上证明(PoR) 部分交易所稳定币 中高 高(需银行侧数据上链)
完全托管银行对账 持牌银行稳定币
仅自我声明 早期 USDT

“链上储备证明(Proof of Reserves, PoR)”是交易所在 FTX 事件后引入的透明化手段。典型做法:

对支付工程师:如果你的收款方案需要接入稳定币清算,储备审计报告的月度对账应当进入风险监控流程,与汇率波动、发行方集中度一起被纳入风险限额表。

3.6 监管:2024–2026 的三张大网

对支付工程师的影响:合规成本 = 稳定币白名单管理 + 制裁名单实时更新 + 报送管线。与 e-CNY 的”可控匿名”相比,稳定币的合规负担更重地落在发行方与受理商户身上。

四、CBDC 跨境互联:从 mBridge 到 Project Agorá

跨境支付的痛点(第 13 篇):代理行链路长、T+N 结算、汇率与对手方风险叠加。CBDC 的跨境试点旨在用”多央行共同账本”压缩这条链路。

4.1 mBridge:最成熟的多边 CBDC 桥

mBridge(Multi-CBDC Bridge) 由人行数字货币研究所、香港金管局(HKMA)、泰国央行(BOT)、阿联酋央行(CBUAE)联合,国际清算银行(BIS)创新中心支持。2022 年完成首次真实交易试点,2024 年进入”最小可行产品(MVP)“阶段。

架构要点:

flowchart TB
  subgraph Ledger[mBridge 共同账本(基于 DLT)]
    CN[e-CNY 节点]
    HK[e-HKD 节点]
    TH[eTHB 节点]
    AE[eAED 节点]
  end

  CBank1[人民银行] --- CN
  CBank2[HKMA] --- HK
  CBank3[泰央行] --- TH
  CBank4[阿联酋央行] --- AE

  subgraph Participants[参与商业银行]
    B1[工行香港]
    B2[HSBC]
    B3[盘谷银行]
    B4[Emirates NBD]
  end

  B1 --- CN
  B2 --- HK
  B3 --- TH
  B4 --- AE

  B1 -. "PvP 结算" .- B2
  B2 -. "PvP 结算" .- B3
  B3 -. "PvP 结算" .- B4

工程特征:

4.2 Project Agorá:BIS 主导的下一代尝试

Project Agorá(2024 发起)由 BIS 与七家央行(英国、法国、日本、韩国、墨西哥、瑞士、美国)+ 40+ 私营机构联合,目标是在单一可编程平台上统一批发 CBDC 与代币化商业银行存款。相比 mBridge,它更强调”代币化存款(tokenized deposits)“与批发 CBDC 的组合。

4.3 mBridge 报文与结算流程

在 mBridge 的 DLT 账本上,一笔跨境 PvP 的典型流程是:

sequenceDiagram
  participant A as 中国进口商
  participant BA as 工行香港分行(CN 节点)
  participant L as mBridge 共同账本
  participant BB as HSBC(HK 节点)
  participant B as 香港供应商

  A->>BA: 申请付款 1,000,000 HKD 给 B
  BA->>BA: 锁定对应 e-CNY(按实时汇率)
  BA->>L: 提交 PvP 订单:e-CNY 锁 ↔ e-HKD 期望
  BB->>L: 匹配订单:e-HKD 锁 ↔ e-CNY 期望
  L->>L: 原子结算:两端 token 同时转移
  L-->>BA: 结算确认
  L-->>BB: 结算确认
  BB-->>B: e-HKD 入账
  BA-->>A: 扣减完成通知

关键工程特征:

相比之下,传统 SWIFT + 代理行跨境支付的路径是”多跳消息 + 各自 RTGS 日终净额”——细节见第 13 篇

4.4 互操作性的三种模式

BIS 综述把 CBDC 跨境方案分成三层互操作性:

模式 描述 代表项目
兼容(Compatible) 各自为政,统一报文标准(ISO 20022 扩展) 部分单边 CBDC 试点
互联(Interlinked) 桥接层打通两个独立系统 新加坡 Ubin、香港 Aurum
整合(Integrated) 单一共同账本上运行多 CBDC mBridge、Dunbar、Agorá

从工程复杂度看,整合模式最复杂但效率最高;兼容模式最简单但效率提升有限。当前主流方向是”整合 + 每个央行保留主权节点”——这是一个政治与工程的折中。

4.5 Project Dunbar 的经验

Project Dunbar(2021–2022)是 BIS + 新加坡金管局(MAS)+ 澳洲央行 + 南非央行 + 马来西亚央行的早期多 CBDC 尝试,已结题。它证明了”多 CBDC 共同账本”在技术上可行,但也暴露出货币主权与准入治理是最难的部分(哪些商业银行可以上链?额度谁来决定?)。这一政治经济学难题被 mBridge 与 Agorá 继承。

五、商户接入 e-CNY 的落地清单

作为支付工程师,给出一套务实的对接清单

5.1 总体流程

flowchart LR
  A[选择运营机构] --> B[商户入网 / KYB]
  B --> C[开通 e-CNY 受理资格]
  C --> D[接入钱包 SDK / 受理 API]
  D --> E[测试环境联调]
  E --> F[灰度上线]
  F --> G[对账与清算]

5.2 钱包 SDK 与受理协议

{
  "out_trade_no": "20260422-000123",
  "total_amount": "100.00",
  "currency": "CNY",
  "channel": "ecny",
  "operator": "ICBC",
  "wallet_class_required": 2,
  "subject": "订单#123",
  "notify_url": "https://merchant.example.com/ecny/notify",
  "offline_allowed": true
}

5.3 离线对账要点

5.4 与微信/支付宝聚合受理

5.5 选型建议

场景 建议
大型零售连锁 接入 2–3 家运营机构 + 聚合 SDK,优先支持 NFC 与 QR
线上电商 先接最大运营机构(本地结算行),离线能力非必需
政务补贴发放 通过运营机构申请”定向支付智能合约”模板,而非自研合约
跨境面向来华外宾 预付卡硬钱包 + 四类匿名钱包组合
中小商户 走聚合支付网关(微信/支付宝服务商)中的 e-CNY 子通道

5.6 受理 API 示例

不同运营机构接口细节不同,但基本要素一致。下面是一个示例的”商户下单 → 用户支付 → 异步通知 → 查询 → 退款”全链路(字段经过简化):

# 1. 统一下单
POST /ecny/v1/order HTTP/1.1
Host: openapi.operator.example.com
Content-Type: application/json
Authorization: MERCHANT-HMAC app_id=...,sig=...

{
  "out_trade_no": "20260422-A000123",
  "total_amount": "100.00",
  "subject": "商品订单 #A000123",
  "channel": "ecny",
  "pay_mode": "C2B_QR",
  "wallet_class_required": 2,
  "offline_allowed": false,
  "notify_url": "https://merchant.example.com/ecny/notify",
  "expire_at": "2026-04-22T12:30:00+08:00"
}

HTTP/1.1 200 OK
{
  "trade_no": "EC20260422100001234567",
  "qr_code": "dcep://pay?tn=EC20260422100001234567&amt=100.00",
  "expire_at": "2026-04-22T12:30:00+08:00"
}
# 2. 异步通知(由运营机构主动 POST 到 notify_url)
POST /ecny/notify HTTP/1.1
X-Operator-Sign: <签名>

{
  "trade_no": "EC20260422100001234567",
  "out_trade_no": "20260422-A000123",
  "status": "SUCCESS",
  "paid_amount": "100.00",
  "pay_time": "2026-04-22T12:15:22+08:00",
  "wallet_masked": "****1234",
  "wallet_class": 2,
  "offline_flag": false,
  "settlement": {
    "mode": "T0_TO_BANK",
    "bank_account": "6227****8899",
    "est_settle_at": "2026-04-22T12:15:30+08:00"
  }
}
# 3. 主动查询
GET /ecny/v1/order?out_trade_no=20260422-A000123
# 4. 退款
POST /ecny/v1/refund
{
  "out_trade_no": "20260422-A000123",
  "out_refund_no": "R20260422-A000123-01",
  "refund_amount": "100.00",
  "reason": "user cancel"
}

几个容易踩坑的字段:

5.7 对账与资金归集

e-CNY 的商户对账文件基本延续了银行卡收单的结构(参见第 11 篇第 23 篇),但增加几个特有字段:

trade_no, out_trade_no, amount, fee, net_amount,
wallet_class, offline_flag, reversal_flag,
operator_code, payee_wallet, pay_time, settle_time

重点:

5.8 一个极简 SDK 封装(示意)

为了让上层业务尽量不感知通道差异,可把 e-CNY 封装成一个薄 SDK。下面是一段伪代码(Go 风格)演示统一接口:

// Package paych 提供多通道支付的统一抽象
package paych

type Money struct {
    Amount   string // 字符串,避免浮点误差(见第 2 篇)
    Currency string // ISO 4217
}

type OrderReq struct {
    OutTradeNo string
    Total      Money
    Subject    string
    Channel    string // "ecny.icbc" / "wxpay" / "usdc.eth"
    PayMode    string // "C2B_QR" / "NFC" / "ONCHAIN_TRANSFER"
    NotifyURL  string
    Options    map[string]string
}

type OrderResp struct {
    TradeNo  string
    PayInfo  string // 二维码 / 合约调用 payload / 支付 URL
    ExpireAt int64
}

type Channel interface {
    CreateOrder(ctx context.Context, req *OrderReq) (*OrderResp, error)
    QueryOrder(ctx context.Context, outTradeNo string) (*OrderStatus, error)
    Refund(ctx context.Context, r *RefundReq) (*RefundResp, error)
    VerifyNotify(ctx context.Context, headers, body []byte) (*NotifyEvent, error)
}

// e-CNY 适配
type ECNYChannel struct {
    Operator   string // ICBC / CCB / ...
    AppID      string
    PrivateKey []byte
    Endpoint   string
}

func (c *ECNYChannel) CreateOrder(ctx context.Context, r *OrderReq) (*OrderResp, error) {
    body := map[string]any{
        "out_trade_no":          r.OutTradeNo,
        "total_amount":          r.Total.Amount,
        "subject":               r.Subject,
        "channel":               "ecny",
        "pay_mode":              r.PayMode,
        "notify_url":            r.NotifyURL,
        "wallet_class_required": r.Options["wallet_class"],
        "offline_allowed":       r.Options["offline_allowed"] == "true",
    }
    return c.postSigned(ctx, "/ecny/v1/order", body)
}

类似地可以实现 WechatChannelUSDCChannelCardChannel;上层业务只面向 Channel 接口。这种封装有两个长期价值:

  1. 新接通道的工作量收敛在”实现一个 Channel“;
  2. 便于做通道级灰度路由回退:某通道故障时自动切换到备用通道。

六、一个典型设计题:商户如何构建”多通道 + e-CNY + 稳定币”统一收款

真实的出海电商、跨境 SaaS 常常面对这样一个问题:国内要支持 e-CNY,出海要支持 USDC,同时还要聚合微信/支付宝/卡组织。如何做收款架构?

6.1 抽象:把货币、通道、通道账户解耦

借鉴第 2 篇对”钱”的建模:

Money        := (amount, currency)
Channel      := WeChat | Alipay | UnionPay | eCNY.ICBC | Stripe | USDC.ETH | ...
ChannelAcct  := (Channel, MerchantId, SettlementBank)
Txn          := (Channel, ChannelAcct, Money, Status, ...)

商户系统内部始终使用”记账币种 + 金额”为主键,通道是属性而非主键。这样新接一条 e-CNY 通道或一条 USDC 通道,对订单模型没有侵入。

6.2 统一下单接口

# 统一下单(内部调用)
def create_payment(order):
    rules = RouteEngine.match(order)   # 基于地域、金额、用户偏好
    channel = rules.select()
    if channel.kind == "ecny":
        return ECNYAdapter(channel).create(order)
    elif channel.kind == "stablecoin":
        return StablecoinAdapter(channel).create(order)
    elif channel.kind == "card":
        return CardAdapter(channel).create(order)
    elif channel.kind == "thirdparty":
        return ThirdPartyAdapter(channel).create(order)
    else:
        raise UnsupportedChannel(channel)

6.3 状态模型

所有通道对外暴露统一的 5 态模型:CREATED → PAYING → PAID → REFUNDED / REVERSED / EXPIRED。e-CNY 的离线冲正映射为 REVERSED,稳定币的回滚(罕见,通常是合约 revert)也映射到 REVERSED

6.4 风险控制

不同通道风险面差别巨大:

风险维度 e-CNY USDC 微信/支付宝 银行卡
对手方违约 无(央行负债) 低(发行方 + 储备) 低(第三方 + 备付金) 中(发卡行/收单行)
交易可撤销 仅离线冲正(小概率) 极低(链上最终性) 可退款(双方发起) 可拒付(6 个月)
合规分级 严(分层实名) 严(KYC + 制裁) 严(实名 + 备付金) 严(PCI DSS)
汇率波动 无(CNY) 按链桥实时价 无(CNY) 视币种

风控引擎(第 19 篇)应为每条通道配单独的风险画像,避免”用银行卡拒付模型套到稳定币”。

七、工程落地挑战

7.1 吞吐量

7.2 隐私与反洗钱的平衡

7.3 离线支付的安全边界

前文已展开双离线威胁模型。离线支付在工程上的本质是:在不可信信道与不可信时钟条件下维持账本一致性。这与分布式系统里”网络分区 + 拜占庭错误”的子问题同源,必须用经济激励(冲正与信用额度)而非纯算法保证最终收敛。

7.4 与传统账户的桥接

7.5 硬钱包生命周期

硬钱包(卡片、手环、SIM 卡)有一些软钱包没有的问题:

八、真实案例

8.1 2022 北京冬奥会:e-CNY 的压力测试

8.2 香港 e-HKD 试点与港币稳定币

8.3 尼日利亚 eNaira:一个反面参考

8.4 Circle CCTP 在跨境 B2B 的应用

2024–2025 年,部分新兴市场电商把 USDC + CCTP 当作”轻量级跨境结算层”:

端到端耗时通常在数分钟,手续费远低于 SWIFT 链路。但这种方案不能在中国大陆合法使用,原因是外汇与支付牌照限制。

8.5 巴哈马 Sand Dollar:设计与采纳的错位

巴哈马 2020 年推出 Sand Dollar,是全球第一个正式流通的 CBDC。设计上充分考虑了海岛分散、银行覆盖不足的问题,技术实现简洁。但实际采纳率长期偏低,反映出CBDC 的使用粘性不是靠”先发”而是靠”场景”。这与中国 e-CNY 早期试点中依赖政府补贴、公交、税费等”高频场景”形成对照。

九、工程坑点

十、选型决策表:何时选什么

把前面的分析压缩成一张决策表,方便在项目评审时直接引用:

业务场景 推荐 理由
境内 C 端零售支付 微信/支付宝 + e-CNY 作为补充 覆盖率 / 法偿性兼顾
境内政府补贴、定向支付 e-CNY + 智能合约模板 可编程 + 可审计
境内老年/农村普惠 e-CNY 硬钱包 + SIM 卡钱包 无需智能手机
跨境 B2C 电商(消费者付款) 卡组织 + 本地钱包 兼容性最高
跨境 B2B 大额结算(合规路径) CIPS / mBridge / SWIFT gpi 规模与合规
加密原生企业跨境 USDC + CCTP 结算速度
Web3 钱包内支付 稳定币(USDC > USDT) 合规优先
交易所间结算 稳定币 + 银行轨并行 双通道冗余
供应链票据结算 e-CNY 智能合约或批发 CBDC 可编程到期释放
证券 DvP 试点 批发 CBDC(Agorá 类) 原子性

十一、未来展望

到 2026 年年中,可以观察到几个趋势:

对工程师而言,真正值得准备的能力是:

  1. 账户 / token / 合约三种账本形态统一到一套内部数据模型。
  2. 熟悉离线、冲正、跨链的失败模式,而不是把它们当作”偶发异常”。
  3. 合规配置化(限额、名单、报送)做成可变更而非硬编码。
  4. 保留多通道冗余,不押注单一数字货币形态。
  5. 对 HSM、SE、多签钱包等密钥管理设施建立常态化运维流程,而不是”出事再建”。

十二、参考资料


上一篇《跨境支付工程:代理行、nostro/vostro、汇率锁定、对手方风险》

下一篇《交易所核心系统架构:撮合、行情、做市、风控、清算》

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-22 · architecture / fintech

【金融科技工程】金融科技未来趋势与工程师路径

系列收官。从货币形态、即时支付、AI、隐私计算、DeFi、监管科技、云原生、后量子密码八大趋势出发,给出未来 5–10 年的工程判断;再给出从入门到专家的金融科技工程师成长路线,以及书单、论文、开源项目与 25 篇全景索引。

2026-04-22 · architecture / fintech

金融科技工程

面向中国工程团队的金融科技系列。从账务底盘、支付、清结算、交易所、风控合规到可靠性与灾备,中国与全球视角并举,讲清楚金融系统在工程落地中的真实挑战。

2026-04-22 · architecture / fintech

【金融科技工程】金融科技工程全景:从支付到交易所的系统分类与读图

金融科技(FinTech)不是普通后端加一张账户表。钱的原子性、监管的硬边界、一个小数点的代价,把这个领域推进到工程强度最高的那一档。本文是【金融科技工程】25 篇的总目录与阅读地图:先交代为什么它比一般业务系统更难,再给出对账体、支付体、交易体、风控合规体四维分类,把后续 24 篇挂到骨架上,最后给出一份绿地项目的落地顺序建议。


By .