Android开发支付集成——支付宝集成
微信支付传送门:https://www.cnblogs.com/dingxiansen/p/9209159.html
一、支付宝支付
1. 支付宝支付流程图
2. 集成前准备
- 去蚂蚁金服注册应用获取appKey等信息
- 创建应用,添加APP支付功能
- 找到APP支付开发文档,下载 SDK&Demo
3. 开始集成
1、导入Demo中需要用到的Jar包
2、配置AndroidManifest.xml(这里直接放常用的权限)
- <!--所需权限-->
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.READ_LOGS" />
- <uses-permission android:name="android.permission.VIBRATE" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <!--广播跳转-->
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <!--百度地图-->
- <!--百度地图权限-->
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
- <!--Mob分享-->
- <uses-permission android:name="android.permission.GET_TASKS" />
- <!-- 短信验证登陆功能需要添加次权限来自动填充验证码,用不到可以去掉 -->
- <uses-permission android:name="android.permission.RECEIVE_SMS" />
- <uses-permission android:name="android.permission.READ_SMS" />
- <!--微信支付权限-->
- <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
- <!--支付宝支付权限-->
- <!-- 安卓读写sd权限 -->
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
支付回调
- <!--支付宝支付-->
- <!-- 支付宝H5页面支付用的 -->
- <activity
- android:name="com.alipay.sdk.app.H5PayActivity"
- android:configChanges="orientation|keyboardHidden|navigation"
- android:exported="false"
- android:screenOrientation="behind" />
- <!-- 支付宝App支付页面用的 -->
- <activity
- android:name="com.alipay.sdk.auth.AuthActivity"
- android:configChanges="orientation|keyboardHidden|navigation"
- android:exported="false"
- android:screenOrientation="behind" />
3、请求后台接口拿到签过名的信息(appKey,订单信息等等),这里我获取数据,是直接给后台传递的商品id,如果有的需要商品数量直接给传给后台,后台根据id查询出商品的信息,然后返回给前台所需要的支付参数。
支付宝返回参数用例(开始集成的时候看过好多博客都没有返回参数数据结构,结果一脸懵逼,在这里贴出,未加密之前的0.0):
格式化后的:
- {
- "msg":"success",
- "code":200,
- "data":"alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=你们申请的app_id&biz_content=%7B%22out_trade_no%22%3A%22HY201806210002%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3A%22%E4%BC%98%E9%93%BA%E4%BC%9A%E5%91%98%E6%9C%8D%E5%8A%A1%E8%B4%B9%22%2C%22total_amount%22%3A%220.01%22%7D&charset=UTF-8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2F你们的回调地址%2FaliPayCallBack%2FcallBack&sign=buipaoj2F8xl5XCAUVoJz%2Fbh8dHbaoRmdzoAEzqKRJqtZATT4bfFdzSHurAAL5C5gvntFrDTGHgNRGw%2BNZBtG4DfetOzcpHMAyjslrmUIMIr1YGC7Qya04mFBCh%2B0UIa1E7RISZWSbIVCHpZISknNgF2oTuTixNosXvDXzkGYGBUoaxdh1f6%2F%2Bw9lqKz7mkhsUc0x8lCeJHw4MnTS4gSLU%2BDmOCk6Tkiwb4Yv4Mz%2F6j7XReeagfX7qxs5qbObnnPX%2FFmu9T%2BF0LwJaPxr5Xys8kr8E4bhd4f7Y5FimXiw%2BG7EFkY0I69boiRob7zo%2BbWQ%2F53TAMeTXX5RJybEdXhrA%3D%3D&sign_type=RSA2×tamp=2018-06-21+14%3A11%3A40&version=1.0",
- "status":"0"
- }
后台返回信息之后接下来就是我们的事情了,调起支付宝进行支付
- /*支付宝测试*/
- private void testZfbPay(final String key, final String value) {
- StringRequest stringRequest = new StringRequest(Request.Method.POST, NetWorkUrl.ZFBPAY, new Response.Listener<String>() {
- @RequiresApi(api = Build.VERSION_CODES.M)
- @Override
- public void onResponse(String s) {
- Log.e("GoPayOrderActivity", "-------getJson2-------" + s.toString());
- /*判断code*/
- String code = (JSONObject.parseObject(s.toString()).getString("code"));
- if (code.equals("200")) {
- String orderInfo = (JSONObject.parseObject(s.toString()).getString("data"));//返回的信息
- MyALipayUtils.ALiPayBuilder builder = new MyALipayUtils.ALiPayBuilder();
- builder.build().toALiPay(GoPayOrderActivity.this, orderInfo);
- }
- }
- }, new Response.ErrorListener() {
- @Override
- public void onErrorResponse(VolleyError volleyError) {
- }
- }) {
- @Override
- public Map<String, String> getParams() throws AuthFailureError {
- Log.e("GoPayOrderActivity", "getParams:-----------------> " + userEntity.getPhone());
- Map<String, String> map = new HashMap<String, String>();
- map.put("account", userEntity.getPhone());
- map.put(key, value);
- map.put("token", userEntity.getToken());
- return map;
- }
- @Override
- public Map<String, String> getHeaders() throws AuthFailureError {
- HashMap<String, String> headers = new HashMap<String, String>();
- if (userEntity.getToken().equals("") && userEntity != null) {
- headers.put("Authorization", userEntity.getToken());
- }
- return headers;
- }
- };
- /*设置请求一次*/
- stringRequest.setRetryPolicy(
- new DefaultRetryPolicy(
- 5000,//默认超时时间,应设置一个稍微大点儿的,例如本处的500000
- DefaultRetryPolicy.DEFAULT_MAX_RETRIES,//默认最大尝试次数
- DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
- )
- );
- AppApplication.getHttpQueues().add(stringRequest);/*请求数据*/
- }
MyALipayUtils.java这个类直接copy使用就可以
- /**
- * Created by dingchao on 2018/3/20.
- */
- public class MyALipayUtils {
- private static final int SDK_PAY_FLAG = 1;
- private Activity context;
- private ALiPayBuilder builder;
- private MyALipayUtils(ALiPayBuilder builder) {
- this.builder = builder;
- }
- private Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- // 返回码 含义
- // 9000 订单支付成功
- // 8000 正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
- // 4000 订单支付失败
- // 5000 重复请求
- // 6001 用户中途取消
- // 6002 网络连接出错
- // 6004 支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
- // 其它 其它支付错误
- PayResult payResult = new PayResult((Map<String, String>) msg.obj);
- switch (payResult.getResultStatus()) {
- case "9000":
- MobclickAgent.onEvent(context, "payment_success", "付款成功");
- Toast.makeText(context, "支付成功", Toast.LENGTH_SHORT).show();
- AppApplication.finishActivity();
- context.finish();
- // Toast.makeText(this, "支付成功", Toast.LENGTH_SHORT).show();
- /*跳转我的会员页面*/
- // Intent intent = new Intent(context, MyVipActivity.class);
- // context.startActivity(intent);
- break;
- case "8000":
- Toast.makeText(context, "正在处理中", Toast.LENGTH_SHORT).show();
- break;
- case "4000":
- MobclickAgent.onEvent(context, "payment_fali", "付款失败");
- Toast.makeText(context, "订单支付失败", Toast.LENGTH_SHORT).show();
- break;
- case "5000":
- Toast.makeText(context, "重复请求", Toast.LENGTH_SHORT).show();
- break;
- case "6001":
- Toast.makeText(context, "已取消支付", Toast.LENGTH_SHORT).show();
- break;
- case "6002":
- Toast.makeText(context, "网络连接出错", Toast.LENGTH_SHORT).show();
- break;
- case "6004":
- Toast.makeText(context, "正在处理中", Toast.LENGTH_SHORT).show();
- break;
- default:
- MobclickAgent.onEvent(context, "payment_fali", "付款失败");
- Toast.makeText(context, "支付失败", Toast.LENGTH_SHORT).show();
- break;
- }
- }
- };
- /**
- * 签名发在客户端来做。
- *
- * @param context
- */
- public void toALiPay(final Activity context) {
- this.context = context;
- boolean rsa2 = (builder.getRsa2().length() > 0);
- Map<String, String> params = buildOrderParamMap(rsa2);
- String orderParam = buildOrderParam(params);
- String privateKey = rsa2 ? builder.getRsa2() : builder.getRsa();
- String sign = getSign(params, privateKey, rsa2);
- final String orderInfo = orderParam + "&" + sign;
- Log.e("chx", "toALiPay: " + orderInfo);
- Runnable payRunnable = new Runnable() {
- @Override
- public void run() {
- PayTask alipay = new PayTask(context);
- Map<String, String> result = alipay.payV2
- (orderInfo, true);
- Message msg = new Message();
- msg.what = SDK_PAY_FLAG;
- msg.obj = result;
- mHandler.sendMessage(msg);
- }
- };
- Thread payThread = new Thread(payRunnable);
- payThread.start();
- }
- /**
- * 签名在服务端来做
- *
- * @param context
- * @param orderInfo
- */
- public void toALiPay(final Activity context, final String orderInfo) {
- this.context = context;
- Runnable payRunnable = new Runnable() {
- @Override
- public void run() {
- PayTask alipay = new PayTask(context);
- Map<String, String> result = alipay.payV2
- (orderInfo, true);
- Message msg = new Message();
- msg.what = SDK_PAY_FLAG;
- msg.obj = result;
- mHandler.sendMessage(msg);
- }
- };
- Thread payThread = new Thread(payRunnable);
- payThread.start();
- }
- /**
- * 构造支付订单参数列表
- *
- * @param
- * @param
- * @return
- */
- private Map<String, String> buildOrderParamMap(boolean rsa2) {
- Map<String, String> keyValues = new HashMap<String, String>();
- keyValues.put("app_id", builder.appid);
- keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"" + builder.money + "\",\"subject\":\"" + builder.title + "\",\"out_trade_no\":\"" + builder.orderTradeId + "\"}");
- keyValues.put("charset", "utf-8");
- keyValues.put("method", "alipay.trade.app.pay");
- //回调接口
- keyValues.put("notify_url", builder.getNotifyUrl());
- keyValues.put("sign_type", rsa2 ? "RSA2" : "RSA");
- // keyValues.put("timestamp", "2016-07-29 16:55:53");
- keyValues.put("timestamp", getCurrentTimeString());
- keyValues.put("version", "1.0");
- return keyValues;
- }
- /**
- * 构造支付订单参数信息
- *
- * @param map 支付订单参数
- * @return
- */
- private 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("&");
- Log.e("chx", "buildOrderParam: " + buildKeyValue(key, value, true));
- }
- String tailKey = keys.get(keys.size() - 1);
- String tailValue = map.get(tailKey);
- sb.append(buildKeyValue(tailKey, tailValue, true));
- return sb.toString();
- }
- /**
- * 对支付参数信息进行签名
- *
- * @param map 待签名授权信息
- * @return
- */
- private String getSign(Map<String, String> map, String rsaKey, boolean rsa2) {
- 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 = sign(authInfo.toString(), rsaKey, rsa2);
- String encodedSign = "";
- try {
- encodedSign = URLEncoder.encode(oriSign, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- return "sign=" + encodedSign;
- }
- private static final String ALGORITHM = "RSA";
- private static final String SIGN_ALGORITHMS = "SHA1WithRSA";
- private static final String SIGN_SHA256RSA_ALGORITHMS = "SHA256WithRSA";
- private static final String DEFAULT_CHARSET = "UTF-8";
- private String getAlgorithms(boolean rsa2) {
- return rsa2 ? SIGN_SHA256RSA_ALGORITHMS : SIGN_ALGORITHMS;
- }
- private String sign(String content, String privateKey, boolean rsa2) {
- try {
- PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
- Base64.decode(privateKey));
- KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);
- PrivateKey priKey = keyf.generatePrivate(priPKCS8);
- java.security.Signature signature = java.security.Signature
- .getInstance(getAlgorithms(rsa2));
- signature.initSign(priKey);
- signature.update(content.getBytes(DEFAULT_CHARSET));
- byte[] signed = signature.sign();
- return Base64.encode(signed);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 拼接键值对
- *
- * @param key
- * @param value
- * @param isEncode
- * @return
- */
- private String buildKeyValue(String key, String value, boolean isEncode) {
- StringBuilder sb = new StringBuilder();
- sb.append(key);
- sb.append("=");
- if (isEncode) {
- try {
- sb.append(URLEncoder.encode(value, "UTF-8"));
- } catch (UnsupportedEncodingException e) {
- sb.append(value);
- }
- } else {
- sb.append(value);
- }
- return sb.toString();
- }
- /**
- * 获取当前日期字符串
- *
- * @return
- */
- private String getCurrentTimeString() {
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- return df.format(new Date());
- }
- public static class ALiPayBuilder {
- private String rsa2 = "";
- private String rsa = "";
- private String appid;
- private String money;
- private String title;
- private String notifyUrl;
- private String orderTradeId;
- public MyALipayUtils build() {
- return new MyALipayUtils(this);
- }
- public String getOrderTradeId() {
- return orderTradeId;
- }
- public ALiPayBuilder setOrderTradeId(String orderTradeId) {
- this.orderTradeId = orderTradeId;
- return this;
- }
- public String getRsa2() {
- return rsa2;
- }
- public ALiPayBuilder setRsa2(String rsa2) {
- this.rsa2 = rsa2;
- return this;
- }
- public String getRsa() {
- return rsa;
- }
- public ALiPayBuilder setRsa(String rsa) {
- this.rsa = rsa;
- return this;
- }
- public String getAppid() {
- return appid;
- }
- public ALiPayBuilder setAppid(String appid) {
- this.appid = appid;
- return this;
- }
- public String getMoney() {
- return money;
- }
- public ALiPayBuilder setMoney(String money) {
- this.money = money;
- return this;
- }
- public String getTitle() {
- return title;
- }
- public ALiPayBuilder setTitle(String title) {
- this.title = title;
- return this;
- }
- public String getNotifyUrl() {
- return notifyUrl;
- }
- public ALiPayBuilder setNotifyUrl(String notifyUrl) {
- this.notifyUrl = notifyUrl;
- return this;
- }
- }
- }
完成上述操作,你的app在蚂蚁金服后台应用上线之后,就完全可以调用支付了,但是在开发阶段,应用没有上线,你是不能进行调试的,所以支付宝有沙箱模式可以进行调试,ios没有哟
进行沙箱调试在Activity的的onCreate()方法中添加
- EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);//支付宝沙箱环境,正式需注释
别忘了让你们后台把appKey等信息换成沙箱的,然后测试支付的时候,需要下载一个沙箱支付宝,这个你可以随意支付,附上链接
沙箱首页:https://sandbox.alipaydev.com/user/accountDetails.htm?currentBar=1
App支付接入文档:https://docs.open.alipay.com/204/105051
沙箱钱包下载:
调试都没有问题之后,就可以在蚂蚁金服开发者平台进行应用上线,然后沙箱代码就可以注释了,这样支付宝支付就接入完成
如果问题或建议请发送到我的邮箱:dingchao7323@qq.com
Android开发支付集成——支付宝集成的更多相关文章
- Android开发支付集成——微信集成
支付宝支付传送门:https://www.cnblogs.com/dingxiansen/p/9208949.html 二.微信支付 1. 微信支付流程图 相比较而言,微信支付是要比支付宝麻烦一些,并 ...
- android开发 ,对接支付宝,服务器(PHP)校验失败
已备忘记,资料链接: http://my.oschina.net/u/256646/blog/174222 注意: 里面有一个设计到支付宝公钥的地方: 注 意这个是2048位的公钥应该是9行或者10行 ...
- android 集成支付宝app支付(原生态)-包括android前端与java后台
本文讲解了 android开发的原生态app集成了支付宝支付, 还提供了java后台服务器处理支付宝支付的加密代码, app前端与java后台服务器使用json数据格式交互信息,java后台服务主要用 ...
- 五步搞定Android开发环境部署
引言 在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立Android开发环境投入 Android浪潮的朋友们,为了确保大家能顺利完成开发 ...
- Android开发学习——搭建开发环境
在学校开课学习了android的一些简单的UI组件,布局,四大组件学习了2个,数据存储及网络通信,都是一些简单的概念,入门而已.许多东西需要自己去学习. 学习一下 Android开发环境的搭建,两种方 ...
- android开发环境搭建日记和嵌入式Android开发环境初探
非常感谢博客园的各位,按照你们的博文,还有利用百度和谷歌逐渐建立了android的开发环境,只是给自己备份参考查看,看过的人可以忽略这篇文章. 本文章大部分参考了:http://www.cnblogs ...
- Android开发环境部署
引言 在windows系统中安装Android的开发环境,将分为五个步骤来完成: 第一步:安装JDK 第二步:配置Windows上JDK的变量环境 第三步: 下载安装Eclipse 第四步:下载安 ...
- 五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立Android开发环境投入Android浪潮的朋友们,为了确保大家能顺利完成开发环境的搭 ...
- 【Android开发】 第一课 环境搭建教程
Windows 开发环境部署: Android Studio 中文社区:http://www.android-studio.org/ 本教程将分为五个步骤来完成Android开发环境的部署. 第一步: ...
随机推荐
- java游戏开发杂谈 - 线程
线程,让游戏拥有了动态变化的能力. java的图形界面,在启动的时候,就开始了一个线程. 这个线程负责处理:JFrame.JPanel等的绘制.事件处理. 它是由操作系统调用的,在程序启动时开启,程序 ...
- 什么是TensorFlow?
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面: 从零开始学TensorFlow[01-搭 ...
- 【干货分享】可能是东半球最全的.NET Core跨平台微服务学习资源
如果你发现还有西半球的资源,烦请相告,不胜感谢! 一..NET Core基础 微软英文官网 .NET Core 微软中文官网 GitHub 用ASP.NET内核和Azure构建现代Web应用程序 博客 ...
- Android之应用市场排行榜、上架、首发
文章大纲 一.应用市场排行榜介绍二.应用市场上架介绍三.应用市场首发介绍四.参考文档 一.应用市场排行榜介绍 iiMedia Research(艾媒咨询)权威发布<2017-2018中国 ...
- CentOS7 使用firewalld打开关闭防火墙与端口
1.firewalld的基本使用 启动: systemctl start firewalld 关闭: systemctl stop firewalld 查看状态: systemctl status f ...
- Unsupported major.minor version 52.0解决办法
一.错误现象:当改变了jdk版本时,在编译java时,会遇到Unsupported major.minor version错误.jdk版本和stanford parser对应关系 JDK版本和Java ...
- spring boot 2.0 集成 shiro 和 pac4j cas单点登录
新开的项目,果断使用 spring boot 最新版本 2.0.3 ,免得后期升级坑太多,前期把雷先排了. 由于对 shiro 比较熟,故使用 shiro 来做权限控制.同时已经存在了 cas ...
- 年轻的工程师如何月入伍万XD
郑昀:你要跟谁比?关键词:成长,自我管理,自我激励,面试,候选人201806 ——你觉得跟你的 Leader 差在什么地方?——肯定有差距,一个是知识面不如他广,二一个是解决问题不如他老练.——怎么追 ...
- Django学习笔记(2)——模型,后台管理和视图的学习
一:Web投票示例 本节我们首先从全局范围再复习一下Django的概念,让自己对Django的设计理念, 功能模块,体系架构,基本用法有初步的印象. Django初始的详细博客内容:请点击我 该应用包 ...
- 痞子衡嵌入式:飞思卡尔Kinetis系列MCU开发那些事 - 索引
大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家介绍的是飞思卡尔Kinetis系列微控制器相关知识. 飞思卡尔半导体(现恩智浦半导体)于2010年开始推出的Kinetis系列昭示着ARM C ...