package com.szwl.service.impl;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.szwl.constant.ConfigConsts;
import com.szwl.constant.JoinpayConstant;
import com.szwl.constant.ResponseCodesEnum;
import com.szwl.constant.WXPayConstants;
import com.szwl.feign.bean.OrderFeign;
import com.szwl.feign.bean.SzwlFeign;
import com.szwl.mapper.TWechatPayConfigMapper;
import com.szwl.model.bo.JsonMessage;
import com.szwl.model.bo.R;
import com.szwl.model.bo.ResponseModel;
import com.szwl.model.entity.*;
import com.szwl.model.utils.PushUtils;
import com.szwl.service.*;
import com.szwl.utils.HuifuUtils;
import com.szwl.utils.IDGenerator;
import com.szwl.utils.MyWXPay;
import com.szwl.utils.WXPayUtil;
import com.szwl.weixin.util.HttpUtils;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.refund.model.AmountReq;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import static com.wechat.pay.java.service.refund.model.Status.PROCESSING;
/**
*
* 服务实现类
*
*
* @author wuhs
* @since 2024-03-07
*/
@Service
public class TWechatPayConfigServiceImpl extends ServiceImpl implements TWechatPayConfigService {
/**
* 用户输入密码,尝试30秒内去查询支付结果
*/
private static Integer remainingTimeMs = 40000;
public static Map configMap = new HashMap<>();
@Autowired
SzwlFeign szwlFeign;
@Autowired
OrderFeign orderFeign;
@Autowired
TOrderService orderService;
@Resource
TAlipayConfigService alipayConfigService;
@Autowired
TEquipmentService equipmentService;
@Autowired
TOrderDetailsService orderDetailsService;
@Override
public Config getWechatConfig(Long id) {
if(configMap==null){
return null;
}
return configMap.get(id);
}
@Override
public void initConfig(Long id) {
TWechatPayConfig wechatPayConfig = this.getById(id);
Config config =
new RSAAutoCertificateConfig.Builder()
.merchantId(wechatPayConfig.getMerchantId())
.privateKeyFromPath(wechatPayConfig.getPrivateKeyPath())
.merchantSerialNumber(wechatPayConfig.getMerchantSerialNumber())
.apiV3Key(wechatPayConfig.getApiv3key())
.build();
configMap.put(wechatPayConfig.getId(), config);
}
@Override
public String decryptFromResource(Map bodyMap) {
// 通知数据
Map resourceMap = (Map) bodyMap.get("resource");
// 数据密文
String ciphertext = resourceMap.get("ciphertext");
// 随机串
String nonce = resourceMap.get("nonce");
// 附加数据
String associatedData = resourceMap.get("associated_data");
List list = this.list();
String plainText = null;
for (TWechatPayConfig wechatPayConfig : list) {
if(StringUtils.isEmpty(plainText)){
AesUtil aesUtil1 = new
AesUtil(wechatPayConfig.getApiv3key().getBytes(StandardCharsets.UTF_8));
try {
plainText = aesUtil1.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),
nonce.getBytes(StandardCharsets.UTF_8),
ciphertext);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
} else {
break;
}
}
return plainText;
}
@Override
public JsonMessage carsPay(String clientId, Map productNameMap, String frpCode, HttpServletRequest request) {
if(productNameMap==null){
return JsonMessage.error("数据出错");
}
StringBuffer note = new StringBuffer();
StringBuffer productName = new StringBuffer();
String productNo = "";
Map productMap = new HashMap<>();
Integer productNumber = 0;
TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(clientId));
if(equipment==null||equipment.getId()==null){
return JsonMessage.error("找不到设备");
}
BigDecimal price = new BigDecimal("0.00");
TEquipmentDesc equipmentDesc = R.getDataIfSuccess(szwlFeign.findEquipmentById(equipment.getId()));
if(equipmentDesc==null||equipmentDesc.getEquipmentId()==null||equipmentDesc.getPayType()==null||equipmentDesc.getPayType().equals("0")){
for (String key : productNameMap.keySet()) {
String entryValue = String.valueOf(productNameMap.get(key));
List value = JSON.parseArray(entryValue, String.class);
List promoCodeList = new ArrayList<>();
//1,校验优惠码
if(value.size()>0){
for(String code:value){
if(!code.equals("0")){
TPromoCode promoCode = new TPromoCode();
ResponseModel tPromoCodeResponseModel = szwlFeign.selectTPromoCode(code, equipment.getAdminId().toString());
TPromoCode tPromoCode = tPromoCodeResponseModel.getData();
promoCode = tPromoCode;
if (tPromoCode == null||tPromoCode.getId()==null) {
//不存在
return JsonMessage.success("1");
}
Date lastUseDate = null;
if (promoCode != null) {
lastUseDate = promoCode.getLastUseDate();
}
if (lastUseDate != null && lastUseDate.getTime() < ((new Date()).getTime())) {
promoCode.setIsUse("2");
szwlFeign.updatePromoCode(String.valueOf(promoCode.getId()),"2");
//过期
return JsonMessage.success("4");
}
if (promoCode.getId() == null) {
//不存在
return JsonMessage.success("1");
}
if (promoCode.getIsUse().equals("1")) {
//被使用
return JsonMessage.success("2");
}
if(!promoCode.getAdminId().equals("1")){
if (String.valueOf(equipment.getAdminId()).equals(promoCode.getAdminId())) {
} else {
//不是本机
return JsonMessage.success("3");
}
}
if (promoCode.getDiscount() == null) {
//旧优惠码
return JsonMessage.success("0");
}
if (promoCode.getDiscount() != null && promoCode.getDiscount() == 0) {
//0折
return JsonMessage.success("0");
}
promoCodeList.add(promoCode);
}
}
}
String[] productNum = key.split("-");
String productNamea = productNum[0];
String num = productNum[1];
productMap.put(productNamea,Integer.valueOf(num));
productNumber += Integer.valueOf(num);
productName.append(productNamea).append("x").append(num).append(",");
TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
if (product == null) {
return JsonMessage.error("找不到商品");
}
note.append(productNamea).append("-").append(product.getNo()).append(":");
BigDecimal productPrice = product.getRmbPrice();
productNo = product.getNo();
if(promoCodeList.size()>0){
//有优惠码
BigDecimal onePrice = new BigDecimal("0.00");
int i;
for( i = 0;i= 0) {
return JsonMessage.error("商品价格异常");
}
Long client6 = Long.parseLong(clientId.substring(clientId.length() - 6));
String sn = orderService.initSn(client6);
//获取分销 关联设备
TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(equipment.getAdminId())));
String companyType = admin.getCompanyType();
JSONArray altInfo = new JSONArray();
BigDecimal amount = price.setScale(2, RoundingMode.HALF_DOWN);
amount = amount.multiply(new BigDecimal(100));
// String notifyUrl = JoinpayConstant.WECHAT_NOTIFY_URL;
// String frpCode = "WEIXIN_NATIVE";
TOrder order = new TOrder();
order.setId(IDGenerator.orderID());
order.setCreateDate(new Date());
order.setModifyDate(new Date());
order.setAdminId(admin.getId());
order.setSn(sn);
if(productNumber == 1) {
productName.delete(productName.length() - 3, productName.length());
} else {
productName.deleteCharAt(productName.length() - 1);
}
order.setProductName(productName.toString());
order.setPrice(price);
order.setClientId(equipment.getClientId());
order.setEquipmentId(equipmentId);
order.setFrpCode(frpCode);
order.setProductNumber(productNumber);
order.setAltInfo(altInfo.toString());
order.setStatus(0);
String payPlatform = "3";
order.setPayPlatform(payPlatform);
order.setCompanyType(companyType);
order.setMachineType(equipment.getMachineType());
order.setProductNo(productNo);
if(StringUtils.isNotEmpty(payPlatform)&&payPlatform.equals("1")){
order.setIsSettlement("0");
}
order.setNote(note.toString());
// 订单明细表
TOrderDetails orderDetails = new TOrderDetails();
orderDetails.setAdminId(admin.getId());
orderDetails.setEquipmentId(equipmentId);
orderDetails.setCreateDate(new Date());
orderDetails.setCompanyType(companyType);
orderDetails.setRefundStatus("0");
orderDetails.setMachineType(equipment.getMachineType());
// 添加到订单明细表
for (String key : productMap.keySet()) {
Integer productNum = productMap.get(key);
TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), key));
orderDetails.setProductNo(product.getNo());
orderDetails.setProductName(key);
orderDetails.setPrice(product.getRmbPrice());
orderDetails.setProductNumber(productNum);
orderDetails.setAmount(product.getRmbPrice().multiply(new BigDecimal(productNum)));
orderDetails.setId(HuifuUtils.initDetailsId());
orderDetails.setOrderSn(sn);
orderDetailsService.save(orderDetails);
}
orderService.save(order);
String productName1 = "";
if(productNumber > 1) {
productName1 = "棉花糖";
} else {
productName1 = productName.toString();
}
String result = null;
try {
if (frpCode.equals(ConfigConsts.WECHAT_NATIVE)) {
result = orderService.wechatPay(
sn, amount, productName1, admin.getWechatPayId(), JoinpayConstant.WECHAT_NOTIFY_URL, clientId, request
);
}
if (frpCode.equals(ConfigConsts.ALIPAY_NATIVE)) {
result = orderService.alipayPay(
sn, price, productName1, admin.getAlipayId(), JoinpayConstant.ALIPAY_NOTIFY_URL, clientId
);
}
} catch (Exception e) {
e.printStackTrace();
return JsonMessage.error("申请支付失败");
}
// 微信支付支付申请返回支付二维码图片
JSONObject kindData = new JSONObject();
kindData.put("sn", sn);
kindData.put("code_url", result);
return JsonMessage.success(kindData.toString());
}
@Override
public String payNotify(HttpServletRequest request) {
Gson gson = new Gson();
// 读取请求体中的数据
String body = HttpUtils.readData(request);
Map bodyMap = gson.fromJson(body, HashMap.class);
// 解密支付通知数据
String plainText = this.decryptFromResource(bodyMap);
if(StringUtils.isNotEmpty(plainText)){
JSONObject resultJson = JSONObject.parseObject(plainText);
// 根据订单号查询订单
String sn = resultJson.getString("out_trade_no");
if(StringUtils.isNotEmpty(sn)) {
LambdaQueryWrapper query = Wrappers.lambdaQuery();
query.eq(TOrder::getSn, sn);
query.eq(TOrder::getStatus, 0);
List list = orderService.list(query);
// 更新订单状态和支付信息
if (list != null && list.size() > 0) {
TOrder order = list.get(0);
order.setStatus(1);
String success_time = resultJson.getString("success_time");
Date date = new Date();
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(success_time);
} catch (ParseException e) {
// 忽略时间转换错误
}
order.setPayDate(date);
order.setTrxNo(resultJson.getString("transaction_id"));
// 更新订单明细状态
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(TOrderDetails::getOrderSn,sn);
List orderDetails = orderDetailsService.list(lambdaQueryWrapper);
for (TOrderDetails orderDetail : orderDetails) {
orderDetail.setRefundStatus("1");
orderDetailsService.updateById(orderDetail);
}
// 发送支付成功消息给设备
TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(order.getClientId()));
JSONObject kindData = new JSONObject();
kindData.put("sn", order.getSn());
kindData.put("productName", order.getProductName());
if (!order.getIsNotified().equals("1")) {
String paySuccess = equipmentService.sentMessage(equipment.getClientId(), PushUtils.buildJson("pay_success", kindData.toString()).toString());
if (paySuccess.equals("success")) {
order.setIsNotified("1");
}
// 推送微信订单
TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(order.getAdminId())));
// 判断是否开启订单推送功能
if(admin != null && StringUtils.isNotEmpty(admin.getOrderNotice()) && admin.getOrderNotice().equals("1")) {
String openId = R.getDataIfSuccess(szwlFeign.getOpenId(order.getAdminId()));
// 获取openId
if(StringUtils.isNotEmpty(openId)) {
orderService.newSendWechatMessage(openId, equipment, order, admin.getCompanyType());
}
}
}
orderService.updateById(order);
try {
// 保存订单信息到ES
if(order.getProductNumber()==null||order.getProductNumber()==0){
order.setProductNumber(1);
}
orderFeign.saveToEs(order);
}catch (Exception e) {
e.printStackTrace();
}
} else {
LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
query.eq(TOrder::getSn, sn);
query.eq(TOrder::getStatus, 1);
List orderList = orderService.list(queryWrapper);
if (list != null && list.size() > 0) {
TOrder tOrder = orderList.get(0);
try {
// 保存订单信息到ES
if(tOrder.getProductNumber()==null||tOrder.getProductNumber()==0){
tOrder.setProductNumber(1);
}
orderFeign.saveToEs(tOrder);
}catch (Exception e) {
e.printStackTrace();
}
return "success";
}
return "fail";
}
}
}
return "success";
}
@Override
public ResponseModel refund(TOrder torder){
// 退款金额: refusePrice
BigDecimal refusePrice = torder.getPrice().setScale(2, RoundingMode.HALF_DOWN);
// 退款数量: refundNumber
Integer refundNumber = torder.getProductNumber();
// 退款原因: refundReason
String refundReason = torder.getRefundReason();
// 退款明细:note
String note = torder.getNote();
String[] refundDetails = note.split(",");
Map refundMap = new HashMap<>();
for (String refundDetail : refundDetails) {
String[] keyValue = refundDetail.split("-");
String key = keyValue[0];
String value = keyValue[1];
refundMap.put(key, Integer.valueOf(value));
}
if(refusePrice.compareTo(new BigDecimal("0.00"))<=0){
return R.fail(ResponseCodesEnum.A0001,"退款金额非法");
}
TOrder order = orderService.getById(torder.getId());
if(order.getRefundQuantity() != null && order.getRefundQuantity()>0) {
order.setRefundQuantity(refundNumber + order.getRefundQuantity());
} else {
order.setRefundQuantity(refundNumber);
}
if(refusePrice.compareTo(order.getPrice()) > 0) {
return R.fail(ResponseCodesEnum.A0001,"退款金额非法");
}
if(order.getRefundAmount() != null && order.getRefundAmount().add(refusePrice).compareTo(order.getPrice()) > 0) {
return R.fail(ResponseCodesEnum.A0001,"退款金额非法");
}
if (order.getStatus().equals("0")) {
return R.fail(ResponseCodesEnum.A0002,"订单非支付状态");
}
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(TOrderDetails::getOrderSn, order.getSn());
List orderDetails = orderDetailsService.list(wrapper);
// 微信支付
TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(order.getAdminId())));
if (order.getFrpCode().equals("WEIXIN_PAYCODE") || order.getFrpCode().equals("WEIXIN_NATIVE")) {
CreateRequest createRequest = new CreateRequest();
createRequest.setOutTradeNo(order.getSn());
AmountReq amount = new AmountReq();
amount.setRefund(refusePrice.multiply(new BigDecimal(100)).longValue());
BigDecimal multiply = order.getPrice().multiply(new BigDecimal(100));
amount.setTotal(multiply.longValue());
amount.setCurrency("CNY");
createRequest.setAmount(amount);
String refundNo = orderService.initSn(order.getEquipmentId());
createRequest.setOutRefundNo(refundNo);
// 上线需要修改回调url
createRequest.setNotifyUrl(JoinpayConstant.WECHAT_NOTIFY_REFUND_URL);
Refund refund = orderService.weixinRefundApi(createRequest, admin.getWechatPayId());
System.out.println("退款参数"+refund.toString());
if(refund.getStatus() == PROCESSING){
order.setStatus(2);
order.setRefundReason(refundReason);
orderService.updateById(order);
// 修改订单明细
for (TOrderDetails orderDetail : orderDetails) {
String productNo = orderDetail.getProductNo();
Integer productNumber = refundMap.get(productNo);
if(productNumber != null) {
// 退款中
orderDetail.setRefundStatus("4");
// 退款数量
orderDetail.setRefundQuantity(productNumber);
// 退款金额
orderDetail.setRefundAmount(orderDetail.getPrice().multiply(new BigDecimal(productNumber)));
orderDetailsService.updateById(orderDetail);
}
}
return R.ok("申请退款已成功");
}
}
// 支付宝支付
if(order.getFrpCode().equals("ALIPAY_NATIVE")) {
// 随机生成退款交易号
String refundTrxNo = HuifuUtils.initRefundTrxNo();
String refundAlipay = alipayConfigService.refundAlipay(refusePrice, order.getSn(), refundTrxNo, admin.getAlipayId());
if(refundAlipay.equals("success")) {
order.setRefundReason(refundReason);
// 已退款
if(order.getRefundQuantity() < order.getProductNumber()) {
order.setStatus(1);
} else {
order.setStatus(3);
}
// 退款金额
BigDecimal refundAmount = order.getRefundAmount();
BigDecimal price = order.getPrice();
if(refundAmount != null) {
if (price.compareTo(refundAmount) == 0) {
order.setRefundAmount(refundAmount);
} else {
order.setRefundAmount(refundAmount.add(refusePrice));
}
} else {
order.setRefundAmount(refusePrice);
}
order.setRefundDate(new Date());
order.setModifyDate(new Date());
order.setRefundTrxNo(refundTrxNo);
// 修改订单明细
for (TOrderDetails orderDetail : orderDetails) {
String productNo = orderDetail.getProductNo();
Integer productNumber = refundMap.get(productNo);
if(productNumber != null) {
// 退款数量
orderDetail.setRefundQuantity(productNumber);
// 退款状态
if(productNumber < orderDetail.getProductNumber()) {
// 部分退款
orderDetail.setRefundStatus("2");
} else {
// 全部退款
orderDetail.setRefundStatus("3");
}
// 退款金额
orderDetail.setRefundAmount(orderDetail.getPrice().multiply(new BigDecimal(productNumber)));
orderDetailsService.updateById(orderDetail);
}
}
try {
orderFeign.saveToEs(order);
}catch (Exception e) {
e.printStackTrace();
}finally {
orderService.updateById(order);
}
return R.ok("申请退款已成功");
}
}
return R.fail(ResponseCodesEnum.B0001,"申请退款失败,请重试");
}
@Override
public String refundNotify(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_BAD_GATEWAY);
hashMap.put("code", "FAIL");
hashMap.put("message", "系统错误");
}
return gson.toJson(hashMap);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public JsonMessage cardPay(String authCode, String clientId, Map productNameMap, HttpServletRequest request) {
if(productNameMap==null){
return JsonMessage.error("数据出错");
}
StringBuilder note = new StringBuilder();
StringBuilder productName = new StringBuilder();
String productNo = "";
Map productMap = new HashMap<>();
int productNumber = 0;
TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(clientId));
if(equipment==null||equipment.getId()==null){
return JsonMessage.error("找不到设备");
}
BigDecimal price = new BigDecimal("0.00");
TEquipmentDesc equipmentDesc = R.getDataIfSuccess(szwlFeign.findEquipmentById(equipment.getId()));
if(equipmentDesc==null||equipmentDesc.getEquipmentId()==null||equipmentDesc.getPayType()==null||equipmentDesc.getPayType().equals("0")){
for (String key : productNameMap.keySet()) {
String entryValue = String.valueOf(productNameMap.get(key));
List value = JSON.parseArray(entryValue, String.class);
List promoCodeList = new ArrayList<>();
//1,校验优惠码
if(value.size()>0){
for(String code:value){
if(!code.equals("0")){
TPromoCode promoCode = new TPromoCode();
ResponseModel tPromoCodeResponseModel = szwlFeign.selectTPromoCode(code, equipment.getAdminId().toString());
TPromoCode tPromoCode = tPromoCodeResponseModel.getData();
promoCode = tPromoCode;
if (tPromoCode == null||tPromoCode.getId()==null) {
//不存在
return JsonMessage.success("1");
}
Date lastUseDate = null;
if (promoCode != null) {
lastUseDate = promoCode.getLastUseDate();
}
if (lastUseDate != null && lastUseDate.getTime() < ((new Date()).getTime())) {
promoCode.setIsUse("2");
szwlFeign.updatePromoCode(String.valueOf(promoCode.getId()),"2");
//过期
return JsonMessage.success("4");
}
if (promoCode.getId() == null) {
//不存在
return JsonMessage.success("1");
}
if (promoCode.getIsUse().equals("1")) {
//被使用
return JsonMessage.success("2");
}
if(!promoCode.getAdminId().equals("1")){
if (!String.valueOf(equipment.getAdminId()).equals(promoCode.getAdminId())) {
return JsonMessage.success("3");
}
}
if (promoCode.getDiscount() == null) {
//旧优惠码
return JsonMessage.success("0");
}
if (promoCode.getDiscount() != null && promoCode.getDiscount() == 0) {
//0折
return JsonMessage.success("0");
}
promoCodeList.add(promoCode);
}
}
}
String[] productNum = key.split("-");
String productNamea = productNum[0];
String num = productNum[1];
productMap.put(productNamea,Integer.valueOf(num));
productNumber += Integer.parseInt(num);
productName.append(productNamea).append("x").append(num).append(",");
TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
if (product == null) {
return JsonMessage.error("找不到商品");
}
note.append(productNamea).append("-").append(product.getNo()).append(":");
BigDecimal productPrice = product.getRmbPrice();
productNo = product.getNo();
if(promoCodeList.size()>0){
//有优惠码
BigDecimal onePrice = new BigDecimal("0.00");
int i;
for( i = 0;i= 0) {
return JsonMessage.error("商品价格异常");
}
Long client6 = Long.parseLong(clientId.substring(clientId.length() - 6));
String sn = orderService.initSn(client6);
//获取分销 关联设备
TAdmin admin = R.getDataIfSuccess(szwlFeign.getAdmin(String.valueOf(equipment.getAdminId())));
String companyType = admin.getCompanyType();
BigDecimal amount = price.setScale(2, RoundingMode.HALF_DOWN);
amount = amount.multiply(new BigDecimal(100)).setScale(0);
String frpCode = "WEIXIN_PAYCODE";
TOrder order = new TOrder();
order.setId(IDGenerator.orderID());
order.setCreateDate(new Date());
order.setModifyDate(new Date());
order.setAdminId(admin.getId());
order.setSn(sn);
if(productNumber == 1) {
productName.delete(productName.length() - 3, productName.length());
} else {
productName.deleteCharAt(productName.length() - 1);
}
order.setProductName(productName.toString());
order.setPrice(price);
order.setClientId(equipment.getClientId());
order.setEquipmentId(equipmentId);
order.setFrpCode(frpCode);
order.setProductNumber(productNumber);
order.setStatus(0);
String payPlatform = "3";
order.setPayPlatform(payPlatform);
order.setCompanyType(companyType);
order.setMachineType(equipment.getMachineType());
order.setProductNo(productNo);
order.setNote(note.toString());
// 订单明细表
TOrderDetails orderDetails = new TOrderDetails();
orderDetails.setAdminId(admin.getId());
orderDetails.setEquipmentId(equipmentId);
orderDetails.setCreateDate(new Date());
orderDetails.setCompanyType(companyType);
orderDetails.setRefundStatus("0");
orderDetails.setMachineType(equipment.getMachineType());
// 添加到订单明细表
for (String key : productMap.keySet()) {
Integer productNum = productMap.get(key);
TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), key));
orderDetails.setProductNo(product.getNo());
orderDetails.setProductName(key);
orderDetails.setPrice(product.getRmbPrice());
orderDetails.setProductNumber(productNum);
orderDetails.setAmount(product.getRmbPrice().multiply(new BigDecimal(productNum)));
orderDetails.setId(HuifuUtils.initDetailsId());
orderDetails.setOrderSn(sn);
orderDetailsService.save(orderDetails);
}
orderService.save(order);
String productName1 = "";
if(productNumber > 1) {
productName1 = "棉花糖";
} else {
productName1 = productName.toString();
}
String result;
try {
result = wechatCardPay(
sn, amount, authCode, productName1, admin.getWechatPayId(), clientId, request
);
} catch (Exception e) {
e.printStackTrace();
return JsonMessage.error("申请支付失败");
}
// 微信支付支付申请返回支付二维码图片
if (result.equals(WXPayConstants.SUCCESS)) {
JSONObject kindData = new JSONObject();
kindData.put("sn", sn);
return JsonMessage.success(kindData.toString());
} else {
return JsonMessage.error(result);
}
}
private String wechatCardPay(String sn, BigDecimal amount, String authCode, String productName, Long wechatPayId, String clientId, HttpServletRequest request) throws Exception {
TWechatPayConfig wechatPayConfig = getById(wechatPayId);
Map resData = new HashMap<>();
resData.put("appid", wechatPayConfig.getAppId());
resData.put("auth_code", authCode);
resData.put("body", productName);
resData.put("device_info", clientId);
resData.put("mch_id", wechatPayConfig.getMerchantId());
resData.put("nonce_str", WXPayUtil.generateNonceStr());
resData.put("out_trade_no", sn);
resData.put("spbill_create_ip", "127.0.0.1");
resData.put("total_fee", amount.toString());
String sign = WXPayUtil.generateSignature(resData, wechatPayConfig.getApiv2key());
// 参数转换成xml的String字符串
resData.put("sign", sign);
String xmlStr = WXPayUtil.mapToXml(resData);
System.out.println("请求参数:" + xmlStr);
// 开始时间(毫秒)
long startTimestampMs = System.currentTimeMillis();
String responseXml = HttpUtil.post("https://api.mch.weixin.qq.com/pay/micropay", xmlStr);
System.out.println("返回参数:" + responseXml);
// 再把响应的xml转换成map
Map responseMap = XmlUtil.xmlToMap(responseXml);
// 先判断 协议字段返回(return_code),再判断 业务返回,最后判断 交易状态(trade_state)
// 通信标识,非交易标识
String returnCode = responseMap.get("return_code").toString();
if (WXPayConstants.SUCCESS.equals(returnCode)) {
// String errCode = responseMap.get("err_code").toString();
// 余额不足,信用卡失效
// if ("USERPAYING".equals(errCode) || "SYSTEMERROR".equals(errCode) || "BANKERROR".equals(errCode)) {
// 查询订单
Map orderQueryMap = null;
Map requestData =new HashMap<>();
requestData.put("appid", wechatPayConfig.getAppId());
requestData.put("mch_id", wechatPayConfig.getMerchantId());
requestData.put("out_trade_no", sn);
requestData.put("nonce_str", WXPayUtil.generateNonceStr());
String sign1 = WXPayUtil.generateSignature(requestData, wechatPayConfig.getApiv2key());
requestData.put("sign", sign1);
String xmlStr1 = WXPayUtil.mapToXml(requestData);
// 用户支付中,需要输入密码或系统错误则去重新查询订单API
// 每次循环时的当前系统时间 - 开始时记录的时间 > 设定的30秒时间就退出
while (System.currentTimeMillis() - startTimestampMs < remainingTimeMs) {
// 商户收银台得到USERPAYING状态后,经过商户后台系统调用【查询订单API】查询实际支付结果。
String responseXml1 = HttpUtil.post("https://api.mch.weixin.qq.com/pay/orderquery", xmlStr1);
orderQueryMap = XmlUtil.xmlToMap(responseXml1);
String returnCodeForQuery = orderQueryMap.get("return_code").toString();
if (WXPayConstants.SUCCESS.equals(returnCodeForQuery)) {
// 通讯成功
String tradeState = orderQueryMap.get("trade_state").toString();
if (WXPayConstants.SUCCESS.equals(tradeState)) {
String transactionId = orderQueryMap.get("transaction_id").toString();
String timeEnd = orderQueryMap.get("time_end").toString();
LambdaQueryWrapper query = Wrappers.lambdaQuery();
query.eq(TOrder::getSn, sn);
query.eq(TOrder::getStatus, 0);
List list = orderService.list(query);
// 更新订单状态和支付信息
if (list != null && list.size() > 0) {
TOrder order = list.get(0);
order.setStatus(1);
order.setTrxNo(transactionId);
Date date = new Date();
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(timeEnd);
} catch (ParseException e) {
// 忽略时间转换错误
}
order.setPayDate(date);
// 更新订单明细状态
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(TOrderDetails::getOrderSn,sn);
List orderDetails = orderDetailsService.list(lambdaQueryWrapper);
for (TOrderDetails orderDetail : orderDetails) {
orderDetail.setRefundStatus("1");
orderDetailsService.updateById(orderDetail);
}
// 发送支付成功消息给设备
TEquipment equipment = R.getDataIfSuccess(szwlFeign.findEquipmentByClientId(order.getClientId()));
JSONObject kindData = new JSONObject();
kindData.put("sn", order.getSn());
kindData.put("productName", order.getProductName());
if (!order.getIsNotified().equals("1")) {
String paySuccess = equipmentService.sentMessage(equipment.getClientId(), PushUtils.buildJson("pay_success", kindData.toString()).toString());
if (paySuccess.equals("success")) {
order.setIsNotified("1");
}
}
orderService.updateById(order);
try {
// 保存订单信息到ES
if(order.getProductNumber()==null||order.getProductNumber()==0){
order.setProductNumber(1);
}
orderFeign.saveToEs(order);
}catch (Exception e) {
e.printStackTrace();
}
// 如果成功了直接将查询结果返回
return tradeState;
}
}
// 如果支付结果仍为USERPAYING,则每隔5秒循环调用【查询订单API】判断实际支付结果
Thread.sleep(5000);
}
}
// 如果用户取消支付或累计90秒用户都未支付,商户收银台退出查询流程后继续调用【撤销订单API】撤销支付交易。
String tradeState = orderQueryMap.get("trade_state").toString();
if ("NOTPAY".equals(tradeState) || "PAYERROR".equals(tradeState)) {
String result = "";
// 调用撤销订单接口,并接受返回的结果
try{
result =
MyWXPay.cancelOrder(wechatPayConfig.getMerchantId(), wechatPayConfig.getApiCertPath(),
"https://api.mch.weixin.qq.com/secapi/pay/reverse", xmlStr1);
System.out.println("=======================撤销订单返回数据:" + result);
}catch (Exception e){
e.printStackTrace();
}
Map reverseMap = XmlUtil.xmlToMap(result);
String returnCodeForReverse = reverseMap.get("return_code").toString();
String resultCode = reverseMap.get("result_code").toString();
if (WXPayConstants.SUCCESS.equals(returnCodeForReverse) && WXPayConstants.SUCCESS.equals(resultCode)) {
// 如果撤销成功,需要告诉客户端已经撤销订单了
return "用户取消支付或尚未支付,后台已经撤销该订单,请重新支付!";
}
}
// }
}
return WXPayConstants.FAIL;
}
public void processRefund(Map bodyMap) {
String decrypt = this.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 = orderService.getOne(query);
if (StringUtils.isNotEmpty(order.getRefundTrxNo()) && order.getRefundTrxNo().equals(refundNo)) {
return;
}
// 已退款
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);
BigDecimal refundAmount = order.getRefundAmount();
BigDecimal price = order.getPrice();
if(refundAmount != null) {
if (price.compareTo(refundAmount) == 0) {
order.setRefundAmount(refundAmount);
} else {
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 {
orderService.updateById(order);
}
}
}
}