package com.zhongzheng.service.impl;
import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.zhongzheng.common.config.WxSmallConfig;
import com.zhongzheng.common.croe.RedisCache;
import com.zhongzheng.common.filter.CustomException;
import com.zhongzheng.common.util.DateUtils;
import com.zhongzheng.common.util.IpUtils;
import com.zhongzheng.common.util.ServletUtils;
import com.zhongzheng.common.util.wx.WXPay;
import com.zhongzheng.common.util.wx.WXPayUtil;
import com.zhongzheng.domian.Order;
import com.zhongzheng.domian.OrderPerson;
import com.zhongzheng.service.IOrderAttachmentService;
import com.zhongzheng.service.IOrderPersonService;
import com.zhongzheng.service.IOrderService;
import com.zhongzheng.service.IWxPayService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Service
public class WxPayServiceImpl implements IWxPayService {
// @Value("${wx.gzh.appid}")
private String appid;
// @Value("${wx.wepay.mchid}")
private String mchid;
// @Value("${wx.wepay.key}")
private String key;
// @Value("${wx.wepay.notifyUrl}")
private String notifyUrl;
@Autowired
private IOrderService iOrderService;
@Autowired
private IOrderPersonService iOrderPersonService;
@Autowired
private RedisCache redisCache;
@Override
public String paymentCallBack(String notifyData) {
String xmlBack = " ";
try {
Map notifyMap = WXPayUtil.xmlToMap(notifyData); // 转换成map
String TenantId = notifyMap.get("attach");
ServletUtils.getRequestAttributes().getResponse().setHeader("TenantId", TenantId);
WxSmallConfig config = new WxSmallConfig(appid, mchid, key);
WXPay wxpay = new WXPay(config);
if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
String result_code = notifyMap.get("result_code");
if ("SUCCESS".equals(result_code)) {
String out_trade_no = notifyMap.get("out_trade_no");
String transaction_id = notifyMap.get("transaction_id");
Order order = iOrderService.getOne(new LambdaQueryWrapper().eq(Order::getOrderSn, out_trade_no));
if (ObjectUtils.isNotNull(order)) {
if (dealOrder(out_trade_no, transaction_id)) {
xmlBack = "";
return xmlBack;
}
}
}
} else {
// 签名错误,如果数据里没有sign字段,也认为是签名错误
}
} catch (Exception e) {
e.printStackTrace();
}
return xmlBack;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean dealOrder(String out_trade_no, String transaction_id) {
String key = out_trade_no;
String ticket = redisCache.getCacheObject(key);
if (Validator.isNotEmpty(ticket)) {
return false;
}
redisCache.setCacheObject(key, "dealing", 30, TimeUnit.SECONDS);//30秒
Order order = iOrderService.getOne(new LambdaQueryWrapper().eq(Order::getOrderSn, out_trade_no));
if (ObjectUtils.isNotNull(order) && order.getOrderStatus() == 0) {
//已支付
order.setOrderStatus(1);
order.setPayTime(DateUtils.getNowTime());
order.setTransid(transaction_id);
order.setPayStatus(2);
order.setCheckStatus(1);
order.setOrderReceived(order.getPayPrice());
//未付
BigDecimal orderUncollected = order.getOrderUncollected();
if (orderUncollected.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal subtract = order.getPayPrice().subtract(orderUncollected);
order.setOrderUncollected(subtract);
}
iOrderService.updateById(order);
//修改订单员工支付状态
iOrderPersonService.update(new LambdaUpdateWrapper()
.set(OrderPerson::getPayStatus,3)//已收费
.eq(OrderPerson::getOrderSn, out_trade_no)
.eq(OrderPerson::getStatus,1));
}
return true;
}
@Override
public Map paymentPc(String out_trade_no, String body, BigDecimal price) {
WxSmallConfig config = new WxSmallConfig(appid, mchid, key);
BigDecimal unit = new BigDecimal(100);
price = price.multiply(unit);
try {
WXPay wxpay = new WXPay(config);
Map data = new HashMap();
data.put("body", body);
data.put("out_trade_no", out_trade_no);
data.put("device_info", "");
data.put("fee_type", "CNY");
data.put("total_fee", price.longValue() + "");
data.put("spbill_create_ip", IpUtils.getIpAddr(ServletUtils.getRequest()));
data.put("notify_url", notifyUrl);
data.put("trade_type", "NATIVE");
Date date = new Date();
Date newDate = new Date(date.getTime() + 60000*30);
String TenantId = ServletUtils.getRequest().getHeader("TenantId");
data.put("attach", TenantId);
Map resp = wxpay.unifiedOrder(data);
Map result = new HashMap<>();
String code_url = resp.get("code_url");
if (Validator.isEmpty(code_url)) {
throw new CustomException("支付错误");
}
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(code_url, BarcodeFormat.QR_CODE, 120, 120);
// 写到输出流
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, "jpg", outputStream);
//转换为base64
Base64.Encoder encoder1 = Base64.getEncoder();
String urlBase64 = "data:image/jpeg;base64,"
+ encoder1.encodeToString(outputStream.toByteArray());
result.put("urlBase64", urlBase64);
Long overTime = (long)(newDate.getTime()/1000);
result.put("overTime", overTime.toString());
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}