微信小程序调用JSAPI进行微信支付
1、小程序中先调用接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易后调起支付;
2、商户server调用再次签名;
3、唤起微信支付页面,进行支付;
4、支付成功后,调用回调接口,进行微信支付通知;
goLoginGetOpenId:function(){
var t = this;
uni.login({
provider: 'weixin',
success: function(res) {
if (res.code) {
console.log("res.code: ",res.code);
util.post(
t.mainUrl + '/xieHuiZhuCe/getOpenId',
{
code:res.code,
recordId:t.id
},
function(result) {
console.log("xieHuiZhuCe/getOpenId",JSON.stringify(result));
t.openid = result.data.openid;
t.hylb = result.data.hylb;
if(t.hylb == 1|| t.hylb == 2){
t.payMoney = 0.01;
}else if(t.hylb == 4){
t.payMoney = 0.01;
}
t.out_trade_no = result.data.out_trade_no;
}
);
}
}
})
}
getPrePayId(){
var t = this;
util.post(
t.mainUrl + '/xieHuiZhuCe/getPrePayId',
{
out_trade_no : t.out_trade_no,
hylb : t.hylb,
openid : t.openid,
payMoney :t.payMoney
},
function(result) {
if(result.status == '0001'){
console.log("getPrePayId: ",result.prepay_id);
t.prepay_id = result.prepay_id;
if(!result.prepay_id){
uni.showToast({
icon: 'none',
mask:true,
duration:2000,
title: '该订单已支付,请勿重复支付!'
});
return;
}
t.WxSecondSign();
}else{
uni.showToast({
title: '服务器忙 请稍后再试'
});
}
}
);
}
WxSecondSign(){
var t = this;
util.post(
t.mainUrl + '/xieHuiZhuCe/WxSecondSign',
{
prepay_id : t.prepay_id
},
function(result) {
if(result.status == '0001'){
uni.requestPayment({
provider: 'wxpay',
timeStamp: result.timeStamp+'',
nonceStr: result.nonce_str,
package: 'prepay_id='+t.prepay_id,
signType: 'MD5',
paySign: result.paySign,
success: function (res) {
console.log(res);
console.log('success:' + JSON.stringify(res));
uni.navigateTo({
url:'./index'
})
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
},
complete(err){
console.log('complete:' + JSON.stringify(err));
}
});
}else{
uni.showToast({
title: '服务器忙 请稍后再试'
});
}
}
);
}
@RequestMapping("/getOpenId")
@ResponseBody
public Map getOpenId(@RequestBody Map paramMap) {
Map resultMap = new HashMap();
String result = HttpClient4.doGet("https://api.weixin.qq.com/sns/jscode2session?appid="+appID+"&secret="+appSecret+"&js_code="+paramMap.get("code")+"&grant_type=authorization_code");
Gson gson = new Gson();
Map map=gson.fromJson(result, HashMap.class);
int recordId = StringUtils.getIntegerByObj(paramMap.get("recordId"));
if(recordId!=0){
XieHui_Record xieHuiRecord = xieHuiRecordRepository.getOne(recordId);
List<XieHui_Order> orderList = xieHuiOrderRepository.findOrderByXiehui_record_idAndIsdel(StringUtils.getStringByObj(paramMap.get("recordId")));
XieHui_Order order = new XieHui_Order();
if(orderList == null || orderList.size() == 0){
order.setXiehui_record_id(StringUtils.getStringByObj(paramMap.get("recordId")));
int randomNum = (int) (Math.random() * 1999 + 5000);
String out_trade_no = TimeUtils.getNowFormatTimeStringyyyyMMddHHmmssSSS() + randomNum;
order.setOrder_number(out_trade_no);
xieHuiOrderRepository.save(order);
}else{
order = orderList.get(0);
}
map.put("out_trade_no",order.getOrder_number());
map.put("hylb",xieHuiRecord.getHylb());
}
resultMap.put("data", map);
resultMap.put("status", ConstantUtil.status_success);
resultMap.put("msg", "请求成功");
return resultMap;
}
@RequestMapping("getPrePayId")
@ResponseBody
public Map getPrePayId(@RequestBody Map param) {
Map resultMap = new HashMap();
String mch_id = "1896584523";
String nonce_str = WechatUtil.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
String subject = "针灸学会-知识";
String out_trade_no = StringUtils.getStringByObj(param.get("out_trade_no"));
String total_amount = StringUtils.getStringByObj(param.get("payMoney"));
int hylb = StringUtils.getIntegerByObj(param.get("hylb"));
if(hylb == 4){
total_amount = StringUtils.getStringByObj(param.get("payMoney"));
}
String finalmoney = WechatUtil.getMoney(total_amount);
String spbill_create_ip = "127.0.0.1";
System.out.println("spbill_create_ip=" + spbill_create_ip);
String notify_url = config.getNotify_url();
String tradeType = "JSAPI";
String openid = StringUtils.getStringByObj(param.get("openid"));
Map<String, String> reqData = new HashMap();
reqData.put("appid", appID);
reqData.put("mch_id", mch_id);
reqData.put("nonce_str", nonce_str);
reqData.put("sign_type", MD5);
reqData.put("body", subject);
reqData.put("out_trade_no", out_trade_no);
reqData.put("total_fee", finalmoney);
reqData.put("spbill_create_ip", spbill_create_ip);
reqData.put("notify_url", notify_url);
reqData.put("trade_type", tradeType);
reqData.put("openid", openid);
String sign = "";
try {
logger.info("签名数据:" + reqData);
System.out.println("reqData=" + reqData);
sign = WechatUtil.generateSignature(reqData, Key);
reqData.put("sign", sign);
} catch (Exception e) {
logger.error("微信签名数据:" + e);
return resultMap;
}
logger.info("签名数据:" + sign);
String xml = WechatUtil.parseXML(reqData);
System.out.println("xml:"+xml);
String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
String prepay_id = "";
Map map = new HashMap();
try {
map = WechatUtil.getMwebUrl(createOrderURL, xml);
String return_code = (String) map.get("return_code");
String return_msg = (String) map.get("return_msg");
if ("SUCCESS".equals(return_code) && "OK".equals(return_msg)) {
prepay_id = (String) map.get("prepay_id");
logger.info("map=" + map);
resultMap.put("prepay_id", prepay_id);
resultMap.put("status", ConstantUtil.status_success);
resultMap.put("msg", "请求成功");
} else {
logger.error("统一支付接口获取预支付订单出错" + map);
resultMap.put("msg", "支付错误");
return resultMap;
}
} catch (Exception e) {
logger.error("统一支付接口获取预支付订单出错" + e);
resultMap.put("msg", "支付错误");
return resultMap;
}
return resultMap;
}
public static String generateSignature(final Map<String, String> data, String key) throws Exception {
Set<String> keySet = data.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (data.get(k).trim().length() > 0) {
sb.append(k).append("=").append(data.get(k).trim()).append("&");
}
}
sb.append("key=").append(key);
try {
return MD5(sb.toString()).toUpperCase();
} catch (Exception e) {
throw new Exception();
}
}
public static String parseXML(Map<String, String> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (null != v && !"".equals(v) && !"appkey".equals(k)) {
sb.append("<" + k + ">" + parameters.get(k) + "</" + k + ">\n");
}
}
sb.append("</xml>");
return sb.toString();
}
public static Map getMwebUrl(String url, String xmlParam) {
String jsonStr = null;
HttpClient httpClient = new HttpClient();
Map map = new HashMap();
try {
PostMethod method = null;
RequestEntity reqEntity = new StringRequestEntity(xmlParam, "text/json", "UTF-8");
method = new PostMethod(url);
method.setRequestEntity(reqEntity);
method.addRequestHeader("Content-Type", "application/json;charset=utf-8");
httpClient.executeMethod(method);
StringBuffer resBodyBuf = new StringBuffer();
byte[] responseBody = new byte[1024];
int readCount = 0;
BufferedInputStream is = new BufferedInputStream(method.getResponseBodyAsStream());
while ((readCount = is.read(responseBody, 0, responseBody.length)) != -1) {
resBodyBuf.append(new String(responseBody, 0, readCount, "utf-8"));
}
jsonStr = resBodyBuf.toString();
System.out.println(jsonStr);
map = parseXmlToList(jsonStr);
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
@RequestMapping("/WxSecondSign")
@ResponseBody
public Map WxSecondSign(HttpServletRequest request,@RequestBody Map paramMap) {
Map resultMap = new HashMap();
try {
String prepay_id = StringUtils.getStringByObj(paramMap.get("prepay_id"));
String nonce_str = WechatUtil.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
Long timeStamp = System.currentTimeMillis()/1000;
StringBuffer signData = new StringBuffer();
signData.append("appId="+appID+"&");
signData.append("nonceStr="+nonce_str+"&");
signData.append("package=prepay_id="+prepay_id+"&");
signData.append("signType="+MD5+"&");
signData.append("timeStamp="+timeStamp+"&");
signData.append("key="+Key);
String paySign = WechatUtil.MD5(signData.toString());
resultMap.put("nonce_str", nonce_str);
resultMap.put("timeStamp", timeStamp);
resultMap.put("paySign", paySign);
resultMap.put("status", ConstantUtil.status_success);
resultMap.put("msg", "请求成功");
} catch (Exception e) {
resultMap.put("status", ConstantUtil.status_error);
resultMap.put("msg", "请求失败");
e.printStackTrace();
}
return resultMap;
}
public static String MD5(String data) throws Exception {
java.security.MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
@RequestMapping(value = "/wxPayCallBack")
public void weixinPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
BufferedReader reader = request.getReader();
String line = "";
Map map = new HashMap();
String xml = "<xml><return_code><![CDATA[FAIL]]></xml>";
StringBuffer inputString = new StringBuffer();
while ((line = reader.readLine()) != null) {
inputString.append(line);
}
request.getReader().close();
logger.info("----接收到的报文---" + inputString.toString());
if (inputString.toString().length() > 0) {
map = WechatUtil.parseXmlToList(inputString.toString());
} else {
logger.info("接受微信报文为空");
}
logger.info("map=" + map);
if (map != null && "SUCCESS".equals(map.get("result_code"))) {
this.updateOrderStatus(map);
xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
logger.info("商户订单号: 【" + map.get("out_trade_no") + "】支付成功");
} else {
logger.error("商户订单号: 【" + map.get("out_trade_no") + "】支付失败, "+"描述:【errCode:"+map.get("err_code")+", errCodeDes:"+map.get("err_code_des")+"】");
}
response.getWriter().write(xml);
}
@SuppressWarnings({"unused", "rawtypes", "unchecked"})
public static Map parseXmlToList(String xml) {
Map retMap = new HashMap();
try {
StringReader read = new StringReader(xml);
InputSource source = new InputSource(read);
SAXBuilder sb = new SAXBuilder();
Document doc = (Document) sb.build(source);
Element root = doc.getRootElement();
List<Element> es = root.getChildren();
if (es != null && es.size() != 0) {
for (Element element : es) {
retMap.put(element.getName(), element.getValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return retMap;
}
public static String getMoney(String amount) {
if (amount == null) {
return "";
}
String currency = amount.replaceAll("\\$|\\¥|\\,", "");
int index = currency.indexOf(".");
int length = currency.length();
Long amLong = 0l;
if (index == -1) {
amLong = Long.valueOf(currency + "00");
} else if (length - index >= 3) {
amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
} else if (length - index == 2) {
amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
} else {
amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
}
return amLong.toString();
}
public final static String getMessageDigest(byte[] buffer) {
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(buffer);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}