您的位置:首页 > 移动开发 > 微信开发

[置顶] android中关于微信支付流程的总结

2016-10-27 10:51 405 查看
一、前期准备

● 在开放平台的“开发者引用登记界面”申请AppID,开通支付功能。只有在开放平台上通过审核并开通支付功能的应用才能集成微信支付的功能。

● 下载微信终端开发工具包【网址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_CN

● 或在微信支付商户平台开发文档页面下载工具包和demo:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1

● 将工具包中libs目录下的libammsdk.jar复制到你的libs目录下,

○ 【eclipse项目】右击选中“Configure Build Path…”—>“Add jars…”导入到工程中。如图



【AndroidStudio项目】选中项目,按“F4”调出“Project Sructure”窗口,添加jar包到项目中。如图





在清单文件中添加权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


添加混淆规则。在混淆配置文件proguard.cfg中,增加如下代码,否则,将导致无法弹出发送第三方消息的确认框。

-keep class com.tencent.mm.sdk.** {

*;

}


二、项目集成【微信支付目前的做法,凡是涉及签名的操作均交由后台服务器去做】

● 与微信建立通信联系:在代码中向微信APP注册你的APPId,可以在程序入口Activity的onCreate方法中,也可以在其他合适的地方进行注册。笔者比较喜欢在调用微信支付的时候才进行注册。

final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
msgApi.registerApp(Constants.APP_ID);


● 将用户选择的订单信息发送给后台服务器,由后台服务器调用微信支付API提供的统一下单接口等一系列和签名相关的操作,签名完成后,APP接收后台传送回来的prepay_id、sign等数据。

● 调用api.sendReq(req)发起支付。

//从后台获取返回的参数

PayReq req = new PayReq();
req.appId   = json.getString("appid");
req.partnerId   = json.getString("partnerid");
req.prepayId    = json.getString("prepayid");
req.nonceStr    = json.getString("noncestr");
req.timeStamp   = json.getString("timestamp");
req.packageValue    = json.getString("package");
req.sign        = json.getString("sign");
req.extData     = "app data"; // optional


// 发起支付。

//在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信

api.sendReq(req);


● 支付完成后,微信会同步返回一个支付结果给APP,并通过异步返回支付结果给后台服务器。

● APP将支付结果发送给后台服务器,查询支付结果, 获取实际支付结果,并展示结果。

三、项目集成【APP端请求统一下单接口、进行签名,这是微信支付之前的做法,目前已经不支持,写在这里只是为了纪念一下那段苦逼的日子】

● 在调用微信支付的Activity的onCreate方法中实例化支付请求对象:

req = new PayReq();


与微信建立通信联系:在代码中向微信APP注册你的APPId,可以在程序入口Activity的onCreate方法中,也可以在其他合适的地方进行注册。笔者比较喜欢在调用微信支付的时候才进行注册。

final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
msgApi.registerApp(Constants.APP_ID);


调用统一下单接口,生成预支付订单号prepay_id:

(1). URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder

(2).开启任务:

GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
getPrepayId.execute();


(3).在任务中调用统一下单接口,获取prepay_id。

private class GetPrepayIdTask extends
AsyncTask<Void, Void, Map<String, String>> {

private ProgressDialog dialog;

@Override
protected void onPreExecute() {

dialog = ProgressDialog.show(context, getString(R.string.app_tip),
getString(R.string.getting_prepayid));
}

@Override
protected void onPostExecute(Map<String, String> result) {
if (dialog != null) {
dialog.dismiss();
}
resultunifiedorder = result;
System.out.println("result=" + result);
// 生成签名参数
genPayReq();
// 调起支付接口
sendPayReq();
}

@Override
protected void onCancelled() {
super.onCancelled();
}

@Override
protected Map<String, String> doInBackground(Void... params) {

// 统一下单接口
String url = String
//genProductArgs方法用来生成订单详细信息,在官方demo中有详细代码。
String entity = genProductArgs();
System.out.println("entity=" + entity);
byte[] buf = Util.httpPost(url, entity);
String content = new String(buf);
System.out.println("content=" + content);
Map<String, String> xml;
try {
xml = decodeXml(new String(content.getBytes("iso8859-1"),
"utf-8"));
return xml;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}


● 订单详细信息中需要注意的几个参数:

○ notify_url:微信和我们后台建立链接的HTTP协议地址,在支付完成后,微信会通过这个地址向我们的后台服务器发送支付结果。

○ out_trade_no:这个参数是我们服务器生成的订单编号。

○ spbill_create_ip:终端IP,我们服务器定好的。

○ total_fee:订单金额,单位为分。

○ 返回订单详情时一定要注意中文编码问题:String(xmlstring.toString().getBytes(), “ISO8859-1”)。

● 任务执行完成后,将参数重新签名。

//在任务执行完成后调用这个方法。

private void genPayReq() {
req.appId = Constants.APP_ID;
req.partnerId = Constants.MCH_ID;
req.prepayId = resultunifiedorder.get("prepay_id");
//参数值是固定的
req.packageValue = "Sign=WXPay";
req.nonceStr = genNonceStr();
req.timeStamp = String.valueOf(genTimeStamp());
List<NameValuePair> signParams = new LinkedList<NameValuePair>();
signParams.add(new BasicNameValuePair("appid", req.appId));
signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
signParams.add(new BasicNameValuePair("package", req.packageValue));
signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
//再次签名
req.sign = genAppSign(signParams);
}


发起支付。

msgApi.sendReq(req);


回调支付结果

在包名路径下创建新的文件夹wxapi,并在此文件夹下创建WXPayEntryActivity类,注意:文件夹名称和类名称必须按照这样命名,否则会导致无法回调。在类中实现onResp方法,支付完成后微信APP会返回到我们的APP上,并回调此方法。我们要做的就是在这个方法中接收通知,判断返回码,如果支付成功则将返回结果发送给后台服务器,查询支付结果再向用户展示实际支付结果。千万要记住:不能以APP返回的结果作为用户支付的结果,要以后台服务器接收的异步通知或从后台查询得知的结果位准。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: