|
@@ -0,0 +1,208 @@
|
|
|
+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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> xml = new HashMap<String, String>(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;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|