概述

TinyDataPay 是一个聚合支付网关,提供统一接口同时支持法币(支付宝 / 微信)与虚拟货币(TRX / USDT)收款。

对接信息

项目说明
API 基地址https://pay.tinydata.cc
商户密钥 safe_key由管理员分配,用于参数签名
签名算法MD5(参数排序 + 拼接密钥)

支付方式

类型pay_type说明
支付宝ALIPAY扫码支付
微信支付WXPAY扫码支付
TRXTRX波场链转账
USDTUSDTTRC20 稳定币

对接流程

商户系统 TinyDataPay 用户 │ │ │ │ 1. POST /payment/create │ │ │ ────────────────────────> │ │ │ payment_url │ │ │ <──────────────────────── │ │ │ │ │ │ 2. 跳转 payment_url │ │ │ ──────────────────────────────────────────────────────> │ │ │ 3. 选择支付方式 & 付款 │ │ │ <───────────────────────── │ │ │ │ │ 4. 回调 notify_url (验签) │ │ │ <──────────────────────── │ │ │ 返回 "success" │ │ │ ────────────────────────> │ │
  1. 商户后端调用 /payment/create 创建订单,获取 payment_url
  2. 将用户浏览器跳转到 payment_url,由用户选择支付方式并完成付款
  3. 支付成功后,系统向商户的 notify_url 发起异步回调
  4. 商户验签后处理业务逻辑,返回纯文本 success

创建订单

POST /api/v1/payment/create
Content-Type: application/json

请求参数

参数说明
merchant_order_id必填商户订单号(唯一)
amount必填订单金额,字符串,如 "10.00"
currency必填CNYUSD
product_name必填商品名称
notify_url可选异步回调地址
redirect_url可选支付完成后跳转地址
sign必填参数签名

响应示例

{
  "code": 0,
  "message": "成功",
  "data": {
    "order_no": "PAY20260522120000123456",
    "amount": "10.00",
    "currency": "CNY",
    "payment_url": "https://pay.tinydata.cc/payment/select?order_no=PAY...",
    "expired_at": "2026-05-22 12:30:00"
  }
}

查询订单

GET /api/v1/payment/status?order_no=PAY20260522120000123456

响应示例

{
  "code": 0,
  "message": "成功",
  "data": {
    "order_no": "PAY20260522120000123456",
    "amount": "10.00",
    "status": "paid",
    "pay_type": "ALIPAY"
  }
}

订单状态

status说明
pending待支付(用户未选择支付方式)
paying支付中(已发起支付)
paid已支付
expired已过期(30 分钟未支付)
failed支付失败

异步回调

支付成功后,系统以 GET 方式请求商户的 notify_url,参数附在 URL 上。

GET https://your-site.com/callback
    ?order_no=PAY20260522120000123456
    &merchant_order_id=YOUR_ORDER_001
    &amount=10.00
    &status=paid
    &pay_type=ALIPAY
    &sign=ABCDEF1234567890...

回调参数

参数说明
order_no系统订单号
merchant_order_id商户订单号
amount订单金额
statuspaid
pay_type实际支付方式
sign参数签名(必须验证)
处理要求:验证签名 · 校验金额 · 幂等处理(同一订单可能收到多次回调)· 成功时返回纯文本 success,失败返回 fail

签名算法

所有请求参数(除 sign 与空值)按 key 的 ASCII 升序排列,拼接为 URL 编码格式后追加 &key={safe_key},对整体做 MD5 并转大写。

步骤

  1. 过滤掉 sign 字段和值为空的参数
  2. 按 key 的 ASCII 升序排序
  3. 拼接为 key1=value1&key2=value2&...&key={safe_key}
  4. 对拼接后的字符串做 MD5,结果转大写

示例

假设 safe_key = "your_key",参数:

amount=10.00
currency=CNY
merchant_order_id=ORDER001
product_name=测试商品

签名字符串:

amount=10.00¤cy=CNY&merchant_order_id=ORDER001&product_name=测试商品&key=your_key

MD5 之后转大写即得 sign

完整接入示例

官方提供 Go / Python / Node.js 三个语言的 SDK,已封装签名生成、订单创建、回调验签。

import (
    "fmt"
    "net/http"
    "time"
    tinydatapay "your-project/sdk/go"
)

func main() {
    client := tinydatapay.NewClient("https://pay.tinydata.cc", "your_safe_key")

    // 1. 创建订单
    resp, _ := client.CreateOrder(&tinydatapay.OrderRequest{
        MerchantOrderID: fmt.Sprintf("ORDER%d", time.Now().Unix()),
        Amount:          "10.00",
        Currency:        "CNY",
        ProductName:     "会员充值",
        NotifyURL:       "https://your-site.com/pay/callback",
        RedirectURL:     "https://your-site.com/pay/success",
    })
    fmt.Println("支付链接:", resp.Data.PaymentURL)

    // 2. 处理异步回调(自动验签)
    http.HandleFunc("/pay/callback", client.HandleCallback(func(data *tinydatapay.CallbackData) error {
        if data.Status == "paid" {
            // TODO: 更新订单 / 发放商品(注意幂等)
        }
        return nil
    }))
    http.ListenAndServe(":8080", nil)
}
from tinydatapay import TinyDataPay
from flask import Flask, request
import time

client = TinyDataPay("https://pay.tinydata.cc", "your_safe_key")

# 1. 创建订单
order = client.create_order(
    merchant_order_id=f"ORDER{int(time.time())}",
    amount="10.00",
    currency="CNY",
    product_name="会员充值",
    notify_url="https://your-site.com/pay/callback",
    redirect_url="https://your-site.com/pay/success",
)
print("支付链接:", order["payment_url"])

# 2. Flask 回调
app = Flask(__name__)

@app.route("/pay/callback")
def callback():
    try:
        data = client.parse_callback(dict(request.args))
        if data["status"] == "paid":
            # TODO: 更新订单 / 发放商品(注意幂等)
            pass
        return "success"
    except Exception as e:
        return "fail"
const TinyDataPay = require("./tinydatapay");
const express = require("express");

const client = new TinyDataPay("https://pay.tinydata.cc", "your_safe_key");

// 1. 创建订单
const order = await client.createOrder({
    merchantOrderId: `ORDER${Date.now()}`,
    amount: "10.00",
    currency: "CNY",
    productName: "会员充值",
    notifyUrl: "https://your-site.com/pay/callback",
    redirectUrl: "https://your-site.com/pay/success",
});
console.log("支付链接:", order.payment_url);

// 2. Express 回调
const app = express();
app.get("/pay/callback", client.callbackHandler(async (data) => {
    if (data.status === "paid") {
        // TODO: 更新订单 / 发放商品(注意幂等)
    }
}));
app.listen(8080);

常见问题

未收到回调?

  • 检查 notify_url 是否可被公网访问
  • 检查商户服务器防火墙是否放行 TinyDataPay 出口 IP
  • 商户也可通过查询接口主动轮询订单状态

签名验证失败?

  • 确认 safe_key 正确,未泄漏
  • 注意空值参数不参与签名
  • 参数排序按 key 的 ASCII 升序,区分大小写

订单超时?

  • 订单有效期 30 分钟,过期需重新创建

多次收到同一订单回调?

  • 属于正常重试机制,商户系统需自行做幂等处理