移動大腦-SpringMVc搭建RestFul後臺服務(六)-微信支付(Android)
阿新 • • 發佈:2019-02-10
目錄:
在上一篇《移動大腦-SpringMVc搭建RestFul後臺服務(五)-支付寶支付》部落格中已經實現了支付寶支付,接下來我滿再新增微信支付功能,這樣支付功能基本就完整了,銀聯就不考慮了。
原來我寫過一篇《Android微信支付爬坑》的部落格,裡面講的就是完全從APP端發起的支付,有需要的可以看看。
先來張例項圖:
首先開始準備工作,在微信開發平臺(https://open.weixin.qq.com/)申請自己的應用,並填寫正確的包名和簽名,稽核通過後再申請微信支付功能,此時或得到商戶賬號,並在商戶後臺設定自己的32位key,以上都準備好後,並下載所需要的微信開發jar包(主要是生成簽名和網路訪問的工具類,可根據自己情況來改成自己的工具類),就可以開始微信的開發了。
微信支付流程和支付寶其實也是一樣的:APP請求服務端支付介面---->服務端生成本地訂單---->服務端構造資料到微信端生成預支付訂單---->服務端拿到預支付訂單返回給APP---->APP拿到微信支付資訊調起微信支付---->微信支付成功通過通知APP---->微信非同步呼叫服務端支付驗證介面---->服務端處理驗證結果返回給微信,就完成了一次支付過程。
開始編碼:
一、在PaySerVice中新增微信下單
else if(payWay == 2)//微信支付 { SortedMap<String, String> parameters = new TreeMap<String, String>(); parameters.put("appid", WX_APPID); parameters.put("body", orderBean.getSubject()); parameters.put("mch_id", WX_MCHID); parameters.put("nonce_str", CommonUtils.genNonceStr()); parameters.put("notify_url", "http://10.50.50.205:8080/pay/verifywxpayresult.do"); parameters.put("out_trade_no", orderBean.getOrderNo()); parameters.put("total_fee", "50"); parameters.put("trade_type", "APP"); parameters.put("spbill_create_ip", "196.168.1.1"); parameters.put("sign", CommonUtils.createSign("UTF-8", parameters, WX_KEY));//傳入簽名好的引數值 StringBuilder xmlBuilder = new StringBuilder(); xmlBuilder.append("<xml>"); Set es = parameters.entrySet();//所有參與傳參的引數按照accsii排序(升序) Iterator it = es.iterator(); CommonUtils.createXml(it, xmlBuilder); xmlBuilder.append("</xml>"); System.out.println(xmlBuilder.toString()); try { String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; byte[] buf = Util.httpPost(url, new String(xmlBuilder.toString().getBytes("UTF-8"), "ISO8859-1")); String content = new String(buf); System.out.println("content:" + content); Map<String, String> map = CommonUtils.xmlToMap(content); String nonceStr = CommonUtils.genNonceStr(); String timeStamp = String.valueOf(CommonUtils.genTimeStamp()); SortedMap<String, String> signparameters = new TreeMap<String, String>(); signparameters.put("appid", map.get("appid")); signparameters.put("partnerid", map.get("mch_id")); signparameters.put("prepayid", map.get("prepay_id")); signparameters.put("package", "Sign=WXPay"); signparameters.put("noncestr", nonceStr); signparameters.put("timestamp", timeStamp); wxPayBean = new WxPayBean(); wxPayBean.setOrderId(order.getOrderNo()); wxPayBean.setAppid(map.get("appid")); wxPayBean.setPartnerid(map.get("mch_id")); wxPayBean.setPrepayid(map.get("prepay_id")); wxPayBean.setNoncestr(nonceStr); wxPayBean.setTimestamp(timeStamp); wxPayBean.setPackageValue("Sign=WXPay"); wxPayBean.setSign(CommonUtils.createSign("UTF-8", signparameters, WX_KEY)); } catch (Exception e) { e.printStackTrace(); } }
二、在PayAction中新增微信支付回撥介面
/** * 微信回撥介面 * @param request * @param resp * @return */ @ResponseBody @RequestMapping(value="/verifywxpayresult.do", method=RequestMethod.POST) public String verifyWxPayRight(HttpServletRequest request, HttpServletResponse resp) { System.out.println("-----------------------------------come here wxpay--------------------------------"); synchronized (wxlock) { System.out.println("-----------------------------------come here wxpay 2--------------------------------"); BufferedReader reader = null ; try { reader = request.getReader() ; String line = "" ; String xmlString = null ; StringBuffer inputString = new StringBuffer() ; while( (line = reader.readLine()) != null ){ inputString.append(line) ; } xmlString = inputString.toString() ; request.getReader().close(); System.out.println("xmlString:" + xmlString); Map<String, String> map = CommonUtils.xmlToMap(xmlString); System.out.println("result sign:" + map.get("sign")); SortedMap<String, String> parameters = new TreeMap<String, String>(); parameters.put("appid", map.get("appid")); parameters.put("bank_type", map.get("bank_type")); parameters.put("cash_fee", map.get("cash_fee")); parameters.put("fee_type", map.get("fee_type")); parameters.put("is_subscribe", map.get("is_subscribe")); parameters.put("mch_id", map.get("mch_id")); parameters.put("nonce_str", map.get("nonce_str")); parameters.put("openid", map.get("openid")); parameters.put("out_trade_no", map.get("out_trade_no")); parameters.put("result_code", map.get("result_code")); parameters.put("return_code", map.get("return_code")); parameters.put("time_end", map.get("time_end")); parameters.put("total_fee", map.get("total_fee")); parameters.put("trade_type", map.get("trade_type")); parameters.put("transaction_id", map.get("transaction_id")); String resultSign = CommonUtils.createSign("UTF-8", parameters, PayService.WX_KEY); System.out.println("create sign:" + resultSign); if(map.get("sign").equals(resultSign)) { if(payService.verifyWxPay(map).equals("success")) { SortedMap<String, String> result = new TreeMap<String, String>(); result.put("return_code", "SUCCESS"); return mapToXml(result); } SortedMap<String, String> result = new TreeMap<String, String>(); result.put("return_code", "FAIL"); return mapToXml(result); } else { SortedMap<String, String> result = new TreeMap<String, String>(); result.put("return_code", "FAIL"); return mapToXml(result); } } catch (IOException e) { e.printStackTrace(); } } SortedMap<String, String> result = new TreeMap<String, String>(); result.put("return_code", "FAIL"); return mapToXml(result); }
三、過濾器中新增支付白名單
else if(uri.endsWith("pay/verifyalipayresult.do"))//支付寶回撥介面
{
return true;
}
else if(uri.endsWith("pay/verifywxpayresult.do"))//微信回撥介面
{
return true;
}
主要程式碼就是這些,就能在服務端生成微信預支付訂單,詳細程式碼請參見文章末尾原始碼,預支付訂單例項如圖:
服務端資訊:
客戶端資訊:
客戶端拿到預支付訂單後就可以調起微信支付了:
調起微信支付程式碼:
PayApi.getInstance().createOrder(MyApplication.getInstance().getUserBean().getId(), MyApplication.getInstance().getPhone(), "微信支付測試", "1", 2, "APP微信SDK支付", new HttpSubscriber<AliWxPayBean>(new SubscriberOnListener<AliWxPayBean>() {
@Override
public void onSucceed(final AliWxPayBean data) {
hideLoadDialog();
System.out.println("微信預支付訂單資訊:" + data.getPrepayid());
System.out.println("sign:" + data.getSign());
PayReq request = new PayReq();
request.appId = data.getAppid();
request.partnerId = data.getPartnerid();
request.prepayId = data.getPrepayid();
request.packageValue = data.getPackageValue();
request.nonceStr = data.getNoncestr();
request.timeStamp = data.getTimestamp();
request.sign = data.getSign();
WxFactory.getInstance().getWxApi(MainActivity.this).sendReq(request);
}
@Override
public void onError(int code, String msg) {
hideLoadDialog();
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
}
}, MainActivity.this));
處理微信支付結果:
package com.ywl5320.rxjavaretrofit.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
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;
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// api = WXAPIFactory.createWXAPI(this, "", true);
// api.registerApp("");
api = WxFactory.getInstance().getWxApi(this);
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
@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();
}
else if(resp.errCode == -1)
{
Toast.makeText(this, "支付出錯:" + resp.errStr, Toast.LENGTH_LONG).show();
}
else if(resp.errCode == -2)
{
Toast.makeText(this, "取消支付", Toast.LENGTH_LONG).show();
}
}
finish();
}
}
服務端和客戶端核心程式碼就是以上的全部,具體例項請參考原始碼:
下一篇將新增增量更新功能。