package com.charging.chargingparking.modules.pay.wechat; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.charging.chargingparking.dto.AccessToken; import com.charging.chargingparking.dto.MessageResult; import com.charging.chargingparking.dto.ParkingCostDTO; import com.charging.chargingparking.dto.UserInfo; import com.charging.chargingparking.entity.ParkingPay; import com.charging.chargingparking.entity.ParkingRecord; import com.charging.chargingparking.modules.pay.properties.WxPayProperties; import com.charging.chargingparking.service.ParkingFeeService; import com.charging.chargingparking.service.ParkingPayService; import com.charging.chargingparking.service.ParkingRecordService; import com.charging.chargingparking.utils.Sign; import com.charging.chargingparking.utils.StringUtils; import com.charging.chargingparking.utils.WeixinUtil; 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 lombok.extern.slf4j.Slf4j; 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; /** * @author 墨鱼_mo * @date 2022/1/18 0018 上午 9:53 */ @RequestMapping("/wxPay") @RestController @Slf4j public class WxPayController { @Autowired private ParkingRecordService parkingRecordService; @Autowired private ParkingFeeService parkingFeeService; @Autowired private WxPayProperties wxPayProperties; @Autowired private ParkingPayService parkingPayService; /** * 停车微信JSAPI支付 * * @param id * @param openId * @return */ @PostMapping("/parkingWxPay") public MessageResult parkingWxPay(String id, String openId,String codePayType) { MessageResult msgResult = new MessageResult<>(); try { if (StrUtil.isBlank(openId)) { throw new Exception("openId不存在"); } if (StrUtil.isBlank(id)) { throw new Exception("订单不存在"); } ParkingRecord parkingRecord = parkingRecordService.getById(id); if (parkingRecord == null) { throw new Exception("记录不存在"); } //记录总应缴 ParkingCostDTO parkingCostDTO = parkingFeeService.parkingCost(parkingRecord); BigDecimal parkCost = parkingCostDTO.getNeedAmount(); parkingRecord.setTotalAmount(parkCost); parkingRecord.setUpdateTime(new Date()); parkingRecordService.updateById(parkingRecord); if (parkCost.subtract(parkingRecord.getPayAmount()).compareTo(BigDecimal.ZERO) <= 0) { throw new Exception("请直接离场"); } //金额处理 int wxTotalTee = parkCost.subtract(parkingRecord.getPayAmount()).multiply(new BigDecimal(100)).intValue(); //创建支付记录 ParkingPay parkingPay = new ParkingPay(); parkingPay.setParkingRecordId(parkingRecord.getId()); parkingPay.setOutOrderNo(wxPayProperties.getUrlKey() + StringUtils.getOutTradeNo()); parkingPay.setCreateTime(new Date()); parkingPay.setOpenId(openId); parkingPay.setCodePayType(codePayType); parkingPayService.save(parkingPay); Map params = UnifiedOrderModel .builder() .appid(wxPayProperties.getAppId()) // .appid(companyPaymentInfo.getSubAppId()) // .mch_id(companyPaymentInfo.getSubMchId()) .mch_id(wxPayProperties.getMchId()) .sub_mch_id(wxPayProperties.getSubMchId()) // .sub_appid(companyPaymentInfo.getSubAppId()) .nonce_str(WxPayKit.generateStr()) .body(parkingRecord.getProductTheme()) .out_trade_no(parkingPay.getOutOrderNo()) .total_fee(String.valueOf(wxTotalTee)) .spbill_create_ip(wxPayProperties.getIp()) .notify_url(wxPayProperties.getNotifyUrl()) .trade_type(TradeType.JSAPI.getTradeType()) .sub_openid(parkingPay.getOpenId()) .build() .createSign(wxPayProperties.getMchKey(), SignType.HMACSHA256); String xmlResult = WxPayApi.pushOrder(false, params); Map resultMap = WxPayKit.xmlToMap(xmlResult); String returnCode = resultMap.get("return_code"); String returnMsg = resultMap.get("return_msg"); if (!WxPayKit.codeIsOk(returnCode)) { log.error(returnCode); throw new Exception(returnMsg); } String resultCode = resultMap.get("result_code"); if (!WxPayKit.codeIsOk(resultCode)) { String errCode = resultMap.get("err_code_des"); log.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(); log.error(e.getMessage(), e); msgResult.setResult(false); msgResult.setCode(400); msgResult.setMessage(e.getMessage()); } return msgResult; } @RequestMapping(value = "/parkingWxPayNotify", method = {RequestMethod.POST, RequestMethod.GET}) @ResponseBody public String parkingWxPayNotify(HttpServletRequest request) { String xmlMsg = HttpKit.readData(request); log.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"); String openId = params.get("openid"); String transactionNo = params.get("transaction_id"); BigDecimal buyerPayAmount = new BigDecimal(params.get("total_fee")).divide(new BigDecimal(100)); Date payTime = DateUtil.parse(payTimeStr); // 注意此处签名方式需与统一下单的签名类型一致 WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey() if (WxPayKit.verifyNotify(params, wxPayProperties.getMchKey(), SignType.HMACSHA256)) { if (WxPayKit.codeIsOk(returnCode)) { try { parkingPayService.saveAndUpdateRecord(outTradeNo,payTime,buyerPayAmount,openId,transactionNo,"wechat"); // 发送通知等 Map xml = new HashMap(2); xml.put("return_code", "SUCCESS"); xml.put("return_msg", "OK"); return WxPayKit.toXml(xml); } catch (Exception e) { log.error(e.getMessage(), e); e.printStackTrace(); } } } return null; } /** * 获取微信配置 * * @param url * @return */ @GetMapping(value = "/getConfig") public MessageResult getConfig(String url) { int code = 200; String message = "获取成功"; Object data = ""; boolean result = true; try { AccessToken token = WeixinUtil.getAccessToken(wxPayProperties.getAppId(), wxPayProperties.getAppSecret()); Map wxMap = Sign.sign(WeixinUtil.getJsAPI(token.getToken()), url); wxMap.put("appId", wxPayProperties.getAppId()); log.warn(JSONObject.toJSONString(wxMap)); HashMap dataMap = new HashMap(); dataMap.put("wxConfig", wxMap); data = dataMap; } catch (Exception ex) { log.error(ex.getMessage(), ex); code = 500; result = false; message = "系统错误"; } return new MessageResult(result, message, data, code); } /** * 获取微信code * * @param url * @return */ @PostMapping(value = "findWechatUrl") public MessageResult findWechatUrl(@RequestBody String url) { String newpath = WeixinUtil.getCodeRequest(wxPayProperties.getSubAppId(), url, "snsapi_userinfo"); HashMap dataMap = new HashMap(); dataMap.put("wechatUrl", newpath); return new MessageResult(true, "获取成功", dataMap, 200); } /** * 获取公众号用户信息 * * @param code * @return */ @GetMapping(value = "findUserInfo/{code}") public MessageResult findUserInfo(@PathVariable String code) { try { log.warn("code=" + code); log.warn("appId=" + wxPayProperties.getSubAppId()); log.warn("appSecret=" + wxPayProperties.getSubAppSecret()); AccessToken at = WeixinUtil.getAccessToken(wxPayProperties.getSubAppId(), wxPayProperties.getSubAppSecret(), code); if (at != null && org.apache.commons.lang3.StringUtils.isNotBlank(at.getOpenid())) { String openId = at.getOpenid(); System.out.println("openId:" + openId); UserInfo userInfo = WeixinUtil.getUserInfo(openId, at.getToken()); HashMap dataMap = new HashMap(); dataMap.put("userInfo", userInfo); return new MessageResult(true, "获取微信信息成功", userInfo, 200); } else { return new MessageResult(false, "获取微信信息失败", "", 400); } } catch (Exception ex) { ex.printStackTrace(); return new MessageResult(false, "系统错误", "", 500); } } }