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);
}
}
}
}