关闭

Android微信支付集成流程及其常见错误

标签: android微信支付支付宝微信错误-1
449人阅读 评论(0) 收藏 举报
分类:
[支付宝集成传送门:http://blog.csdn.net/hx7013/article/details/61476320]

一、你需要关心的东西

1.申请与认证

2.上传密钥(商户KEY),包名和签名的修改

3.服务端集成

4.安卓集成

本篇就全部写了吧,让我们一步步来。

二、申请与认证

1.提交您的开发者资料

微信开放平台: https://open.weixin.qq.com/
进入后申请账户 -> 创建移动应用 -> 开发者认证[300 RMB] -> 申请微信支付,基本上无坑点,公司资料齐全可以很顺利可以通过。

2.获得商户平台帐号

认证时你需要登陆 微信支付商户平台:https://pay.weixin.qq.com
提交腾讯打给你公司对公账户上的审核款,登陆微信商户平台的账户密码在开发者账户认证通过或会通过邮件发送到申请时填写的邮箱,不能自主注册。

三、上传密钥、配置包名、配置应用签名

Tips:本是很简单的功能,为何要单独列一个来说呢?
因为网上的其它教程基本上是老的提交方法了,当初在这也迷糊密钥在何处生成或提交。所以单独列出来图文说明。

1.配置商户KEY

登陆微信支付商户平台:https://pay.weixin.qq.com,用你获得的账户密码进行登陆。
然后点击 账户中心 -> API安全 -> 设置API密钥
微信支付集成
微信支付集成

Tips:密钥使用的是32位大小写+数字的密串,推荐自动生成。
百度[随机密码]很多的,注意只勾选大小写+数字,长度为32既可。
例如:bXubGehLcukfQc2OyP76qPs84LBuq8oO
当然你也可以自己填写,但是个人感觉随机密码相对更加安全。至少社工不能破掉。

2.设置包名

登陆微信开放平台: https://open.weixin.qq.com/
点击 管理中心 -> 选择应用点击查看 -> 在最下面有[开发信息] -> 点击修改填入包名。

当初审核时提交的是豌豆荚的App链接,所以包名和签名已自动填入。
如没有自动填入或错误,可以自行修改。

3.设置签名

Tips:在翻阅其它文档时说修改签名后需要审核,但是在测试中发现并不需要审核,估计是以前微信支付刚上线时有该限制。所以现在可以放心修改为Debug签名直接调试,免得先发布,在adb install...

同样和上一步设置包名一样,先登陆微信开发者平台,而后在 管理中心 -> 选择应用点击查看 -> 在最下面有[开发信息] -> 点击修改。

正式发布的签名和Debug签名可以通过几种方法获取:http://blog.csdn.net/hx7013/article/details/61671633

四、服务端的集成

服务端集成重点只说签名Sign的生成,其它都是傻瓜式集成,这点我们自己集成时也遇到了坑,所以单独说一下。
当初在集成服务端的时候调用的是微信提供的开发包,但不知为何在Android上调用后,总是弹不出支付的页面,调用时就闪退回来直接反 -1 错误(不得不吐槽一下,-1有那么多情况,就不能学支付宝弹个详细点的错误码吗?)耽搁半天,终于解决。

首先来看看微信提供的这个接口调试工具:https://pay.weixin.qq.com/wiki/tools/signverify/ (貌似IE打不开)

先来张图看看:
微信支付集成

Tips:不用纠结我为何没打码,因为都是虚假参数。但是签名的过程一样,大家能看懂既可。

首先进去后把接口方式从【提交被扫支付】改为【自定义】,然后填入appid、partnerid、prepayid、package、noncestr、timestamp和对应的值。在该调试工具页面,记住我强调是该调试页面提交这些参的顺序是不强求的,但是如果你是自己服务端签名的时候就一定得按顺序提交,这个顺序马上会说到。

填入值后点击生成签名,会发现下面有#1、#2、#3、#4四个流程,其实这个流程就是签名的过程。
认证看后会发现,其实就是参数排序连接,然后再连接商户Key,最后取MD5。

重点来了,也许你会纠结为何参数正确的,但是Sign签名一直不对呢?其实了解MD5的就应该知道,MD5是摘要算法,只知道通过文本去取Hash值。所以appid=123456&partnerid=123456 和 partnerid=123456&appid=123456计算出来的值一定是不同的。这也是坑之一,签名一定得按顺序组合后再取MD5值。

这个顺序就是微信接口调试工具中#2步骤中所提示的,从上图中我们可以看到我提交的是appid、partnerid、prepayid、package、noncestr、timestamp,但是微信给我组合成了appid、noncestr、package、partnerid、prepayid、timestamp、key。

appid=wx666888abc8defg88&noncestr=VCG4w95nS5Ku7mCi&package=Sign=WXPay&partnerid=1668866888&prepayid=wx20170312211500a8y53pgb0klvyh2rmoyu&timestamp=1489324509&key=UWMOIg1qJdHLZfEzAbm91BOBJG4oyC5C

而这个顺序就是签名通常出错的地方,自己在服务端生成签名时一不小心顺序出错,虽然参数正确,但是由于取出来的MD5是和微信那边取出的MD5是不同的,所以固然签名错误。
所以后面服务器生成签名的最简单解决方法就是硬接+取MD5

string signStr = "appid="+valAppid+"&noncestr="+valNoncestr+"&package=Sign=WXPay&partnerid="+valPartnerid+"&prepayid="+valPrepayid+"&timestamp="+valTimestamp+"&key="+valKEY
//c#的取MD5方法,其它语言自行Google
string signMd5 = FormsAuthentication.HashPasswordForStoringInConfigFile(signStr , "MD5") //signMd5即为最终签名

获得Sign后Android提交调用既可。

五、Android的集成

1.Manifest的声明

<!-- 这个也可以不设置,只是习惯跟着官方的Demo了,顺便填写了一下appid,也就是data android:scheme="wx666888abc8defg88" -->
 <application
   android:name="com.wx.wxTest.xApplication"
   android:allowBackup="true"
   android:icon="@drawable/app_icon"
   android:label="@string/app_name"
   android:screenOrientation="portrait"
   android:theme="@style/AppTheme" >
      <activity
        android:name="com.wx.wxTest.Activity.Welcome"
        android:screenOrientation="portrait"
        android:theme="@style/Welcome" >
          <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.VIEW" />
              <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="wx666888abc8defg88" />
          </intent-filter>
      </activity>

<!-- 该activity是申明给微信回调时通知的Activity -->
      <activity
        android:name="com.wx.wxTest.wxapi.WXPayEntryActivity"
        android:exported="true"
        android:launchMode="singleTop"
        android:screenOrientation="portrait" >
      </activity>

又一个坑点来了,我们先来看看官方的文档。
微信支付集成

什么叫“在net.sourceforge.simcpux.wxapi包路径中实现WXPayEntryActivity类(包名或类名不一致会造成无法回调)“我就傻不拉唧的新建了一个包,名为net.sourceforge.simcpux.wxapi,再新建了一个Activity名为WXPayEntryActivity。后面果断调不起…后面尝试 自己的包名(也就是)Manifest中的package=”com.wx.wxTest”,组合为com.wx.wxTest.wxapi.WXPayEntryActivity就可以回调了。微信你不能说清楚是自己的包名+wxapi.WXPayEntryActivity吗?来个必须和你说的一致!

2.调用类Test_WxActivity

package com.wx.wxTest.activity;

import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

public class Test_WxActivity extends Activity {
    private IWXAPI msgApi;
    private PayReq request;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 可以在Application中注册,也可以在这里注册
        // 如果在当前注册即为
        // msgApi = WXAPIFactory.createWXAPI(this, null);
        // msgApi.registerApp("wx666888abc8defg88");

        // 如果在Application注册即为,如果在当前注册请注释掉该代码
        msgApi = WXAPIFactory.createWXAPI(this, "wx666888abc8defg88");

        new Thread(wxPay).start();
    }

    Handler mainHandler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case 100:

                Boolean mSendReq = msgApi.sendReq(request);
                Toast.makeText(Test_WxActivity.this, "调起微信sendReq=>" + mSendReq, Toast.LENGTH_SHORT).show();

                break;
            default:
                break;
            }

        };
    };

    Runnable wxPay = new Runnable() {

        @Override
        public void run() {
            // 这些值应该从服务器获取,这里只是为了演示
            request = new PayReq();

            request.appId = "wx666888abc8defg88";
            request.partnerId = "1668866888";
            request.prepayId = "wx20170312211500a8y53pgb0klvyh2rmoyu";
            request.nonceStr = "VCG4w95nS5Ku7mCi";
            request.timeStamp = "1489324509";
            request.packageValue = "Sign=WXPay";
            request.sign = "19890233F9E17CC54E0B6285032AE419";

            mainHandler.sendEmptyMessage(100);
        }
    };

}

3.回调类WXPayEntryActivity

package com.wx.wxTest.wxapi;

import com.jhx.hyxs.R;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {

    private IWXAPI api;

    private ImageView ivImg;
    private TextView tvText, tvSub;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wxentry);

        // 通过WXAPIFactory工厂,获取IWXAPI的实例
        api = WXAPIFactory.createWXAPI(this, "wx666888abc8defg88", false);

        // 注意:
        // 第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
        try {
            api.handleIntent(getIntent(), this);
        } catch (Exception e) {
            e.printStackTrace();
        }

        initView();
    }

    private void initView() {
        ((TextView) findViewById(R.id.head_title)).setText("支付结果");
        ((ImageView) findViewById(R.id.head_back)).setVisibility(View.INVISIBLE);

        ivImg = (ImageView) findViewById(R.id.wxentry_img);
        tvText = (TextView) findViewById(R.id.wxentry_text);
        tvSub = (TextView) findViewById(R.id.wxentry_sub);

        tvSub.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
            }
        });

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onResp(BaseResp resp) {
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            if (resp.errCode == 0) {
                Toast.makeText(this, "支付成功", Toast.LENGTH_LONG).show();
                ivImg.setImageResource(R.drawable.pay_success);
                tvText.setText("支付成功");
                tvText.setTextColor(Color.parseColor("#39BC32"));
            } else {
                Toast.makeText(this, "支付失败! (" + resp.errCode + ")", Toast.LENGTH_LONG).show();
                ivImg.setImageResource(R.drawable.pay_error);
                tvText.setText("支付失败");
                tvText.setTextColor(Color.parseColor("#FFA800"));
            }
        }
    }

    @Override
    public void onReq(BaseReq arg0) {
        // TODO Auto-generated method stub

    }
}

六、常见集成时遇到的坑和解决的方法

1. 微信回调errCode = -1

官方文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
各种填坑后发现,这个可以相信官方文档,虽然模糊不清,但是说的的确大部分可能也都为“签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配”,再加一条包名错误(虽然可能性很低)
解决方法:
1. 检查在开发者平台设置的应用签名是否和当前APP签名一致(Debug签名或发布版签名)
2. 是否调用了注册微信的代码

final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
msgApi.registerApp("wx666888abc8defg88");

2.签名错误

一定得按照appid、noncestr、package、partnerid、prepayid、timestamp、key的顺序组合后取MD5。
例如:

appid=wx666888abc8defg88&noncestr=VCG4w95nS5Ku7mCi&package=Sign=WXPay&partnerid=1668866888&prepayid=wx20170312211500a8y53pgb0klvyh2rmoyu&timestamp=1489324509&key=UWMOIg1qJdHLZfEzAbm91BOBJG4oyC5C

3.回调错误

这个错误其实为微信的坑,是的,我就是那么直白!
解决方法:
别听信微信说的net.sourceforge.simcpux.wxapi包路径中实现WXPayEntryActivity类(包名或类名不一致会造成无法回调)。
而是使用你的包名+wxapi.WXPayEntryActivity,例如com.wx.wxTest.wxapi.WXPayEntryActivity

4.签名

说一个不是错误但一定得注意的地方,签名过程一定得在服务端完成!若你在客户端(如:Android)上完成时,你的商户KEY泄露可能很大(毕竟反调试Android并不是什么难事),而商户KEY的泄露将导致你的整个支付系统崩塌。

七、总结

微信支付的坑比支付宝支付的坑要多,大多数是因为官方的文档模糊不清,但是若按照我刚说的配置,基本没有问题。如果问题欢迎留言,定知无不言。
0
0
查看评论

Android微信app支付集成步骤详解

Android微信app支付集成步骤
  • VRoymond
  • VRoymond
  • 2016-12-11 17:30
  • 1921

Android开发第三方支付微信支付实例集成过程介绍

最近开发的项目需要集成第三方微信支付,于是查看了微信开放平台的开发指南顺利完成,下面为大家分享一下。 一、在集成之前先到微信开放平台拿到以下三个参数: 项目APP ID, 商户平台的商户号MCH_ID, 项目签名(一般是3232位的md5串)。 拿到这三个参数之后就可以开始集成了,添加微信支付官方的...
  • xuchao_blog
  • xuchao_blog
  • 2017-02-27 16:36
  • 2212

Android微信支付开发流程

Android微信支付开发流程 需要内容: 账号信息:appId,appKey,mchId(商户号) libammsdk.jar包  MD5.java类 开发步骤: 1、libammsdk.jar包  MD5.java类拷入项目,将jar包AddLibrary; 2、在清单文件中...
  • jiashuai94
  • jiashuai94
  • 2017-07-05 19:51
  • 975

关于Android集成微信支付的过程

本来是不打算写关于微信支付的,网上有太多了,但是前些天一个哥们居然还问我微信支付怎么集成,所以准备做个记录。 以下内容是将微信支付的所有过程都放在在app端,这是不推荐的,实际中前几步由服务器来做比较安全些。当然,我这样写一个是为了展示微信支付的一个流程,二是服务器端哥们不愿写,老大让我全在客户端...
  • yuanlvmao
  • yuanlvmao
  • 2016-08-06 15:48
  • 2273

Android微信支付功能集成【全攻略】

Android版微信支付官方文档和Demo问题很多,官方也没有及时更新和细化开发集成文档。 这里分享我集成Android客户端微信支付的思路和部分代码。希望对大家有帮助。 遇到的问题无非以下几种: 1、提示签名不对; 2、打包签名后的APK无法调起微信支付客户端,直接返回回调页; 3、不支持中文...
  • jay100500
  • jay100500
  • 2016-10-28 14:30
  • 4415

微信支付集成方案

简介 首先我们来到微信支付官网瞅瞅: Paste_Image.png 可以看到这就是微信支付首页,下面有几种支付方式,而我们今天的主角就是APP支付,我们可以直接点进去,或者从左上角接入指引-APP支付,进去的文档式样的,这是这个文档的位置如下图所示: Paste_Image.p...
  • intenttao
  • intenttao
  • 2016-08-11 08:47
  • 2105

Android集成微信支付功能

准备工作这里就不说了,包括签约和申请APPID,附上微信开放平台APP开发步骤,不懂的同学可以参考这里: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5 上面的步骤很详细,这里主要说下调起支付的注意事项。按照上面文档中说...
  • shineflowers
  • shineflowers
  • 2016-04-01 14:07
  • 3407

Android微信支付集成和踩过的坑

近公司需要微信支付,所以不得不去看看微信支付文档。但是你懂得,那文档写的真带劲,看不懂。我直接放弃,开始集成。但是调起微信支付的时候:结果码为-1,心里一惊,肯定哪里错了,就开始找坑。所以把自己解决的过程分享给大家,让集成微信支付成为很容易的一件事。 1、前期的准备:把App安装到手机,然后去微信平...
  • csclmf
  • csclmf
  • 2017-10-26 16:49
  • 500

Android集成微信支付主要步骤和特别需要注意的问题

一:介绍 大家在商城类等需要支付功能的项目中,一般需要集成支付宝和微信支付,集成支付宝比较简单,官方文档清晰明了.但是相比于支付宝,微信支付就显得坑爹得多,下面说一下微信支付的主要步骤和特别需要注意的问题,首先声明博客里没用官方的demo,官方demo的参数都是从服务器得到的,而有的公司的服务器并没...
  • lzyang187
  • lzyang187
  • 2016-02-04 09:48
  • 2208

Android App支付系列(一):微信支付接入详细指南(附官方支付demo)

一家移动互联网公司,说到底,要盈利总是需要付费用户的,自己开发支付系统显然是不明智的,国内已经有多家成熟的移动支付提供商,腾讯就是其中之一。梳理了下微信支付的接入,今天给大家分享下腾讯旗下的微信支付SDK的接入流程
  • Xiong_IT
  • Xiong_IT
  • 2016-06-15 20:16
  • 59616
    个人资料
    • 访问:18920次
    • 积分:337
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类