1. 创建 API Key
商户管理员登录后台,在开发者中心创建 Key。Secret 只展示一次,请写入商户服务端密钥管理系统。
https://payadmin.globaldevsoft.com/#login此页是外部商户的接入总览。详细工程文档仍保留在项目仓库中,线上页面先提供稳定入口、签名规则、核心接口和验收清单。
商户管理员登录后台,在开发者中心创建 Key。Secret 只展示一次,请写入商户服务端密钥管理系统。
https://payadmin.globaldevsoft.com/#login商户所有系统接口使用 HMAC-SHA256。签名材料包括方法、路径、时间戳、nonce、query 和 body 摘要。
X-UFlow-Key
X-UFlow-Timestamp
X-UFlow-Nonce
X-UFlow-SignatureWebhook 投递带签名和事件 ID。商户系统必须幂等处理,不能只靠 HTTP 200 判断业务入账。
POST /merchant/webhooks/payment-paid创建订单后返回订单 ID、收款网络、资产、金额、过期时间和收银台地址。当前环境为 Sandbox 验证。
POST /api/v1/merchant/payment-orders
GET /api/v1/merchant/payment-orders/{id}代付请求会冻结金额与费用快照,并进入风险/审批/执行流程。主网执行器默认关闭。
POST /api/v1/merchant/payouts
GET /api/v1/merchant/payouts/{id}余额来自双分录账本投影,前端和商户系统不能自行计算权威余额。
GET /api/v1/merchant/balances平台运营先在总后台绑定商户套餐与费率版本,商户管理员再在后台创建最小权限 API Key。
payadmin → 商业配置
payadmin → 开发者 → API 凭证正式对接统一使用独立 API 域名,收银台跳转使用 hosted checkout 域名。
API_BASE=https://payapi.globaldevsoft.com
CHECKOUT_BASE=https://paycheckout.globaldevsoft.com商户费率按版本发布,代付创建时会读取当前生效的商户费率并把费用写入订单快照。
fee_rate_bps + flat_fee_atomic
历史订单不随新费率变动以下示例只展示签名核心。商户应把 Key 和 Secret 放在服务端密钥管理系统中,前端页面不得保存或计算签名。
import crypto from 'node:crypto'
const body = JSON.stringify({
merchant_order_no: 'ORD-10001',
amount_atomic: '128500000',
asset_code: 'USDT',
network_code: 'TRON',
notify_url: 'https://merchant.example/webhooks/uflow'
})
const timestamp = Math.floor(Date.now() / 1000).toString()
const nonce = crypto.randomUUID()
const bodyHash = crypto.createHash('sha256').update(body).digest('hex')
const canonical = ['UFLOW-HMAC-SHA256', timestamp, nonce, 'POST', '/api/v1/merchant/payment-orders', '', bodyHash].join('\n')
const signature = crypto.createHmac('sha256', process.env.UFLOW_SECRET).update(canonical).digest('hex')
$body = json_encode([
'merchant_order_no' => 'ORD-10001',
'amount_atomic' => '128500000',
'asset_code' => 'USDT',
'network_code' => 'TRON',
], JSON_UNESCAPED_SLASHES);
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));
$bodyHash = hash('sha256', $body);
$canonical = implode("\n", ['UFLOW-HMAC-SHA256', $timestamp, $nonce, 'POST', '/api/v1/merchant/payment-orders', '', $bodyHash]);
$signature = hash_hmac('sha256', $canonical, getenv('UFLOW_SECRET'));
import hashlib, hmac, json, os, time, uuid
body = json.dumps({
"merchant_order_no": "ORD-10001",
"amount_atomic": "128500000",
"asset_code": "USDT",
"network_code": "TRON"
}, separators=(",", ":"))
timestamp = str(int(time.time()))
nonce = str(uuid.uuid4())
body_hash = hashlib.sha256(body.encode()).hexdigest()
canonical = "\n".join(["UFLOW-HMAC-SHA256", timestamp, nonce, "POST", "/api/v1/merchant/payment-orders", "", body_hash])
signature = hmac.new(os.environ["UFLOW_SECRET"].encode(), canonical.encode(), hashlib.sha256).hexdigest()
const received = req.rawBody
const delivered = req.header('X-UFlow-Signature')
const timestamp = req.header('X-UFlow-Timestamp')
const eventId = req.header('X-UFlow-Event-Id')
const expected = hmacSha256Hex(webhookSecret, timestamp + '\n' + eventId + '\n' + sha256(received))
timingSafeEqual(delivered, expected)
await idempotentHandle(eventId, JSON.parse(received))
审核开通后,商户可在开发者中心创建 API Key、配置 Webhook、复制 SDK 示例,并使用 Sandbox 模拟器验证收款闭环。