package com.jpsoft.smart.modules.pay.weixin; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.ijpay.core.enums.SignType; import com.ijpay.core.enums.TradeType; import com.ijpay.core.kit.HttpKit; import com.ijpay.core.kit.WxPayKit; import com.ijpay.wxpay.WxPayApi; import com.ijpay.wxpay.model.UnifiedOrderModel; import com.jpsoft.smart.modules.base.entity.ElectricClientInfo; import com.jpsoft.smart.modules.base.entity.RechargeRecord; import com.jpsoft.smart.modules.base.service.ElectricClientInfoService; import com.jpsoft.smart.modules.base.service.RechargeRecordService; import com.jpsoft.smart.modules.business.service.RechargeService; import com.jpsoft.smart.modules.common.dto.MessageResult; import com.jpsoft.smart.modules.communication.server.protocol.MeterReceivePacket; import com.jpsoft.smart.modules.pay.properties.WxJpsoftProperties; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @author 墨鱼_mo * @date 2019-11-26 10:35 */ @RequestMapping("/wxPay") @RestController public class WxPayController { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private WxJpsoftProperties wxJpsoftProperties; @Autowired private RechargeRecordService rechargeRecordService; @Autowired private RechargeService rechargeService; @Autowired private ElectricClientInfoService electricClientInfoService; @ApiOperation(value = "微信JSAPI支付") @GetMapping("/webPay") public MessageResult webPay(String recordId,String openId) { MessageResult msgResult = new MessageResult<>(); try { RechargeRecord rechargeRecord = rechargeRecordService.get(recordId); rechargeRecord.setOpenId(openId); rechargeRecord.setUpdateTime(new Date()); rechargeRecordService.update(rechargeRecord); if (rechargeRecord == null) { throw new Exception("订单不存在"); } if (StrUtil.isBlank(rechargeRecord.getOpenId())) { throw new Exception("openId不存在"); } if (rechargeRecord.getBuyAmount().compareTo(BigDecimal.ZERO) != 1) { throw new Exception("金额有误"); } if (rechargeRecord.getPaymentStatus().equals("20")) { throw new Exception("订单已支付"); } //金额处理 int wxTotalTee = rechargeRecord.getBuyAmount().multiply(new BigDecimal(100)).intValue(); Map params = UnifiedOrderModel .builder() .appid(wxJpsoftProperties.getAppId()) .mch_id(wxJpsoftProperties.getMchId()) .sub_mch_id(wxJpsoftProperties.getSubMchId()) .nonce_str(WxPayKit.generateStr()) .body(rechargeRecord.getProductTheme()) .out_trade_no(rechargeRecord.getSerialNumber()) .total_fee(String.valueOf(wxTotalTee)) .spbill_create_ip(wxJpsoftProperties.getIp()) .notify_url(wxJpsoftProperties.getNotifyUrl()) .trade_type(TradeType.JSAPI.getTradeType()) .openid(rechargeRecord.getOpenId()) .build() .createSign(wxJpsoftProperties.getMchKey(), SignType.HMACSHA256); String xmlResult = WxPayApi.pushOrder(false, params); logger.info(xmlResult); Map resultMap = WxPayKit.xmlToMap(xmlResult); String returnCode = resultMap.get("return_code"); String returnMsg = resultMap.get("return_msg"); if (!WxPayKit.codeIsOk(returnCode)) { logger.error(returnCode); throw new Exception(returnMsg); } String resultCode = resultMap.get("result_code"); if (!WxPayKit.codeIsOk(resultCode)) { String errCode = resultMap.get("err_code_des"); logger.error(errCode); throw new Exception(errCode); } // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回 String prepayId = resultMap.get("prepay_id"); Map packageParams = WxPayKit.prepayIdCreateSign(prepayId, wxJpsoftProperties.getAppId(), wxJpsoftProperties.getMchKey(), SignType.HMACSHA256); msgResult.setData(packageParams); msgResult.setResult(true); } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage(), e); msgResult.setResult(false); msgResult.setMessage(e.getMessage()); } return msgResult; } @RequestMapping(value = "/payNotify", method = {RequestMethod.POST, RequestMethod.GET}) @ResponseBody public String payNotify(HttpServletRequest request) { String xmlMsg = HttpKit.readData(request); logger.warn("支付通知=" + xmlMsg); Map params = WxPayKit.xmlToMap(xmlMsg); String returnCode = params.get("return_code"); String outTradeNo = params.get("out_trade_no"); String payTimeStr = params.get("time_end"); Date payTime = DateUtil.parse(payTimeStr); // 注意此处签名方式需与统一下单的签名类型一致 WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey() if (WxPayKit.verifyNotify(params, wxJpsoftProperties.getMchKey(), SignType.HMACSHA256)) { if (WxPayKit.codeIsOk(returnCode)) { // 更新订单信息 try { RechargeRecord rechargeRecord = rechargeRecordService.getBySerialNum(outTradeNo); if (rechargeRecord == null) { throw new Exception("支付已完成,但未找到此订单号的流水"); } if (rechargeRecord.getBuyAmount().multiply(new BigDecimal(100)).compareTo(new BigDecimal(params.get("total_fee"))) !=0) { throw new Exception("支付金额与系统金额不一致"); } rechargeRecord.setUpdateTime(new Date()); rechargeRecord.setUpdateBy(params.get("openid")); rechargeRecord.setBuyType("weipay"); rechargeRecord.setPaymentStatus("20"); rechargeRecord.setTransactionNumber(params.get("transaction_id")); rechargeRecord.setPaymentTime(payTime); try { MeterReceivePacket mp = rechargeService.recharge(rechargeRecord.getRoomId(), rechargeRecord.getBuyElectricity(), 3, TimeUnit.SECONDS); if (mp == null){ rechargeRecord.setErrorLog("相应超时"); }else { if (!mp.isValidateResult()){ rechargeRecord.setErrorLog("校验失败"); }else { rechargeRecord.setChargingStatus("20"); rechargeRecord.setDumpEnergy(mp.getRemain()); //当前剩余电量 ElectricClientInfo clientInfo = electricClientInfoService.findOneByRoomId(rechargeRecord.getRoomId()); if (clientInfo!=null){ //记录剩余电量 clientInfo.setElectricityRemaining(mp.getRemain()); //记录充电次数 clientInfo.setRechargeTimes(mp.getRechargeTimes()); clientInfo.setActive(mp.getState()!=1); clientInfo.setUpdateTime(new Date()); electricClientInfoService.update(clientInfo); } } } } catch (Exception e) { rechargeRecord.setErrorLog(e.getMessage()); logger.error(e.getMessage(), e); e.printStackTrace(); } rechargeRecordService.update(rechargeRecord); // 发送通知等 Map xml = new HashMap(2); xml.put("return_code", "SUCCESS"); xml.put("return_msg", "OK"); return WxPayKit.toXml(xml); } catch (Exception e) { logger.error(e.getMessage(), e); e.printStackTrace(); } } } return null; } }