mobile.securitypay.pay(中文)
请求参数
请求参数是商户在与支付宝进行数据交互时,提供给支付宝的请求数据,以便支付宝根据这些数据进一步处理。
特殊说明(很重要):
1、商户在请求参数中,自己附属的一些额外参数,不要和支付宝系统中约定的key(下表中)重名,否则将可能导致未知的异常。
比如请求参数格式 out_trade_no="1234566"&total_fee="123.5"&rn_check="TRE" 其中out_trade_no、total_fee、rn_check都是支付业务处理关键key,这个里面商户自己将out_trade_no、total_fee认为是支付宝必须传输的参数,rn_check=“TRE”是商户自己的业务数据,但是由于rn_check也是支付宝关键key,支付宝将会认为这个rn_check是支付宝业务的参数,将导致误解析,导致支付出现不可预料的异常。
2、支付宝建议,商户不要在请求参数中添加除了支付宝指定的关键key外,还有其他的key用&连接。
比如 out_trade_no="1234566"&total_fee="123.5"&homepage="http://www.xxx.com" ,其中homepage是商户自己的业务key,支付宝建议不要在请求参数中附带和支付无关的业务系统自身的key相关数据。
3、商户的请求参数中,所有的key(支付宝关键key或者商户自己的key),其对应的value中都不应该出现支付宝关键key,比如out_trade_no、total_fee等,否则该类交易将可能被支付宝拦截,禁止支付。
比如如下的请求 out_trade_no="1234566"&total_fee="123.5"&homepage="http://www.xxx.com"&body="这个辣条不错 out_trade_no=123 total_fee=123.5"&memo="备忘seller_id=2088123213", 这个请求里面的body对应的value值中有支付宝关键key“out_trade_no”以及“total_fee”,请求中对于memo字段中含有seller_id,这样的业务请求参数支付宝将会拦截。
partner="2088101568358171"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&sign="lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type="RSA"
4、外币金额和人民币金额的值(如total_fee
和rmb_fee
的值)必须精确到小数点后两位。如100.00 USD。 其它格式将导致报错,如100.999 USD. 但当外币金额单位是JPY时,金额必须是整数,如100 JPY。
参数 | 类型(字节长度) | 参数说明 | 是否可空 | 样例 |
service | String | 接口名称,固定值。 | 不可空 | mobile.securitypay.pay |
partner | String(16) | 签约的支付宝账号对应的支付宝唯一用户号。以2088开头的16位纯数字组成。 | 不可空 | 2088101568358171 |
_input_charset | String | 商户网站使用的编码格式,固定为utf-8。 | 不可空 | utf-8 |
sign_type | String | 签名类型,目前支持RSA,RSA2。备注:RSA2不可用于同步返回验签。 | 不可空 | RSA |
sign | String | 签名值。 | 不可空 | lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJI |
notify_url | String(200) | 支付宝服务器主动通知商户网站里指定的页面http路径。 | 可空 | http://notify.msp.hk/notify.htm |
refer_url | String(200) | 二级商户网站地址 | 不可空 | http://testmerchant.com |
appenv | String | 标识客户端来源。参数值内容约定如下:appenv="system=客户端平台名^version=业务系统版本" | 可空 | appenv="system=android^version=3.0.1.2" |
out_trade_no | String(64) | 支付宝合作商户网站唯一订单号。 | 不可空 | 0819145412-6177 |
subject | String(128) | 商品的简要介绍。特殊字符不支持。备注:本字段的值会在客户支付时被展示给客户。 | 不可空 | 婴儿服 |
payment_type | String(4) | 支付类型。默认值为:1(商品购买)。 | 不可空 | 1 |
seller_id | String(16) | 卖家支付宝账号(邮箱或手机号码格式)或其对应的支付宝唯一用户号(以2088开头的纯16位数字) | 不可空 | xxx@alipay.com |
total_fee | Number | 商品的外币金额,范围:0.01~1000000.00 | 当rmb_fee为空时此参数不可空 | 0.01 |
currency | String(8) | 币种,见7.1支持的币种列表 | 不可空 | USD |
rmb_fee | Number | 该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位。 | 当total_fee为空时,此参数不可空 | |
body | String(1000) | 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。特殊字符不支持。 | 可空 | 大码婴儿服 |
forex_biz | String(2) | 只填FP | 不可空 | FP |
it_b_pay | String | 设置未付款交易的超时时间,一旦超时,该笔交易就会自动被关闭。当用户输入支付密码、点击确认付款后(即创建支付宝交易后)开始计时。取值范围:1m~15d,或者使用绝对时间(示例格式:2014-06-13 16:00:00)。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。该参数数值不接受小数点,如1.5h,可转换为90m。 | 可空 | 30m |
extern_token | String(32) | 开放平台返回的包含账户信息的token(授权令牌,商户在一定时间内对支付宝某些服务的访问权限)。通过授权登录后获取的alipay_open_id,作为该参数的value,登录授权账户即会为支付账户。 | 可空 | 1b258b84ed2faf3e88b4d979ed9fd4db |
secondary_merchant_id | String(64) | 由支付机构给二级商户分配的唯一ID。 注:机构必填。 | 可空 | A80001 |
secondary_merchant_name | String(128) | 由支付机构给二级商户分配的唯一名称。 注:机构必填。 | 可空 | Muku |
secondary_merchant_industry | String(4) | 支付宝分配的二级商户的行业代码,如 注:机构必填。 | 可空 | 7011 |
product_code | String(32) | NEW_WAP_OVERSEAS_SELLER | 不可空 | NEW_WAP_OVERSEAS_SELLER |
split_fund_info | String(1600) | 分账信息,json 格式,具体请参见 “分账明细说明” | 可空 | |
trade_information | String(6000) | 交易信息, 详情参见trade_information | 不可空 | {"business_type":"1","hotel_name":"zlidu, sluhg-987, 889utng","check_in_time":"2018-10-20","check_out_time":"2018-10-22"} |
trade_information
参数 | 类型 (长度是字节) | 描述 | 是否可空 | 示例 |
business_type | String | 业务类型。该字段仅支持以下5类入参: 1: 酒店 2: 航空 3: 留学 4: 贸易 5: 其他, 包含所有不属于前四类的其他业务类型。例如,流量充值,机场接机服务等。 若业务类型超过一种,则传入多个且用竖线(|)分隔。 | 不可空 | 1|2|3|4|5 or 1 |
hotel_name | String | 酒店名称,仅支持数字,字母,空格,及,.<>()[]/\-等特殊字符。若存在多个酒店名称,则传入多个且用竖线(|)分隔。备注:仅在business_type字段值为1时,本字段为必填。 | 不可空 | zlidu, sluhg-987, 889utng |
check_in_time | Date | 入住酒店时间,格式为yyyy-MM-dd。 时区: GMT +8. 备注:仅在business_type字段值为1时,本字段为必填。 | 不可空 | 2018-10-20 |
check_out_time | Date | 离开酒店时间。格式: yyyy-MM-dd。时区: GMT +8。备注:仅在business_type字段值为1时,本字段为必填。 | 不可空 | 2018-10-22 |
flight_number | String | 飞机乘客对应的飞机航班号,如存在转机场景,则传入多个且用竖线(|)分隔。备注:仅在business_type字段值为2时,本字段为必填。 | 不可空 | NWS 996|TWF 8854 |
departure_time | Date | 起飞时间 格式: yyyy-MM-dd HH:mm Timezone: GMT +8. 如存在转机场景,则传入多个且用竖线(|)分隔。备注:仅在business_type字段值为2时,本字段为必填 | 不可空 | 2018-10-22 20:49 |
admission_notice_url | String | 学生的留学录取通知书图片链接。备注:仅在business_type字段值为3时,本字段为必填。 | 不可空 | https://www.iconfont.cn/search/index?test |
goods_info | String | 商品信息,包含商品的SKU名和相应的数量,格式为 SKU_名^数量。若存在超过一件商品,用竖线(|)分隔。备注:仅在business_type字段值为4时,本字段为必填。 | 不可空 | pencil^ 2|eraser^5|iPhone XS 256G^1 |
total_quantity | Number | 一个订单中的商品总量。备注:仅在business_type字段值为4时,本字段为必填。 | 不可空 | 8 |
other_business_type | String | 如果business_type字段值为5(其他),请务必在此字段写明具体从事的行业类型。 | 不可空 | 机场接机服务 |
同步通知参数说明
支付宝对商户的请求数据处理完成后,会将处理的结果数据直接通知给商户。这些处理结果数据就是同步通知参数。
同步返回的数据,对于商户在服务端没有收到异步通知的时候,可以依赖服务端对同步返回的结果来进行判断是否支付成功。同步返回的结果中,sign字段描述了请求的原始数据和服务端支付的状态一起拼接的签名信息。验证这个过程包括两个部分:1、原始数据是否跟商户请求支付的原始数据一致(必须验证这个);2、验证这个签名是否能通过。上述1、2通过后,在result字段中success=true才是可信的。【特别注意,同步结果校验的逻辑,必须放在服务端处理,切记不要放在客户端】【强烈建议商户直接依赖服务端的异步通知,忽略同步返回】
说明:
这里的规则仅限于接入sdk支付模式,对于纯粹的WAP浏览器接入的模式不适用,也就是只针对签约mobile.securitypay.pay这个服务的业务适用,浏览器模式,建议走异步通知的方式。
· iOS
{ memo = ""; result = "partner=\"2088101568358171\"&out_trade_no=\"0819145412-6177\"&subject=\"测试\"&body=\"测试测试\"&total_fee=\"0.01\"¬ify_url=\"http://notify.msp.hk/notify.htm\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&success=\"true\"&sign_type=\"RSA\"&sign=\"hkFZr+zE9499nuqDNLZEF7W75RFFPsly876QuRSeN8WMaUgcdR00IKy5ZyBJ4eldhoJ/2zghqrD4E2G2mNjs3aE+HCLiBXrPDNdLKCZgSOIqmv46TfPTEqopYfhs+o5fZzXxt34fwdrzN4mX6S13cr3UwmEV4L3Ffir/02RBVtU=\""; resultStatus = "9000"; }
· Android
resultStatus={9000};memo={};result={partner="2088101568358171"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&success="true"&sign_type="RSA"&sign="hkFZr+zE9499nuqDNLZEF7W75RFFPsly876QuRSeN8WMaUgcdR00IKy5ZyBJ4eldhoJ/2zghqrD4E2G2mNjs3aE+HCLiBXrPDNdLKCZgSOIqmv46TfPTEqopYfhs+o5fZzXxt34fwdrzN4mX6S13cr3UwmEV4L3Ffir/02RBVtU="}
参数 | 类型(长度范围) | 参数说明 | 是否可空 | 样例 |
resultStatus | String | 本次操作的状态返回值,标识本次调用的结果,参见“客户端返回码”。 | 不可空 | 9000 |
result | String | 本次操作返回的结果数据。其中:&success=“true”&sign_type=“RSA”&sign=“xxx”之前的部分为商户的原始数据。success用来标识本次支付结果。sign=“xxx”为支付宝对本次支付结果的签名(加签内容为:案例中原始数据&支付结果,例如,partner="2088101568358171"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&success="true"),商户可以使用签约时支付宝提供的公钥进行验证。 | 不可空 | partner="2088101568358171"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&success="true"&sign_type="RSA"&sign="hkFZr+zE9499nuqDNLZEF7W75RFFPsly876QuRSeN8WMaUgcdR00IKy5ZyBJ4eldhoJ/2zghqrD4E2G2mNjs3aE+HCLiBXrPDNdLKCZgSOIqmv46TfPTEqopYfhs+o5fZzXxt34fwdrzN4mX6S13cr3UwmEV4L3Ffir/02RBVtU=" |
memo | String | 保留参数,一般无内容。 | 可空 |
· iOS同步通知参数获取:请参考“iOS->回调接口”。
· Android同步通知参数获取:在新线程实例化PayTask对象,调用pay方法,通过Handler对象通知主线程获取支付结果。可参考alipay_sdk_demo工程实现。
客户端返回码
返回码 | 含义 |
9000 | 订单支付成功 |
8000 | 正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 .(支付宝服务端返回的错误码) |
4000 | 订单支付失败 |
6001 | 用户中途取消 |
6002 | 网络连接出错 |
6004 | 支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 。(支付宝客户端不能得到服务端的响应,往往是因为网络原因) |
其它 | 其它支付错误 |
异步通知
支付宝对商户的请求数据处理完成后,会将处理的结果数据通过服务器主动通知的方式通知给商户网站。这些处理结果数据就是服务器异步通知参数。
参数 | 类型(长度范围) | 参数说明 | 是否可空 | 样例 |
notify_time | Date | 通知的发送时间。格式为yyyy-MM-dd HH:mm:ss。 | 不可空 | 2013-08-22 14:45:24 |
notify_type | String | 通知的类型。 | 不可空 | trade_status_sync |
notify_id | String | 通知校验ID。 | 不可空 | 64ce1b6ab92d00ede0ee56ade98fdf2f4c |
sign_type | String | 固定取值为RSA。 | 不可空 | RSA |
sign | String | 签名值。 | 不可空 | lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJI |
out_trade_no | String(64) | 对应商户网站的订单系统中的唯一订单号,非支付宝交易号。需保证在商户网站中的唯一性。是请求时对应的参数,原样返回。 | 可空 | 082215222612710 |
trade_no | String(64) | 该交易在支付宝系统中的交易流水号。最短16位,最长64位。 | 不可空 | 2013082244524842 |
trade_status | String | 交易状态,两个可能的值TRADE_FINISHED TRADE_CLOSED。 | 不可空 | TRADE_FINISHED |
total_fee | Number | 该笔订单的总金额。请求时对应的参数,原样通知回来。(外币金额) | 不可空 | 1.00 |
currency | String | 币种 | 可空 | USD |
异步通知示例:
http://notify.java.jpxx.org/index.jsp?currency=USD&trade_no=2013082244524842¬ify_type=trade_status_sync&out_trade_no=082215222612710¬ify_time=2013-08-22 14:45:24 &trade_status=TRADE_FINISHED &total_fee=1.00¬ify_id=64ce1b6ab92d00ede0ee56ade98fdf2f4c&sign_type=RSA&sign=1glihU9DPWee+UJ82u3+mw3Bdnr9u01at0M/xJnPsGuHh+JA5bk3zbWaoWhU6GmLab3dIM4JNdktTcEUI9/FBGhgfLO39BKX/eBCFQ3bXAmIZn4l26fiwoO613BptT44GTEtnPiQ6+tnLsGlVSrFZaLB9FVhrGfipH2SWJcnwYs=
通知触发条件
触发条件名 | 触发条件描述 | 备注 |
TRADE_FINISHED | 交易成功 | true(触发通知) |
WAIT_BUYER_PAY | 交易创建 | true(触发通知) |
TRADE_CLOSED | 交易关闭 | false(不触发通知) |
说明:true(触发通知)/false(不触发通知)具体值和签约配置时保持同步。
服务器异步通知参数获取
1. 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等;
2. 支付宝是用POST方式发送通知信息,因此该页面中获取参数的方式,如:
request.Form(“out_trade_no”)、$_POST[‘out_trade_no’];
3. 支付宝主动发起通知,该方式才会被启用;
4. 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的;
5. 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。
一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:2m,10m,10m,1h,2h,6h,15h);
6. 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到success字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知;
7. cookies、session等在此页面会失效,即无法获取这些数据;
8. 该方式的调试与运行必须在服务器上,即互联网上能访问;
9. 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理;
10. 当商户收到服务器异步通知并打印出success时,服务器异步通知参数notify_id才会失效。也就是说在支付宝发送同一条异步通知时(包含商户并未成功打印出success导致支付宝重发数次通知),服务器异步通知参数notify_id是不变的。
商户通知参数合法性验证
当支付宝处理完成后会把数据结果反馈给商户。 商户获得这些数据时,必须进行如下处理。
验证签名
首先必需验证签名,然后验证是否是支付宝发来的通知。
验证是否是支付宝发来的通知
请参见验证是否是支付宝发来的通知。
业务数据处理注意事项
商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为TRADE_FINISHED时,支付宝才会认定为买家付款成功。 如果商户需要对同步返回的数据做验签,必须通过服务端的签名验签代码逻辑来实现。如果商户未正确处理业务通知,存在潜在的风险,商户自行承担因此而产生的所有损失。
交易状态
枚举名称 | 枚举说明 |
WAIT_BUYER_PAY | 交易创建,等待买家付款。 |
TRADE_CLOSED | 在指定时间段内未支付时关闭的交易; 在交易完成全额退款成功时关闭的交易。 |
TRADE_FINISHED | 交易成功且结束,即不可再做任何操作。 |
验证是否是支付宝发来的通知
该处的验证是指,对支付宝通知回来的参数notify_id合法性验证。这个验证动作实际上是调用了支付宝的另一个接口“通知验证接口(notify_verify)”来完成的。这个接口请求时使用的是模拟远程HTTP提交,回调模式是“直接在当前页面输出结果”,返回的数据是纯文本格式。
请求的完整链接如下:
https://intlmapi.alipay.com/gateway.do?service=notify_verify&partner=2088002396712354¬ify_id=RqPnCoPT3K9%252Fvwbh3I%252BFioE227%252BPfNMl8jwyZqMIiXQWxhOCmQ5MQO%252FWd93rvCB%252BaiGg
得到的处理结果有两种:
- 成功时:true
- 不成功时:报对应错误
业务逻辑处理
1、商户的业务逻辑处理代码应该写在哪?
一般建议商户业务逻辑的重要处理代码需要写在------
验证签名及notify_id合法性校验都是true的判断逻辑里
如果是“主动回调”(异步通知 notify_url)的页面文件中,那么必须在执行完业务逻辑处理代码且成功改动了业务逻辑的情况下才在当前页面打印success,且不能有页面重定向功能存在。
2、商户业务逻辑处理时要注意的事项
1)务必要判断验证签名及notify_id合法性校验
2)务必要判断被重复调用的可能
3)根据实际的业务逻辑情况执行不同的代码。尤其是根据交易状态的不同而执行不同代码
4)主动回调模式的页面文件中,success是否有成功打印且没有其他信息
5)主动回调模式的页面文件中不能存在cookie、session
6)主动回调模式且需要打印success的页面文件中不能进行页面重定向动作
注意事项
规范点 | 注意事项 |
签名注意 | 商户在接入的过程中,对于订单的签名行为需发生在服务端(私钥需要妥善保管),切忌将私钥落在客户端进行签名 |
通知地址 | 通知地址建议走https,确保商户的订单信息不外泄 |
测试场景 | 商户在测试支付的过程中,需要包括的场景:安装支付宝钱包、无支付宝钱包,并确保两个模式都能支付成功 |
错误码
错误代码(error_code) | 含义 |
ILLEGAL_SIGN | 签名不正确 |
ILLEGAL_DYN_MD5_KEY | 动态密钥信息错误 |
ILLEGAL_ENCRYPT | 加密不正确 |
ILLEGAL_ARGUMENT | 参数不正确 |
ILLEGAL_SERVICE | 接口名称不正确 |
ILLEGAL_PARTNER | 合作伙伴ID不正确 |
ILLEGAL_EXTERFACE | 接口配置不正确 |
ILLEGAL_PARTNER_EXTERFACE | 合作伙伴接口信息不正确 |
ILLEGAL_SECURITY_PROFILE | 未找到匹配的密钥配置 |
ILLEGAL_AGENT | 代理ID不正确 |
ILLEGAL_SIGN_TYPE | 签名类型不正确 |
ILLEGAL_CHARSET | 字符集不合法 |
ILLEGAL_CLIENT_IP | 客户端IP地址无权访问服务 |
ILLEGAL_DIGEST_TYPE | 摘要类型不正确 |
ILLEGAL_DIGEST | 文件摘要不正确 |
ILLEGAL_FILE_FORMAT | 文件格式不正确 |
ILLEGAL_ENCODING | 不支持该编码类型 |
ILLEGAL_REQUEST_REFERER | 防钓鱼检查不支持该请求来源 |
ILLEGAL_ANTI_PHISHING_KEY | 防钓鱼检查非法时间戳参数 |
ANTI_PHISHING_KEY_TIMEOUT | 防钓鱼检查时间戳超时 |
ILLEGAL_EXTER_INVOKE_IP | 防钓鱼检查非法调用IP |
ILLEGAL_NUMBER_FORMAT | 数字格式不合法 |
ILLEGAL_INTEGER_FORMAT | Int类型格式不合法 |
ILLEGAL_MONEY_FORMAT | 金额格式不合法 |
ILLEGAL_DATA_FORMAT | 日期格式错误 |
REGEXP_MATCH_FAIL | 正则表达式匹配失败 |
ILLEGAL_LENGTH | 参数值长度不合法 |
PARAMTER_IS_NULL | 参数值为空 |
HAS_NO_PRIVILEGE | 无权访问 |
SYSTEM_ERROR | 支付宝系统错误 |
SESSION_TIMEOUT | session超时 |
ILLEGAL_TARGET_SERVICE | 错误的target_service |
ILLEGAL_ACCESS_SWITCH_SYSTEM | partner不允许访问该类型的系统 |
ILLEGAL_SWITCH_SYSTEM | 切换系统异常 |
EXTERFACE_IS_CLOSED | 接口已关闭 |