Files
PayPro/OPEN_API.md
2026-03-04 14:39:47 +08:00

6.5 KiB
Raw Permalink Blame History

外部订单接口文档

接口概述

该接口用于外部系统向支付系统添加订单支持MD5签名验证、时间戳校验、事务处理等功能。

接口信息

  • 接口路径: POST /api/openapi/add
  • 请求方法: POST
  • Content-Type: application/json

请求参数

参数名 类型 必填 说明
orderNo String 订单号,唯一标识
amount BigDecimal 订单金额必须大于0且小于等于100000
payType String 支付方式alipay/wechat/alipay_dmf/wechat_zs
nickName String 用户昵称
description String 订单描述
email String 用户邮箱
notifyUrl String 异步通知地址
userId String 用户ID
productId Long 产品ID
timestamp Long 请求时间戳毫秒有效期5分钟
expireSeconds Integer 过期时间(秒),订单将在该时间后过期
sign String MD5签名

签名算法

  1. 将所有参数除sign外按字母顺序排序
  2. 拼接成 key1=value1&key2=value2&...&key=secretKey 格式
  3. 对拼接后的字符串进行MD5加密并转为大写

签名示例

假设配置的密钥为:your_openapi_secret_key_here

参数:

{
  "orderNo": "EXT20250303001",
  "amount": 10.00,
  "payType": "alipay",
  "timestamp": 1733232000000
}

排序后的参数:

amount=10.00&orderNo=EXT20250303001&payType=alipay&timestamp=1733232000000&key=your_openapi_secret_key_here

MD5签名XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

响应格式

成功响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "orderNo": "EXT20250303001",
    "amount": 10.00,
    "payType": "alipay",
    "payNum": "随机支付标识",
    "state": 0,
    "message": "订单创建成功",
    "timestamp": 1733232000000,
    "qrCodeUrl": "支付二维码URL",
    "returnUrl": "支付完成返回URL"
  }
}

返回值说明

字段名 类型 说明
orderNo String 外部订单号
amount BigDecimal 订单金额
payType String 支付方式alipay/wechat/alipay_dmf/wechat_zs
payNum String 支付标识,用于后续查询订单
state Integer 订单状态0-待支付1-已支付2-已失败3-已支付4-已扫码)
message String 处理结果消息
timestamp Long 系统处理完成时间戳(毫秒)
qrCodeUrl String 支付二维码URL用于展示支付二维码
returnUrl String 跳转url可以跳转至改地址进行后续处理

失败响应

{
  "code": 400,
  "msg": "错误信息描述",
  "data": null
}

错误码说明

错误码 说明
200 成功
400 参数错误
401 签名验证失败
402 时间戳无效或已过期
403 订单号已存在
404 金额错误
500 系统内部异常

请求示例

cURL 示例

curl -X POST http://localhost:8892/api/openapi/add \
  -H "Content-Type: application/json" \
  -d '{
    "orderNo": "EXT20250303001",
    "amount": 10.00,
    "payType": "alipay",
    "nickName": "测试用户",
    "description": "测试订单",
    "email": "test@example.com",
    "userId": "USER001",
    "productId": 1,
    "notifyUrl": "http://example.com/notify",
    "timestamp": 1733232000000,
    "expireSeconds": 3600,
    "sign": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  }'

Java 示例

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.crypto.SecureUtil;

public class ExternalOrderClient {

    private static final String API_URL = "http://localhost:8892/api/openapi/add";
    private static final String SECRET_KEY = "your_openapi_secret_key_here";

    public static void main(String[] args) {
        JSONObject params = new JSONObject();
        params.put("orderNo", "EXT20250303001");
        params.put("amount", 10.00);
        params.put("payType", "alipay");
        params.put("nickName", "测试用户");
        params.put("description", "测试订单");
        params.put("email", "test@example.com");
        params.put("userId", "USER001");
        params.put("productId", 1);
        params.put("notifyUrl", "http://example.com/notify");
        params.put("timestamp", System.currentTimeMillis());
        params.put("expireSeconds", 3600); // 过期时间为1小时

        String sign = generateSign(params);
        params.put("sign", sign);

        String response = HttpRequest.post(API_URL)
                .header("Content-Type", "application/json")
                .body(params.toString())
                .execute()
                .body();

        System.out.println(response);
    }

    private static String generateSign(JSONObject params) {
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);

        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            Object value = params.get(key);
            if (value != null && !"".equals(value) && !"sign".equals(key)) {
                sb.append(key).append("=").append(value).append("&");
            }
        }
        sb.append("key=").append(SECRET_KEY);

        return SecureUtil.md5(sb.toString()).toUpperCase();
    }
}

配置说明

application.yml 中配置外部接口密钥:

paypro:
  openapi:
    secret: your_openapi_secret_key_here

安全特性

  1. MD5签名验证:确保请求参数未被篡改
  2. 时间戳校验防止重放攻击时间戳有效期5分钟
  3. 订单号唯一性:防止重复订单
  4. 金额限制单笔订单金额不超过100000元
  5. 事务处理:确保订单创建的原子性

注意事项

  1. 请妥善保管密钥,不要泄露给第三方
  2. 时间戳必须使用毫秒级时间戳
  3. 订单号必须唯一,重复的订单号会返回错误
  4. 建议在生产环境中使用HTTPS协议
  5. 建议实现IP白名单等额外的安全措施

测试页面

访问 http://localhost:8889/open-api-test.html 可以使用测试页面进行接口测试。