微信支付-簡易例項程式碼
阿新 • • 發佈:2018-12-31
最近由於專案需要整合微信支付,這裡記錄一下整合過程中的步驟。
要整合微信支付首先需要到微信開發者平臺註冊企業開發者。註冊成功之後,收集專案用的唯一id,iOS為Boundle ID,Android為包名。然後在開發中心建立應用,得到專案的AppId、MchId-商戶賬戶,獲取支付能裡後,從郵件中得到、AppSercret-商戶金鑰,32位字串,在商戶平臺中設定。得到這三個值後就可以開始開發了。
本例項僅僅完成了調起微信完成支付的過程,後續的成功支付之後的回撥沒有完善。
一、客戶端,此處以iOS程式碼示例
1、將得到的AppId設定為iOS工程的Schemes,然後設定正確的Boundle ID。
2、按照官網的文件,將微信支付的SDK整合到現有專案中,然後在任意頁面新增一個按鈕,用來調起微信支付。程式碼如下。
NSString *res = [WXApiRequestHandler jumpToBizPay]; if( ![@"" isEqual:res] ){ UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"支付失敗" message:res delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alter show]; }
至此,微信支付客戶端的事情就簡單的完成了,下面是服務端的簡單例項。// // WXApiRequestHandler.m // PayDemo // // Created by yb on 2017/2/27. // Copyright © 2017年 yb. All rights reserved. // #import "WXApiRequestHandler.h" #import "WXApi.h" @implementation WXApiRequestHandler + (NSString *)jumpToBizPay { //============================================================ // V3&V4支付流程實現 // 注意:引數配置請檢視伺服器端Demo // 更新時間:2015年11月20日 //============================================================ NSString *urlString = @"http://192.168.2.67:8080/WXPay/WXPay/getPreyId.do"; //解析服務端返回json資料 NSError *error; //載入一個NSURL物件 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; //將請求的url資料放到NSData物件中 NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; if ( response != nil) { NSMutableDictionary *dict = NULL; //IOS5自帶解析類NSJSONSerialization從response中解析出資料放到字典中 dict = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error]; NSLog(@"url:%@",urlString); if(dict != nil){ NSMutableString *retcode = [dict objectForKey:@"retcode"]; if (retcode.intValue == 0){ NSMutableString *stamp = [dict objectForKey:@"timestamp"]; //調起微信支付 PayReq* req = [[PayReq alloc] init]; req.partnerId = [dict objectForKey:@"partnerid"]; req.prepayId = [dict objectForKey:@"prepayid"]; req.nonceStr = [dict objectForKey:@"noncestr"]; req.timeStamp = stamp.intValue; req.package = [dict objectForKey:@"package"]; req.sign = [dict objectForKey:@"sign"]; [WXApi sendReq:req]; //日誌輸出 NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[dict objectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign ); return @""; }else{ return [dict objectForKey:@"retmsg"]; } }else{ return @"伺服器返回錯誤,未獲取到json物件"; } }else{ return @"伺服器返回錯誤"; } } @end
二、服務端
服務端需要注意的事情是從微信獲取預支付訂單的時候,簽名的引數一定要按照官網指定的引數循序,不然順序不對,簽名的MD5值就不對了。從微信拿到支付id之後,需要將引數再次簽名後給客戶端返回,此時參與簽名的有7個引數。下面給出官網提供的簽名驗證工具地址。二次簽名的時候引數順序也不能錯。
http://mch.weixin.qq.com/wiki/tools/signverify/
@RequestMapping("/getPreyId.do")
public void getPreyId(HttpServletRequest request, HttpServletResponse response) throws IOException{
SortedMap<String, String> reqMap = new TreeMap<String, String>();
reqMap.put("appid", WeiChartConfig.AppId);//必填
reqMap.put("mch_id", WeiChartConfig.MchId);//必填
reqMap.put("nonce_str", MD5Util.getRandomStringByLength(32));
reqMap.put("body", "交易-線上支付");
reqMap.put("device_info","WEB");
reqMap.put("sign_type", "MD5");
reqMap.put("out_trade_no", MD5Util.getCurrTime()+1); //商戶系統內部的訂單號,
reqMap.put("total_fee", "100"); //訂單總金額,單位為分 必填 必填 必填 重要的事情說3遍
reqMap.put("product_id", "11111");
reqMap.put("spbill_create_ip", MD5Util.getHostIp()); //使用者端實際ip
reqMap.put("notify_url", "http://*.*.*.*:8080/WXPay/resultInfo.do"); //通知地址
reqMap.put("trade_type", "APP"); //交易型別
String sign = MD5Util.getSign(reqMap, WeiChartConfig.AppSercret);
String reqStr = MD5Util.parseString2Xml(reqMap,sign);
String getInfo = HttpClientUtil.postHtpps(WeiChartConfig.PrepayUrl, reqStr);
Map<String, String> map = Snippet.getResult(getInfo);
JSONObject jsonObject1 = JSONObject.fromObject(map);
System.out.println("微信返回過來的所有資料====="+jsonObject1);
Map<String,String> responseMap = new LinkedHashMap<String, String>();
responseMap.put("appid", map.get("appid"));
responseMap.put("noncestr", map.get("nonce_str"));
responseMap.put("package", "Sign=WXPay");
responseMap.put("partnerid", map.get("mch_id"));
responseMap.put("prepayid", map.get("prepay_id"));
responseMap.put("timestamp", "1489572241");
String signAgain = MD5Util.getSign(responseMap, WeiChartConfig.AppSercret);
responseMap.put("sign", signAgain);
JSONObject jsonObject = JSONObject.fromObject(responseMap);
response.setCharacterEncoding("gb2312");
PrintWriter out = response.getWriter();
out.println(jsonObject);
System.out.println("返回給客戶端的資料======"+jsonObject);
}
/**
* 獲取簽名 md5加密(微信支付必須用MD5加密)
* 獲取支付簽名
* @param responseMap
* @return
*/
public static String getSign(Map<String, String> responseMap,String key){
String sign = null;
StringBuffer sb = new StringBuffer();
Set es = responseMap.entrySet();
Iterator iterator = es.iterator();
while(iterator.hasNext()){
Map.Entry entry = (Map.Entry)iterator.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if (null != v && !"".equals(v) && !"sign".equals(k)&& !"key".equals(k)) {
sb.append(k+"="+v+"&");
}
}
sb.append("key="+key);
System.out.println("簽名結果:" + sb.toString());
sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
return sign;
}
完善好之後,客戶端就能夠開啟微信進行支付了。