`
xumingrencai
  • 浏览: 1180207 次
文章分类
社区版块
存档分类
最新评论

Android学习系列--App集成支付宝

 
阅读更多

手机的在线支付,被认为是2012年最看好的功能,我个人认为这也是移动互联网较传统互联网将会大放光彩的一个功能。
人人有手机,人人携带手机,花钱买东西,不再需要取钱付现,不再需要回家上网银,想买什么,扫描一下,或者搜索一下,然后下单,不找零,直接送到你家,这将是手机支付给我们带来的全新交易体验。
谷歌刚推出了谷歌钱包,这必是我们后面要使用的主要手段,但是鉴于当前国情,我觉得有必要介绍一下android手机集成支付宝功能。

1.下载官方架包和说明文档
其实官方已经提供了安装指南,下载地址:
https://mobiless.alipay.com/product/product_down_load.htm?code=SECURITY_PAY
里面有有个pdf,详细说明了说用指南,写的比较详细,可以重点参考。


下载下来,我们主要是用到Android(20120104)目录下的alipay_plugin.jar和AppDemo/assets下的alipay_plugin223_0309.apk,这两个文件是我们不能修改的支付宝api和安装包。

2. 商户签约
现在的安全机制,都是这样,客户端需要先和服务端请求验证后才能进行进一步操作,oauth也是如此。
打开https://ms.alipay.com/,登陆支付宝,点击签约入口,选择"应用类产品",填写并等待审核,获取商户ID和账户ID。
签约的时候还要向需要提供实名认证和上传应用,所以我建议先把应用做好了,最后再集成支付宝。


我大概等了1-2天审核,审核是失败的,回复是应用类型啥的应该是"虚拟货币",我改成那个马上自动就审核通过了。

3.密钥配置
解压openssl-0.9.8k_WIN32(RSA密钥生成工具).zip,打开cmd,命令行进入openssl-0.9.8k_WIN32(RSA密钥生成工具)\bin目录下,
(1).执行

1
openssl genrsa -out rsa_private_key.pem 1024

生成rsa_private_key.pem文件。
(2).再执行

1
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

生成rsa_public_key.pem 文件。
(3).在执行

1
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

将RSA私钥转换成 PKCS8 格式,去掉begin和end那两行,把里面的内容拷贝出来,保存到某个txt中,如rsa_private_pkcs8_key.txt中(我好像没用到这个)。
打开rsa_public_key.pem,即商户的公钥,复制到一个新的TXT中,删除文件头”-----BEGIN PUBLIC KEY-----“与文件尾”-----END PUBLIC KEY-----“还有空格、换行,变成一行字符串并保存该 TXT 文件,然后在网站的“我的商家服务”切换卡下的右边点击“密钥管理”,然后有个"上传商户公钥(RSA)"项,选择上传刚才的TXT文件.
好了,服务器配置OK,因为这一段之前没有截图,现在弄好了又不好截图,如果有不明白的地方请大家参考官方文档。

4.引用jar和包含安装包
(1).新建android工程;
(2).copy上面说的alipay_plugin.jar到工程的libs目录下,并在java build path中通过Add External JARs找到并引用该jar;
(3).copy上面说的alipay_plugin223_0309.apk安装包到assets目录下,后面配置路径用到。

如果libs和assets目录没有,手动建立者两个目录。

5.调用代码整理
这里我们要严重的参考文档中AppDemo,我们建一个包com.tianxia.lib.baseworld.alipay,把AppDemo的com.alipay.android.appDemo4包下的源码全部copy到刚才我们自己的包下,还有res目录下的资源文件也合并到我们工程res下。
其中AlixDemo.java,ProductListAdapter.java,Products.java是示例类,我们借鉴完后可以删除。
PartnerConfig.java是配置类,配置商户的一些配置参数。
其他的类是严重参考类,直接留下使用。
PartnerConfig.java代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
publicclassPartnerConfig {
//合作商户ID。用签约支付宝账号登录ms.alipay.com后,在账户信息页面获取。
publicstaticfinalString PARTNER = "xxx";
//账户ID。用签约支付宝账号登录ms.alipay.com后,在账户信息页面获取。
publicstaticfinalString SELLER = "xxx";
//商户(RSA)私钥 ,即rsa_private_key.pem中去掉首行,最后一行,空格和换行最后拼成一行的字符串
publicstaticfinalString RSA_PRIVATE = "xxx";
//支付宝(RSA)公钥 用签约支付宝账号登录ms.alipay.com后,在密钥管理页面获取。
publicstaticfinalString RSA_ALIPAY_PUBLIC = "xxx";
//下面的配置告诉应用去assets目录下找安装包
publicstaticfinalString ALIPAY_PLUGIN_NAME ="alipay_plugin223_0309.apk";
}

AlixDemo中代码是最终的调用代码在onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {}中,下面我们提取其中的核心代码。

6.提取核心调用代码
在AlixDemo.java同目录下新建AlixPay.java,来提取AlixDemo.java的核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
packagecom.tianxia.lib.baseworld.alipay;
importjava.net.URLEncoder;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importcom.tianxia.lib.baseworld.R;
importandroid.app.Activity;
importandroid.app.ProgressDialog;
importandroid.content.DialogInterface;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.view.KeyEvent;
importandroid.widget.Toast;
publicclassAlixPay {
staticString TAG = "AlixPay";
privateActivity mActivity;
publicAlixPay(Activity activity) {
mActivity = activity;
}
privateProgressDialog mProgress = null;
// the handler use to receive the pay result.
privateHandler mHandler = newHandler() {
publicvoidhandleMessage(Message msg) {
try{
String strRet = (String) msg.obj;
switch(msg.what) {
caseAlixId.RQF_PAY: {
closeProgress();
BaseHelper.log(TAG, strRet);
try{
String memo = "memo=";
intimemoStart = strRet.indexOf("memo=");
imemoStart += memo.length();
intimemoEnd = strRet.indexOf(";result=");
memo = strRet.substring(imemoStart, imemoEnd);
ResultChecker resultChecker = newResultChecker(strRet);
intretVal = resultChecker.checkSign();
if(retVal == ResultChecker.RESULT_CHECK_SIGN_FAILED) {
BaseHelper.showDialog(
mActivity,
"提示",
mActivity.getResources().getString(
R.string.check_sign_failed),
android.R.drawable.ic_dialog_alert);
}else{
BaseHelper.showDialog(mActivity,"提示", memo,
R.drawable.infoicon);
}
}catch(Exception e) {
e.printStackTrace();
BaseHelper.showDialog(mActivity,"提示", strRet,
R.drawable.infoicon);
}
}
break;
}
super.handleMessage(msg);
}catch(Exception e) {
e.printStackTrace();
}
}
};
// close the progress bar
voidcloseProgress() {
try{
if(mProgress != null) {
mProgress.dismiss();
mProgress = null;
}
}catch(Exception e) {
e.printStackTrace();
}
}
publicvoidpay() {
MobileSecurePayHelper mspHelper = newMobileSecurePayHelper(mActivity);
booleanisMobile_spExist = mspHelper.detectMobile_sp();
if(!isMobile_spExist)
return;
if(!checkInfo()) {
BaseHelper.showDialog(mActivity,"提示",
"缺少partner或者seller,", R.drawable.infoicon);
return;
}
try{
// prepare the order info.
String orderInfo = getOrderInfo();
String signType = getSignType();
String strsign = sign(signType, orderInfo);
strsign = URLEncoder.encode(strsign);
String info = orderInfo + "&sign="+"\""+ strsign + "\""+"&"
+ getSignType();
// start the pay.
MobileSecurePayer msp = newMobileSecurePayer();
booleanbRet = msp.pay(info, mHandler, AlixId.RQF_PAY, mActivity);
if(bRet) {
// show the progress bar to indicate that we have started paying.
closeProgress();
mProgress = BaseHelper.showProgress(mActivity, null,"正在支付",false,
true);
}else
;
}catch(Exception ex) {
Toast.makeText(mActivity, R.string.remote_call_failed,
Toast.LENGTH_SHORT).show();
}
}
privatebooleancheckInfo() {
String partner = PartnerConfig.PARTNER;
String seller = PartnerConfig.SELLER;
if(partner == null|| partner.length() <= 0|| seller == null
|| seller.length() <= 0)
returnfalse;
returntrue;
}
// get the selected order info for pay.
String getOrderInfo() {
String strOrderInfo = "partner="+"\""+ PartnerConfig.PARTNER + "\"";
strOrderInfo += "&";
strOrderInfo += "seller="+"\""+ PartnerConfig.SELLER + "\"";
strOrderInfo += "&";
strOrderInfo += "out_trade_no="+"\""+ getOutTradeNo() + "\"";
strOrderInfo += "&";
//这笔交易价钱
strOrderInfo += "subject="+"\""+ mActivity.getString(R.string.donate_subject) + "\"";
strOrderInfo += "&";
//这笔交易内容
strOrderInfo += "body="+"\""+ mActivity.getString(R.string.donate_body) + "\"";
strOrderInfo += "&";
//这笔交易价钱
strOrderInfo += "total_fee="+"\""+"10.00"+"\"";
strOrderInfo += "&";
strOrderInfo += "notify_url="+"\""
returnstrOrderInfo;
}
// get the out_trade_no for an order.
String getOutTradeNo() {
SimpleDateFormat format = newSimpleDateFormat("MMddHHmmss");
Date date = newDate();
String strKey = format.format(date);
java.util.Random r = newjava.util.Random();
strKey = strKey + r.nextInt();
strKey = strKey.substring(0,15);
returnstrKey;
}
// get the sign type we use.
String getSignType() {
String getSignType = "sign_type="+"\""+"RSA"+"\"";
returngetSignType;
}
// sign the order info.
String sign(String signType, String content) {
returnRsa.sign(content, PartnerConfig.RSA_PRIVATE);
}
// the OnCancelListener for lephone platform.
staticclassAlixOnCancelListenerimplements
DialogInterface.OnCancelListener {
Activity mcontext;
AlixOnCancelListener(Activity context) {
mcontext = context;
}
publicvoidonCancel(DialogInterface dialog) {
mcontext.onKeyDown(KeyEvent.KEYCODE_BACK,null);
}
}
}

这个类的pay方法就是支付的方法,最简单的不设置的话,调用方法如下:

1
2
AlixPay alixPay = newAlixPay(SettingTabActivity.this);
alixPay.pay();

如果没有安装支付宝,它会提示你安装,如果已经安装,它直接让你选择付款:

这说明已经配置成功了。
然后可以删掉那些示例java文件了:AlixDemo.java,ProductListAdapter.java,Products.java。
你也可以通过调整参数来修改订单信息,如主题,价格等。
另外在BaseHelper的94行:

1
dialog.setOnCancelListener(newAlixDemo.AlixOnCancelListener( (Activity)context ) );

需要修改为:

1
dialog.setOnCancelListener(newAlixPay.AlixOnCancelListener( (Activity)context ) );

7.注意
我在测试的时候,调用的activity是框在一个ActivityGroup里的(与tabhost类似,据说tabhost也有这个问题),导致MobileSecurePayer.java的pay方法中调用服务的两行代码:

mActivity.bindService(newIntent(IAlixPay.class.getName()), mAlixPayConnection, Context.BIND_AUTO_CREATE);
mActivity.unbindService(mAlixPayConnection);

需要修改为:

1
2
mActivity.getApplicationContext().bindService(newIntent(IAlixPay.class.getName()), mAlixPayConnection, Context.BIND_AUTO_CREATE);
mActivity.getApplicationContext().unbindService(mAlixPayConnection);

不然会报错java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.android.server.am.ActivityRecord$Token...

8.小结
支付宝的集成比我想象的要复杂一些,比较麻烦,首先需要审核,然后代码需要提取,所以写出来与大家分享。
在做集成配置的时候,一定要仔细认真,一个地方出错,可能要导致后面查错查很长时间。
因为本人是先集成成功后才写的这篇文章,难免会漏掉一些重要的细节或者步骤,如有不对,请留言指正。


from:http://www.cnblogs.com/qianxudetianxia/archive/2012/04/04/2432406.html

Android支付接入(一):支付宝

http://blog.csdn.net/simdanfeg/article/details/9011603


Android alipay sdk

http://www.pudn.com/downloads443/sourcecode/comm/android/detail1871145.html

http://pan.baidu.com/s/1dDzixOX


分享到:
评论

相关推荐

    android APP集成支付宝

    android集成了APP支付宝功能的Demo,通过测试

    swift-cordova-plugin-alipay支付宝App支付插件支持AndroidiOS

    cordova-plugin-alipay, 支付宝App支付插件,支持Android、iOS

    Android支付宝授权,支付宝登录demo

    Android支付宝授权,支付宝登录demo,非常简洁高效集成

    支付宝支付移动端(原生Android)

    在App内集成支付宝支付。APP调用支付宝提供的SDK,SDK再调用支付宝APP内的支付模块。如果用户已安装支付宝APP,商家APP会跳转到支付宝中完成支付,支付完后跳回到商家APP内。如果用户没有安装支付宝APP,商家APP内会...

    支付宝官方app支付详细demo

    适用于商家在App应用中集成支付宝支付功能。 商家APP调用支付宝提供的SDK,SDK再调用支付宝APP内的支付模块。如果用户已安装支付宝APP,商家APP会跳转到支付宝中完成支付,支付完后跳回到商家APP内,最后展示支付...

    Android代码-第三方SDK集成库(授权分享支付)

    第三方SDK集成库,支持 授权/分享/支付 等功能 授权 目前支持 微信/QQ/新浪微博,客户端只需要配置APPID(新浪微博) 分享 目前支持 微信(会话/朋友圈/收藏),QQ/QZone,新浪微博 支付 目前支持 支付宝/微信支付 对于...

    如何在Android App中集成支付宝和微信支付功能

    下面这篇文章主要给大家介绍了关于如何在Android App中集成支付宝和微信支付功能的相关资料,文中通过示例代码介绍的非常详细,需要的朋友下面随着小编来一起学习学习吧

    jenly1314-AppPay-master.zip

    AppPay for Android 是一个专注于App支付的库,将主流的官方App支付集成方式进行封装、简化,让实现App支付简单到只需几句代码。 AppPay目前包括的库 WXPay 封装的微信支付库,使用起来更简单。 AliPay 封装...

    安卓集成支付宝的 签名获取工具

    使用说明:安装到手机,直接输入你想签名的apk 的包名,获取签名

    CN5E-shop-master:商城类的应用

    仿京东商城系列14------用户登录以及app登录拦截 仿京东长城系列15------用户注册,SMSSDK集成 仿京东商城系列16------支付SDK集成 仿京东商城系列17------支付功能实现 仿京东商城系列18------xml文件读取(地址...

    uni-app框架.rar

    uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到 iOS,Android,H5,以及各种小程序(微信/支付宝/百度/头条/ QQ /钉钉)等多个平台。 uni-app在手,做啥都不愁。甚至不跨端,也...

    Android支付宝和微信支付集成

    随着移动支付的兴起,在我们的app’中,会经常有集成支付的需求.这时候一般都会采用微信和支付宝的sdk 来集成 (一)支付宝支付 在使用支付宝支付的过程中,我们是在服务器端生成订单,客户端访问接口,并得到订单信息,...

    android简历app

    1、集成友盟分享,登录,统计,推送; 2、集成zxing扫描二维码和生成二维码; 3、集成sqlite数据库存储信息;...11、支付宝和微信支付(均未签约无法真实支付,但是支付宝可以调用沙箱应用完成支付流程)

    支付宝集成过程详解

    最近在做APP接入支付宝支付的功能,找到一个不错的资料,里面是Android和iOS接入支付宝支付功能的相关demo源码。

    校园代领快递APP

    Ionic-bate(测试版)开发的校园代领快递APP,Ionic可同时部署...缺点就是现有的第三方SDK比如百度地图,支付宝,推送等都还是JS SDK,在Typescript上集成不太方便,So,坐等Typescript发展&普及&Ionic2;稳定版的推出。

    博客社区APP源代码 知识支付社区APP源代码 资源小区源码 独特的付费广告 安卓苹果

    7.适应Android苹果APP、H5网页、小程序、QQ小程序,理论适应所有小程序平台,开发更多支持... 8.拥有管理员页面,完成权限分级,整个网站只能在APP中管理。 9.独特的付费广告模块:文章拉流广告、横幅广告、启动图...

    多端商城app/小程序(自研项目)

    商城基于thinkphp6+element-ui+uniapp打造的面向开发的小程序商城,方便二次开发或直接使用,可发布到多端,包括微信小程序、微信公众号、QQ小程序、支付宝小程序、字节跳动小程序、百度小程序、android端、ios端。...

    应用商店-机锋市场Android源码.zip

    项目内所有数据直接在机锋网获取 本项目源码为商业源码 售价50专家币 以下截图是项目编译后的工程截图 截图中的功能都已经实现 识货的朋友可以在后台在线充值后下载涉及模块&技术通知栏网络检测支付宝集成登录注册...

    微信公众号极速开发实战项目源代码

    Android 微信、支付App支付SDK IJPay 让支付触手可及,实现微信、支付宝系列支付 博客 简易的微信公众号管理平台 搭建属于自己的网穿透工具 SpringBoot 2.x 集成QQ邮箱、网易系邮箱、Gmail邮箱发送邮件 项目...

Global site tag (gtag.js) - Google Analytics