创建订单
| 字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|---|
| 应用ID | app_id | 是 | String | app_9ba59abbe56e057f20f | 由易码付平台生成的应用ID,全局唯一。 |
| 商户订单号 | out_trade_no | 是 | String | 1217752501201407 | 商户系统内部订单号,由数字、大小写字母_-*组成,且在同一个商户号下唯一 |
| 支付方式 | pay_type | 是 | Int | 20 | 支付方式,固定选择值: 20:微信扫码支付(用户主扫) 21:微信APP支付 22:微信JSAPI(适用于公众号或小程序) 30:支付宝扫码支付(用户主扫) 31:支付宝APP支付 40:快捷支付(扫码) 50:H5跳转微信小程序支付 |
| 商品描述 | description | 是 | String | 苹果13Pro | 商品描述 签名时无需转码,为避免中文乱码,传递时使用UrlEncode(UTF-8)编码,可参考编码/解码工具 |
| 订单金额 | amount | 是 | Int | 100 | 订单金额,单位为分,1元等于100分 |
| 客户端IP | client_ip | 是 | String | 127.0.0.1 | 发起支付请求客户端的 IP地址 |
| 通知地址 | notify_url | 是 | String | http://api.qdoto.com/transactions/notify.html | 通知URL必须为直接可访问的URL,不能携带查询串 |
| 签名串 | sign | 是 | String | e10adc3949ba59abbe56e057f20f883e | 待签名字符串进行MD5加密得出的32位签名值,参考签名规则 |
| 订单超时时长 | time_expire | 否 | Int | 60 | 单位为分钟,取值为1-21600 |
| 附加参数 | attach | 否 | String | {"userId":888,"level":3}(编码后:%7B%22userId%22%3A888%2C%22level%22%3A3%7D) | 附加数据,推荐JSON格式,在查询订单和支付通知中原样返回,可作为自定义参数使用。 签名时无需转码,传递时使用UrlEncode(UTF-8)编码,可参考编码/解码工具 |
| 用户openid | openid | 否 | String | oZwt6wvYaXMHC1mBJ0Ek0y1uU | 微信JSAPI必传,其他部分渠道需要使用openid的,详情可询问客服 |
| 分账标识 | split | 否 | Int | 1 | 1:分账 0:不分账 默认为0 |
| 支付扩展参数 | pay_extra | 否 | String | JSON格式 | 根据不同渠道的需要进行传递,详情请咨询技术人员 |
举例如下:
{BASE_URL}/v1/transactions/order.html?app_id=app_9ba59abbe56e057f20f&out_trade_no=1217752501201407&pay_type=20&description=%E8%8B%B9%E6%9E%9C13Pro&client_ip=127.0.0.1¬ify_url=http://api.qdoto.com/transactions/notify.html&time_expire=60&attach={"userId":888,"level":3}&sign=e10adc3949ba59abbe56e057f20f883e
| 字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|---|
| 业务状态码 | resultCode | 是 | Int | 200 | 200/201/500 此字段是业务标识状态码,200代表业务处理成功,并成功返回 |
| 业务状态描述 | message | 是 | String | 成功 | 当resultCode非200时返回信息为错误原因 ,例如 app_id错误或不存在 |
| 数据集 | Data | 否 | String | - | 当resultCode为200时,数据会装入该字段一并返回 |
| out_trade_no | 是 | String | 1217752501201407 | Data内的字段:商户订单号 | |
| trade_no | 是 | String | YH2307190011178361713 | Data内的字段:平台订单号 | |
| body | 是 | String | https://qr.alipay.com/bax04775wixee8ieymjz00d8 | Data内的字段:支付凭证,用于客户端发起支付。 扫码支付时为二维码链接,将此链接转换成二维码呈现,供用户扫码付款。 APP支付或JSAPI支付时,为客户端调起支付的凭据(JSON格式,具体凭据可参考微信支付宝官方文档)。 |
|
| channel | 是 | String | wx_qr | Data内的字段:支付渠道编码,如: wx_app:微信官方APP支付 fuyou_wx_app:富友微信APP支付 alipay_qr:支付宝官方扫码支付 不同渠道的body数据不一致,建议根据channel的值,来处理body里的数据 |
举例如下:
如:channel=alipay_qr时
{
"resultCode": 200,
"message": "成功",
"Data": {
"out_trade_no": "1217752501201407",
"trade_no": "YH2307190011178361713",
"channel": "alipay_qr",
"body": "https://qr.alipay.com/bax04775wixee8ieymjz00d8"
}
}
如:channel=wx_jsapi时
{
"resultCode": 200,
"message": "成功",
"Data": {
"out_trade_no": "1217752501201407",
"trade_no": "YH2307190011178361713",
"channel": "wx_jsapi",
"body": "{\"timeStamp\":\"1705286208\",\"signType\":\"RSA\",\"package\":\"prepay_id=wx151036489648973c12c386b755d62a0000\",\"paySign\":\"CV0aZEwXBiHg4mk+WF5DJ9t6r7+9wgp8hkbs+0jkYhRygwAhfy+1XjQLmc0XHcBr6VuXvoQcrpDr6EVw157ngbHcflZeN0TfXz0wVMoGmNJJyL5tA3IXbECX3MBTI5oWclzWc0yaWNQrJ19JPm1tAa1hSBlGpZLtS7octAUP00qVDNkfb4UFTdQvcj+tq0uC3Wd/OsZsdXNTCM/caGzC3K4R+/l5Akwz+yzEBYlmpZ8AHc67bnIV9sEFRWMYEtEodyg62uJ8PXFSOhthJfqQ+G+NoVlY7WXTvgSTby7j3vANl+txqODBY57oh2Br6kadr0eipZYHyaCz8oavAZOsWg==\",\"nonceStr\":\"1705286208306\",\"appId\":\"wx6c380e0eda7c6c71\"}",
}
}
# 创建订单
curl -X POST "{BASE_URL}/v1/transactions/order.html" \
-d "app_id={YOUR_APP_ID}" \
-d "pay_type=1" \
-d "out_trade_no=20240101123456" \
-d "description=%E8%8B%B9%E6%9E%9C13Pro" \
-d "amount=100" \
-d "client_ip=127.0.0.1" \
-d "notify_url=https://merchant.com/notify" \
-d "sign=E10ADC3949BA59ABBE56E057F20F883E"
<?php
$appId = '{YOUR_APP_ID}';
$apiKey = '{YOUR_API_KEY}';
$params = [
'app_id' => $appId,
'pay_type' => '1',
'out_trade_no'=> '20240101123456',
'description' => urlencode('苹果13Pro'),
'amount' => '100',
'client_ip' => '127.0.0.1',
'notify_url' => 'https://merchant.com/notify',
];
// 签名:参数按key ASCII排序,拼接后追加key,MD5大写
ksort($params);
$signStr = urldecode(http_build_query($params)) . '&key=' . $apiKey;
$params['sign'] = strtoupper(md5($signStr));
$ch = curl_init('{BASE_URL}/v1/transactions/order.html');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$response = json_decode($result, true);
print_r($response);
import hashlib
import requests
from urllib.parse import urlencode, quote
app_id = '{YOUR_APP_ID}'
api_key = '{YOUR_API_KEY}'
params = {
'app_id': app_id,
'pay_type': '1',
'out_trade_no': '20240101123456',
'description': quote('苹果13Pro'),
'amount': '100',
'client_ip': '127.0.0.1',
'notify_url': 'https://merchant.com/notify',
}
# 签名:参数按key ASCII排序,拼接后追加key,MD5大写
sorted_keys = sorted(params.keys())
sign_str = '&'.join(f'{k}={params[k]}' for k in sorted_keys) + '&key=' + api_key
params['sign'] = hashlib.md5(sign_str.encode()).hexdigest().upper()
resp = requests.post('{BASE_URL}/v1/transactions/order.html', data=params)
print(resp.json())
import java.io.*;
import java.net.*;
import java.security.MessageDigest;
import java.util.*;
public class CreateOrder {
public static void main(String[] args) throws Exception {
String appId = "{YOUR_APP_ID}";
String apiKey = "{YOUR_API_KEY}";
Map<String, String> params = new TreeMap<>();
params.put("app_id", appId);
params.put("pay_type", "1");
params.put("out_trade_no", "20240101123456");
params.put("description", URLEncoder.encode("苹果13Pro", "UTF-8"));
params.put("amount", "100");
params.put("client_ip", "127.0.0.1");
params.put("notify_url", "https://merchant.com/notify");
// 签名
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> e : params.entrySet())
sb.append(e.getKey()).append("=").append(e.getValue()).append("&");
sb.append("key=").append(apiKey);
String sign = md5(sb.toString()).toUpperCase();
params.put("sign", sign);
// 发送POST请求
String result = doPost("{BASE_URL}/v1/transactions/order.html", params);
System.out.println(result);
}
static String md5(String s) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(s.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte b : digest) sb.append(String.format("%02x", b));
return sb.toString();
}
static String doPost(String url, Map<String, String> params) throws Exception {
StringBuilder body = new StringBuilder();
for (Map.Entry<String, String> e : params.entrySet())
body.append(URLEncoder.encode(e.getKey(), "UTF-8"))
.append("=").append(URLEncoder.encode(e.getValue(), "UTF-8")).append("&");
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.getOutputStream().write(body.toString().getBytes("UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
StringBuilder resp = new StringBuilder();
String line; while ((line = br.readLine()) != null) resp.append(line);
return resp.toString();
}
}
const crypto = require('crypto');
const axios = require('axios');
const querystring = require('querystring');
const appId = '{YOUR_APP_ID}';
const apiKey = '{YOUR_API_KEY}';
const params = {
app_id: appId,
pay_type: '1',
out_trade_no: '20240101123456',
description: encodeURIComponent('苹果13Pro'),
amount: '100',
client_ip: '127.0.0.1',
notify_url: 'https://merchant.com/notify',
};
// 签名
const sortedKeys = Object.keys(params).sort();
const signStr = sortedKeys.map(k => `=`).join('&') + '&key=' + apiKey;
params.sign = crypto.createHash('md5').update(signStr).digest('hex').toUpperCase();
axios.post('{BASE_URL}/v1/transactions/order.html', querystring.stringify(params))
.then(res => console.log(res.data));
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
var appId = "{YOUR_APP_ID}";
var apiKey = "{YOUR_API_KEY}";
var paramList = new List<KeyValuePair<string, string>> {
new("app_id", appId),
new("pay_type", "1"),
new("out_trade_no", "20240101123456"),
new("description", Uri.EscapeDataString("苹果13Pro")),
new("amount", "100"),
new("client_ip", "127.0.0.1"),
new("notify_url", "https://merchant.com/notify"),
};
paramList.Sort((a, b) => string.Compare(a.Key, b.Key, StringComparison.Ordinal));
var signStr = string.Join("&", paramList.Select(p => $"{p.Key}={p.Value}")) + "&key=" + apiKey;
using var md5 = MD5.Create();
var sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(signStr))).Replace("-","").ToUpper();
paramList.Add(new("sign", sign));
using var client = new HttpClient();
var resp = await client.PostAsync("{BASE_URL}/v1/transactions/order.html", new FormUrlEncodedContent(paramList));
Console.WriteLine(await resp.Content.ReadAsStringAsync());
package main
import (
"crypto/md5"
"fmt"
"io"
"net/http"
"net/url"
"sort"
"strings"
)
func main() {
appId := "{YOUR_APP_ID}"
apiKey := "{YOUR_API_KEY}"
params := url.Values{}
params.Set("app_id", appId)
params.Set("pay_type", "1")
params.Set("out_trade_no", "20240101123456")
params.Set("description", url.QueryEscape("苹果13Pro"))
params.Set("amount", "100")
params.Set("client_ip", "127.0.0.1")
params.Set("notify_url", "https://merchant.com/notify")
// 签名
keys := make([]string, 0)
for k := range params { keys = append(keys, k) }
sort.Strings(keys)
var parts []string
for _, k := range keys { parts = append(parts, k+"="+params.Get(k)) }
signStr := strings.Join(parts, "&") + "&key=" + apiKey
sign := fmt.Sprintf("%X", md5.Sum([]byte(signStr)))
params.Set("sign", sign)
resp, _ := http.PostForm("{BASE_URL}/v1/transactions/order.html", params)
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}