12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112 |
- 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;
- /**
- * <p>
- * 服务实现类
- * </p>
- *
- * @author wuhs
- * @since 2024-03-07
- */
- @Service
- public class TWechatPayConfigServiceImpl extends ServiceImpl<TWechatPayConfigMapper, TWechatPayConfig> implements TWechatPayConfigService {
- /**
- * 用户输入密码,尝试30秒内去查询支付结果
- */
- private static Integer remainingTimeMs = 40000;
- public static Map<Long, Config> 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<String, Object> bodyMap) {
- // 通知数据
- Map<String, String> resourceMap = (Map) bodyMap.get("resource");
- // 数据密文
- String ciphertext = resourceMap.get("ciphertext");
- // 随机串
- String nonce = resourceMap.get("nonce");
- // 附加数据
- String associatedData = resourceMap.get("associated_data");
- List<TWechatPayConfig> 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<String, String> productNameMap, String frpCode, HttpServletRequest request) {
- if(productNameMap==null){
- return JsonMessage.error("数据出错");
- }
- StringBuffer note = new StringBuffer();
- StringBuffer productName = new StringBuffer();
- String productNo = "";
- Map<String, Integer> 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<String> value = JSON.parseArray(entryValue, String.class);
- List<TPromoCode> promoCodeList = new ArrayList<>();
- //1,校验优惠码
- if(value.size()>0){
- for(String code:value){
- if(!code.equals("0")){
- TPromoCode promoCode = new TPromoCode();
- ResponseModel<TPromoCode> 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<promoCodeList.size();i++){
- BigDecimal discount = BigDecimal.valueOf(promoCodeList.get(i).getDiscount()).setScale(2, RoundingMode.HALF_DOWN);
- BigDecimal price1 = productPrice.multiply(discount).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN);
- price = price.add(price1);
- onePrice = onePrice.add(price1);
- }
- if(i<Integer.valueOf(num)){
- int a = Integer.valueOf(num)-i;
- BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
- price =price.add(price2);
- onePrice = onePrice.add(price2);
- }
- note.append(onePrice).append("-").append(num).append(",");
- }else {
- //1,type=0,原始设定,没有第二件半价
- int a = Integer.valueOf(num);
- BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
- price =price.add(price2);
- note.append(price2).append("-").append(num).append(",");
- }
- }
- }else {
- for (String key : productNameMap.keySet()) {
- String[] productNum = key.split("-");
- String productNamea = productNum[0];
- String num = productNum[1];
- productMap.put(productNamea,Integer.valueOf(num));
- TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
- productNo = product.getNo();
- BigDecimal productPrice = product.getRmbPrice();
- productName.append(productNamea).append("x").append(num).append(",");
- note.append(productNamea).append("-").append(product.getNo()).append(":");
- switch (num) {
- case "1":
- //1个 0个半价
- price =price.add(productPrice);
- note.append(price).append("-").append(num).append(",");
- break;
- case "2":
- //2个 1个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- note.append(price).append("-").append(num).append(",");
- break;
- case "3":
- //3个 1个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- note.append(price).append("-").append(num).append(",");
- break;
- case "4":
- //4个 2个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- note.append(price).append("-").append(num).append(",");
- break;
- case "5":
- //5个 2个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- note.append(price).append("-").append(num).append(",");
- break;
- }
- }
- }
- Long equipmentId = equipment.getId();
- //查找商品
- if (BigDecimal.ZERO.compareTo(price) >= 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<String, Object> 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<TOrder> query = Wrappers.lambdaQuery();
- query.eq(TOrder::getSn, sn);
- query.eq(TOrder::getStatus, 0);
- List<TOrder> 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<TOrderDetails> lambdaQueryWrapper = new LambdaQueryWrapper<>();
- lambdaQueryWrapper.eq(TOrderDetails::getOrderSn,sn);
- List<TOrderDetails> 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<TOrder> queryWrapper = Wrappers.lambdaQuery();
- query.eq(TOrder::getSn, sn);
- query.eq(TOrder::getStatus, 1);
- List<TOrder> 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<String, Integer> 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<TOrderDetails> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(TOrderDetails::getOrderSn, order.getSn());
- List<TOrderDetails> 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<String, Object> hashMap = new HashMap<>(3);
- try {
- // 处理退款通知参数
- String body = HttpUtils.readData(request);
- Map<String, Object> 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<String, String> productNameMap, HttpServletRequest request) {
- if(productNameMap==null){
- return JsonMessage.error("数据出错");
- }
- StringBuilder note = new StringBuilder();
- StringBuilder productName = new StringBuilder();
- String productNo = "";
- Map<String, Integer> 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<String> value = JSON.parseArray(entryValue, String.class);
- List<TPromoCode> promoCodeList = new ArrayList<>();
- //1,校验优惠码
- if(value.size()>0){
- for(String code:value){
- if(!code.equals("0")){
- TPromoCode promoCode = new TPromoCode();
- ResponseModel<TPromoCode> 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<promoCodeList.size();i++){
- BigDecimal discount = BigDecimal.valueOf(promoCodeList.get(i).getDiscount()).setScale(2, RoundingMode.HALF_DOWN);
- BigDecimal price1 = productPrice.multiply(discount).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN);
- price = price.add(price1);
- onePrice = onePrice.add(price1);
- }
- if(i<Integer.parseInt(num)){
- int a = Integer.parseInt(num)-i;
- BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
- price =price.add(price2);
- onePrice = onePrice.add(price2);
- }
- note.append(onePrice).append("-").append(num).append(",");
- }else {
- //1,type=0,原始设定,没有第二件半价
- int a = Integer.parseInt(num);
- BigDecimal price2 = productPrice.multiply(new BigDecimal(a)).setScale(2, RoundingMode.HALF_DOWN);
- price =price.add(price2);
- note.append(price2).append("-").append(num).append(",");
- }
- }
- }else {
- for (String key : productNameMap.keySet()) {
- String[] productNum = key.split("-");
- String productNamea = productNum[0];
- String num = productNum[1];
- productMap.put(productNamea,Integer.valueOf(num));
- TProduct product = R.getDataIfSuccess(szwlFeign.getProduct(String.valueOf(equipment.getId()), productNamea));
- productNo = product.getNo();
- BigDecimal productPrice = product.getRmbPrice();
- productName.append(productNamea).append("x").append(num).append(",");
- note.append(productNamea).append("-").append(product.getNo()).append(":");
- switch (num) {
- case "1":
- //1个 0个半价
- price =price.add(productPrice);
- note.append(price).append("-").append(num).append(",");
- break;
- case "2":
- //2个 1个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- note.append(price).append("-").append(num).append(",");
- break;
- case "3":
- //3个 1个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- note.append(price).append("-").append(num).append(",");
- break;
- case "4":
- //4个 2个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- note.append(price).append("-").append(num).append(",");
- break;
- case "5":
- //5个 2个半价
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- price =price.add(productPrice.multiply(new BigDecimal(5)).divide(new BigDecimal(10)).setScale(2, RoundingMode.HALF_DOWN));
- price =price.add(productPrice);
- note.append(price).append("-").append(num).append(",");
- break;
- }
- }
- }
- Long equipmentId = equipment.getId();
- //查找商品
- if (BigDecimal.ZERO.compareTo(price) >= 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<String, String> 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<String, Object> 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<String, Object> orderQueryMap = null;
- Map<String, String> 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<TOrder> query = Wrappers.lambdaQuery();
- query.eq(TOrder::getSn, sn);
- query.eq(TOrder::getStatus, 0);
- List<TOrder> 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<TOrderDetails> lambdaQueryWrapper = new LambdaQueryWrapper<>();
- lambdaQueryWrapper.eq(TOrderDetails::getOrderSn,sn);
- List<TOrderDetails> 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<String, Object> 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<String, Object> bodyMap) {
- String decrypt = this.decryptFromResource(bodyMap);
- Gson gson = new Gson();
- Map<String,Object> 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<String,Object> amountMap = gson.fromJson(amount, HashMap.class);
- String refundPrice = amountMap.get("refund").toString();
- if(StringUtils.isNotEmpty(sn)){
- LambdaQueryWrapper<TOrder> 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<TOrderDetails> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(TOrderDetails::getOrderSn, sn);
- // 处理退款中状态的明细
- queryWrapper.eq(TOrderDetails::getRefundStatus, "4");
- List<TOrderDetails> 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);
- }
- }
- }
- }
|