Appearance
支付接口文档
协议规则
提交数据格式:application/x-www-form-urlencoded
返回数据格式:JSON
字符编码:UTF-8
签名算法:SHA256WithRSA
获取RSA密钥对
登录商户后台 -> 进入用户中心 -> API密钥 -> 点击V2接口的用户RSA公钥重置按钮 -> 获取RSA密钥对
注意事项
- 商户私钥(private key)需妥善保管,避免遗失,不要泄露。
- 平台公钥(public key)用于接口返回数据、异步通知回调数据的验签。
- 具体发起支付相关流程的示例代码可下载SDK查看
签名规则
签名算法:SHA256WithRSA
签名步骤:
对于向平台发起的请求,签名步骤如下:
- 将请求参数按照参数名的ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
- 把商户私钥用PKCS8格式转换为PKCS1格式。
- 把stringA用商户私钥进行SHA256WithRSA算法签名,生成签名sign。
验签步骤:
对于平台接口返回的数据,验签步骤如下:
- 将返回参数按照参数名的ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringB。
- 把平台公钥用PKCS8格式转换为PKCS1格式。
- 把stringB用平台公钥进行SHA256WithRSA算法验签,验证签名sign是否正确。
签名示例:
php
// 假设请求参数如下:
$params = [
'merchant_id' => '123456',
'timestamp' => '2023-05-10 12:34:56',
'nonce_str' => 'abcdefg',
'sign_type' => 'RSA',
'sign' => '...' // 签名结果
];
// 按照参数名的ASCII码从小到大排序,拼接成字符串stringA
ksort($data);
$stringA = '';
foreach($data as $k => $v) {
if(is_array($v) || $this->isEmpty($v) || $k == 'sign' || $k == 'sign_type') {
continue;
}
$stringA .= '&' . $k . '=' . $v;
}
$stringA = substr($stringA, 1);
// 假设商户私钥为:
$privateKey = '-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----';
// 把商户私钥用PKCS8格式转换为PKCS1格式
$privateKey = openssl_pkey_get_private($privateKey);
// 把stringA用商户私钥进行SHA256WithRSA算法签名,生成签名sign
openssl_sign($stringA, $sign, $privateKey, OPENSSL_ALGO_SHA256);
// 把签名结果转换为Base64编码
$sign = base64_encode($sign);
// 把签名结果添加到请求参数中
$params['sign'] = $sign;php
// 假设平台返回的数据如下:
$data = [
'merchant_id' => '123456',
'timestamp' => '2023-05-10 12:34:56',
'nonce_str' => 'abcdefg',
'sign_type' => 'RSA',
'sign' => '...' // 签名结果
];
// 按照参数名的ASCII码从小到大排序,拼接成字符串stringB
ksort($params);
$stringB = '';
foreach ($params as $k => $v) {
if(is_array($v) || $this->isEmpty($v) || $k == 'sign' || $k == 'sign_type') continue;
$stringB .= '&' . $k . '=' . $v;
}
$stringB = substr($stringB, 1);
// 假设平台公钥为:
$publicKey = '-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----';
// 把平台公钥用PKCS8格式转换为PKCS1格式
$publicKey = openssl_pkey_get_public($publicKey);
// 把stringB用平台公钥进行SHA256WithRSA算法验签,验证签名sign是否正确
openssl_verify($stringB, base64_decode($data['sign']), $publicKey, OPENSSL_ALGO_SHA256);
// 如果验签结果为true,则说明签名正确,否则说明签名错误。支付接口
统一下单接口
接口地址:https://api.9py.cn/api/pay/create
接口说明:用于创建支付订单, 并返回支付参数。
请求方式:POST
请求参数:
| 字段名 | 变量名 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|
| 商户号 | pid | string | 商户号 | |
| 订单号 | out_trade_no | string | 商户订单号 | |
| 订单金额 | amount | int | 订单金额,单位为分 | |
| 商品名称 | subject | string | 商品名称 | |
| 用户IP地址 | client_ip | string | 用户发起支付的IP地址 | |
| 附加数据 | extra | string | 附加数据,业务扩展参数 | |
| 支付方式 | pay_type | string | 支付方式 | |
| 设备类型 | device | string | 设备类型,仅pay_type为web时需要传 | |
| 支付平台 | payment_gateway | string | 支付平台(alipay/wxpay/qqpay) | |
| 异步通知地址 | notify_url | string | 异步通知地址 | |
| 同步通知地址 | return_url | string | 同步通知地址 | |
| 取消支付跳转地址 | quit_url | string | 取消支付跳转地址,当pay_type为jump时可填,例如手机网站调取支付 | |
| 被扫支付授权码 | auth_code | string | 被扫支付授权码 | |
| 用户openid | sub_openid | string | 当pay_type为wxpay时填,当pay_type为jsapi时填 | |
| 公众号AppId | sub_appid | string | 当pay_type为wxpay时填,当pay_type为jsapi时填 | |
| 签名字符串 | sign | string | 签名,用于验证一致性 | |
| 签名类型 | sign_type | string | RSA | 签名类型 |
| 时间戳 | timestamp | int | 当前时间戳 |
返回参数:
| 字段名 | 变量名 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|
| 状态码 | code | int | 200 | 200成功,其他值为失败 |
| 返回信息 | message | string | 失败时为错误信息 | |
| 订单号 | out_trade_no | string | 订单号 | |
| 支付方式 | pay_type | string | 支付方式 | |
| 支付参数 | pay_info | string | 根据不同的发起支付类型,返回内容也不一样 | |
| 当前时间戳 | timestamp | int | 当前时间戳 | |
| 签名 | sign | string | 参考签名规则,用于验证一致性 | |
| 签名类型 | sign_type | string | RSA | 签名类型 |
返回示例:
支付方式选择为web时,会返回自动处理后的pay_type类型,例如电脑网页支付返回html,手机网站支付,会返回jump类型。
按pay_type区分返回示例:
json
{
"code": 200,
"message": "创建成功",
"out_trade_no": "202505101234567890",
"pay_type": "html",
"pay_info": "html代码",
}json
{
"code": 200,
"message": "创建成功",
"out_trade_no": "202505101234567890",
"pay_type": "qrcode",
"pay_info": "跳转地址",
}json
{
"code": 200,
"message": "创建成功",
"out_trade_no": "202505101234567890",
}json
{
"code": 200,
"message": "创建成功",
"out_trade_no": "202505101234567890",
}json
{
"code": 200,
"message": "创建成功",
"out_trade_no": "202505101234567890",
}json
{
"code": 200,
"message": "创建成功",
"out_trade_no": "202505101234567890",
}json
{
"code": 200,
"message": "创建成功",
"out_trade_no": "202505101234567890",
}异步通知结果
| 字段名 | 变量名 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|
| 商户号 | pid | string | 商户号用户id | |
| 订单号 | trade_no | string | 订单号 | |
| 商户订单号 | out_trade_no | string | 商户系统内部的订单号 | |
| 支付平台 | payment_gateway | string | (alipay/wxpay/qqpay) | |
| 商品名称 | subject | string | 商品名称 | |
| 订单金额 | amount | String | 订单金额,单位为分 | |
| 支付状态 | trade_status | string | TRADE_SUCCESS | 支付状态,只有TRADE_SUCCESS是成功 |
| 扩展数据 | extra | string | 附加数据,业务扩展参数 | |
| 签名字符串 | sign | string | 签名算法 | |
| 签名类型 | sign_type | string | RSA | |
| 时间戳 | timestamp | int | 当前时间戳 |
收到异步通知后,需返回 success 以表示服务器接收到了订单通知
支付方式说明 pay_type
| 调用值 | 描述 |
|---|---|
| web | 通用网页支付(会根据device判断,自动返回跳转url/二维码/小程序跳转url等) |
| jump | 跳转支付(仅会返回跳转url)例如手机网站支付案例 |
| html | 内嵌支付(仅会返回内嵌html) |
| qrcode | 二维码支付 |
| jsapi | 微信公众号支付(仅会返回jsapi参数),这类使用需传入sub_openid和sub_appid参数 |
| app | APP支付,返回用于发起APP支付的参数(iOS/安卓APP内支付使用,仅返回APP支付参数,或APP拉起微信) |
| scan | 被扫码支付(需传入auth_code参数,支付成功后返回订单信息) |
| miniapp | 微信小程序支付,微信小程序内使用,返回微信小程序插件参数或跳转小程序参数 |
关于设备类型 device
当pay_type为web时,会用上。
| 调用值 | 描述 |
|---|---|
| pc | 电脑端浏览器 |
| mobile | 手机浏览器 |
| 手机QQ内浏览器 | |
| 微信内浏览器 | |
| alipay | 支付宝APP |
订单查询
接口地址:https://api.9py.cn/api/pay/order/query
接口说明:
请求方式:POST