• 支付
  • 业务流程
  • 相关接口说明
  • 1, 判断用户是否有相关权益
    • 接口说明
    • 请求说明
    • Cookie要求
    • 参数说明
    • Header说明
    • 返回
  • 2, 预下单接口
    • 接口说明
    • 请求说明
    • 参数说明
    • Header说明
    • 返回
  • 3, 使用用户自身权益
    • 接口说明
    • 请求说明
    • 参数说明
    • Header说明
    • 返回
  • 4, 零售下单
    • 接口说明
    • 请求说明
    • 参数说明
    • Header说明
    • 返回
  • 5, 支付完成后的回调
    • 接口说明
    • 请求说明
    • 参数说明
    • 返回
  • 6, 支付完成后的回调实例

    支付

    业务流程

    以下是支付时序图, 相关接口调用都必须在合作方服务器端完成。image

    支付流程说明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

    参数说明

    参数参数类型是否必须说明
    access_tokenstringrequiredaccess_token
    appidstringrequired应用唯一标识
    openidstringrequired用户标识openid
    service_idstringrequired服务id,开发者对接后可用的服务
    total_numint64required查询数量,仅消耗类型的服务需要传对应的数量,其他的传0

    Header说明

    Header名称是否必须说明
    Content-typerequired值为: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_tokenstringrequiredaccess_token
    appidstringrequired应用唯一标识
    openidstringrequired用户标识openid
    service_idstringrequired服务id,开发者对接后可用的服务
    total_numint64required查询数量,仅消耗类型的服务需要传对应的数量,其他的传0
    billnostringrequired合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符
    subjectstringoptional购买内容,当服务类型为第三方自己的服务时传对应的服务id
    csourcestringrequired购买来源
    client_ipstringrequired客户端IP,由接入方获取客户端ip后传过来

    Header说明

    Header名称是否必须说明
    Content-typerequired值为:application/json

    返回

    { "result":0 "msg":"success"}

    3, 使用用户自身权益

    使用用户自身权益

    接口说明

    使用用户自身权益

    请求说明

    [POST] https://openapi.wps.cn/oauthapi/v2/vas/service/use

    参数说明

    参数参数类型是否必须说明
    access_tokenstringrequiredaccess_token
    appidstringrequired应用唯一标识
    openidstringrequired用户标识openid
    service_idstringrequired服务id,开发者对接后可用的服务
    total_numint64required查询数量,仅消耗类型的服务需要传对应的数量,其他的传0
    billnostringrequired合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符

    Header说明

    Header名称是否必须说明
    Content-typerequired值为:application/json

    返回

    { "result":0 "msg":"success"}

    4, 零售下单

    零售下单

    接口说明

    零售下单

    请求说明

    [POST] https://openapi.wps.cn/oauthapi/v2/vas/pay/customorder

    参数说明

    参数参数类型是否必须说明
    access_tokenstringrequiredaccess_token
    appidstringrequired应用唯一标识
    billnostringrequired合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符
    openidstringrequired用户标识openid
    paymentstringrequired支付方式,目前只支持 qrcode: 二维码支付 ios: ios支付 (预下单) android_wechat: 安卓微信支付 (预下单) android_alipay: 安卓支付宝支付 (预下单)
    service_idstringrequired服务id,开发者对接后可用的服务
    subjectstringrequired购买内容,当服务类型为第三方自己的服务时传对应的服务id
    csourcestringrequired购买来源
    total_feeint64required订单金额(单位: 分)
    countint64required购买数量

    Header说明

    Header名称是否必须说明
    Content-typerequired值为: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

    参数说明

    参数参数类型是否必须说明
    billnostringrequired合作方自己的订单号,需要合作方每次下单时保证唯一未使用的订单号,长度不超过32位字符
    app_idstringrequired应用唯一标识
    service_idstringrequired用户实际购买的服务id
    sigstringrequired签名值

    返回

    1. 接口需要直接输出”ok”字符串,代表通知处理业务成功,其他输出都会视为回调失败,失败后前三次间隔1s左右,失败三次后间隔半小时重试一次

    6, 支付完成后的回调实例

    支付完成后的回调实例下载Demo

    1. 将请求的参数和对应的值以keyvalue形式放在数组中,对key按自然序排列后。
    2. 对数组循环以key=value形式拼接成字符串str,将screatkey拼接在str后面,再md5加密成32位小写字符串。

    java 代码实现:

    1. import java.util.TreeMap;
    2. import java.util.Map.Entry;
    3. public class Sig{
    4. public static void main(String []args){
    5. TreeMap<String, String> params = new TreeMap<String, String>();
    6. params.put("billno", "");
    7. params.put("app_id", "");
    8. params.put("service_id", "");
    9. params.put("sig", "");
    10. System.out.println(validSig(params));
    11. }
    12. private static String getKeySortparamters(TreeMap<String, String> map) {
    13. StringBuffer sb = new StringBuffer();
    14. if (map == null) {
    15. return "";
    16. }
    17. for (Entry<String, String> entry : map.entrySet()) {
    18. sb.append(entry.getKey()).append("=").append(entry.getValue());
    19. }
    20. return sb.toString();
    21. }
    22. public static Boolean validSig(TreeMap<String, String> map){
    23. String RequestSig = map.get("sig");
    24. map.remove("sig");
    25. MD5Util md5 = new MD5Util();
    26. String sort = getKeySortparamters(map);
    27. String sig = md5.getMD5(getKeySortparamters(map) + "YOUR SECRET KEY");
    28. if(sig.equals(RequestSig)){
    29. return true;
    30. }
    31. return false;
    32. }
    33. }

    php 代码实现:

    1. $params = array(
    2. 'billno' => "",
    3. 'app_id' => '',
    4. 'sig' => '',
    5. 'service_id' => '',
    6. );
    7. $sig_helper = new Sig();
    8. $key = 'xxxxx'; // 支付回调密钥
    9. list($allow_access, $msg) = $sig_helper->wps_valid_invoke($params, $key);
    10. <?php
    11. class Sig
    12. {
    13. public function wps_generate_sig($param_array, $key)
    14. {
    15. $str = '';
    16. //对param_array中的参数名称进行升序排序
    17. if (is_array($param_array)) {
    18. $this->wps_mksort($param_array);
    19. //按照如下格式转换数组为string格式
    20. $str = $this->wps_key_value($param_array);
    21. } else {
    22. $str = $param_array;
    23. }
    24. //string末端补充api_secret密钥
    25. $str .= $key;
    26. //生成32位小写MD5为最终的数据签名
    27. return array(TRUE, md5($str));
    28. }
    29. /**
    30. * 多维数组的 ksort 排序
    31. * @param array $a
    32. */
    33. private function wps_mksort(& $a)
    34. {
    35. ksort($a);
    36. foreach ($a as &$value) {
    37. if (is_array($value)) {
    38. $this->wps_mksort($value);
    39. }
    40. }
    41. }
    42. private function wps_key_value($data)
    43. {
    44. $str = "";
    45. if (is_array($data)) {
    46. foreach ($data as $k => $v) {
    47. if ($v !== NULL) {
    48. $str .= $k . "=" . $this->wps_key_value($v);
    49. }
    50. }
    51. } else {
    52. $str = $data;
    53. }
    54. return $str;
    55. }
    56. //参数校验
    57. public function wps_valid_invoke($param, $signKey)
    58. {
    59. //加密键值
    60. $sig_keys = array('sig', 'pass');
    61. foreach ($sig_keys as $key) {
    62. if (isset($param[$key])) {
    63. $sig_request = $param[$key];
    64. unset($param[$key]);
    65. }
    66. }
    67. if (!isset($sig_request)) {
    68. return array(FALSE, 'needSigParam');
    69. }
    70. list($success, $sig) = $this->wps_generate_sig($param, $signKey);
    71. if (!$success) {
    72. return array($success, $sig);
    73. }
    74. if ($sig != $sig_request) {
    75. return array(FALSE, 'wrongSigParam');
    76. }
    77. return array(TRUE, 'passed');
    78. }
    79. }