注意:以下文档只适用于TOP接口,请谨慎使用!

文档中心 > YunOS开放平台

支付服务接入文档

更新时间:2017/06/30 访问次数:9991

 

 

 

阿里巴巴 YunOS开放平台

 

系统支付SDK集成说明文档

 

v 2.0.0

 

 

 

 

 

1. YunOS平台概述

1.1.    开发平台接入方法

 

  1. 成为YunOS开发者

注册并登录YunOS开放平台,按照系统提示完成身份验证手机号绑定等。

  1. 创建应用

进入“控制台”,左侧栏中打开应用配置并创建应用,按要求填写应用信息,如下图,创建应用后请等待工作人员审核,审核通过后继续。

 

 

  1. 开通支付功能并生成客户端SDK

(1)进入 应用管理 页,点击“查看”,如图:

 

 

 

 

 

 

 

(2)点击“查看”,进入应用功能页,如图一:打开“客户端SDK”,跳转到“生成最新SDK”的页面;如下图:

 

 

(3)点击“生成SDK”,进入如下图:

 

(4)根据提示操作,“点击开通”,跳转到开通页面按照流程申请支付功能需要的key和secret;如下图:

 

 

请仔细阅读上传页面中的注意事项,上传需要集成支付服务的APK文件,勾选“支付服务”选项,“生成最新SDK”。

注意: 如果应用的APK文件比较大,生成 SDK 的时候建议生成一个同样包名和 keystore 的空包进行上传,以节约时间。

 

 

1.2.    系统支付能力申请

  1. 进入申请“系统支付”服务的流程中,申请完成后如下图,如果开发者需要通过Server接收支付结果的异步通知,在申请过程中的最后一个页面设置“安全域名”。(可以填写 IP;若非80或443端口,还需要标明端口号,如 yunpay.demo.com:9999 )正文

 

 

 

 

 

  1. 也可以回到应用功能页,打开 系统支付(点击开通)流程如上;打开 系统支付(已开通)进入系统支付服务页,如下图,可进行操作

 

 

  

 

 

 

2. 支付服务

2.1.    SDK引入方法

下载生成的SDK后,解压,内容如下:

将其中的 libs/ res/ 和 AndroidManifest.xml 的内容合并至待集成的工程目录。

注意事项:

  1. 支付服务SDK具有动态升级功能,请不要在应用的files目录下使用 yunpay 开头文件
  2. 如果你的工程需要混淆,请添加如下规则:

       -keepattributes Signature
       -keep class sun.misc.Unsafe { *; }
       -keep class com.taobao.** {*;}
       -keep class com.alibaba.** {*;}
       -keep class com.alipay.** {*;}
       -dontwarn com.taobao.**
       -dontwarn com.alibaba.**
       -dontwarn com.alipay.**
       -keep class com.ut.** {*;}
       -dontwarn com.ut.**
       -keep class com.ta.** {*;}
       -dontwarn com.ta.**
       -keep class com.aliyun.violet.** {*;}
       -keep class com.yunos.violet.** {*;}
       -keep class com.yunos.upay.client.** {*;}
       -keep class com.snowfish.**{*;}
       -dontwarn com.unity3d.**
       -keep class com.unity3d.**{*;}

 

2.2.    客户端接口

2.2.1. 概述

支付服务是YunOS系统具有的安全,高效的支付能力。 由支付sdk和系统支付服务组成。 支付sdk提供调用支付宝支付和调用系统支付服务的能力。 系统 支付服务会提供用户更多的支付方式,如支付宝,短信支付等。

2.2.2. 接口说明

2.2.2.1       SDK初始化接口

  1. 接口描述:

SDK初始化

 

  1. 前置条件:

SDK初始化必须在Application中进?行

 

  1. 函数原型:

static void asyncInit(Context, InitResultCallback callback);

 

  1. 参数说明:

callback 用于回调初始化结果。

 

  1. 代码使用范例:

import com.alibaba.sdk.android.AlibabaSDK;
import com.alibaba.sdk.android.callback.InitResultCallback;

public class MyApplication extends Application {
   @Override
   public void onCreate() {
       super.onCreate();
       /* SDK初始化必须在Application中进?行 */
       AlibabaSDK.asyncInit(this, new InitResultCallback() {
           @Override
           public void onSuccess() {
           }
      
           @Override
           public void onFailure(int code, String message) {
               //失败原因可能下载sdk的应?用签名与当前应?用签名不?一致
           }
       });
   }
}

2.2.2.2       设置用户信息接口(建议)

1 接口描述:

为便于支付订单统计及管理,在SDK初始化完成后,建议开发者在适当的时机(如用户的登录状态更新时)调用以下接口设置用户信息。 开发者设置的用户信息将会在支付服务的后台管理页面中与订单关联,可以此作为对用户退款及售后的依据。

 

  1. 前置条件:

 

  1. 函数原型:

void setUserInfo(Map<String, String> map);

 

  1. 参数说明:

map 可选的key有: userID, nick

 

  1. 代码使用范例:

YunpayService yunpayService = AlibabaSDK.getService(YunpayService.class);
HashMap<String, String> map = new HashMap();
map.put("userID", "xxxxx");
map.put("nick", "xxxxx");
yunpayService.setUserInfo(map);

 

2.2.2.3       支付接口

1 接口描述:

通过YunPayService的showPage接口对订单发起支付

 

  1. 前置条件: 无

 

  1. 函数原型:

void showPayPage(Activity activity, String orderInfo, PayCallback callback);

 

  1. 参数说明:

orderInfo: 发起支付的订单, 将以下参数,通过key=value&进行拼接生成的字符串.

参数

参数名称

参数说明

参数要求

bizOrderNo

订单号

 

必选

subject

商品名称

 

必选

currency

货币代码

当前只支持人民币:CNY

必选

price

商品金额

单位分

必选

notifyUrl

服务器异步通知路径

支付服务服务器主动通知应用服务器

可以不传,但不能传空字符串,端口: 80 或 443

publicKey

公钥

支付服务颁发给应用的公钥

必选

extraData

开发者自定义数据

 

可以不传,但不能传空字符串

sign

签名

签名是将其余字段按照key的字母升序排列,以key=value&进行拼接,然后进行HmacSHA256加密的结果

必选

 

  1. 代码使用范例:

YunpayService yunpayService = AlibabaSDK.getService(YunpayService.class);
if (yunpayService == null) {
   //插件没有初始化,无法获取 YunpayService"
   return;
}
String id = UUID.randomUUID().toString();//生成订单id
String extraData = "开发者自定义的额外信息,保存在支付服务服务器";
String publicKey = PUBLIC_KEY;

// 注意:订单字符串一定要按照key字母升序排列,例如:"bizOrderNo=%s&currency=%s&price=%s&publicKey=%s&subject=%s"
String origin = "bizOrderNo=" + id + "&currency=" + currency + "&extraData=" + extraData + "&notifyUrl=" + url + "&price=" + price + "&publicKey=" + publicKey + "&subject=" + subject;

//将未编码的字符串进行HmacSHA256 进行加密
String sign = DemoUtils.sign(origin, SECRET);

//对订单参的Value值数做 URL encode,生成传输用的字符串
String order = "bizOrderNo=" + encode(id) + "&currency=" + encode(currency) + "&extraData=" + encode(extraData) + "&notifyUrl=" + encode(url) + "&price=" + encode(price) + "&publicKey=" + encode(publicKey) + "&subject=" + encode(subject) + "&sign=" + encode(sign);

//创建支付结果的回调
PayCallback callback = new PayCallback() {
   @Override
   public void onPay(Result result) {
       //result.getCode() 获取的的是支付状态码
       if (result.getCode() == 9000) {
           //TODO:成功
      
} else {
           //TODO:失败。4000: 订单无效,6001:用户取消,6002: 网路错误,8000: 正在处理
      
}
   }
};

//发起支付, 必须在UI线程中调用
yunpayService.showPayPage(this, orderInfo, callback);

 

  1. 异常及错误码:

 

错误码

含义

备注

钱是否到账

4000

订单无效

订单已失效(过期或其他原因关闭)

6001

用户取消

 

6002

网络错误

 

8000

正在处理

小概率场景,要与服务端再确认

待确认

9000

支付成功

 

 

2.2.2.4       支付结果查询接口

  1. 接口描述:

对支付结果进行查询

 

  1. 前置条件:

 

  1. 函数原型:

QueryOrderStatusResult queryOrderStatus(Context context, String queryString);

 

  1. 参数说明:
       queryString 是将key:bizOrderNo, publicKey 按照key的字母升序,以key=value&进行拼接,然后再结尾附加签名信息格式:"bizOrderNo=%s&publicKey=%s&sign=%s"其中sign是对其之前字符串进行 HmacSHA256 进行加密的结果

 

  1. 代码使用范例:

YunpayService yunpayService = AlibabaSDK.getService(YunpayService.class);
        
/*
* 这个函数不能在UI线程调用。建议作为后台service来调用
* queryString 是将key:bizOrderNo, publicKey 按照key的字母升序,以
* key=value&进行拼接,然后再结尾附加签名信息
* 格式:"bizOrderNo=%s&publicKey=%s&sign=%s"
* 其中sign是对其之前字符串进行 HmacSHA256 进行加密的结果。例如:
*/
QueryOrderStatusResult result =
       yunpayService.queryOrderStatus(getApplicationContext(),
               queryString);

/*
* 1. 当result.getCode() == 200时:可以通过result.getOrderStatus()获取
*   订单状态. 订单状态有:"WAIT_PAY":待支付,"PAY_SUCCESS": 交易成功,
*   "PAY_CLOSED":交易关闭
* 2. 当result.getCode() 其他值见错误码定义
*/

 

  1. 异常及错误码:

错误码

含义

建议

200

成功

 

2

订单过期

重建订单

3

网络错误

检查网络

7

创建订单失败

 

10001

Server系统错误

稍后再试,或联系服务端开发人员

10002

参数错误

检查传递的参数

10003

签名错误

检查对参数的签名,请检查参数及对参数的签名

 

 

2.3.    服务端接口

2.3.1. 概述

支付服务端面向开发者服务端提供的接口

2.3.2. 接口说明

2.3.2.1       支付结果异步云端通知接口

1 接口描述:

支付服务对开发者的请求数据处理完成后,会将处理的结果数据通过服务器主动通知的方式通知给开发者服务器。

 

2 通知触发条件:

支付成功

 

3 参数说明:

参数

参数名称

参数说明

是否可空

样例

notifyTime

通知时间

通知的发送时间。格式为yyyy-MM-dd HH:mm:ss

2014-11-24 00:22:07

notifyType

通知类型

通知的类型。

pay

notifyId

通知ID

通知ID,可用作校验使用

bb7620a82f057fadfadfa1d05d05be77fc3w

bizOrderNo

业务订单号

开发者内部唯一订单号

1511111180

tradeNo

支付服务交易号

该交易在支付服务系统中的交易流水号。最长64位。

2014112400001000340011111111

tradeStatus

交易状态

取值范围: PAY_SUCCESS、PAY_CLOSED

PAY_SUCCESS

gmtCreate

交易创建时间

该笔交易创建的时间。格式为yyyy-MM-dd HH:mm:ss。

2014-11-24 00:21:52

gmtPayment

交易付款时间

该笔交易的买家付款时间。格式为yyyy-MM-dd HH:mm:ss。

可空

2014-11-24 00:22:07

totalAmount

交易金额

该笔订单的总金额。请求时对应的参数,单位分

136

extraData

开发自定义参数

开发者支付时提供的额外的自定义参数

可空

abc

trade_platform

三方

三方交易平台

可空

alipay

trade_platform_no

三方流水

三方交易平台流水号

可空

 

signType

签名方式

HmacSHA256

HmacSHA256

sign

签名

签名是按着其余字段(不包含signType)将key的字母按着升序,以key=value&进行拼接,然后进?HmacSHA256加密的结果,例如:bizOrderNo=%s&tradeNo=%s& tradeStatus=%s

39528c90dda85058896ddb18505a661ddd72d2efc950e5236e54eac3aa5ab373

 

4 报文范例:

notifyTime=2016-05-24 20:34:27&notifyType=pay&notifyId=94640932674445476389&bizOrderNo=9b15b61b76f44636bc3391d24c5a1fe8&tradeNo=14640932403117846429&tradeStatus=PAY_SUCCESS&gmtCreate=2016-05-24 20:34:00&gmtPayment=2016-05-24 20:34:27&totalAmount=100&signType=HmacSHA256&sign=xxxxxxxxxx

 

 

  • 代码使用范例(JAVA版):
  • 获取通知报文

       //获取云支付POST过来反馈信息

       Map<String,String> params = new HashMap<String,String>();

          Map requestParams = request.getParameterMap();

          for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {

                 String name = (String) iter.next();

                 String[] values = (String[]) requestParams.get(name);

                 String valueStr = "";

                 for (int i = 0; i < values.length; i++) {

                        valueStr = (i == values.length - 1) ? valueStr + values[i]

                                      : valueStr + values[i] + ",";

                 }

                 params.put(name, valueStr);

          }

 

  • 验证通知报文

   /**

     * 验证消息是否是云支付发出的合法消息

     * @param params 通知返回来的参数数组

     * @return 验证结果

     */

   public static boolean verify(Map<String, String> params) {

       //isSign不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关

          String sign = "";

          if(params.get("sign") != null) {sign = params.get("sign");}

          boolean isSign = getSignVeryfy(params, sign);

       if (isSign) {

           return true;

       } else {

           return false;

       }

 

 

  • 处理交易结果及返回通知结果

         //交易号

         String bizOrderNo = params.get("bizOrderNo");

         //交易状态

         String tradeStatus = params.get("tradeStatus");

         //获取云支付的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//

         if(UpayNotify.verify(params)){//验证成功

                //请在这里加上开发者的业务逻辑程序代码

                //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——

                if(tradeStatus.equals("PAY_SUCCESS")){

                       //判断该笔订单是否在开发者系统中已经做过处理

                       //如果没有做过处理,根据订单号(bizOrderNo)在开发者的订单系统中查到该笔订单的详细,并执行开发者的业务程序

                       //如果有做过处理,不执行开发者的业务程序

                }

                //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——

                out.print("success");    //请不要修改或删除

         }else{//验证失败

                out.print("fail");

         }

 

 

 

 

  • 注意事项:
  • notify_url所包含的域名必须与之前申请开通支付服务功能时设置的“安全域名”一致,才能接收到通知

 

  • 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等;

 

  • 用POST方式发送通知信息,因此该页面中获取参数的方式,如:
    Form(“out_trade_no”)、$_POST[‘out_trade_no’];

 

 

  • 支付服务主动发起通知,该方式才会被启用;

 

  • 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的;

 

 

  • 程序执行完后必须打印输出“success”(不包含引号)。如果开发者反馈给支付服务的字符不是success这7个字符,支付服务服务器会不断重发通知,直到超过上限次数。
    一般情况下,14小时以内完成16次通知(通知的间隔频率一般是:30s,30s,2m,2m,5m,20m,30m,1h,1h,1h,2h,2h,2h,2h,2h);

 

  • 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付服务会收不到success字符,会被支付服务服务器判定为该页面程序运行出现异常,而重发处理结果通知;

 

  • cookies、session等在此页面会失效,即无法获取这些数据;

 

  • 该方式的调试与运行必须在服务器上,即互联网上能访问;

 

  • 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理;

 

  • 当开发者收到服务器异步通知并打印出success时,服务器异步通知参数notify_id才会失效。也就是说在支付服务发送同一条异步通知时(包含开发者并未成功打印出success导致支付服务服务重发数次通知),服务器异步通知参数notify_id是不变的。

 

FAQ

关于此文档暂时还没有FAQ
返回
顶部