微信支付,支付宝支付,银联支付——三大支付总结

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

微信支付,支付宝支付,银联支付——三大支付总结:html

blog.csdn.net/androidstar…android

支付宝植入总结:git

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

微信支付总结:web

Android 微信支付总结json

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

以前有作过支付宝支付和微信支付,因此此次作起来碰到的问题不多,key申请下来以后很快就搞定了。吼吼缓存

效果图:安全

Markdown
Markdown

因为用鲁大师去截屏获取gif,鲁大师一针一针绘制图片的时候应该没作好处理,致使跳转到相应的界面出现黑屏现象。在手机上正常跳转,无黑屏现象。你们不用担忧这个

准备

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

支付宝支付

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

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

    1. 首先支付宝申请并集成支付宝SDK 这里再也不详细介绍
参考文档:

 https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1复制代码
    1. 获取订单信息(根据本身公司的实际状况:能够在服务端完成,也能够在本地完成)

      如:

      price=12.5&num=12 //价格为12.5,数量为12

    1. 客户端拿这些订单信息向服务器后台进行请求,返回支付签名信息signInfo
    1. 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<String, String> result = payTask.payV2(signInfo, true);
                    Message message = mHandler.obtainMessage();
                    message.what = SDK_PAY_FLAG;
                    message.obj = result;
                    mHandler.sendMessage(message);

                }
            }.start();
        }复制代码
    1. 用户操做,输入密码支付,支付成功;直接返回取消支付;出现错误,支付失败;进入支付界面,但输入密码支付,支付待确认;
    1. 支付宝客户端将支付结果告诉app客户端,商户服务器通知app服务器支付结果;
    1. app客户端处理支付结果;
    1. 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<String, String>) 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;
            }
        }
    };复制代码

银联支付

先看一下官方给咱们的银联支付流程图:复制代码

Markdown
Markdown

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

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

    官方文档:

    open.unionpay.com/ajweb/help/…

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

    特别注意:

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

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

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

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

    注意:

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

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

结果返回

处理银联手机支付控件返回的支付结果

调用银联支付后,返回app的时候用了,看返回结果传,成功,失败,或者是什么返回。

如图所示:复制代码

Markdown
Markdown
Markdown
Markdown

最后注意在调用:

/*****************************************************************
 * mMode参数解释: "00" - 启动银联正式环境 "01" - 链接银联测试环境
 *****************************************************************/
private final String mMode = "00";复制代码

注意:

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

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

微信支付:

接入流程图:

Markdown
Markdown

  • 接入流程:

    1. 申请开发者帐号
      地址:open.weixin.qq.com/
      进入管理中心,建立移动应用
    2. 申请支付能力
    3. 代码集成微信支付
  • 代码集成微信支付

    • 1.客户端代码获得用户购买的商品信息,将之传给本身公司app服务器,参数包含但不限于如下:
HashMap<String ,String> 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服务器支付结果(服务器的工做,与客户端无关)复制代码

相关的支付调用代码:

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.首先若是要使用微信支付的话

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

    • 注册时须要填应用的包名和签名,注意这里的签名是App正式版的签名,能够找一个已上线的包或打一个正式包,使用微信提供的工具(签名工具下载地址为open.weixin.qq.com/zh_CN/htmle…

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

    • 最好让公司财务部门去申请,申请成功后会拿到一个商户id,后面生成sign时会用到。
    • 只有全部审核都经过后,才可调用微信支付功能,这点是前提。
  • 2.微信分享和微信支付SDK是同一个架包,名为libammsdk.jar。

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

    Markdown
    Markdown

    • 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只支持这种写法。

Android集成微信支付的出现-1等错误须要注意的要点

  • 1.微信支付和支付宝支付是如今APP经常使用的支付方式,可是真正接入过两种支付方式的猿友会很明显的感受到微信支付真心比支付宝麻烦不少,会出现不少莫名其妙的错误,可是官方的文档却很难给出较好的解决方案.

  • 2.前几天公司的APP须要支付功能而后也须要这个-1问题,简直感受微信支付丧心病狂,这里总结下本身出现的问题和一些其余网友出现的问题作个总结

reso.errCode = -1 官方的描述: -1 错误 可能的缘由:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其余异常等。

1.签名错误:
  • (1).签名的参数集合没有按照参数名ASCII码从小到大排序(字典序)

  • (2).签名的是时候漏了使用key,(key的由来能够看下面第三条的分析)

  • (3).签名的KEY错误. 这里用来签名的key是申请支付功能之后,微信给你的一个商户帐号里面设置的.具体key设置路径:微信商户平台(pay.weixin.qq.com)–>帐户设置–>API安全–>密钥设置

  • (4).签名后的key没有进行转化成大写或者其余例如前面的签名参数先排好序最后才加上key(key字段不参与ASCII码的大小排序,而是直接放到最后)

  • (5),还有一些其余的格式错误请参看官方文档的详细说明 微信官方的签名说明,请认真对比.

  • (6),签名问题的终极大招—–使用官方的签名认证工具一一对比.注:最好在链接生成的key和最终MD5以后的结果 在log下打印出来,能够方便查看出错的位置 接口调试工具

2.APPID错误
  • (1)APPID是在open.weixin.qq.com上建立的应用,能够经过 点击管理中心–>应用详情 来查看APPID

    image
    image

  • (2)建立APP时候上传的证书与如今使用的不一致.商户在微信开放平台申请开发应用后,微信开放平台会生成APP的惟一标识APPID。因为须要保证支付安全,须要在开放平台绑定商户应用包名和应用签名,设置好后才能正常发起支付。设置界面在【开放平台】中的栏目【 管理中心 –> 修改应用 –> 修改开发信息】里面

image
image

应用包名:是在APP项目配置文件AndroidManifest.xml中声明的package值,例如DEMO中的package=”com.nmm.paydemo”。

应用签名:根据项目的应用包名和编译使用的keystore,可由签名工具生成一个32位的md5串,在调试的手机上安装签名工具后,运行可生成应用签名串,如图8.9所示,绿色串即应用签名。签名工具下载地址

对比查看应用签名是否一致,特别注意,通常上传都是使用release版本的key因此在测试的时候就须要使用签名版的apk,普通的debug版本key是不一致的

微信支付相关的demo地址:

github.com/androidstar…

以上是我以前作微信支付的时候的一些总结,今天再次拿出来供你们参考

以前的历史文章:
>

支付宝植入总结:

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

微信支付总结:

Android 微信支付总结

相信本身,没有作不到的,只有想不到的

若是你以为此文对您有所帮助,欢迎入群 QQ交流群 :232203809
微信公众号:终端研发部

Markdown
Markdown

(欢迎关注学习和交流)

相关文章
相关标签/搜索