微信支付传送门:https://www.cnblogs.com/dingxiansen/p/9209159.html

一、支付宝支付

1. 支付宝支付流程图

2. 集成前准备

  1. 去蚂蚁金服注册应用获取appKey等信息
  2. 创建应用,添加APP支付功能
  3. 找到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&notify_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&timestamp=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开发支付集成——支付宝集成的更多相关文章

  1. Android开发支付集成——微信集成

    支付宝支付传送门:https://www.cnblogs.com/dingxiansen/p/9208949.html 二.微信支付 1. 微信支付流程图 相比较而言,微信支付是要比支付宝麻烦一些,并 ...

  2. android开发 ,对接支付宝,服务器(PHP)校验失败

    已备忘记,资料链接: http://my.oschina.net/u/256646/blog/174222 注意: 里面有一个设计到支付宝公钥的地方: 注 意这个是2048位的公钥应该是9行或者10行 ...

  3. android 集成支付宝app支付(原生态)-包括android前端与java后台

    本文讲解了 android开发的原生态app集成了支付宝支付, 还提供了java后台服务器处理支付宝支付的加密代码, app前端与java后台服务器使用json数据格式交互信息,java后台服务主要用 ...

  4. 五步搞定Android开发环境部署

    引言   在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立Android开发环境投入 Android浪潮的朋友们,为了确保大家能顺利完成开发 ...

  5. Android开发学习——搭建开发环境

    在学校开课学习了android的一些简单的UI组件,布局,四大组件学习了2个,数据存储及网络通信,都是一些简单的概念,入门而已.许多东西需要自己去学习. 学习一下 Android开发环境的搭建,两种方 ...

  6. android开发环境搭建日记和嵌入式Android开发环境初探

    非常感谢博客园的各位,按照你们的博文,还有利用百度和谷歌逐渐建立了android的开发环境,只是给自己备份参考查看,看过的人可以忽略这篇文章. 本文章大部分参考了:http://www.cnblogs ...

  7. Android开发环境部署

    引言   在windows系统中安装Android的开发环境,将分为五个步骤来完成: 第一步:安装JDK 第二步:配置Windows上JDK的变量环境 第三步: 下载安装Eclipse 第四步:下载安 ...

  8. 五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程

      在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立Android开发环境投入Android浪潮的朋友们,为了确保大家能顺利完成开发环境的搭 ...

  9. 【Android开发】 第一课 环境搭建教程

    Windows 开发环境部署: Android Studio 中文社区:http://www.android-studio.org/ 本教程将分为五个步骤来完成Android开发环境的部署. 第一步: ...

随机推荐

  1. 购物网站首页(学习ING)

    这几天在学着做购物网站,初步的完成了首页的框架吧,记录下.慢慢加强.主要难点,是样式的设置问题,如果自己想,自己摸索,可能会需要很长的调试.也是一个孰能生巧的过程吧,有些部分没有按照学习资料的方法也做 ...

  2. 原生js获取pc和移动端屏幕宽、高的方法

    pc端: var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; ...

  3. gitbook 入门教程之使用 gitbook-cli 开发电子书

    gitbook 生成电子书主要有三种方式: gitbook-cli 命令行操作,简洁高效,适合从事软件开发的相关人员. gitbook-editor 编辑器操作,可视化编辑,适合无编程经验的文学创作者 ...

  4. 清理buffer/cache/swap的方法梳理

    一.缓存机制介绍 在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果 ...

  5. Win10常见问题记录

    基本信息 记录我在使用win10过程中遇到的一些问题 我所使用的两个win10系统 Win10 企业版 1607(家里电脑) Win10 专业版 1806(公司电脑) win10 开启Sets 请问您 ...

  6. 20170310 - Python 3 下 SQLAlchemy 的 MySQL 数据库 URI 配置

    MySQL-Python 只用于 Python 2,URI配置为 mysql://username:password@server/db Python 3 下要使用另一个 PyMySQL 包,相应的U ...

  7. windows 安装zookeeper

    1 .下载 java sdk 和zookeeper  安装包 因为zookeeper是依赖java sdk,运行zookeeper先要,安装javaSDK . 2.安装zookeeper,zookee ...

  8. sql xml中 in 的用法

    在xml中,动态传参去数据库查询,下面是in的示例. 比如有条sql SELECT * FROM corp_tax c WHERE c.id in (387419,387423) AND c.corp ...

  9. 不可思议的纯 CSS 实现鼠标跟随效果

    直接进入正题,鼠标跟随,顾名思义,就是元素会跟随着鼠标的移动而作出相应的运动.大概类似于这样: 通常而言,CSS 负责表现,JavaScript 负责行为.而鼠标跟随这种效果属于行为,要实现通常都需要 ...

  10. select * 和 select 所有字段的区别

    阅读本文大概需要 1 分钟. 之前发过的文章中,关于 select * 和 select 所有字段的知识,有描述不恰当,这次重新纠正下,加深下理解. MySQL 5.1.37 表记录数 41,547, ...