支付回调结果
重要提示
- 服务端回调的金额(
real_amount
和amount
)为单位为RMB分
, 接收回调时请注意单位转换 - 申请
appid
时有生成回调密文(notify_secret
)和 接口密文(api_secret
)两个加密密文, 服务端处理回调时使用的是回调密文, 而不是加密密文, 请不要混用 - 在用户支付完成后会立即进行第一次通知,如果没有返回
success
字符, 我们会周期性地进行7次通知, 重复通知间隔为:1 分钟,5 分钟,10 分钟,30 分钟, 60 分钟,12小时,24小时。直到周期性7次通知结束。 - 重复订单处理,对于CP传入的一个订单号
apporder
, 可能会有多笔成功支付, 这种情况下sdkorder
会不同,所以如果所有校验都成功,请同样返回成功应答字符success
。使用须知
在申请 Pay2 支付ID时需要提供 产品厂商(公司)名字 和 产品包名 以及 加密字符 和 回调 URL 给支付平台, 当前可立即进行支付的平台有:爱贝支付,掌支付和盾形支付。 斯凯(短代) 和 话费支付(短代) 需要进行申请后才可进行, 如需要申请短代, 请与我们的工作人员进行联系,申请完毕后方可以短代方式进行支付。在下列文档中, 我们指智品 Pay2 支付。
服务端回调接口说明
回调样例:GET
notify_url?amount=200&apporder=00000&real_amount=100&sdkorder=10001704281657168760781&sign=3b1eb7f7d1372ccf8544bc773a4c38bd&sign2=2610b0446555e93f907f133bdf532c84&success=1&test=0&ts=1494209825&userdata=test
参数说明:
参数 | 类型 | 说明 | 值 | 备注 |
---|---|---|---|---|
amount |
int |
以分 为单位的 RMB 金额 |
200 |
整数, 合作方应当做好单位转换 |
real_amount |
int |
实际支付金额,以分 为单位的 RMB 金额 |
100 |
2017 年5 月8 日上线, 对账时使用, amount 建议用于发送金币 |
apporder |
string |
App传入的订单ID | 00000 |
合作方应当做唯一区分 |
sdkorder |
string |
Pay2平台中的订单ID | 100 |
暂无 |
sign |
string |
md5 加密密文 | 3b1eb7f7d1372ccf8544bc773a4c38bd |
小写 |
sign2 |
string |
md5 加密密文 | 2610b0446555e93f907f133bdf532c84 |
小写 |
success |
string |
1 为成功, 非1 为失败 |
1 |
|
ts |
int |
订单支付时间 | 1494209825 |
Unix 时间戳 |
userdata |
string |
app 透传数据 | test |
|
test |
int |
1 为测试数据, 0 为上架通知 |
0 |
当使用网页支付时才会为1 ,用于区分支付来源, test 不参与sign验证于2017年4月25日 添加 |
注: 加密列子样例:
// sign 加密列子
string str_for_sign = apporder + sdkorder+ amount + success + ts + notify_secret;
// sign2 加密列子, 保留 sign 是为了兼容历史版本, 2017年5月8日后只需要验证 sign2 即可, 如果不在乎实际金额(仅短代时 real_amount 和 amount 会不一致)
string str_for_sign2 = apporder + sdkorder+ amount + success + ts + notify_secret + real_amount;
Notify secret 为 管理后台配置的 回调密文
。加密算法为 MD5。合作伙伴处理完 服务器回调后需要返回字符串 success 返回其他字符串默认为处理失败, 在后续 30 秒钟还会发送5次支付结果通知
回调样例处理代码:php
<?php
$secret ="xxxx"; // 在产品申请单中填入的通知加密字符
// 下列各参数都不需要调用 urldecode 进行解码
$amount = $_GET['amount'];
$apporder = $_GET['apporder'];
$sdkorder = $_GET['sdkorder'];
$sign = $_GET['sign']; // 小写字符
$success = $_GET['success'];
$ts = $_GET['ts'];
$user_data = $_GET['userdata'];
$real_amount = $_GET['real_amount']; // 实际金额, 添加于 2017年5月8日
$sign2 = $_GET['sign2'];// 小写字符
// 组合加密列子
$str = $apporder.$sdkorder.$amount.$success.$ts.$secret;
// string for sign2
$str_2 = $str + $real_amount
$md5_str = md5($str); // 不要转换为大写
$md5_str2 = md5($str_2);// 不要转换为大写
$succ = "success"; // 正确处理完逻辑后必须返回 'success'. 其他字符将被认为处理失败
$fail = "fail";
// 验证 sign2 即可, sign 是为了兼容而没有删除的, 5月8日后不需要验证 sign 了
if ($sign2 == $md5_str2){
// 处理业务逻辑,
$result = do_logic_handle_by_notify_result...
if($result){
echo $succ;
} else {
echo $fail;
}
} else {
echo $fail;
}
}
合作方服务器给我们返回 success 后, Pay Sdk 才会接收到支付(回调)结果通知
订单状态查询 API
++由于上游支付服务器回调给 Pay2 服务器有不可预测的时长延迟, 在等待超时(30秒)会再次弹出支付选择窗口,此时用户 app_order(apporder) 是没有更新的,这就会造成部分同一个 app_order 对应 多个 pay2 订单号(id) 的情况(目前统计到的比例为千分之一左右), 因此在处理上面回调时发现有重复订单号的情况,可用下面的 api 来获取 pay2 对应的订单号。尽量避免掉单的情况发生++
|请求地址|https://pay2.badambiz.com/api/order/query_order/
|
|-|-|
|请求方法|POST
|
请求参数
参数 | 类型 | 是否必填 | 说明 |
---|---|---|---|
ids |
string 数组 |
必填 | |
appid |
string |
必填 | 应用id |
type |
int |
必填 | 0 (默认值) ids 为 pay2 order id, 即 1000 开头的订单号1 ids 为 应用订单号 |
返回 json 格式:
{
"result": 0, // 出错时为 -1, 错误信息参考 msg
"msg": "",
"data": {
"list": [
{
"id": "10001706051027500840717",
"app_id": "BADAMBIZ", // 上面对应的应用ID
"amount": 20, // 金额, 单位为分
"real": 0,
"status": 1, // 订单状态, 1支付中, 2,4,10 已支付, 3 支付失败, 255 通知失败
"app_order": "00000", // 应用订单号
"sdk_order": "",
"pay_time": "0001-01-01 08:00:00", // 订单支付时间
"user_data": "test", // 透传参数
"cre_at": "2017-06-05 10:27:50", // 订单创建时间
"upd_at": "2017-06-05 10:28:33", // 订单最后一次更新时间
"goods_name": "", // 商品 ID
"goods_id": "2",
}
],
"len": 1 // list 的长度
}
}
注意
- 如果传入的 ids 为应用id,即返回中的 app_order, 则可能会出现一个 ids 对应多个返回结果, 此时可可选择最大 cre_at 的一条来判定最终状态
- 如果传入的 ids 为 返回值中的 id(pay2 平台订单ID),则不会出现 1 中的情形
- 返回的 list 已根据 cre_at 进行降序排列