- 支付
- 业务流程
- 相关接口说明
- 1, 判断用户是否有相关权益
- 接口说明
- 请求说明
- Cookie要求
- 参数说明
- Header说明
- 返回
- 2, 预下单接口
- 接口说明
- 请求说明
- 参数说明
- Header说明
- 返回
- 3, 使用用户自身权益
- 接口说明
- 请求说明
- 参数说明
- Header说明
- 返回
- 4, 零售下单
- 接口说明
- 请求说明
- 参数说明
- Header说明
- 返回
- 5, 支付完成后的回调
- 接口说明
- 请求说明
- 参数说明
- 返回
- 6, 支付完成后的回调实例
支付
业务流程
以下是支付时序图, 相关接口调用都必须在合作方服务器端完成。
支付流程说明1.如时序1预支付前需要先判断用户是否具有相关的权益。参见【判断用户是否有相关权益】2.如时序2会返回当前用户相关权益信息。3.若用户已具有相关权益,直接执行行时序10使用用户自身权益(需带上合作方订单号)。参见【使用用户自身权益】4.若用户没有相关权益,执行时序3预支付下单接口(需带上合作方订单号),开发平台会返回相关信息及合作方订单号。参见【预下单接口】5.时序5将 billno带给WPS 客户端,WPS客户端会完成后续的支付流程。6.时序8 WPS客户端会将支付成功信息同步通知给合作方客户端。7.时序9 开发平台会异步将支付成功信息通知给合作方服务端(是否支付成功以此为准)。8.开发平台会记录用户的购买记录、使用记录,并和合作方订单号关联,后续以此对账。
相关接口说明
1, 判断用户是否有相关权益2, 预下单接口3, 使用用户自身权益4, 零售下单5, 支付完成后的回调6, 支付完成后的回调实例
1, 判断用户是否有相关权益
判断用户是否有相关权益
接口说明
判断用户是否有相关权益
请求说明
[POST] https://openapi.wps.cn/oauthapi/v2/vas/service/usable
Cookie要求
无
参数说明
| 参数 | 参数类型 | 是否必须 | 说明 |
|---|---|---|---|
| access_token | string | required | access_token |
| appid | string | required | 应用唯一标识 |
| openid | string | required | 用户标识openid |
| service_id | string | required | 服务id,开发者对接后可用的服务 |
| total_num | int64 | required | 查询数量,仅消耗类型的服务需要传对应的数量,其他的传0 |
Header说明
| Header名称 | 是否必须 | 说明 |
|---|---|---|
| Content-type | required | 值为:application/json |
返回
{ "result":0 "msg":"success", "data":{ "docervip":946656000, #说明:稻壳会员过期时间 "supervip":946656000, #说明:超级会员过期时间 "wpsvip":946656000, #说明:WPS会员过期时间 "expire_time":946656000, #说明:特权过期时间 "total":TOTAL #说明:特权剩余总次数 }}
2, 预下单接口
预下单接口
接口说明
预下单接口
请求说明
[POST] https://openapi.wps.cn/oauthapi/v2/vas/pay/preorder
参数说明
| 参数 | 参数类型 | 是否必须 | 说明 |
|---|---|---|---|
| access_token | string | required | access_token |
| appid | string | required | 应用唯一标识 |
| openid | string | required | 用户标识openid |
| service_id | string | required | 服务id,开发者对接后可用的服务 |
| total_num | int64 | required | 查询数量,仅消耗类型的服务需要传对应的数量,其他的传0 |
| billno | string | required | 合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符 |
| subject | string | optional | 购买内容,当服务类型为第三方自己的服务时传对应的服务id |
| csource | string | required | 购买来源 |
| client_ip | string | required | 客户端IP,由接入方获取客户端ip后传过来 |
Header说明
| Header名称 | 是否必须 | 说明 |
|---|---|---|
| Content-type | required | 值为:application/json |
返回
{ "result":0 "msg":"success"}
3, 使用用户自身权益
使用用户自身权益
接口说明
使用用户自身权益
请求说明
[POST] https://openapi.wps.cn/oauthapi/v2/vas/service/use
参数说明
| 参数 | 参数类型 | 是否必须 | 说明 |
|---|---|---|---|
| access_token | string | required | access_token |
| appid | string | required | 应用唯一标识 |
| openid | string | required | 用户标识openid |
| service_id | string | required | 服务id,开发者对接后可用的服务 |
| total_num | int64 | required | 查询数量,仅消耗类型的服务需要传对应的数量,其他的传0 |
| billno | string | required | 合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符 |
Header说明
| Header名称 | 是否必须 | 说明 |
|---|---|---|
| Content-type | required | 值为:application/json |
返回
{ "result":0 "msg":"success"}
4, 零售下单
零售下单
接口说明
零售下单
请求说明
[POST] https://openapi.wps.cn/oauthapi/v2/vas/pay/customorder
参数说明
| 参数 | 参数类型 | 是否必须 | 说明 |
|---|---|---|---|
| access_token | string | required | access_token |
| appid | string | required | 应用唯一标识 |
| billno | string | required | 合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符 |
| openid | string | required | 用户标识openid |
| payment | string | required | 支付方式,目前只支持 qrcode: 二维码支付 ios: ios支付 (预下单) android_wechat: 安卓微信支付 (预下单) android_alipay: 安卓支付宝支付 (预下单) |
| service_id | string | required | 服务id,开发者对接后可用的服务 |
| subject | string | required | 购买内容,当服务类型为第三方自己的服务时传对应的服务id |
| csource | string | required | 购买来源 |
| total_fee | int64 | required | 订单金额(单位: 分) |
| count | int64 | required | 购买数量 |
Header说明
| Header名称 | 是否必须 | 说明 |
|---|---|---|
| Content-type | required | 值为:application/json |
返回
{ "result":0 "msg":"success", "data":{ "url":"URL", "billno":"BILLNO" }}
5, 支付完成后的回调
支付完成后的回调
接口说明
支付完成后的回调
请求说明
[POST] redirect_uri?billno=BILLNO&app_id=APPID&service_id=SERVICEID&sig=SIG
参数说明
| 参数 | 参数类型 | 是否必须 | 说明 |
|---|---|---|---|
| billno | string | required | 合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符 |
| app_id | string | required | 应用唯一标识 |
| service_id | string | required | 用户实际购买的服务id |
| sig | string | required | 签名值 |
返回
接口需要直接输出”ok”字符串,代表通知处理业务成功,其他输出都会视为回调失败,失败后前三次间隔1s左右,失败三次后间隔半小时重试一次
6, 支付完成后的回调实例
支付完成后的回调实例下载Demo
将请求的参数和对应的值以key、value形式放在数组中,对key按自然序排列后。对数组循环以key=value形式拼接成字符串str,将screatkey拼接在str后面,再md5加密成32位小写字符串。
java 代码实现:
import java.util.TreeMap;import java.util.Map.Entry;public class Sig{public static void main(String []args){TreeMap<String, String> params = new TreeMap<String, String>();params.put("billno", "");params.put("app_id", "");params.put("service_id", "");params.put("sig", "");System.out.println(validSig(params));}private static String getKeySortparamters(TreeMap<String, String> map) {StringBuffer sb = new StringBuffer();if (map == null) {return "";}for (Entry<String, String> entry : map.entrySet()) {sb.append(entry.getKey()).append("=").append(entry.getValue());}return sb.toString();}public static Boolean validSig(TreeMap<String, String> map){String RequestSig = map.get("sig");map.remove("sig");MD5Util md5 = new MD5Util();String sort = getKeySortparamters(map);String sig = md5.getMD5(getKeySortparamters(map) + "YOUR SECRET KEY");if(sig.equals(RequestSig)){return true;}return false;}}
php 代码实现:
$params = array('billno' => "",'app_id' => '','sig' => '','service_id' => '',);$sig_helper = new Sig();$key = 'xxxxx'; // 支付回调密钥list($allow_access, $msg) = $sig_helper->wps_valid_invoke($params, $key);<?phpclass Sig{public function wps_generate_sig($param_array, $key){$str = '';//对param_array中的参数名称进行升序排序if (is_array($param_array)) {$this->wps_mksort($param_array);//按照如下格式转换数组为string格式$str = $this->wps_key_value($param_array);} else {$str = $param_array;}//string末端补充api_secret密钥$str .= $key;//生成32位小写MD5为最终的数据签名return array(TRUE, md5($str));}/*** 多维数组的 ksort 排序* @param array $a*/private function wps_mksort(& $a){ksort($a);foreach ($a as &$value) {if (is_array($value)) {$this->wps_mksort($value);}}}private function wps_key_value($data){$str = "";if (is_array($data)) {foreach ($data as $k => $v) {if ($v !== NULL) {$str .= $k . "=" . $this->wps_key_value($v);}}} else {$str = $data;}return $str;}//参数校验public function wps_valid_invoke($param, $signKey){//加密键值$sig_keys = array('sig', 'pass');foreach ($sig_keys as $key) {if (isset($param[$key])) {$sig_request = $param[$key];unset($param[$key]);}}if (!isset($sig_request)) {return array(FALSE, 'needSigParam');}list($success, $sig) = $this->wps_generate_sig($param, $signKey);if (!$success) {return array($success, $sig);}if ($sig != $sig_request) {return array(FALSE, 'wrongSigParam');}return array(TRUE, 'passed');}}
