app支付宝alipay支付qq音乐付费包账号共享 成功却未开通

支付宝移动支付之IOSApp调用支付宝钱包
最近客户提出要开发一个IOS上的app作为访问他们网站的途径之一,为什么说之一呢,因为目前PC和Mobile这两个站目前都已经上线了。所以问题就简单了,我们只需要把mobile站UI修改一下,然后在根据客户的新需求修改下程序,之后把这个站套个IOS的壳子就可以了。那么问题来了,我们的mobile支付的时候调用的是支付宝的网页支付,这个页面是支付宝的,我们没办法修改,所以如果套在壳子里继续使用这种支付方式会有点不伦不类的感觉,所以我们就决定调用支付宝钱包,也就是支付宝客户端。下面是我参考支付宝移动支付文档整理出来的一些资料:这是demo的下载地址,包括IOS和Android两个版本 -hangzhou.alipay-pub./demo/WS_MOBILE_PAY_SDK_BASE.zip?spm=0.0.0.0.LJBZ4o&file=WS_MOBILE_PAY_SDK_BASE.zip首先要调用支付宝钱包你必须你登录商户的支付宝账户的“签约管理”里面去申请签约开通“移动支付”PID和密钥管理支付宝提供商户接口产品时,会自主提供一个保障商户接入安全的一组信息及其对应的配置平台,这组信息就是密钥。由商户密钥与支付宝密钥交换后与支付宝商户标识(如partnerID、APPID等)绑定。合作伙伴密钥在服务市场签约获得的大部分接口,签约主体是商户,接口权限属于具体的商户,这部分接口需要使用PID和密钥来调用,此类接口网关一般为mapi(/gateway.do),PID对应的密钥一共有三种签名方式,分别是MD5、RSA、DSA。由于产品的特殊性,每个产品支持哪些签名方式不尽相同,具体需参考各个产品的接口技术文档。 使用合作伙伴密钥的典型功能包括:快捷登录、移动支付、即时到账收款、手机网站支付等。查看PID和密钥
查看MD5(Key)
查看RSA商户公钥与支付宝公钥
查看DSA商户公钥与支付宝公钥上传公钥
上传RSA公钥
上传DSA公钥密钥生成
RSA私钥及公钥生成
DSA私钥及公钥生成 这块流程可以让你上层领导来处理,这里的相关操作都要在商户支付宝账户中操作。我们来看一下我们开发人员需要care的点 ①交互流程:
流程说明(以Android平台为例):第2步:调用支付接口:此消息就是本接口所描述的开发包提供的支付对象PayTask,将商户订单信息传进pay方法唤起支付宝收银台,订单格式具体参见“请求参数说明”。 第3步:手机支付宝支付开发包将会按照商户App提供的参数发送支付请求。 第5步:异步发送支付通知:手机支付宝支付服务器端发送异步通知消息给商户服务器端,参见“服务器异步通知参数说明”。 第7步:接口返回支付结果:商户应用客户端通过当前调用支付的Activity的Handler对象,通过它的回调函数获取支付结果,参见“同步通知参数说明”。数据交互
1.构造订单数据并签名 商户客户端根据手机支付宝支付开发包的接口规则,通过程序生成得到签名结果及要传输给手机支付宝支付开发包的数据集合。签名相关的公私钥生成及配置规则,见PID和密钥管理。 2.发送请求数据 把构造完成的数据集合传递给手机支付宝支付开发包。 手机支付宝支付开发包对请求数据进行处理 手机支付宝支付开发包将请求数据根据业务规则包装后传递给支付宝服务端,服务端得到这些集合后,会先进行安全校验等验证,一系列验证通过后便会处理完成这次发送过来的数据请求。 3.返回处理的结果数据 对于处理完成的交易,支付宝会以两种方式把数据分别反馈给商户应用和商户服务器。 在手机客户端上,开发包客户端直接把处理的数据结果反馈给商户客户端; 支付宝服务器主动发起通知,调用商户在请求时设定好的页面路径(参数notify_url,如果商户没设定,则不会进行该操作)。 4.对获取的返回结果数据进行处理 商户在客户端同步通知接收模块或服务端异步通知接收模块获取支付宝返回的结果数据后,可以结合商户自身业务逻辑进行数据处理(如:订单更新、自动充值到会员账号中等)。同步通知结果仅用于结果展示,入库数据需以异步通知为准。②客户端调用 iOS Alipay接口主要为商户提供订单支付功能。接口所提供的方法,如下表所示:方法名称 方法描述+(Alipay *)defaultS 获取服务实例。 -(BOOL)isL 检测本地是否曾登录使用过。 -(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionB 支付并通过回调返回结果。 快捷订单支付iOS
方法名称:pay方法
方法原型:(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionB
方法功能:提供给商户快捷订单支付功能。 参数名称参数描述NSString* scheme 商户程序注册的URL protocol,供支付完成后回调商户程序使用。(CompletionBlock)completionBlock 快捷支付开发包回调函数,返回免登、支付结果。相应的结果参考“同步通知参数说明”。NSString* orderStr 主要包含商户的订单信息,key=“value”形式,以&连接。支付参数示例如下,参数说明见“请求参数说明”:[code]partner="8171"&seller_id=""&out_trade_no="-6177"&subject="测试"&body="测试测试"&total_fee="0.01"&notify_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"处理客户端返回url
方法名称:处理客户端方法
方法原型:-(void)processOrderWithPaymentResult:(NSURL*)resultUrl standbyCallback:(CompletionBlock)completionB
方法功能:设备已安装支付宝客户端情况下,处理支付宝客户端返回的url。 注意:该方法必须实现,否则将会导致在安装手机支付宝的情况下,支付结果无法正常同步返回。参数名称参数描述NSURL *resultUrl 支付宝客户端回传的url CompletionBlock completionBlock 当支付宝客户端在操作时,商户app进程在后台被结束,只能通过这个block输出支付结果。 备注:请在APPDelegate的- (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation中调用该方法,具体可参见Demo。[code]回调接口在支付过程结束后,会通过callbackBlock同步返回支付结果。[code]返回结果需要通过resultStatus以及result字段的值来综合判断并确定支付结果。在resultStatus=9000,并且success=“true”以及sign=“xxx”校验通过的情况下,证明支付成功。其它情况归为失败。较低安全级别的场合,也可以只通过检查resultStatus以及success=“true”来判定支付结果。以下为订单支付成功的完成信息示例:[code]ResultStatus={9000};memo={};result={partner="8171"&seller_id=""&out_trade_no="-6177"&subject="测试"&body="测试测试"&total_fee="0.01"&notify_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="}注意:支付结果的提取,必须通过CompletionBlock获取,禁止开发者私自解析支付结果返回的URL。获取值的Key对应resultStatus、memo与result(result中的值,开发者可以自行解析);为了保障已有商户的正常使用,返回参数ResultStatus首字母为大写。在新的SDK中已经用统一的工具类实现了ResultStatus到resultStatus的转换,商户从CompletionBlock中获取resultStatus即可。③导入代码: 步骤1:启动IDE(如Xcode),把iOS包中的压缩文件中以下文件拷贝到项目文件夹下,并导入到项目工程中。[code]AlipaySDK.bundleAlipaySDK.framework在Build Phases选项卡的Link Binary With Libraries中,增加以下依赖:
其中,需要注意的是:如果是Xcode 7.0之后的版本,需要添加libc++.tbd、libz.tbd; 如果是Xcode 7.0之前的版本,需要添加libc++.dylib、libz.dylib(如下图)。
步骤2:在需要调用AlipaySDK的文件中,增加头文件引用。[code]#import &AlipaySDK/AlipaySDK.h&步骤3:如果你的app基于9.0编译,那么为了适配iOS9.0中的App Transport Security(ATS)对http的限制,这里需要对支付宝的请求地址、做例外,在app对应的info.list中添加如下配置(文中以XML格式描述)。[code]&key&NSAppTransportSecurity&/key&
&dict&&key&NSExceptionDomains&/key&&dict&
&key&&/key&
&dict&&key&NSIncludesSubdomains&/key&&true/&&key&NSTemporaryExceptionAllowsInsecureHTTPLoads&/key&&true/&&key&NSTemporaryExceptionMinimumTLSVersion&/key&&string&TLSv1.0&/string&&key&NSTemporaryExceptionRequiresForwardSecrecy&/key&&false/&
&key&&/key&
&dict&&key&NSIncludesSubdomains&/key&&true/&&key&NSTemporaryExceptionAllowsInsecureHTTPLoads&/key&&true/&&key&NSTemporaryExceptionMinimumTLSVersion&/key&&string&TLSv1.0&/string&&key&NSTemporaryExceptionRequiresForwardSecrecy&/key&&false/&
&/dict&&/dict&
&/dict&说明:如果商户配置了如下的配置:[code]&key&NSAppTransportSecurity&/key&
&key&NSAllowsArbitraryLoads&/key&&true/&
&/dict&则上述的NSAppTransportSecurity可以不配置。步骤4:配置请求信息。[code]Order *order = [[Order alloc] init];order.partner =order.seller =order.tradeNO = [self generateTradeNO]; //订单ID(由商家?自?行制定)order.productName = product. //商品标题order.productDescription = product. //商品描述order.amount = [NSString stringWithFormat:@"%.2f",product.price]; //商品价格order.notifyURL = @""; //回调URLorder.service = @"mobile.securitypay.pay";order.paymentType = @"1";order.inputCharset = @"utf-8";order.itBPay = @"30m";//应用注册scheme,在AlixPayDemo-Info.plist定义URL typesNSString *appScheme = @"alisdkdemo";//将商品信息拼接成字符串NSString *orderSpec = [order description];NSLog(@"orderSpec = %@",orderSpec);//获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncodeid&DataSigner& signer = CreateRSADataSigner(privateKey);NSString *signedString = [signer signString:orderSpec];//将签名成功字符串格式化为订单字符串,请严格按照该格式NSString *orderString =if (signedString != nil) {
orderString = [NSString stringWithFormat:@"%@&sign=/"%@/"&sign_type=/"%@/"",
orderSpec, signedString, @"RSA"];
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {//【callback处理支付结果】
NSLog(@"reslut = %@",resultDic);
[tableView deselectRowAtIndexPath:indexPath animated:YES];}详细可参见Demo中示例文件AliSDKDemo/APViewController.h AliSDKDemo/APViewController.m AliSDKDemo/Order.h AliSDKDemo/Order.m 步骤5:配置支付宝客户端返回url处理方法。(外部存在支付包钱包,支付宝钱包将处理结果通过url返回。)如示例AliSDKDemo/APAppDelegate.m文件中,增加引用代码:[code]#import &AlipaySDK/AlipaySDK.h&在@implementation AppDelegate中增加如下代码:[code]- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
//如果极简开发包不可用,会跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给开发包
if ([url.host isEqualToString:@"safepay"]) {[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
//【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
NSLog(@"result = %@",resultDic);}];
if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回authCode[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
//【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
NSLog(@"result = %@",resultDic);}];
return YES;}④针对demo的运行注意: 1、关于签名代码问题AliSDKDemo/Util及下面所有文件 AliSDKDemo/openssl及下面所有文件 libcrypto.a libssl.a 这些文件是为示例签名所在客户端本地使用。出于安全考虑,请商户尽量把私钥保存在服务端,在服务端进行签名验签。2、如果遇到运行后报错,类似于以下提示信息:[code]Cannot find interface declaration for 'NSObject', superclass of 'Base64'那么需要打开报错了的文件,增加头文件。[code]#import &Foundation/Foundation.h&3、如果商户要在某个文件中使用支付宝的开发包类库,需增加引用头文件。[code]#import &AlipaySDK/AlipaySDK.h&4、点击项目名称,点击“Build Settings”选项卡,在搜索框中,以关键字“search”搜索,对“Header Search Paths”增加头文件路径:$(SRCROOT)/项目名称。如果头文件信息已增加,可不必再增加。
5、点击项目名称,点击“Build Phases”选项卡,在“Link Binary with Librarles”选项中,新增“AlipaySDK.framework”和“SystemConfiguration.framework”两个系统库文件。如果商户项目中已有这两个库文件,可不必再增加。
6、点击项目名称,点击“Info”选项卡,在“URL Types”选项中,点击“+”,在“URL Schemes”中输入“alisdkdemo”。“alisdkdemo”来自于文件“APViewController.m”的NSString *appScheme = @“alisdkdemo”;。注意:这里的URL Schemes中输入的alisdkdemo,为测试demo,实际商户的app中要填写独立的scheme,建议跟商户的app有一定的标示度,要做到和其他的商户app不重复,否则可能会导致支付宝返回的结果无法正确跳回商户app。 ⑤基本配置信息: 打开“APViewController.m”文件,对以下三个参数进行编辑。[code]NSString *partner = @"";NSString *seller = @"";NSString *privateKey = @"";IOS基本信息配置表:参数含义partner合作身份者ID,以2088开头由16位纯数字组成的字符串。请参考查看PID。seller支付宝收款账号,手机号码或邮箱格式。private_key商户方的私钥,pkcs8格式。请参考RSA私钥及公钥生成。注意:这些参数配置是为客户端签名功能服务的,仅作为示例使用。商户在接入支付宝产品时,请把这些信息通过商户项目自己的服务端传递。⑥代码示例运行逻辑: 步骤1:调用order.m里的函数description将商品信息拼接成字符串作为待签名字符串,如:[code]"partner=/"3491/"&seller_id=/"3491/"&out_trade_no=/"YR2VGG3G1I31XDZ/"&subject=/"1/"&body=/"我是测试数据/"&total_fee=/"0.02/"&notify_url=/"/"&service=/"mobile.securitypay.pay/"&payment_type=/"1/"&_input_charset=/"utf-8/"&it_b_pay=/"30m/""步骤2:使用类CreateRSADataSigner,调用signString签名函数做签名,如:[code]"GsSZgPloF1vn52XAItRAldwQAbzIgkDyByCxMfTZG%2FMapRoyrNIJo4U1LUGjHp6gdBZ7U8jA1kljLPqkeGv8MZigd3kH25V0UK3Jc3C94Ngxm5S%2Fz5QsNr6wnqNY9sx%2Bw6DqNdEQnnks7PKvvU0zgsynip50lAhJmflmfHvp%2Bgk%3D"步骤3:把签名结果赋值给参数sign,并把sign加入之前的待签名数组中,此时得到的便是要请求给支付宝的全部数据。[code]"partner=/"3491/"&seller_id=/"3491/"&out_trade_no=/"YR2VGG3G1I31XDZ/"&subject=/"1/"&body=/"我是测试数据/"&total_fee=/"0.02/"&notify_url=/"/"&service=/"mobile.securitypay.pay/"&payment_type=/"1/"&_input_charset=/"utf-8/"&it_b_pay=/"30m/"&sign=/"GsSZgPloF1vn52XAItRAldwQAbzIgkDyByCxMfTZG%2FMapRoyrNIJo4U1LUGjHp6gdBZ7U8jA1kljLPqkeGv8MZigd3kH25V0UK3Jc3C94Ngxm5S%2Fz5QsNr6wnqNY9sx%2Bw6DqNdEQnnks7PKvvU0zgsynip50lAhJmflmfHvp%2Bgk%3D/"&sign_type=/"RSA/""步骤4:调用(AlipaySDK *)defaultService类下面的支付接口函数,唤起支付宝支付页面。[code](void)payOrder:(NSString *)orderStr
fromScheme:(NSString *)schemeStr
callback:(CompletionBlock)completionBlockappScheme为app在info.plist注册的scheme。支付宝支付页面:
后面的动作全由买家在支付宝收银台中操作完成。如果设备中有支付宝客户端,会优先调用支付宝客户端进行支付,支付完成后会重新唤起商户app。步骤5:当这笔交易被买家支付成功后支付宝收银台上显示该笔交易成功,并提示用户“返回”。此时在APAppDelegate.m的 - (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 中调用获取返回数据的代码:[code][[AlipaySDK defaultService]processOrderWithPaymentResult:urlstandbyCallback:^(NSDictionary *resultDic) {NSLog(@"result = %@",resultDic);//返回的支付结果//【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】}];拿到返回数据:点取消后返回[code]"alisdkdemo://safepay/?%7B%22memo%22:%7B%22result%22:%22%22,%22memo%22:%22%E7%94%A8%E6%88%B7%E4%B8%AD%E9%80%94%E5%8F%96%E6%B6%88%22,%22ResultStatus%22:%%7D,%22requestType%22:%22safepay%22%7D"对其做URLDecode[code]"alisdkdemo://safepay/?{"memo":{"result":"","memo":"用户中途取消","ResultStatus":"6001"},"requestType":"safepay"}"点确认后返回[code]"alisdkdemo://safepay/?%7B%22memo%22:%7B%22result%22:%22partner=%5C%C%22&seller_id=%5C%C%22&out_trade_no=%5C%22QU6ZOD85K4HVQFN%5C%22&subject=%5C%221%5C%22&body=%5C%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%5C%22&total_fee=%5C%220.02%5C%22&notify_url=%5C%22http:%5C/%5C/%5C%22&service=%5C%22mobile.securitypay.pay%5C%22&payment_type=%5C%221%5C%22&_input_charset=%5C%22utf-8%5C%22&it_b_pay=%5C%&success=%5C%22true%5C%22&sign_type=%5C%22RSA%5C%22&sign=%5C%22pg16DPA%5C/cIRg1iUFCl8lYZG54de+kfw+vCj32hGWye97isZ1A4bW6RNaDXHhZXVaI5Vk2YDxhNUl85EHRd+EL7%5C/+ogQTnsaEHl+D13PuZExIXRKGBnkYqaNV6kH6hDygnf5IOtoojHWLQyem7oRBVzB0vlF%5C/+YGFpzFHZyTVpM8=%5C%22%22,%22memo%22:%22%22,%22ResultStatus%22:%%7D,%22requestType%22:%22safepay%22%7D"对其做URLDecode[code]"alisdkdemo://safepay/?{"memo":{"result":"partner=/"3491/"&seller_id=/"3491/"&out_trade_no=/"QU6ZOD85K4HVQFN/"&subject=/"1/"&body=/"我是测试数据/"&total_fee=/"0.02/"&notify_url=/"http://///"&service=/"mobile.securitypay.pay/"&payment_type=/"1/"&_input_charset=/"utf-8/"&it_b_pay=/"30m/"&success=/"true/"&sign_type=/"RSA/"&sign=/"pg16DPA//cIRg1iUFCl8lYZG54de+kfw+vCj32hGWye97isZ1A4bW6RNaDXHhZXVaI5Vk2YDxhNUl85EHRd+EL7//+ogQTnsaEHl+D13PuZExIXRKGBnkYqaNV6kH6hDygnf5IOtoojHWLQyem7oRBVzB0vlF//+YGFpzFHZyTVpM8=/"","memo":"","ResultStatus":"9000"},"requestType":"safepay"}"之后,对这些数据做处理。 注意:由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理;同步返回数据时,建议通过服务端的验签功能代码做验签处理,之后再对返回的数据做业务逻辑处理;须以服务器异步通知的结果数据为准,并对其做业务逻辑处理;SDK付款有两种模式:如果外部存在支付宝钱包,则直接跳转到支付宝钱包付款;不存在的场景下,在SDK内部进行H5支付。测试同学需要关注这两类测试场景。至此文档结束,由于我本人对于IOS开发并不精通,所以以上绝大部分借鉴支付宝相关文档,但都是我认为比较重要的地方,仅供参考。
最新教程周点击榜
微信扫一扫1624人阅读
android_支付相关(1)
http://blog.csdn.net/u/article/details/
http://blog.csdn.net/u/article/details/
&700人阅读&&&
android(71)&
项目需要,需要在客户端集成支付宝接口。第一次集成,过程还是挺简单的,不过由于支付宝官方文档写的不够清晰,也是走了一些弯路,下面把过程写出来分享给大家。就研究了一下:因为使用支付宝接口,就需要到支付宝官网:注册帐号,并申请。下面讲的是申请好之后的操作。登录成功之后,
& 店家我的商家服务—在页面的下方找到——&签约管理—&找打 移动支付—–&点击下载集成文档—&跳到新的页面,在页面下方—&找到下载开发包,下载移动支付即可。然后解压出来之后一般会得到三个文件夹。
一、申请移动支付权限
首先登录【支付宝开放平台】,添加应用,申请移动支付权限。申请开通支付,是需要公司文件的,个人是不允许开始支付的。
具体细节就不再详聊了,下面就讲讲如何将阿里给出的demo运行起来。
二、阿里支付DEMO
(1)支付调用页面及测试
支付宝在调用时,会首先看本地是不是存在支付宝客户端,如果有的话,就直接调用客户端进行支付,如果没有,则调用jar包中的H5页面支付。
所以在测试时,需要有测试两种情境:有支付宝客户端和没有支付宝客户端的情况。
(2)、客户端与服务器
在demo中大家可以看到,有客户端的demo也有服务端的demo,大家可能觉得需要服务端写好之后,客户端才能集成,其实并不是。整个流程是这样的:
1,APP客户端通过SDK发送支付请求 (客户端处理)
2,SDK支付成功并同步返回支付结果(客户端处理)
3,支付宝服务器向我们的服务器发送支付结果字符串(服务端处理)
客户端:从上面的流程可以看出,服务端只是用来接出异步返回的支付结果的。而支付与同步结果返回都是在客户端可以直接看得到的。所以在集成支付宝支付接口时,主要功能是在客户端,即便服务端没有做集成,也是可能付款成功的。
服务端:服务端只需要添加一个功能:接口支付结果返回
下面几张图显示了整个demo的运行过程,由于没办法在真机上录制gif,所以只能用图片来代替了。
初始化界面:
点击支付后,跳出确认付款界面:
点击确认付款后,跳出输入密码界面:
最后是支付成功界面:
在看DEMO的代码之前,我们需要先配置几个变量:
2、配置几个变量
这部分会对代码中用到的几个变量的找到方法或生成方法进行讲述,部分资料引自支付宝开放平台。
合作者身份ID(PID)是商户与支付宝签约后,商户获得的支付宝商户唯一识别码。当商户把支付宝功能接入商户网站时会用到PID,以便让支付宝认证商户。
查看PID步骤如下:
1、登录支付宝官方网站
2、点击导航栏中“商家服务”
3、点击“查询PID、Key”
(2)、APPID、APP SECRET和支付宝公钥
在页面,创建一个应用
完成之后:在我的应用中是可以看得到的:
然后转到帐户基本信息页面:
在开放平台密钥栏,可以找到APPID,APP SECRET,和支付宝密钥
这三个数据,都是在应用创建后,支付宝为我们生成好的,无法更改!
(3)、生成商户私钥【windows生成方法】
(有关mac的生成方法,下面会再补充)
1、下载DEMO及SDK
到文档中心,查看移动支付对应的文档,文档地址:http://doc./doc2/detail?treeId=59&articleId=103563&docType=1
然后,点击(SDK&DEMO下载)下载代码
2、得到原始私钥
在代码中的DEMO/openssl/bin目录下,有openssl.exe文件
打开openssl.exe
得到生成成功的结果,如下图:
此时,我们可以在bin文件夹中看到一个文件名为rsa_private_key.pem的文件
用记事本方式打开它,可以看到-----BEGIN RSA PRIVATE KEY-----开头,-----END RSA PRIVATE KEY-----结尾的没有换行的字符串,这个就是原始的私钥。
但这段原始私钥代码中是用不到的,我们需要将它转化为PKCS8格式
3、转换为PKCS8格式
在openssl.exe中输入:并回车
得到生成功的结果,这个结果就是PKCS8格式的私钥,如下图:
注意,私钥是红框包括的那部分,是不包含BEGIN PRIVATE KEY和END PRIVATE KEY这两行的。
右键点击openssl窗口上边边缘,选择编辑→标记,选中要复制的文字(如上图),
此时继续右键点击openssl窗口上边边缘,选择编辑→复制,
把复制的内容粘土进一个新的记事本中,可随便命名,只要知道这个是PKCS8格式的私钥即可。
(4)、生成商户私钥【MAC生成方法】
这里来讲一下mac端如何生成用户私钥的,由于mac系统是自带openssl的,所以只需要打开终端,利用cd 命令切到任意一个想存放生成Key的文件夹下:
比如,切到下载目录下
然后运行下面的命令来生成私钥原始密钥
然后运行下面的命令来生成转换的PCKS8格式的命令。
然后将生成的私钥复制保存起来。
从上面的命令可以看出,与windows相比,mac上需要在前面添加openssl指定运行的是openssl命令。其它命令是完全一致的。
(5)、生成用户公钥及网页填充
1、生成公钥
同样对于windows用户而言,直接在openssl.exe中输入下面的命令:
同样,如果是Mac的同学,输入的命令应该是如下:
得到生成成功的结果,如下图:
此时,我们可以在bin文件夹中看到一个文件名为rsa_public_key.pem的文件,用记事本方式打开它,可以看到-----BEGIN PUBLIC KEY-----开头,
-----END PUBLIC KEY-----结尾的没有换行的字符串,这个就是公钥。
在生成网页以后,复制----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----之间的部分,即那段纯代码,不要把----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----给复制进去了。中间的这部分就是公钥。
2、网页填充
上传RSA公钥,在“合作伙伴密钥管理”下,点击“RSA加密”后的“添加密钥”,把自己的公钥复制进去。注意不能有空格,换行之类的。
点击确认上传,若是提示上传成功。则就是成功。
这个时候就可查看支付宝公钥了。如图:
至此,将对应的私钥与公钥填到相应位置我们的Demo&&就可一运行了。到这里,所有的准备工作都已经结束了。下面就是配置DEMO的过程了
3、配置DEMO
在刚才下载的sdk&demo的源码中,打开DEMO/客户端demo/支付宝Android 15.0.1/alipay_demo工程
将Demo中libs 文件夹下面的支付宝jar 包拷贝到 所需要引入的项目中的libs 文件下,如果没有此文件,可以自己在项目中新建libs 文件,并将sdk的jar包引入其中。
配置AndroidManifest.xml文件。此文件大都是配置信息的。集成支付宝,当然也不例外。下面的代码也是从Demo中拷贝过来的,信息如下:
&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&&!-- alipay sdk begin --&&/span&
&span class=&tag& style=&color: rgb(0, 0, 128);&&&&span class=&title&&activity
&span class=&indent&&
&/span&android:name=&com.alipay.sdk.app.H5PayActivity&
&span class=&indent&&
&/span&android:configChanges=&orientation|keyboardHidden|navigation&
&span class=&indent&&
&/span&android:exported=&false&
&span class=&indent&&
&/span&android:screenOrientation=&behind&
&span class=&indent&&
&/span&android:windowSoftInputMode=&adjustResize|stateHidden&&/span& &&/span&
&span class=&tag& style=&color: rgb(0, 0, 128);&&&/&span class=&title&&activity&/span&&&/span&
&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&&!-- alipay sdk end --&&/span&
可以看到的是这是一个Activity.配置文件。就如平常的注册Activity 一样,放在application节点之中即可。下面是权限的配置:
&span class=&tag& style=&color: rgb(0, 0, 128);&&&&span class=&title&&uses-permission&/span& &span class=&attribute& style=&color: rgb(0, 128, 128);&&android:name&/span&=&span class=&value& style=&color: rgb(221, 17, 68);&&&android.permission.INTERNET&&/span& /&&/span&
&span class=&tag& style=&color: rgb(0, 0, 128);&&&&span class=&title&&uses-permission&/span& &span class=&attribute& style=&color: rgb(0, 128, 128);&&android:name&/span&=&span class=&value& style=&color: rgb(221, 17, 68);&&&android.permission.WRITE_EXTERNAL_STORAGE&&/span& /&&/span&
&span class=&tag& style=&color: rgb(0, 0, 128);&&&&span class=&title&&uses-permission&/span& &span class=&attribute& style=&color: rgb(0, 128, 128);&&android:name&/span&=&span class=&value& style=&color: rgb(221, 17, 68);&&&android.permission.ACCESS_NETWORK_STATE&&/span& /&&/span&
&span class=&tag& style=&color: rgb(0, 0, 128);&&&&span class=&title&&uses-permission&/span& &span class=&attribute& style=&color: rgb(0, 128, 128);&&android:name&/span&=&span class=&value& style=&color: rgb(221, 17, 68);&&&android.permission.READ_PHONE_STATE&&/span& /&&/span&
&span class=&tag& style=&color: rgb(0, 0, 128);&&&&span class=&title&&uses-permission&/span& &span class=&attribute& style=&color: rgb(0, 128, 128);&&android:name&/span&=&span class=&value& style=&color: rgb(221, 17, 68);&&&android.permission.ACCESS_WIFI_STATE&&/span& /&&/span&
这是必要的权限,如果添加过的,就不需要重新添加了。没有的,则需要添加到里面。
拷贝文件,同样是Demo 文件中,在你需要引入支付宝的项目中新建一个包,来存放必须要的java 文件。分别是下面几个文件: Base64.java,PayResult.java与SignUtils.java
文件,我下载的是alipaySDK.jar 的jar 包。只需要引入这些文件即可。
下面就是主要Activity的代码的引入了。主要代码如下:
&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&static&/span& &span class=&keyword& style=&font-weight:&&final&/span& String PARTNER = &span class=&string& style=&color: rgb(221, 17, 68);&&&注册账户的PID&&/span&;
&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 商户收款账号&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&static&/span& &span class=&keyword& style=&font-weight:&&final&/span& String SELLER = &span class=&string& style=&color: rgb(221, 17, 68);&&&支付宝收款账户&&/span&;
&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 商户私钥,pkcs8格式&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&static&/span& &span class=&keyword& style=&font-weight:&&final&/span& String RSA_PRIVATE = &span class=&string& style=&color: rgb(221, 17, 68);&&&商户私钥&&/span&;
&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 支付宝公钥&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&static&/span& &span class=&keyword& style=&font-weight:&&final&/span& String RSA_PUBLIC = &span class=&string& style=&color: rgb(221, 17, 68);&&&支付宝公钥&&/span&;
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&private&/span& &span class=&keyword& style=&font-weight:&&static&/span& &span class=&keyword& style=&font-weight:&&final&/span& &span class=&keyword& style=&font-weight:&&int&/span& SDK_PAY_FLAG = &span class=&number& style=&color: rgb(0, 153, 153);&&1&/span&;
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&private&/span& &span class=&keyword& style=&font-weight:&&static&/span& &span class=&keyword& style=&font-weight:&&final&/span& &span class=&keyword& style=&font-weight:&&int&/span& SDK_CHECK_FLAG = &span class=&number& style=&color: rgb(0, 153, 153);&&2&/span&;
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&private&/span& Handler mHandler = &span class=&keyword& style=&font-weight:&&new&/span& Handler() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&void&/span& handleMessage(Message msg) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&switch&/span& (msg.what) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&case&/span& SDK_PAY_FLAG: {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&PayResult payResult = &span class=&keyword& style=&font-weight:&&new&/span& PayResult((String) msg.obj);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&String resultInfo = payResult.getResult();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&String resultStatus = payResult.getResultStatus();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&if&/span& (TextUtils.equals(resultStatus, &span class=&string& style=&color: rgb(221, 17, 68);&&&9000&&/span&)) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.makeText(PayDemoActivity.&span class=&keyword& style=&font-weight:&&this&/span&, &span class=&string& style=&color: rgb(221, 17, 68);&&&支付成功&&/span&,
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.LENGTH_SHORT).show();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&} &span class=&keyword& style=&font-weight:&&else&/span& {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 判断resultStatus 为非“9000”则代表可能支付失败&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// “8000”代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&if&/span& (TextUtils.equals(resultStatus, &span class=&string& style=&color: rgb(221, 17, 68);&&&8000&&/span&)) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.makeText(PayDemoActivity.&span class=&keyword& style=&font-weight:&&this&/span&, &span class=&string& style=&color: rgb(221, 17, 68);&&&支付结果确认中&&/span&,
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.LENGTH_SHORT).show();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&} &span class=&keyword& style=&font-weight:&&else&/span& {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.makeText(PayDemoActivity.&span class=&keyword& style=&font-weight:&&this&/span&, &span class=&string& style=&color: rgb(221, 17, 68);&&&支付失败&&/span&,
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.LENGTH_SHORT).show();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&break&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&case&/span& SDK_CHECK_FLAG: {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.makeText(PayDemoActivity.&span class=&keyword& style=&font-weight:&&this&/span&, &span class=&string& style=&color: rgb(221, 17, 68);&&&检查结果为:&&/span& + msg.obj,
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.LENGTH_SHORT).show();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&break&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&default&/span&:
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&break&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
这段代码,是一个Handler,放在Java 文件的顶部。
&span class=&javadoc& style=&color: rgb(153, 153, 136); font-style:&&/**
&span class=&indent&&
&/span& * call alipay sdk pay. 调用SDK支付
&span class=&indent&&
&span class=&indent&&
&/span& */&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&void&/span& pay() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 订单&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&String orderInfo = getOrderInfo(&span class=&string& style=&color: rgb(221, 17, 68);&&&测试的商品&&/span&, &span class=&string& style=&color: rgb(221, 17, 68);&&&该测试商品的详细描述&&/span&, &span class=&string& style=&color: rgb(221, 17, 68);&&&0.01&&/span&);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 对订单做RSA 签名&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&String sign = sign(orderInfo);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&try&/span& {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 仅需对sign 做URL编码&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&sign = URLEncoder.encode(sign, &span class=&string& style=&color: rgb(221, 17, 68);&&&UTF-8&&/span&);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&} &span class=&keyword& style=&font-weight:&&catch&/span& (UnsupportedEncodingException e) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&e.printStackTrace();
&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 完整的符合支付宝参数规范的订单信息&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&final&/span& String payInfo = orderInfo + &span class=&string& style=&color: rgb(221, 17, 68);&&&&sign=\&&&/span& + sign + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&+ getSignType();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&Runnable payRunnable = &span class=&keyword& style=&font-weight:&&new&/span& Runnable() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&annotation&&@Override&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&void&/span& run() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 构造PayTask 对象&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&PayTask alipay = &span class=&keyword& style=&font-weight:&&new&/span& PayTask(PayDemoActivity.&span class=&keyword& style=&font-weight:&&this&/span&);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 调用支付接口,获取支付结果&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&String result = alipay.pay(payInfo);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Message msg = &span class=&keyword& style=&font-weight:&&new&/span& Message();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&msg.what = SDK_PAY_FLAG;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&msg.obj =
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&mHandler.sendMessage(msg);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 必须异步调用&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&Thread payThread = &span class=&keyword& style=&font-weight:&&new&/span& Thread(payRunnable);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&payThread.start();
&span class=&indent&&
&span class=&indent&&
&/span&&span class=&javadoc& style=&color: rgb(153, 153, 136); font-style:&&/**
&span class=&indent&&
&/span& * check whether the device has authentication alipay account.
&span class=&indent&&
&/span& * 查询终端设备是否存在支付宝认证账户
&span class=&indent&&
&span class=&indent&&
&/span& */&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&void&/span& check(View v) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&Runnable checkRunnable = &span class=&keyword& style=&font-weight:&&new&/span& Runnable() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&annotation&&@Override&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&void&/span& run() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 构造PayTask 对象&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&PayTask payTask = &span class=&keyword& style=&font-weight:&&new&/span& PayTask(PayDemoActivity.&span class=&keyword& style=&font-weight:&&this&/span&);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 调用查询接口,获取查询结果&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&boolean&/span& isExist = payTask.checkAccountIfExist();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Message msg = &span class=&keyword& style=&font-weight:&&new&/span& Message();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&msg.what = SDK_CHECK_FLAG;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&msg.obj = isE
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&mHandler.sendMessage(msg);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&Thread checkThread = &span class=&keyword& style=&font-weight:&&new&/span& Thread(checkRunnable);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&checkThread.start();
&span class=&indent&&
&span class=&indent&&
&/span&&span class=&javadoc& style=&color: rgb(153, 153, 136); font-style:&&/**
&span class=&indent&&
&/span& * get the sdk version. 获取SDK版本号
&span class=&indent&&
&span class=&indent&&
&/span& */&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& &span class=&keyword& style=&font-weight:&&void&/span& getSDKVersion() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&PayTask payTask = &span class=&keyword& style=&font-weight:&&new&/span& PayTask(&span class=&keyword& style=&font-weight:&&this&/span&);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&String version = payTask.getVersion();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&Toast.makeText(&span class=&keyword& style=&font-weight:&&this&/span&, version, Toast.LENGTH_SHORT).show();
&span class=&indent&&
&span class=&indent&&
&/span&&span class=&javadoc& style=&color: rgb(153, 153, 136); font-style:&&/**
&span class=&indent&&
&/span& * create the order info. 创建订单信息
&span class=&indent&&
&span class=&indent&&
&/span& */&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& String getOrderInfo(String subject, String body, String price) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 签约合作者身份ID&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&String orderInfo = &span class=&string& style=&color: rgb(221, 17, 68);&&&partner=&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span& + PARTNER + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 签约卖家支付宝账号&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&seller_id=&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span& + SELLER + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 商户网站唯一订单号&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&out_trade_no=&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span& + getOutTradeNo() + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 商品名称&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&subject=&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span& + subject + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 商品详情&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&body=&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span& + body + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 商品金额&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&total_fee=&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span& + price + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 服务器异步通知页面路径&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&¬ify_url=&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span& + &span class=&string& style=&color: rgb(221, 17, 68);&&&http://notify.msp.hk/notify.htm&&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&+ &span class=&string& style=&color: rgb(221, 17, 68);&&&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 服务接口名称, 固定值&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&service=\&mobile.securitypay.pay\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 支付类型, 固定值&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&payment_type=\&1\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 参数编码, 固定值&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&_input_charset=\&utf-8\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 设置未付款交易的超时时间&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 默认30分钟,一旦超时,该笔交易就会自动被关闭。&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 取值范围:1m~15d。&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 该参数数值不接受小数点,如1.5h,可转换为90m。&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&it_b_pay=\&30m\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// orderInfo += &&extern_token=& + &\&& + extern_token + &\&&;&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&orderInfo += &span class=&string& style=&color: rgb(221, 17, 68);&&&&return_url=\&\&&&/span&;
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&comment& style=&color: rgb(153, 153, 136); font-style:&&// orderInfo += &&paymethod=\&expressGateway\&&;&/span&
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&return&/span& orderI
&span class=&indent&&
&span class=&indent&&
&/span&&span class=&javadoc& style=&color: rgb(153, 153, 136); font-style:&&/**
&span class=&indent&&
&/span& * get the out_trade_no for an order. 生成商户订单号,该值在商户端应保持唯一(可自定义格式规范)
&span class=&indent&&
&span class=&indent&&
&/span& */&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& String getOutTradeNo() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&SimpleDateFormat format = &span class=&keyword& style=&font-weight:&&new&/span& SimpleDateFormat(&span class=&string& style=&color: rgb(221, 17, 68);&&&MMddHHmmss&&/span&,
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&indent&&
&/span&Locale.getDefault());
&span class=&indent&&
&/span&&span class=&indent&&
&/span&Date date = &span class=&keyword& style=&font-weight:&&new&/span& Date();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&String key = format.format(date);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&Random r = &span class=&keyword& style=&font-weight:&&new&/span& Random();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&key = key + r.nextInt();
&span class=&indent&&
&/span&&span class=&indent&&
&/span&key = key.substring(&span class=&number& style=&color: rgb(0, 153, 153);&&0&/span&, &span class=&number& style=&color: rgb(0, 153, 153);&&15&/span&);
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&return&/span&
&span class=&indent&&
&span class=&indent&&
&/span&&span class=&javadoc& style=&color: rgb(153, 153, 136); font-style:&&/**
&span class=&indent&&
&/span& * sign the order info. 对订单信息进行签名
&span class=&indent&&
&span class=&indent&&
&/span& * &span class=&javadoctag&&@param&/span& content
&span class=&indent&&
待签名订单信息
&span class=&indent&&
&/span& */&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& String sign(String content) {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&return&/span& SignUtils.sign(content, RSA_PRIVATE);
&span class=&indent&&
&span class=&indent&&
&/span&&span class=&javadoc& style=&color: rgb(153, 153, 136); font-style:&&/**
&span class=&indent&&
&/span& * get the sign type we use. 获取签名方式
&span class=&indent&&
&span class=&indent&&
&/span& */&/span&
&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&public&/span& String getSignType() {
&span class=&indent&&
&/span&&span class=&indent&&
&/span&&span class=&keyword& style=&font-weight:&&return&/span& &span class=&string& style=&color: rgb(221, 17, 68);&&&sign_type=\&RSA\&&&/span&;
&span class=&indent&&
}这一段代码要和上一段代码放在一个Java
文件中,需要注意的一个方法是。 pay() 方法和getOrderInfo(); 需要注意的是,在我们选择支付宝支付的按钮中调用的 是 pay() 方法。而放在pay()方法中则需要调用getOrderInfo(),仔细发现,getOrderInfo()方法里面的三个参数。其中price 参数就是我们要消费的金额,当我们调用pay()方法的时候,就需要传入一个price 的参数,就是我们需要支付的金额。具体的金额怎么传入,计算,要根据项目需要来自己获取了,这样项目集成支付宝就圆满结束了。
配置的具体操作:
在PayDemoActivity中配置几个变量:
在这里填上我们上面找到的PID;
然后在SELLER上写上我们支付宝的登录帐户,即那个你申请移动支付的支付宝账号
然后在RSA_PUBLIC这里填上支付宝公钥
最后是填上RSA_PRIVATE对应的商户私钥,注意是PKCS8格式的。
私钥这部分,注意是----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----之间的部分,即那段纯代码,不要把----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----给复制进去了。中间的这部分就是公钥。
现在运行demo就直接可以支付了。
本文中对应的DEMO在文章底部给出。
4、代码讲解
通过上面的配置,demo应该就直接可以运行了,但这里所涉及的代码,我们再仔细看看
主要的支付与结果返回就是pay()这个函数,这里完成了支付所需要的所有功能。代码如下:
这里总是分了四步来完成支付与结果接收。
第一步:构造定单信息:
主要是这句,即在getOrderInfo()函数中完成定单信息的构造:(这里对getOrderInfo函数做的精减,更多字段及意义参考源码)
有关paymethod的方法使用,参考:
各个字段的意义及取值参考:
这里就是通过我们的提供的商家ID,产品信息,价格等信息来构造定单及回调页面,这里需要非常注意的一个地方:
服务器异步通知页面路径,首先我们用支付宝支付之后,支付宝会返回给我们两个通知,一个是同步的,就是我们点击支付后支付宝直接反馈给我们客户端的信息,我们可以直接拿到,根据反馈的结果可以初步判定该次交易是否成功,第二个就是服务器异步的通知,这个异步的通知是支付宝的服务器端发给我们服务器端的信息,我们在客户端是直接获取不了的,那支付宝的服务器怎么知道我们服务器的路径呢,那就是这参数的作用了,我们给支付宝服务器一个路径,它就会在订单状态改变的时候给我们服务器端一个反馈,告诉服务器这次交易的状态,如果服务器结果判定该次交易成功了,就必须返给支付宝服务器一个success,要不服务器会一直给我们异步通知,因为它不知道该次交易是否完成了(一般情况下25小时内8次通知,频率一般是2m
10m 10m 1h 2h 6h 15h),我们一般会在收到异步通知时,对订单的状态进行更新。
其它的就不讲了,通过看源码都能看得懂,比如构造订单号啥的。
第二步:对订单字符串做RSA签名
为什么要签名呢?当然是防止传输出错了,这可是跟钱相关的,如果orderInfo传输过程中出错了,那怎么样来校验它是不是出错了呢,只有通过签名算法来了。所以这里就需要对订单字符串做签名。
具体签名算法就不讲了,直接应用到项目中就行,不需要理解,如果想看看怎么实现的,里面有对应的源码,可以去研究一下。
第三步:构造完成的请求字符串
在订单字符串和签名做完以后,就可以用他们来构造完整的请求字符串了:
第四步:请求与结果返回
最后是发送请求,代码如下:
最关键的部分在这里:
在String result = alipay.pay(payInfo);中,就直接获得了支付结果;
然后通过handler将结果发送出去。
这就是同步的方式获取支付结果的方式。
好了,有关支付宝对接的方法全部都在这了。至于getOrderInfo函数里,使用的调用银行卡支付,我觉得也没啥用,在我们程序里也没接上。
DEMO 传送门:
上传的demo可以直接运行,但是为了个人隐私把相关配置信息删了,然后去支付的时候会提示你去配置相关的东西。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:30480次
排名:千里之外
转载:298篇
评论:58条
(10)(76)(62)(40)(59)(59)

我要回帖

更多关于 qq音乐付费歌曲 的文章

 

随机推荐