银联支付,支付宝支付,微信支付的三大支付总结,之前也有写过两篇。

三大支付总结:

http://blog.csdn.net/androidstarjack/article/details/72669394

支付宝植入总结:

android 支付宝的植入 《曾经踩过的坑》

微信支付总结:

Android 微信支付总结

正文

之前有做过支付宝支付和微信支付,所以这次做起来碰到的问题很少,key申请下来之后很快就搞定了。吼吼

效果图:

Android集成第三方支付_第1张图片

由于用鲁大师去截屏获取gif,鲁大师一针一针绘制图片的时候应该没做好处理,导致跳转到相应的界面出现黑屏现象。在手机上正常跳转,无黑屏现象。大家不用担心这个

备注:出于安全考虑,验签我们都是放到后台进行验签的。对于我们移动端节省了很多的劳动力。

准备:

需要以公司名义,在支付宝,微信等平台上开通公司账户并且认证,如:支付过程中需要公司的帐号和商户号。

支付宝支付

如果碰到一些坑的话,请参考我之前写过的意一篇支付宝踩坑的文章:

android 支付宝的植入 《曾经踩过的坑》

  • 参考文档:

    https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1

  1. 首先支付宝申请并集成支付宝SDK 这里不再详细介绍
  • 如:

    price=12.5&num=12 //价格为12.5,数量为12
  1. 获取订单信息(根据自己公司的实际情况:可以在服务端完成,也可以在本地完成)

  2. 客户端拿这些订单信息向服务器后台进行请求,返回支付签名信息signInfo

  3. app携带支付信息,调用支付接口请求支付宝客户端,从而调起支付界面

/**         * 支付宝进行请求         *         * @param signInfo         */        private void payToOrderService(final String signInfo) {            new Thread() {                @Override                public void run() {                    super.run();                                        PayTask payTask = new PayTask(MyScannerPayActivity.this);                    // String result = payTask.pay(signInfo, true);                                        Map result = payTask.payV2(signInfo, true);                                      Message message = mHandler.obtainMessage();                    message.what = SDK_PAY_FLAG;                    message.obj = result;                    mHandler.sendMessage(message);                }            }.start();        }
  1. 用户操作,输入密码支付,支付成功;直接返回取消支付;出现错误,支付失败;进入支付界面,但输入密码支付,支付待确认;

  2. 支付宝客户端将支付结果告诉app客户端,商户服务器通知app服务器支付结果;

  3. app客户端处理支付结果;

  4. app服务器处理支付结果。

处理结果通知:

private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {                        super.handleMessage(msg);                           switch (msg.what) {                    case SDK_PAY_FLAG:                    PayResult payResult = null;                                                  try {                        payResult = new PayResult((Map) msg.obj);                    } catch (Exception e) {                        e.printStackTrace();                    }                    /**                     对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。                     */                    String resultInfo = payResult.getResult();// 同步返回需要验证的信息                    String resultStatus = payResult.getResultStatus();                    // 判断resultStatus 为9000则代表支付成功                    if (TextUtils.equals(resultStatus, PAY_OK)) {                        ActivityUtils.showActivity(MyScannerPayActivity.this, ScannerPaySuccessActivity.class);                        finish();                    } else if (TextUtils.equals(resultStatus, PAY_FAILED)) {//------------------------->支付失败                        // 该笔订单真实的支付结果,需要依赖服务端的异步通知。                        Toast.makeText(MyScannerPayActivity.this, "" + payResult.getMemo(), Toast.LENGTH_LONG).show();                    } else if (TextUtils.equals(resultStatus, PAY_CANCLE)) {//-------------------------->交易取消                        Toast.makeText(MyScannerPayActivity.this, "" + payResult.getMemo(), Toast.LENGTH_LONG).show();                    } else if (TextUtils.equals(resultStatus, PAY_NET_ERR)) {//------------------------->网络出现错误                        Toast.makeText(MyScannerPayActivity.this, "" + payResult.getMemo(), Toast.LENGTH_LONG).show();                    } else if (TextUtils.equals(resultStatus, PAY_WAIT_CONFIRM)) {//--------------------->交替等待                    }                     break;            }        }    };

银联支付

先看一下官方给我们的银联支付流程图:
image.gif

大家不要被这张图片搞懵逼的了,其实很简单,这里我将其分为5小步。

  • 第一步:根据官方文档选择符合自己的sdk

    官方文档:

    https://open.unionpay.com/ajweb/help/file/techFile?productId=3

  • 第二步:将相对应的.so文件copy到 自己的工程里面去。

    特别注意:

    .so文件要放在src/main 目录下,和Java文件并行。还有就是把用到的权限复制到自己项目中)

  • 第三步: 和支付宝一样,APP客户端带着这些订单号向服务器后台请求订单号orderNo

  • 第四步:服务器后台接收到购买信息之后,将信息提交给银联后台,银联接收到后台之后给服务器返回tn号

  • 第五步:开启调用银联支付。APP客户端带着这个流水号,也就是第三步中服务器返回的tn号,调用银联SDK所提供的方法

    注意:

    这个订单流水号为21位纯数字号

    调用方法: UPPayAssistEx.startPay(this, null, null, tn, mMode);

结果返回:

处理银联手机支付控件返回的支付结果调用银联支付后,返回app的时候用了,看返回结果传,成功,失败,或者是什么返回。如图所示:
Android集成第三方支付_第2张图片 image image.gif
最后注意在调用:/***************************************************************** * mMode参数解释: "00" - 启动银联正式环境 "01" - 连接银联测试环境 *****************************************************************/private final String mMode = "00";

注意:

tn值就是上面第三后台给的tn,给到服务器那里, 这里我这边是通过后台请求下来的,关于mMode,看第一步骤,自己改一下就行了,00开发环境,01测试环境。但是要注意,这个只是个回调接口方法。

总感觉银联支付的SDK调用起来怪怪的,貌似回到了原始深林。

微信支付:

  • 建议先参考我之前写的 Android 微信支付总结的一篇博文:

微信支付总结:

http://blog.csdn.net/androidstarjack/article/details/50951941

接入流程图:
Android集成第三方支付_第3张图片
  • 接入流程:
  1. 申请开发者账号 地址:https://open.weixin.qq.com/ 进入管理中心,创建移动应用

  2. 申请支付能力

  3. 代码集成微信支付

  • 代码集成微信支付

  • HashMap params = getHeadMap();    params.put("appid", appID);// 微信appid,选择性上传,服务器写死亦可    params.put("money", money);// 支付金额,单位:分    params.put("goodName", goodsName);// 商品名称    params.put("productNum", String.valueOf(12));// 商品的数量
  • 2.app服务器调用微信“统一下单”接口,得到prePayId订单号并返回prePayId给手机客户端;

    3.手机客户端使用prePayId及商品信息调起微信客户端进行支付;

    3.1用户操作:输入密码进行支付;返回键取消支付;网络无连接支付失败等;

    4.微信客户端回调支付结果给咱们的APP客户端;

    5.微信服务器异步通知咱们公司app服务器支付结果(服务器的工作,与客户端无关)

  • 1.客户端代码得到用户购买的商品信息,将之传给自己公司app服务器,参数包含但不限于以下:

相关的支付调用代码:

IWXAPI mWxApi = WXAPIFactory.createWXAPI(mContext, WX_APPID, true); mWxApi.registerApp(WX_APPID);         /**          * 请求app服务器得到的回调结果          */         @Override         public void onGet(JSONObject jsonObject) {                         if (mWxApi != null) {                 PayReq req = new PayReq();                 req.appId = WX_APPID;// 微信开放平台审核通过的应用APPID                 try {                     req.partnerId = jsonObject.getString("partnerid");// 微信支付分配的商户号                     req.prepayId = jsonObject.getString("prepayid");// 预支付订单号,app服务器调用“统一下单”接口获取                     req.nonceStr = jsonObject.getString("noncestr");// 随机字符串,不长于32位,服务器小哥会给咱生成                     req.timeStamp = jsonObject.getString("timestamp");// 时间戳,app服务器小哥给出                     req.packageValue = jsonObject.getString("package");// 固定值Sign=WXPay,可以直接写死,服务器返回的也是这个固定值                     req.sign = jsonObject.getString("sign");// 签名,服务器小哥给出,他会根据:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3指导得到这个                 } catch (JSONException e) {                     e.printStackTrace();                 }                 mWxApi.sendReq(req);                 Log.d("发起微信支付申请");             }         }
注意事项:
  • 1.首先如果要使用微信支付的话

  • 必须先到微信开放平台注册应用,具体地址为https://open.weixin.qq.com/

  • 注册时需要填应用的包名和签名,注意这里的签名是App正式版的签名,可以找一个已上线的包或打一个正式包,使用微信提供的工具(签名工具下载地址为https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk)来获取,获取后填上即可。

  • 待审核通过后,会得到一个AppID和AppSecret,AppID分享和支付都要用到,AppSecret没什么实际用途,此时微信分享能力是直接拥有的,支付能力还要额外申请,其中涉及到财务信息等

  • 最好让公司财务部门去申请,申请成功后会拿到一个商户id,后面生成sign时会用到。

  • 只有所有审核都通过后,才可调用微信支付功能,这点是前提。

  • 2.微信分享和微信支付SDK是同一个架包,名为libammsdk.jar。

  • 3.官方开发文档中有一处错误,需要注意下,如下图最后一行参数req应该为request,照搬代码的估计IDE也不会放过你,哈哈

    image.gif
  • 4.测试微信支付时,务必对自己的App做正式签名,因为一开始就在微信平台注册过签名信息,微信SDK会做校验,只有这样才能调起微信分享和微信支付,直接debug版的包则绝对调不起来,这点务必注意,很多人是跌在这里了!当初做微信分享曾遇到过,所以会很留心,也因为如此,如果微信分享能调起来,微信支付不行,那就不要怀疑签名问题了。

  • 5.还是签名,网上有人说要注意大小写,这点其实是不必的。在微信开放平台看到审核通过的App的签名是大写的,而用微信签名获取工具获得的则显示小写,这个没关系,不要贸然改动平台注册信息,不然又可能导致漫长的审核等待,上面也说了,微信分享如可以,那就不是签名问题。

  • 6.来说下官方demo,这东西害人不浅啊!很多人参考其写法,如生成sign放在客户端啊,调支付的Activity添加intent-filter啊,最主要的还是签名问题。其实客户端逻辑很简单,直接上手集成即可,demo看看逻辑就行,照抄小心掉坑里。

  • 7.网上有人说需要给调用支付的Activity配置如下intent-filter(见下图),可能也是被demo误导了

  • 8.对于errCode返回-1,有人说清除微信缓存或切换账户就好了,这种解决方案治标不治本啊,根本不能算解决方案。虽然我没遇到能用这方法解决的问题,但目测是签名的问题,建议还得找到真正的问题所在。

  • 9.生成sign时特别需要注意:

  • 首先将key-value键值对拼成字符串,注意key都要小写,如appid,noncestr,package,partnerid,prepayid,timestamp,key,并且名字得按上述名称

  • 我们遇到的错误就是因为partnerid写成了partnerId,prepayid写成了PrepayId,当然我们是在服务端写的,如果在客户端生成sign的话,也需要注意大小写及名称,详细信息请参考官方文档。

  • 还有这里的key并非AppID或AppSectet,而是在商户平台设置的,官方描述为“key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置”。对于noncestr,申请prepayid和生成sign时两次需要用到,由于iOS同事看到相关文章说noncestr前后需要一致,因此这个随机字符串我们是设置成一样的了,这样做Android平台也是OK的,不过个人感觉这里可以不一致,由于这个逻辑在服务器端,我并没有验证,方便的同学可以验证下。

  • 10.req.packageValue=”Sign=WXPay”,一般都是这样写死这个参数值。也有人说写成req.packageValue=”prepay_id=” + prepayid,经测试Android两种写法都是可以调起微信支付的,至少最新版本SDK是可以的,以后则不清楚,官方也建议写Sign=WXPay,据说iOS只支持这种写法。

更多相关文章

  1. android客户端首次进入轮播引导图(五)
  2. Android判断App前台运行还是后台运行(运行状态)
  3. (Android)JavaSocket编程,文件上传到服务器,客户端Android,服务器端J2
  4. java搭建本地服务器,android客户端访问,tomcat配置详细步骤
  5. Android利用JDBC连接服务器数据库
  6. android后台安装apk
  7. Android App 应用前后台的切换
  8. mtk android内置nginx服务器的方法
  9. 在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端

随机推荐

  1. HTML5能取代Android和iOS应用程序吗?
  2. 高德地图的调试版SHA1与发布版SHA1分别的
  3. Android在网络中与JavaWeb的项目进行交互
  4. Android应用程序整合第三方API(以高德Map
  5. Android第一次亲密接触
  6. Android关于C:/Documents and Settings/A
  7. 为什么Google并不担心Android的营收
  8. Android(安卓)studio中Kotlin配置和使用
  9. Android专题之AsyncTask(三)异步方法操作之
  10. Android消息推送(一)--AndroidPn(XMPP协