1.微信預支付交易單(unifiedorder)
/**
* @ 生成預支付交易單
* @Title: unifiedorder
* @param type 1 預約支付;2 購買次卡支付
* @param orderCode
* @param openid
* @param total_fee
* @return
* @return JSONObject
* @date 2019年9月9日 下午4:38:09
* @author Minglij
*/
@ApiOperation("生成預支付交易單")
@RequestMapping(value = "/unifiedorder", method = RequestMethod.GET)
@ResponseBody
public JSONObject unifiedorder(int type, String categoryId, String orderCode, String openid, String total_fee) {
JSONObject result = new JSONObject();
try {
Map<String, Object> map = new HashMap<String, Object>();
/**
* 生成預支付交易單
*/
String prepay_id = "";
String nonce_str = "";
nonce_str = ToolsUtil.randomString(32);
long timeStamp = new Date().getTime();
String body = "燃奇球館預約支付";
if(type == 2) { // 購買次卡訂單編號
orderCode = "K"+new Date().getTime()+""+ToolsUtil.randomInt(3);
}
String out_trade_no = orderCode;
long total_fee_ = (long)(Float.parseFloat(total_fee)*100);
prepay_id = wxServerService.unifiedorder(nonce_str, body, out_trade_no, total_fee_, SystemConstants.WX_NOTIFY_URL, "JSAPI", openid);
map.put("timeStamp", timeStamp);
map.put("nonceStr", nonce_str);
map.put("package", prepay_id);
//順序按照ASCII字典序排序
String signA = "appId="+ SystemConstants.APPID_CUSTOMER +"&nonceStr="+ nonce_str +"&package=prepay_id="+ prepay_id
+"&signType=MD5&timeStamp="+ timeStamp +"&key="+SystemConstants.MCH_KEY;
String paySign = ToolsUtil.md5(signA).toUpperCase();
// 緩存簽名,微信支付通知校驗
// log.info("cache_wxPaySign:"+JSONObject.toJSONString(SystemCache.cache_wxPaySign));
// SystemCache.setPaySignCache(out_trade_no, paySign);
// 保存爲統一支付記錄
UnifiedorderRecord unifiedorderRecord = new UnifiedorderRecord();
unifiedorderRecord.setType(type);
unifiedorderRecord.setCategoryId(categoryId);
unifiedorderRecord.setOrderCode(orderCode);
unifiedorderRecord.setOpenid(openid);
unifiedorderRecord.setTotalFee(new BigDecimal(total_fee_));
unifiedorderRecord.setInsertDate(new Date());
unifiedorderRecord.setFlag(0);
if(type == 1) {
unifiedorderRecord.setRemark("微信用戶("+ openid +")預約球館,需預支付:"+total_fee_+"分");
} else if(type == 2) {
unifiedorderRecord.setRemark("微信用戶("+ openid +")購買次卡,需預支付:"+total_fee_+"分");
}
EntityWrapper<UnifiedorderRecord> wrapper = new EntityWrapper<UnifiedorderRecord>();
wrapper.eq("orderCode", orderCode);
wrapper.eq("type", type);
wrapper.eq("flag", 0);
UnifiedorderRecord unifiedorderRecord_ = unifiedorderRecordService.selectOne(wrapper);
if(null != unifiedorderRecord_) {
unifiedorderRecord_.setFlag(-1);
unifiedorderRecordService.update(unifiedorderRecord_, wrapper);
}
unifiedorderRecordService.insert(unifiedorderRecord);
map.put("paySign", paySign);
result.put("obj", map);
result.put("success", true);
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
result.put("success", false);
}
return result;
}
2.微信支付成功回調(wxNotify)
/**
* @ 接收支付成功後,微信返回
* @Title: wxNotify
* @Description: TODO
* @return void
* @date 2019年9月9日 下午4:41:15
* @author Minglij
* @throws Exception
*/
@ApiOperation("支付成功後通知")
@RequestMapping(value = "/wxNotify", method = RequestMethod.POST)
@ResponseBody
public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray(), "utf-8");
log.info(">>>>>>>>支付成功,微信回調結果:"+result);
SortedMap<String, String> map = ToolsUtil.xmlToMap(result);
PrintWriter writer = response.getWriter();
// 是否已經接收過通知
EntityWrapper<WxPayNotice> wrapper_wxpn = new EntityWrapper<WxPayNotice>();
wrapper_wxpn.eq("transaction_id", map.get("transaction_id"));
WxPayNotice wxPayNotice = wxPayNoticeService.selectOne(wrapper_wxpn);
if(null != wxPayNotice) {
// 微信到賬通知已經收到
log.info("===============支付通知重複==============");
String noticeStr = setXML("SUCCESS", "");
writer.write(noticeStr);
writer.flush();
} else {
// 簽名校驗
if(WxHandler.isTenpaySign(map.get("sign").toString(), map)) {
log.info("===============支付失敗,簽名不一致==============");
String noticeStr = setXML("FAIL", "簽名錯誤");
writer.write(noticeStr);
writer.flush();
} else {
// 校驗訂單是否存在,訂單金額是否一致
boolean isSucc = reqOrderQueryResult(map);
if (!isSucc) {
// 支付失敗, 記錄流水失敗
log.info("===============支付失敗,到賬金額和訂單金額不一致==============");
String noticeStr = setXML("FAIL", "");
writer.write(noticeStr);
writer.flush();
} else {
// 支出成功,處理業務
EntityWrapper<User> wrapper = new EntityWrapper<User>();
wrapper.eq("openid", map.get("openid"));
User user = userService.selectOne(wrapper);
String out_trade_no = map.get("out_trade_no");
//
EntityWrapper<UnifiedorderRecord> wrapper_un = new EntityWrapper<UnifiedorderRecord>();
wrapper_un.eq("orderCode", out_trade_no);
wrapper_un.eq("openid",map.get("openid"));
wrapper_un.eq("flag", 0);
UnifiedorderRecord unifiedorderRecord_ = unifiedorderRecordService.selectOne(wrapper_un);
if(null == unifiedorderRecord_) {
log.info("===============微信通知錯誤,爲找到統一支付訂單==============");
String noticeStr = setXML("FAIL", "");
writer.write(noticeStr);
writer.flush();
} else {
// 更新統一支付記錄
unifiedorderRecord_.setFlag(1);
unifiedorderRecordService.update(unifiedorderRecord_, wrapper_un);
//
if(unifiedorderRecord_.getType() == 1) {
// 預約訂單業務
boolean uc = businessOrderService.doWXPayNotice(user.getId(), map.get("out_trade_no"), map.get("transaction_id"));
log.info("===============付款成功,業務處理完畢(預約)=============="+uc);
} else if(unifiedorderRecord_.getType() == 2) {
// 購買次卡業務
boolean uc = cardOrderService.doWXPayNotice(user.getId(), map.get("out_trade_no"), unifiedorderRecord_.getCategoryId(), map.get("transaction_id"));
log.info("===============付款成功,業務處理完畢(購買次卡)=============="+uc);
}
String noticeStr = setXML("SUCCESS", "");
writer.write(noticeStr);
writer.flush();
}
// 刪除緩存中籤名
// SystemCache.removePaySignCache(map.get("out_trade_no"));
// 通知微信已經收到消息,不要再給我發消息了,否則微信會8連擊調用本接口
}
}
}
}