开发文档

SDK(Android)

开发前准备:

商户需要具备以下条件才接入QQ钱包支付:

1、申请QQ钱包商户号:商户可以在QQ钱包商户平台自助申请:https://qpay.qq.com/

2、提交APP信息审核:商户需登录QQ钱包商户平台,在“账户管理--开发配置--APP支付”一栏,提交APP支付信息审核。审核通过后,才能正常调用SDK拉起支付。


SDK说明

1、 SDK和开发文档

QQWalletSDK-Android(点击下载)libs”目录存放“mqqopenpay.jarjar文件。它作为QQ钱包支付提供的接入AndroidQQ钱包支付的SDK,需复制mqqopenpay.jar至商户应用工程libs下。

2、 示例工程

QQWalletSDKDemo-Android(点击下载)为一个调用QQ钱包支付的示例工程。

注意:示例工程为了演示方便,在终端进行数据签名的相关操作。为了保证数据据传输过程中的真实性和完整性,商户App不应在终端代码进行数据签名。建议在商户服务器下发tokenid时,同时按QQ钱包支付的要求下发数字签名相关数据。

3、 接口说明

1判断手机是否安装手Q

方法名:isMobileQQInstalled

请求参数:无

2判断手Q是否支持指定的Api

方法名:isMobileQQSupportApi

请求参数:

字段名

类型

说明

apiName

String

所有的ApiName都申明在OpenConstants类中。如支付的ApiName为:OpenConstants.API_NAME_PAY

3执行指定的Api

方法名:execApi

请求参数:

字段名

类型

说明

api

BaseApi

如果要支付时,传入PayApi,它继承于BaseApi

4Api参数说明

PayApi存放调用QQ钱包支付的所需要的所有参数。下表中“参与签名”项目中被打“√”的参数需要进行数字签名。其参数列表:

字段名

类型

参与签名

说明

appId

String

应用唯一idhttp://open.qq.com申请

nonce

String

随机串,随机字段串每次请求都要不一样

timeStamp

long

时间戳,时间戳,为19701100:00到请求发起时间的秒数

tokenId

String

QQ钱包的预支付会话标识,具体值请传入调用统一下单接口后返回的“prepay_id”的值

注:参与签名参数key为“tokenId,如“tokenId=8888888

pubAcc

String

Q公众帐号,暂时未对外开放申请。

注:所有参与签名的参数,如果value为空, 生成格式如“pubAcc=

pubAccHint

String

关注手Q公众帐号提示语

bargainorId

String

QQ钱包支付商户号,具体值请传入调用统一下单接口时传入的“mch_id” 的值

注:参与签名参数key为“bargainorId

sigType

String

加密方式,签名时,使用的加密算法。目前只支持"HMAC-SHA1",因此该参数填写"HMAC-SHA1"

sig

String

签名串,参看数字签名

5response参数说明

PayResponse存放QQ钱包支付结果的所有参数:

字段名

类型

说明

apiMark

int

执行的Api标识

apiName

String

执行的Api名称

retCode

int

支付结果代码,0 : 表示成功。非0:表示失败

retMsg

String

支付结果描述,仅支付成功有效

serialNumber

String

支付序号,用于标识此次支付

openId

String

腾讯开放平台openId,注,仅开通获得openId权限App返回

transactionId

String

财付通交易号(订单号),仅支付成功有效

payTime

String

支付时间,仅支付成功有效

callbackUrl

String

商户提供的回调url地址(HTML5方式调用适用,其它情形为空),仅支付成功有效

totalFee

String

订单总金额,以分为单位,仅支付成功有效

spData

String

返回给商户的信息,商户前端可解析校验订单支付结果,仅支付成功有效,该值被URL encode

其中 retCode错误信息描述表

返回

说明

0

成功

-1

用户主动放弃支付

-2

登录态超时

-3

重复提交订单

-4

快速注册用户手机号不一致

-5

账户被冻结

-6

支付密码输入错误次数超过上限

-100

网络异常错误

-101

参数错误

其它非0

错误

其中 sp_data为订单相关信息,URL decode之后示例为:

attach=100001000002&bank_type=0&bargainor_id=1900000109&charset=1&fee_type=1&pay_result=0&purchase_alias=242509874&sign=C932267553D4EE236E5C24640A0B03F6&sp_billno=0311207301109290002810000107631&time_end=20130917152936&total_fee=1&transaction_id=1900000109201309170000212327

sp_data中各字段含义见下表。

字段名

属性

说明

charset

字符串

1 UTF-8, 2 GB2312

bank_type

字符串

银行类型:财付通支付填0

pay_result

字符串

支付结果: 0—成功;其它失败

purchase_alias

字符串

买家唯一标识,由财付通生成。注意不同于purchase_id财付通帐户。

bargainor_id

字符串

卖方账号(商户spid),值等同于后台接口中的“mch_id

transaction_id

字符串

财付通交易号(订单号)

sp_billno

字符串

商户系统内部的定单号,此参数仅在对账时提供,值等同于后台接口中的“out_trade_no

total_fee

字符串

订单总金额,以分为单位

fee_type

字符串

现金支付币种

attach

字符串

商家数据包,原样返回

time_end

字符串

支付完成时间,格式为yymmddhhmmss,如2009122791010秒表示为20091227091010。时区为GMT+8 beijing。该时间取自财付通服务器

sign

字符串

MD5签名结果,详见“3.2商户后台签名规则

仅此data数据包中字段参与签名

SDK使用方法

1、 准备工作

1)将“mqqopenpay.jar”复制到商户App工程的libs目录下:


2)通过OpenApiFactory工厂类获得开放Api实例:

IOpenApi openApi = OpenApiFactory.getInstance(this, APP_ID);

2、前提条件判断

调用isMobileQQSupportApi函数判断手Q是否支持QQ钱包支付:

boolean isSupport = openApi.isMobileQQSupportApi(OpenConstants.API_NAME_PAY);

3、启动QQ钱包支付

1)初始化PayApi,并将数据填写完整:

        PayApi api = new PayApi();

        api.appId = APP_ID; // http://open.qq.com注册的AppId,参与支付签名,签名关键字keyappId       

        api.serialNumber = ...; // 支付序号,用于标识此次支付

        api.callbackScheme = ...; // QQ钱包支付结果回调给urlschemecallbackSchemeactivity.,参看后续的“支付回调结果处理”      

        api.tokenId = ...; // QQ钱包支付生成的token_id

        api.pubAcc = ...; // Q公众帐号id.参与支付签名,签名关键字keypubAcc

        api.pubAccHint = ...; // 支付完成页面,展示给用户的提示语:提醒关注公众帐号

        api.nonce = ...; // 随机字段串,每次支付时都要不一样.参与支付签名,签名关键字keynonce

        api.timeStamp = ...; // 时间戳,为19701100:00到请求发起时间的秒数

        api.bargainorId = ...; // 商户号.参与支付签名,签名关键字keybargainorId 

        api.sig = ...; // 商户Server下发的数字签名,生成的签名串,参看“数字签名”

        api.sigType = "HMAC-SHA1"; // 签名时,使用的加密方式,默认为"HMAC-SHA1"

2)在启动QQ钱包支付前,判断一下数据是否完整,再启动QQ钱包支付:

     if (api.checkParams()) {

         openApi.execApi(api);

}

4、 支付回调结果处理

1)在AndroidManifest.xml配置接支付收回的Activity,其中android:scheme建议填写规则:qwallet + APP_ID。该值在启动QQ钱包支付时填写在api.callbackScheme中。

示例:

        <activity

            android:name="com.pay.sample.CallbackActivity"

            android:launchMode="singleTop"

            android:exported="true" >

            <intent-filter>

               <action android:name="android.intent.action.VIEW" />

               <category android:name="android.intent.category.BROWSABLE"/>

               <category android:name="android.intent.category.DEFAULT"/>

               <data android:scheme="qwallet100619284"/>

            </intent-filter>

        </activity>

2ActivityonCreateonNewIntent里调用OpenApihandleIntent处理支付回调。

示例:

        @Override

        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_callback);

    

            openApi = OpenApiFactory.getInstance(this, appId);

            openApi.handleIntent(getIntent(), this);

        }

    

        @Override

        protected void onNewIntent(Intent intent) {

            super.onNewIntent(intent);

            setIntent(intent);

            openApi.handleIntent(intent, this);

        }

3)在Activity实现支付回调响应。

示例:

        public class CallbackActivity extends Activity implements IOpenApiListener {

      @Override

        public void onOpenResponse(BaseResponse response) {

            if (response == null) {

                // 不能识别的intent

                return;

            } else {

                if (response instanceof PayResponse) {

 // 支付回调响应

                    PayResponse payResponse = (PayResponse) response;

    

                    message = " apiName:" + payResponse.apiName

                            + " serialnumber:" + payResponse.serialNumber

                            + " isSucess:" + payResponse.isSuccess()

                            + " retCode:" + payResponse.retCode

                            + " retMsg:" + payResponse.retMsg

                            + " openId:" + payResponse.openId;

                    if (payResponse.isSuccess()) {

 // 支付成功,这个支付结果不能作为发货的依据

                    }

                } else {

                    // 不能识别的响应

                }

            }

}

数字签名

为了保障商户利益与安全,商户App调用QQ钱包支付时启用另一套签名机制。该签名机制与“商户后台与QQ钱包支付后台的签名机制”是不同的

1、源串构造方法

1)将需要参与签名所有参数按key进行字典升序排列。

2将第1步中排序后的参数(key=value)&拼接起来

3key中存在大小写字母,保持大小写字母的存在。不要将key进行统一转换为大写或小写操作;

4如果value为空, 生成格式为“key=”,这点与后台之间签名方法是不一样的;

5签名原始串中,字段名和字段值都采用原始值,不进行URL Encode

举例:

调用某个接口,接口有如下字段:

appIdnoncetokenIdpubAccbargainorId

实际调用接口时,各字段的值:

appId=100619284nonce=ksjfwierwfjktokenId=1000000002pubAcc=bargainorId=1900000109

正确的签名原始串是:

appId=100619284&bargainorId=1900000109&nonce=ksjfwierwfjk&pubAcc=&tokenId=1000000002

常见的错误有:

appId=100619284&bargainorId=1900000109&nonce=ksjfwierwfjk&tokenId=1000000002

appid=100619284&bargainorid=1900000109&nonce=ksjfwierwfjk&pubacc=&tokenid=1000000002

appId=100619284&nonce=ksjfwierwfjk&tokenId=1000000002&pubAcc=&bargainorId=1900000109

2、 密钥构造方法

1http://open.qq.com申请appId,并获得appKey

2构造到密钥的方式:在应用的appkey末尾加上一个字“&”,即appkey&

示例

appkey 值为 d139ae6fb0175e5659dce2a7c1fe84d5

正确的密钥为:d139ae6fb0175e5659dce2a7c1fe84d5&

3、 生成签名值方法

1使用HMAC-SHA1加密算法,使用密钥构造方法中得到的密钥对源串构造方法中得到的源串进行加密(注:一般程序语言中会内置HMAC-SHA1加密算法的函数,例如PHP5.1.2之后的版本可直接调用hash_hmac函数)

2然后将加密后的字符串进行Base64编码(注:一般程序语言中会内置Base64编码函数,例如PHP中可直接调用 base64_encode() 函数)

3最后得到的签名值sig结果如下:

c6xXw0tNABhOMc869h1bfxTp9Mk=


示例截图



FAQ

Q:接入QQ钱包支付,对手机QQ Android版本有什么要求?

A:手机QQAndroid5.3.0版本以上对第三方商户应用提供了支付接入的功能。因此,商户应用在调用QQ钱包支付前需要作一下判断,参看“前提条件判断”。

Q:  商户生成订单token_id是否可以在前端访问财付通下单接口生成?

A: 技术上是可以的,但为避免商户的签名Key泄露,建议商户通过后台服务器访问此接口,得到订单token_id后再传回商户的前台应用。

Q:用户在手机QQ侧支付完成后,商户应用怎样知道支付是否成功?

A:手机QQ侧支付成功后,其会发出特定协议格式的Intent,回调商户应用,返回支付成功信息;商户应用可依赖手机QQ前端回调进行支付结果的展示,可依赖财付通后台回调notify_url进行发货等逻辑处理。