代收下单接口
接口路径: /alliesPay/bussiness/order
请求方式: POST
Content-Type: application/x-www-form-urlencoded 或 application/json(两种均支持)
提交方式
本接口支持表单提交和 JSON 提交两种方式,业务参数和签名规则完全一致。详见 旧版 API 概览 - 提交方式说明。
一、请求参数
| 参数名称 | 参数变量名 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| 签名 | sign | String | 是 | 按签名规则(MD5) |
| 友商编号 | alliesNo | String(32) | 是 | 接入方友商的唯一 ID,由平台方提供 |
| 订单号 | tradeNo | String(50) | 是 | 友商系统订单唯一编号 |
| 订单金额 | totalAmount | Number(9,2) | 是 | 订单总金额以元为单位,精确到小数点后两位。例如:10000.22 |
| 支付方式 | tradeType | int | 是 | 支付通道编码,如 31 |
| 客户IP | clientIp | String(20) | 否 | 支付用户 IP |
| 商品名称 | productName | String(100) | 否 | 商品名称 |
| 附加参数 | attach | String(100) | 否 | 附加参数(原样返回) |
| 前台跳转地址 | frontNotifyUrl | String(128) | 是 | 支付完成后前端显示地址 |
| 异步回调地址 | noticeUrl | String(128) | 是 | 支付成功后,异步返回订单情况的接入方提供的接口回调地址 |
| 付款人姓名 | payerName | String(32) | 否 | 订单付款人名称 |
| 附言 | remark | String(132) | 否 | 下单人备注信息 |
| 付款人手机号 | payerPhone | String(20) | 否 | 下单人手机号 |
| 产品ID | productId | Int | 是 | 默认填 310,详情请查看开户资料或咨询客服 |
请求示例
表单提交:
bash
curl -X POST "http://接口域名/alliesPay/bussiness/order" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "alliesNo=test001&tradeNo=ORDER20250115001&totalAmount=100.00&tradeType=31¬iceUrl=https://example.com/notify&frontNotifyUrl=https://example.com/return&productId=310&sign=3E541783111209F709ACDA0F4BFD17EA"JSON 提交:
bash
curl -X POST "http://接口域名/alliesPay/bussiness/order" \
-H "Content-Type: application/json" \
-d '{
"alliesNo": "test001",
"tradeNo": "ORDER20250115001",
"totalAmount": "100.00",
"tradeType": "31",
"productId": "310",
"noticeUrl": "https://example.com/notify",
"frontNotifyUrl": "https://example.com/return",
"clientIp": "127.0.0.1",
"payerName": "张三",
"remark": "测试订单",
"sign": "3E541783111209F709ACDA0F4BFD17EA"
}'PHP 请求示例:
php
<?php
$params = [
'alliesNo' => 'test001',
'tradeNo' => 'ORDER' . date('YmdHis') . mt_rand(1000, 9999),
'totalAmount' => '100.00',
'tradeType' => '31',
'productId' => '310',
'noticeUrl' => 'https://example.com/notify',
'frontNotifyUrl' => 'https://example.com/return',
'clientIp' => $_SERVER['REMOTE_ADDR'],
'payerName' => '张三',
'remark' => '测试订单',
];
// 排除空值和sign,按ASCII字典序排序
$filteredParams = [];
foreach ($params as $k => $v) {
if ($v !== '' && $v !== null) {
$filteredParams[$k] = $v;
}
}
ksort($filteredParams);
$stringA = http_build_query($filteredParams, '', '&');
// 拼接密钥并生成签名
$key = 'your_api_key_here';
$sign = strtoupper(md5($stringA . '&key=' . $key));
$params['sign'] = $sign;
// 发送请求(表单提交)
$ch = curl_init('http://接口域名/alliesPay/bussiness/order');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if ($result['code'] === '10000') {
// 跳转至支付链接
header('Location: ' . $result['payUrl']);
exit;
}JSON 提交方式(PHP)
php
<?php
// 生成签名同上($params['sign'] = $sign)
// 发送请求(JSON 提交)
$ch = curl_init('http://接口域名/alliesPay/bussiness/order');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);Java 请求示例:
java
import java.util.*;
import java.security.MessageDigest;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class PaymentDemo {
public static void main(String[] args) throws Exception {
Map<String, String> params = new TreeMap<>();
params.put("alliesNo", "test001");
params.put("tradeNo", "ORDER" + System.currentTimeMillis());
params.put("totalAmount", "100.00");
params.put("tradeType", "31");
params.put("productId", "310");
params.put("noticeUrl", "https://example.com/notify");
params.put("frontNotifyUrl", "https://example.com/return");
params.put("clientIp", "127.0.0.1");
params.put("payerName", "张三");
params.put("remark", "测试订单");
// 排除空值和sign,按ASCII字典序排序(TreeMap已自动排序)
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() != null && !entry.getValue().isEmpty()) {
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8")).append("&");
}
}
sb.deleteCharAt(sb.length() - 1);
// 拼接密钥并生成签名
String key = "your_api_key_here";
String signStr = sb.toString() + "&key=" + key;
String sign = md5(signStr).toUpperCase();
params.put("sign", sign);
// 发送请求...
}
private static String md5(String input) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}二、响应参数
| 参数名称 | 参数变量名 | 类型 | 是否有值 | 是否参与加密 | 说明 |
|---|---|---|---|---|---|
| 返回码 | code | String(10) | 是 | 否 | 编码为 10000 成功,其他为失败 |
| 返回消息 | msg | String(128) | 是 | 否 | 订单成功失败的详细信息 |
| 交易号 | tradeNo | String(50) | 是 | 是 | 请求下单的订单号 |
| 支付 url | payUrl | String(128) | 是 | 是 | 返回支付地址 |
| 平台单号 | outTradeNo | String(32) | 是 | 是 | 平台生成返回的唯一单号 |
| 银行卡号 | bankCard | String(128) | 是 | 是 | 收款卡号 |
| 银行名称 | bankName | String(128) | 是 | 是 | 收款银行/通道名称 |
| 银行户主名称 | bankAccount | String(128) | 是 | 是 | 收款账户姓名 |
| 支行地址 | bankAddress | String(128) | 是 | 否 | 例:北京支行 |
| 签名 | sign | String | 是 | 否 | 按签名规则(MD5) |
成功响应示例
json
{
"code": "10000",
"msg": "成功",
"tradeNo": "ORDER20250115001",
"payUrl": "https://pay.example.com/pay?token=xxx",
"outTradeNo": "PO20250115001001",
"bankCard": "6222xxxxxxxx1234",
"bankName": "建设银行",
"bankAccount": "张某某",
"bankAddress": "北京支行",
"sign": "3E541783111209F709ACDA0F4BFD17EA"
}失败响应示例
json
{
"code": "2010",
"msg": "签名错误"
}六、注意事项
- 订单号唯一性:
tradeNo必须全局唯一,建议使用时间戳 + 随机数 - 金额格式:必须保留两位小数,如
100.00 - 回调地址:
noticeUrl必须是公网可访问的 URL,用于接收支付结果通知 - 前台跳转地址:
frontNotifyUrl是用户完成支付后前端跳转的地址 - 签名验证:回调数据需要验证签名确保数据安全性
- 支付方式:
tradeType需要根据实际支持的通道类型填写
七、错误码说明
| 代码 | 描述 | 说明 |
|---|---|---|
| 10000 | Success | 处理成功 |
| 1001 | Unable to find user | alliesNo 错误,商户不存在 |
| 1002 | Merchant forbidden | 商户未开启代收功能,请联系客服 |
| 1003 | Amount exceeds limit | 金额超出商户限额(最小/最大) |
| 1004 | Channel amount limit | 金额超出通道限额(最小/最大) |
| 1005 | ProductID not supported | 该商户不支持此产品ID |
| 1008 | IP whitelist not configured | 请联系管理员配置IP白名单 |
| 2004 | Merchant null | alliesNo 参数为空或无效 |
| 2005 | Amount null | 订单金额为空或无效 |
| 2006 | TradeNo null | 订单号为空 |
| 2007 | NoticeUrl null | 回调地址为空 |
| 2008 | TradeNo already exists | 订单号已存在,请更换 |
| 2009 | PayType null | 支付方式 tradeType 为空 |
| 2010 | Sign Fail | 签名校验失败 |
| 2011 | Order creation failed | 订单创建失败,请重试 |
| 2017 | Channel unauthorized | 通道未配置或未授权 |
| 8001 | Order request too frequent | 下单请求过于频繁,请3秒后重试 |
| 9999 | Channel close / System error | 通道关闭或系统异常 |
