Android 支付开发(支付宝)
支付宝更新了开发文档,针对最近的支付开发,做一下详细的开发流程总结。
一、接入流程
1.1、第一步:创建应用并获取APPID
创建应用,获取APPID,并且可以申请开通开放产品使用权限,通过APPID您的应用才能正常使用有权限调用的开放产品的接口能力。
具体参考:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105308&docType=1
1.2、第二步:配置密钥
这一步可以找后台人员配置,也可以自己配置,具体不作详叙,需要用到的是支付宝私钥。
具体参考:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105310&docType=1
1.3 第三部:集成并配置SDK
下载SDK,添加到项目中。
在商户应用工程的AndroidManifest.xml文件里面添加声明:
<activity
android:name="com.alipay.sdk.app.H5PayActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind" >
</activity>
<activity
android:name="com.alipay.sdk.auth.AuthActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind" ></activity>
权限声明:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
添加混淆:
-libraryjars libs/alipaySDK-20150602.jar-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
1.4、第四步:调用接口
这里看的很清晰,我们需要考虑的是2345678这几步即可。主要说一下获取的订单是签名后的订单信息,并没有将配置信息放在客户端来进行操作,这是为了安全性来考虑的。
构造交易数据并签名必须在商户服务端完成,商户的应用私钥绝对不能保存在商户APP客户端中,也不能从服务端下发。
同步返回的数据,只是一个简单的结果通知,商户确定该笔交易付款是否成功需要依赖服务端收到支付宝异步通知的结果进行判断。
商户系统接收到通知以后,必须通过验签(验证通知中的sign参数)来确保支付通知是由支付宝发送的。建议使用支付宝提供的SDK来完成
1.5、如何调用以及订单参数详解
这一步可以参考修改一下demo。
public void payV2(View v) {if (TextUtils.isEmpty(APPID) || TextUtils.isEmpty(RSA_PRIVATE)) {new AlertDialog.Builder(this).setTitle("警告").setMessage("需要配置APPID | RSA_PRIVATE").setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialoginterface, int i) {//finish();}}).show();return;}Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APPID);String orderParam = OrderInfoUtil2_0.buildOrderParam(params);String sign = OrderInfoUtil2_0.getSign(params, RSA_PRIVATE);final String orderInfo = orderParam + "&" + sign;Runnable payRunnable = new Runnable() {@Overridepublic void run() {PayTask alipay = new PayTask(PayDemoActivity.this);Map<String, String> result = alipay.payV2(orderInfo, true);Log.i("msp", result.toString());Message msg = new Message();msg.what = SDK_PAY_FLAG;msg.obj = result;mHandler.sendMessage(msg);}};Thread payThread = new Thread(payRunnable);payThread.start();}
支付行为需要在独立的非ui线程中执行。
支付结果获取和处理:
同步结果
private Handler mHandler = new Handler() {public void handleMessage(Message msg) {@SuppressWarnings("unchecked")PayResult payResult = new PayResult((Map<String, String>) msg.obj);/*** 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.com/doc2/* detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&* docType=1) 建议商户依赖异步通知*/String resultInfo = payResult.getResult();// 同步返回需要验证的信息String resultStatus = payResult.getResultStatus();// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档if (TextUtils.equals(resultStatus, "9000")) {Toast.makeText(PayDemoActivity.this, "支付成功", Toast.LENGTH_SHORT).show();} else {// 判断resultStatus 为非"9000"则代表可能支付失败// "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)if (TextUtils.equals(resultStatus, "8000")) {Toast.makeText(PayDemoActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();} else {// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误Toast.makeText(PayDemoActivity.this, "支付失败", Toast.LENGTH_SHORT).show();}}};};
异步结果:
在订单中返回一个key为notify_url的链接,支付宝会以POST方式调用notify_url传输数据。
支付参数:
Map<String, String> result = alipay.payV2(orderInfo, true);
orderInfo:加签后的订单信息,app支付请求参数字符串,主要包含商户的订单信息,key=value形式,以&连接。
true:boolean isShowPayLoading,加载过渡。
订单参数:
public static Map<String, String> buildOrderParamMap(String app_id) {Map<String, String> keyValues = new HashMap<String, String>();keyValues.put("app_id", app_id);keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"0.01\",\"subject\":\"1\",\"body\":\"我是测试数据\",\"out_trade_no\":\"" + getOutTradeNo() + "\"}");keyValues.put("charset", "utf-8");keyValues.put("method", "alipay.trade.app.pay");keyValues.put("sign_type", "RSA");keyValues.put("timestamp", "2016-07-29 16:55:53");keyValues.put("version", "1.0");return keyValues;}
包含公共参数和业务参数。biz_content是业务参数,其他均是公共参数。
这里虽然不是必须参数,但是还要具体配置,还是写上为好。毕竟别支付到别人账户去了哈哈!
订单加签流程:
- 请求参数按照key=value&key=value方式拼接的未签名原始字符串:
/*** 构造支付订单参数信息* * @param map* 支付订单参数* @return*/public static String buildOrderParam(Map<String, String> map) {List<String> keys = new ArrayList<String>(map.keySet());StringBuilder sb = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);sb.append(buildKeyValue(key, value, true));sb.append("&");}String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);sb.append(buildKeyValue(tailKey, tailValue, true));return sb.toString();}
- 再对原始字符串进行签名
/*** 对支付参数信息进行签名* * @param map* 待签名授权信息* * @return*/public static String getSign(Map<String, String> map, String rsaKey) {List<String> keys = new ArrayList<String>(map.keySet());// key排序Collections.sort(keys);StringBuilder authInfo = new StringBuilder();for (int i = 0; i < keys.size() - 1; i++) {String key = keys.get(i);String value = map.get(key);authInfo.append(buildKeyValue(key, value, false));authInfo.append("&");}String tailKey = keys.get(keys.size() - 1);String tailValue = map.get(tailKey);authInfo.append(buildKeyValue(tailKey, tailValue, false));String oriSign = SignUtils.sign(authInfo.toString(), rsaKey);String encodedSign = "";try {encodedSign = URLEncoder.encode(oriSign, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return "sign=" + encodedSign;}
具体参考:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105351&docType=1
- 最后对请求字符串value进行encode,编码格式按请求串中的charset为准,没传charset按UTF-8处理,获得最终的请求字符串:
// 仅需对sign 做URL编码
sign = URLEncoder.encode(sign, "UTF-8");
demo已经将2,3合并成一步。
支付结果验证:
当然,前面所述,基本支付功能不成问题,但是为了程序的严谨性和支付的安全性考虑,还是需要对支付结果进行验证。
同步通知验证:
示例:
{"memo" : "xxxxx","result" : "{\"alipay_trade_wap_pay_response\":{\"code\":\"10000\",\"msg\":\"Success\",\"app_id\":\"2014072300007148\",\"out_trade_no\":\"081622560194853\",\"trade_no\":\"2016081621001004400236957647\",\"total_amount\":\"0.01\",\"seller_id\":\"2088702849871851\",\"charset\":\"utf-8\"},\"sign\":\"NGfStJf3i3ooWBuCDIQSumOpaGBcQz+aoAqyGh3W6EqA/gmyPYwLJ2REFijY9XPTApI9YglZyMw+ZMhd3kb0mh4RAXMrb6mekX4Zu8Nf6geOwIa9kLOnw0IMCjxi4abDIfXhxrXyj********\",\"sign_type\":\"RSA\"}","resultStatus" : "9000"
}
code结果码:
具体意思即验证返回结果信息跟订单信息是否一致,当然验证的参数也比较多
具体参考:
https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.1N7QWY&treeId=193&articleId=105302&docType=1
异步验证:
这里是服务端做的验证,支付成功后支付宝会吊起notify_url上的链接,返回支付参数,服务端对支付参数进行解析验证。
具体参考:
https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.q9gQhV&treeId=193&articleId=105301&docType=1
旧版支付当前还在兼容使用,当然需要使用旧版的SDK,具体需要注意的是
Android 支付开发(支付宝)相关推荐
- Android 开发中如何实现在webview中打开微信支付、支付宝、QQ钱包支付
在Android实际开发中往往会遇到不在项目中添加微信,支付宝,QQ钱包支付的SDK,但是还是要调用本地App进行支付,我们可以在webview中进行解决这样的问题,具体的代码如下: @Overrid ...
- android支付宝、微信支付开发流程
这一段时间项目需要加上微信支付和支付宝支付,经过一段时间摸索,总算能够正常进行支付使用了.想想在支付上遇到的坑,我觉得有必要进行一个记录,在后续的开发中避开支付中遇到的坑: 一.支付宝支付: ps:支 ...
- android条码支付开发,详解支付宝条码支付:1分钟完成收单 成本降低
条码支付详细信息 支付宝条码支付演示 新浪科技讯 7月1日下午消息,今天上午支付宝在2011广州网货会上宣布推出手机支付产品--条码支付(Barcode Pay).该方案为微小商户提供了只需使用智能手 ...
- Android支付宝错误码62009,hb混合开发app 微信支付提示支付宝62009未知错误
问题描述 hb混合开发app 微信支付提示支付宝62009未知错误 问题出现的环境背景及自己尝试过哪些方法 真机模拟测试 相关代码 获取通道 mounted(){ plus.payment.getCh ...
- android 支付模块封装,Android集成支付----支付宝支付总结与封装
前言 类似于Android集成支付----微信支付总结与封装(可以查看本人另外一篇文章),本文对支付宝支付进行一个总结与封装.相比于微信支付,支付宝支付没有那么多坑. 集成支付宝支付SDK 这里只是简 ...
- 移动支付--银联,支付宝,微信(android)
在这个移动互联网快速发展的时代,手机已经成为人们生活或者出行之中必不可少的设备了,如今非常多城市的商户都能够採用支付宝,微信支付了.人们出门仅仅须要随身携带带手机.不用带大量现金就能够放心购物了.如今 ...
- 微信支付及支付宝支付开发指南
从开始学习android开始到现在还没搞过三方支付,感觉挺遗憾的.看到最近有几篇关于微信支付和支付宝支付的文章,稍微进行一下整合,供大家参考. ---------------------------- ...
- Android端集成支付宝支付
Android端集成支付宝支付 1.申请账号及配置变量 支付宝快速接入链接点击打开链接 支付宝扫码或者账号密码登录 下面是支付宝给出的接入介绍 第一步:创建应用并获取APPID 要在您的应用中接入支付 ...
- Android 如何开发指纹支付
一.为什么要指纹支付 趋势,就这么简单. 二.什么是指纹支付 指纹支付是一种便捷的生物认证支付方式,它让用户摆脱繁琐的密码.短信认证,便捷性得到大大的提高.提高应用的易用性,使用率和用户留存率. 三. ...
最新文章
- TIOBE 9 月编程语言排行榜发布,C++ 增速最快,C++20 的功劳?
- 某互联网大厂出现招聘事故!HR告知应聘者肯定会发offer,应聘者拒绝另一家公司耐心等待,hr却说流程有变,offer被卡!...
- python【蓝桥杯vip练习题库】ADV-350珠心算测验
- python连通域标记_pythonamp;#8212;二值图像连通域标记 - 易采站长站
- 魔域几点服务器重置,服务器维护后第一轮BOSS时间以及每张地图的BOSS点!
- 网页按钮跳转位置_RPA工具BizRobo!之运用网页数据处理
- CCF之地铁修建(100分)
- Linux 图片传输功能c/c++(初版)
- 网站能拿到其他网站的cookie_网站能给公司带来哪些好处?
- c语言排序方法有哪几种?
- 浅谈Dynamic 关键字系列之三(下):ExpandoObject,DynamicObject,DynamicMetaObject
- 循环中的continue功能
- rostcm6情感分析案例分析_情感分析师在线指导情感挽回
- 文本标注工具之BRAT
- ubuntu1804安装显卡驱动
- 计算机监理培训计划,监理人员培训计划书.doc
- greendao的简单使用
- html将数据永久保存起来,数据保存(永久保存)方式(示例代码)
- win10和win11系统,手机或者其他设备连接不上电脑热点,一直在转圈圈的解决方法
- 【Python数据挖掘课程】八.关联规则挖掘及Apriori实现购物推荐