Android 微信支付开发流程

首先奉上调起支付页面截图

002.png

一:介绍

项目中要用到支付功能,需要支付宝支付、微信支付、银联支付,所以打算总结一下,方便以后的查阅,也方便大家, 用到的地方避免再次被坑。
今天我们就主要介绍一下微信支付,其他支付也写了对应教程,并且给出了连接。

集成前首先要看看文档,微信支付开发文档里面有详细的字段和说明。
微信支付是需要签名的,跟支付宝一样,可以在客户端签名,也可以在后台签名(当然,为了安全还是推荐在服务器上做签名,逻辑也比较好理解)

二:业务流程

以下是交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成。

交互时序图

商户系统和微信支付系统主要交互说明:

    1. 用户在商户APP中选择商品,提交订单,选择微信支付。
    1. 商户后台收到用户支付单,调用微信支付统一下单接口。
    1. 统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。
    1. 商户APP调起微信支付。
    1. 商户后台接收支付通知。
    1. 商户后台查询支付结果。

三:下载微信SDK

微信开放平台下载SDK
建议把Android头文件和支付示例都下载下来

下载微信SDK

四:后台设置

商户在微信开放平台申请开发应用后,微信开放平台会生成APP的唯一标识APPID。由于需要保证支付安全,需要在开放平台绑定商户应用包名和应用签名,设置好后才能正常发起支付。设置界面在【开放平台】中的栏目【管理中心 / 修改应用 / 修改开发信息】里面。如下图:

102.png

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

package="net.sourceforge.simcpux"

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

签名工具下载地址

https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk

103.png

net.sourceforge.simcpux 是项目包名

五:导入开发SDK

导入sdk流程同支付宝导入流程一样,这里就借用支付宝导入流程进行介绍。

5.1 如果项目开发使用的Eclipse软件,导入步骤如下:

1.将alipaySDK-20150602.jar包放入商户应用工程的libs目录下,如下图。

201.png

2.进入商户应用工程的Java Build Path,将libs目录下的alipaySDK-20150602.jar导入,如下图。

202.png

3.选中Order and Export,勾选alipaySDK-20150602.jar,如下图。

203.png

将上图的支付宝sdk更换成微信sdk即可

5.2 如果项目开发使用的Android Studio软件,导入步骤如下:

1.将微信SDK拷贝到项目libs文件夹下,如果没有libs文件夹,就新建一个。

301.png

2.如果sdk使用过程中,提示找不到文件。
进行如下操作,选中sdk文件,右击选择Reveal in Finder

302.png

六:修改AndroidManifest.xml配置

1.在商户应用工程的AndroidManifest.xml文件里面添加声明:

<!--微信-->
<activity
     android:name=".wxapi.WXPayEntryActivity"
     android:exported="true"
     android:launchMode="singleTop">
</activity>

和权限声明:

<!--微信-->
<uses-permission android:name="android.permission.INTERNET"/>

到这里,微信支付的前期配置已经完成,下面需要完成支付代码编写。

七:支付接口调用

  1. 在点击支付按钮的点击事件中,我提供的是从后端获取订单信息。
  2. 需要在新线程中调用支付接口。代码如下:
//    微信按钮
    public void onClick(View view) {
        //起一个线程
        Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                String data = null;
                PayBean payBean = new PayBean();
                payBean.setOrderTime("");
                String json = new Gson().toJson(payBean);
                //json为获取后端结果时需要提供给后端订单信息,例如:时间、金额、订单属性等
                Log.i("charge request", json);
                try {
                    //data为后端返回数据,其中包括订单字符串
                    data = postJson(CHARGE_URL, json);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                // Json解析data
                ChargeWXBean charge = new Gson().fromJson(data.replace("package", "packages"), ChargeWXBean.class);
                //在mHandler中处理微信调起支付和返回结果回调
                Message msg = new Message();
                msg.what = SDK_PAY_WECHAT;
                msg.obj = charge;
                mHandler.sendMessage(msg);
            }
        };
        // 必须异步调用
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
  1. 在mHandler中处理调起支付
private Handler mHandler = new Handler() {

        public void handleMessage(Message msg) {
            if (msg.what == SDK_PAY_WECHAT) {

                ChargeWXBean charge =  (ChargeWXBean) msg.obj;
                String packsges = charge.getResult().getCredential().getPackages();
                String appid = charge.getResult().getCredential().getAppid();
                String partenerid = charge.getResult().getCredential().getPartnerid();
                String prepayid = charge.getResult().getCredential().getPrepayid();
                String noncestr = charge.getResult().getCredential().getNoncestr();
                String timestamp = charge.getResult().getCredential().getTimestamp();
                String sign = charge.getResult().getCredential().getSign();
//              商户APP工程中引入微信JAR包,调用API前,需要先向微信注册您的APPID,代码如下:
                final IWXAPI msgApi = WXAPIFactory.createWXAPI(ThirdActivity.this, null);
               // 将该app注册到微信   
                msgApi.registerApp(appid);

                PayReq req = new PayReq();
                req.appId = appid;
                req.partnerId = partenerid;
                req.prepayId = prepayid;
                req.nonceStr = noncestr;
                req.timeStamp = timestamp;
                req.packageValue = packsges;
                req.sign = sign;
                msgApi.sendReq(req);

            }
        }
    };
  1. 支付结果回调

参照微信SDK Sample,在net.sourceforge.simcpux.wxapi包路径中实现WXPayEntryActivity类(包名或类名不一致会造成无法回调),在WXPayEntryActivity类中实现onResp函数,支付完成后,微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准。(net.sourceforge.simcpux为你的项目包名)代码示例如下:

    @Override
    public void onResp(BaseResp resp) {
        Log.d(TAG,"onPayFinish,errCode="+resp.errCode);

        // 判断resultStatus 为“0”则代表支付成功,具体状态码代表含义可参考接口文档
        if (resp.errCode.equals("0")) {
            Toast.makeText(ThirdActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
        }else if (resp.errCode.equals("-1")){

            // -1为支付失败,包括用户主动取消支付,或者系统返回的错误
            Toast.makeText(ThirdActivity.this, "支付失败", Toast.LENGTH_SHORT).show();

        }else if (resp.errCode.equals("-2")){

            // -2为取消支付,或者系统返回的错误
            Toast.makeText(ThirdActivity.this, "取消支付", Toast.LENGTH_SHORT).show();

        }else {
            // 其他为系统返回的错误
            Toast.makeText(ThirdActivity.this, "支付错误", Toast.LENGTH_SHORT).show();

        }

    }

以下三种为常用结果判断

0为支付成功
-1为支付失败
-2为取消支付

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容