package com.szwl.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.gson.Gson; import com.szwl.constant.JoinpayConstant; import com.szwl.feign.bean.OrderFeign; import com.szwl.model.entity.TOrder; import com.szwl.mapper.TOrderMapper; import com.szwl.model.entity.TOrderDetails; import com.szwl.model.entity.TWechatPayConfig; import com.szwl.model.utils.HttpClientUtils; import com.szwl.service.*; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.szwl.weixin.util.HttpUtils; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.service.payments.nativepay.model.Amount; import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest; import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse; import com.wechat.pay.java.service.payments.nativepay.model.SceneInfo; import com.wechat.pay.java.service.refund.model.CreateRequest; import com.wechat.pay.java.service.refund.model.Refund; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpStatus; import org.apache.http.message.BasicNameValuePair; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.util.*; import static com.szwl.service.impl.TJoinpayMchServiceImpl.createHmacSign; /** *

* 服务实现类 *

* * @author wuhs * @since 2022-06-17 */ @Service public class TOrderServiceImpl extends ServiceImpl implements TOrderService { @Autowired private TWeixinPayConfigService weixinPayConfigService; @Autowired OrderFeign orderFeign; @Autowired private TWechatPayConfigService wechatPayConfigService; @Autowired private TOrderDetailsService orderDetailsService; @Override public synchronized String initSn(Long equipmentId) { StringBuilder number = new StringBuilder(); if (equipmentId != null) { Random random = new Random(); /** * 6位随机 */ for (int i = 0; i < 6; i++) { number.append(String.valueOf(random.nextInt(10))); } /** * 设备id */ number.append(equipmentId.toString()); /** * 日期 */ number.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); } return number.toString(); } @Override public String wechatPay(String sn, BigDecimal amount, String productName, Long id, String notifyUrl, String clientId, HttpServletRequest request) { TWechatPayConfig wechatPayConfig = wechatPayConfigService.getById(id); Config config = wechatPayConfigService.getWechatConfig(id); if(config==null){ wechatPayConfigService.initConfig(id); config = wechatPayConfigService.getWechatConfig(id); } // 构建service NativePayService service = new NativePayService.Builder().config(config).build(); PrepayRequest payRequest = new PrepayRequest(); Amount amount1 = new Amount(); amount1.setTotal(amount.intValue()); payRequest.setAmount(amount1); payRequest.setAppid(wechatPayConfig.getAppId()); payRequest.setMchid(wechatPayConfig.getMerchantId()); payRequest.setDescription(productName); // 添加设备编号 String ipAddress = HttpClientUtils.getIpAddress(request); SceneInfo sceneInfo = new SceneInfo(); sceneInfo.setPayerClientIp(ipAddress); sceneInfo.setDeviceId(clientId); payRequest.setSceneInfo(sceneInfo); payRequest.setNotifyUrl(notifyUrl); // payRequest.setNotifyUrl("http://evxz5m.natappfree.cc/wechatPay/notify");; payRequest.setOutTradeNo(sn); // 调用下单方法,得到应答 PrepayResponse response = service.prepay(payRequest); return response.getCodeUrl(); } /** * 处理退款回调通知 * @param request * @param response * @return */ @Override public String wechatRefund(HttpServletRequest request, HttpServletResponse response) { Gson gson = new Gson(); Map hashMap = new HashMap<>(3); try { // 处理退款通知参数 String body = HttpUtils.readData(request); Map bodyMap = gson.fromJson(body, HashMap.class); String eventType = (String)bodyMap.get("event_type"); if (eventType.equals("REFUND.SUCCESS")) { // 处理退款单 processRefund(bodyMap); //成功应答 response.setStatus(HttpStatus.SC_OK); hashMap.put("code", "SUCCESS"); } else { response.setStatus(HttpStatus.SC_OK); hashMap.put("code", "FAIL"); hashMap.put("message", "系统错误"); } return gson.toJson(hashMap); } catch (Exception e) { e.printStackTrace(); } return null; } @Override public Refund weixinRefundApi(CreateRequest createRequest, Long id) { Config config = wechatPayConfigService.getWechatConfig(id); if(config==null){ wechatPayConfigService.initConfig(id); config = wechatPayConfigService.getWechatConfig(id); } // 构建service NativePayService service = new NativePayService.Builder().config(config).build(); Refund refund = service.refund(createRequest); return refund; } /** * 汇聚查询退款状态 * @param refundTrxNo * @return */ @Override public JSONObject queryRefund(String refundTrxNo) { String url = "https://www.joinpay.com/trade/queryRefund.action"; List data = new ArrayList(); data.add(new BasicNameValuePair("p1_MerchantNo", JoinpayConstant.mch_no)); data.add(new BasicNameValuePair("p2_RefundOrderNo", refundTrxNo)); data.add(new BasicNameValuePair("p3_Version", "2.1")); String hmac = null; try { hmac = createHmacSign(data, JoinpayConstant.key); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } data.add(new BasicNameValuePair("hmac", hmac)); String result = HttpClientUtils.postKeyValue(url, data); JSONObject resultJson = JSONObject.parseObject(result); return resultJson; } public void processRefund(Map bodyMap) { String decrypt = weixinPayConfigService.decryptFromResource(bodyMap); Gson gson = new Gson(); Map map = gson.fromJson(decrypt, HashMap.class); String sn = map.get("out_trade_no").toString(); String refundNo = map.get("out_refund_no").toString(); String amount =map.get("amount").toString(); Map amountMap = gson.fromJson(amount, HashMap.class); String refundPrice = amountMap.get("refund").toString(); if(StringUtils.isNotEmpty(sn)){ LambdaQueryWrapper query = Wrappers.lambdaQuery(); query.eq(TOrder::getSn,sn); TOrder order = getOne(query); // 已退款 if(order.getRefundQuantity() < order.getProductNumber()) { order.setStatus(1); } else { order.setStatus(3); } // 更改订单明细表 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(TOrderDetails::getOrderSn, sn); // 处理退款中状态的明细 queryWrapper.eq(TOrderDetails::getRefundStatus, "4"); List tOrderDetails = orderDetailsService.list(queryWrapper); for (TOrderDetails tOrderDetail : tOrderDetails) { Integer refundQuantity = tOrderDetail.getRefundQuantity(); Integer productNumber = tOrderDetail.getProductNumber(); if(refundQuantity < productNumber) { // 部分退款 tOrderDetail.setRefundStatus("2"); orderDetailsService.updateById(tOrderDetail); } else { // 全部退款 tOrderDetail.setRefundStatus("3"); orderDetailsService.updateById(tOrderDetail); } } //退款金额要除以100 BigDecimal r4_refundAmount = new BigDecimal(refundPrice).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP).setScale(2, RoundingMode.HALF_DOWN); // if(order.getRefundMarketingAmount()!=null){ // r4_refundAmount =r4_refundAmount.add(order.getRefundMarketingAmount()); // } BigDecimal refundAmount = order.getRefundAmount(); if(refundAmount != null) { order.setRefundAmount(refundAmount.add(r4_refundAmount)); } else { order.setRefundAmount(r4_refundAmount); } order.setRefundDate(new Date()); order.setModifyDate(new Date()); order.setRefundTrxNo(refundNo); try { orderFeign.saveToEs(order); }catch (Exception e) { e.printStackTrace(); }finally { updateById(order); } } } }