package com.jpsoft.epay.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.WxPayApiConfigKit; import com.ijpay.wxpay.model.UnifiedOrderModel; import com.jpsoft.epay.modules.base.entity.RechargeRecord; import com.jpsoft.epay.modules.base.service.ElectricMeterInfoService; import com.jpsoft.epay.modules.base.service.RechargeRecordService; import com.jpsoft.epay.modules.business.controller.DemoController; import com.jpsoft.epay.modules.business.service.RechargeService; import com.jpsoft.epay.modules.common.dto.MessageResult; import com.jpsoft.epay.modules.communication.server.protocol.MeterReceivePacket; import com.jpsoft.epay.modules.pay.properties.WxPayProperties; 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 WxPayProperties wxPayProperties; @Autowired private RechargeRecordService rechargeRecordService; @Autowired private RechargeService rechargeService; @ApiOperation(value = "微信JSAPI支付") @GetMapping("/webPay") public MessageResult webPay(@RequestParam("rechargeRecordId") String rechargeRecordId) { MessageResult msgResult = new MessageResult<>(); try { RechargeRecord rechargeRecord = rechargeRecordService.get(rechargeRecordId); 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(wxPayProperties.getAppId()) .mch_id(wxPayProperties.getMchId()) .sub_mch_id(wxPayProperties.getSubMchId()) .nonce_str(WxPayKit.generateStr()) .body(rechargeRecord.getProductTheme()) .out_trade_no(rechargeRecord.getSerialNumber()) .total_fee(String.valueOf(wxTotalTee)) .spbill_create_ip(wxPayProperties.getIp()) .notify_url(wxPayProperties.getNotifyUrl()) .trade_type(TradeType.JSAPI.getTradeType()) .openid(rechargeRecord.getOpenId()) .build() .createSign(wxPayProperties.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, wxPayProperties.getAppId(), wxPayProperties.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.info("支付通知=" + 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); // 注意此处签名方式需与统一下单的签名类型一致 if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), 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("wechat"); 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"); } } } 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; } }