ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/PaylogController.java
@@ -8,6 +8,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.order.domain.pojo.Paylog; import com.ruoyi.order.service.IPaylogService; import com.ruoyi.order.service.impl.PaylogServiceImpl; import com.ruoyi.order.util.DateUtil; import com.ruoyi.order.util.SinataUtil; import com.ruoyi.order.util.alipay.config.AlipayConfig; @@ -67,99 +68,23 @@ @Resource private IPaylogService iPaylogService; @Resource private PaylogServiceImpl paylogServiceImpl; Logger log = LoggerFactory.getLogger(getClass()); @ResponseBody @RequestMapping("getPayInfo") @RequestMapping("/getPayInfo") public R<Map<String, Object>> getPayInfo(Integer uid, Integer type, String subject, String body, String orderID, HttpServletRequest request) { Double price = 0.0; try { if(judgeContainsStr(orderID)){ price= Double.valueOf(1); body = "商品支付"; subject = "商品支付"; Map<String, Object> map = new HashMap<String, Object>(); if (type == 1) { // 支付宝预下单 return alipay("1", subject, body, price, request); } else { // 微信预下单 return wxpay(1, "1", body, price, request); } } return paylogServiceImpl.getPayInfo(uid, type, subject, body, orderID,request); } catch (Exception e) { e.printStackTrace(); return R.fail("获取异常"); } return R.fail("获取异常"); } /** * 支付宝订单退款 * * @author tzj * @param out_trade_no * 商品订单号 * @param trade_no * 支付宝交易号 * @param refund_amount * 退款金额 * @return */ public boolean refundForAlipay(String out_trade_no, String trade_no, Double refund_amount) { try { // 实例化客户端 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.input_charset, AlipayConfig.ali_public_key,"RSA2"); // 实例化具体API对应的request类,类名称和接口名称对应 AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); // SDK已经封装掉了公共参数,这里只需要传入业务参数 // 此次只是参数展示,未进行字符串转义,实际情况下请转义 request.setBizContent("{" + "\"out_trade_no\":\"" + out_trade_no + "\", " + "\"trade_no\":\"" + trade_no + "\", " + "\"refund_amount\":" + refund_amount + ", " + "\"refund_reason\":\"正常退款\"," + "\"out_request_no\":\"HZ01RF001\"" + "}"); AlipayTradeRefundResponse response = alipayClient.execute(request); // 调用成功,则处理业务逻辑 if (response.isSuccess()) { return true; } } catch (Exception e) { e.printStackTrace(); return false; } return false; } /** * 获取支付信息支付(签约app支付2.0) * * @param subject * @param body * @param price * @param request * @return */ public R<Map<String, Object>> alipay(String orderNo, String subject, String body, Double price, HttpServletRequest request) { try { // 接口封装支付宝请求参数 // Map<String, Object> mData = new HashMap<String, Object>(); // 构建请求支付签名参数 Map<String, Object> pay = PayDemoActivity.appPay(subject, body, price, orderNo); /* * Set<Entry<String, String>> entrySet = pay.entrySet(); * Iterator<Entry<String, String>> iterator = entrySet.iterator(); * while (iterator.hasNext()) { Entry<String, String> next = * iterator.next(); mData.put(next.getKey(), next.getValue()); } */ return R.ok(pay); } catch (Exception e) { e.printStackTrace(); return R.fail("支付异常!"); } } /** * 服务器异步通知处理支付宝 @@ -168,116 +93,15 @@ * @param res */ @RequestMapping("/alipay/notify") public void notifyUrl(HttpServletRequest request, HttpServletResponse res) { HttpServletResponse response = (HttpServletResponse) res; response.setContentType("text/html;charset=UTF-8"); PrintWriter out; public void notifyUrl(HttpServletRequest request, HttpServletResponse response) { try { out = response.getWriter(); // 获取支付宝POST过来反馈信息 Map<String, String> params = new HashMap<String, String>(); Map requestParams = request.getParameterMap(); log.debug("AlipayController.notifyUrl__requestParams:\n" + requestParams); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); params.put(name, valueStr); } paylogServiceImpl.notifyUrl(request,response); } catch (Exception e) { Paylog paylog = getPayLog_alipay(request); // 验证成功 if ("TRADE_FINISHED".equals(paylog.getTradeStatus())) { System.out.println("AlipayController.notifyUrl__验证成功:success"); // 支付失败 } else if ("TRADE_SUCCESS".equals(paylog.getTradeStatus())) { // 支付成功 try { if(judgeContainsStr(paylog.getOutTradeNo())){ } // ——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— log.debug("AlipayController.notifyUrl__回调处理:success"); out.println("success"); // 请不要修改或删除 // ——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— log.debug("AlipayController.notifyUrl__回调处理:success"); out.println("success"); // 请不要修改或删除 } catch (Exception e) { log.debug("AlipayController.notifyUrl__回调逻辑代码处理异常!fail"); // 返回失败 out.println("fail"); e.printStackTrace(); } // //////////////////////////////////////////////////////////////////////////////////////// } else {// 验证失败 log.debug("AlipayController.notifyUrl__回调处理失败!fail"); out.println("fail"); } } catch ( IOException e) { log.debug("AlipayController.notifyUrl__支付宝服务器异步通知数据处理失败!"); e.printStackTrace(); } } /////////////////////////////////////////////////////////////////////////////////////////////////// /** * 统一下单 * * @param apptype * @param outTradeNo * @param body * @param price * @param request * @return */ public static R<Map<String, Object>> wxpay(Integer apptype, String outTradeNo, String body, Double price, HttpServletRequest request) { // 获取预支付接口返回参数 Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> appPayMap = new HashMap<String, Object>(); try { // 构建接口请求参数 UnifiedorderReqData unifiedorderReqData = new UnifiedorderReqData(apptype, outTradeNo, body, price, Configure.wx_notify_url); // 请求接口获取返回接口 String result = requestUnifiedorderService(apptype, unifiedorderReqData); System.out.println(result); System.out.println("WxpayController.createOrder__result:\n" + result); // 获取预支付接口返回参数 map = XMLParser.getMapFromXML(result); System.out.println("WxpayController.createOrder__result:\n" + result); // 捕获预支付接口错误提示 if ("FAIL".equals(map.get("result_code")) || "FAIL".equals(map.get("return_code"))) { return R.fail(String.valueOf(map.get("return_msg"))); } // 对获取预支付返回接口参数进行封装(生成支付订单接口数据) AppPayReqData appPay = new AppPayReqData(apptype, (String) map.get("appid"), (String) map.get("mch_id"), (String) map.get("prepay_id"), unifiedorderReqData.getNonce_str()); // 对获取预支付返回接口参数进行封装(生成支付订单接口数据) appPayMap.put("appid", appPay.getAppid());// 公众账号ID appPayMap.put("nonceStr", appPay.getNoncestr());// 随机字符串(32位) appPayMap.put("package", appPay.get_package());// 扩展字段(暂填写固定值Sign=WXPay) appPayMap.put("partnerId", appPay.getPartnerid());// 商户号 appPayMap.put("prepayId", appPay.getPrepayid());// 预支付编号(微信返回的支付交易会话ID) appPayMap.put("timeStamp", appPay.getTimestamp());// 时间戳 appPayMap.put("sign", appPay.getSign());// 根据API给的签名规则进行签名 return R.ok(appPayMap); } catch (Exception e) { System.out.println("统一下单_API_处理异常!"); e.printStackTrace(); } return R.fail("统一下单失败"); } /** * 微信支付回调(参考财付通回调接口) @@ -288,159 +112,13 @@ @RequestMapping("/wxpay/notify") public void wxnotify(HttpServletRequest request, HttpServletResponse response) { try { System.out.println("微信支付回调!!!!!!!!!!!!!!!!!!!!!!!!!"); // 异步通知返回报文 StringBuffer notityXml = new StringBuffer(); String inputLine; while ((inputLine = request.getReader().readLine()) != null) { notityXml.append(inputLine); } request.getReader().close(); // log.debug("WxpayController.notify__notityXml:\n" + notityXml); System.out.println("WxpayController.notify__notityXml:\n" + notityXml); // 验证签名 if (Signature.checkIsSignValidFromResponseString(1, notityXml.toString()) || Signature.checkIsSignValidFromResponseString(2, notityXml.toString())) { Map<String, Object> map = XMLParser.getMapFromXML(notityXml.toString()); // log.debug("WxpayController.notify__map:\n" + map); // 接口返回状态 String result_code = (String) map.get("result_code"); if ("SUCCESS".equals(result_code)) { // // 商户订单号 String out_trade_no = (String) map.get("out_trade_no"); // // 微信支付交易号 String trade_no = (String) map.get("transaction_id"); // // 金额,以分为单位 String total_fee = (String) map.get("total_fee"); // // 优惠金额 // String discount = (String) map.get("discount"); // // 支付完成时间 String time_end = (String) map.get("time_end"); // // 支付者唯一Id(对应买家账号的一个加密串 ) String buyer_id = (String) map.get("buyer_id"); ///////////////////////////// 这里程序处理支付回调逻辑 ///////////////////////////// //////////////////// Paylog paylog = new Paylog(); paylog.setOutTradeNo(out_trade_no); paylog.setPayType(2); paylog.setBuyerId(buyer_id); paylog.setTradeNo(trade_no); paylog.setPayMoney(Double.parseDouble(total_fee) / 100); paylog.setState(1); System.out.println("支付完成时间"+time_end); paylog.setAddTime(LocalDateTime.now()); iPaylogService.save(paylog); if(judgeContainsStr(paylog.getOutTradeNo())){ log.debug("WxpayController.notify__回调处理成功:SUCCESS"); response.getOutputStream().print("success"); } log.debug("WxpayController.notify__回调处理成功:SUCCESS"); response.getOutputStream().print("success"); } else { log.debug("WxpayController.notify__回调处理:验证状态错误!" + result_code); System.out.println("验证状态错误!" + result_code); } } else { log.debug("WxpayController.notify__回调处理:通知签名验证失败!"); System.out.println("通知签名验证失败!"); } paylogServiceImpl.notifyUrl(request,response); } catch (Exception e) { e.printStackTrace(); } } /** * 微信退款 * * @param transactionID * 【支付交易号】是微信系统为每一笔支付交易分配的订单号,通过这个订单号可以标识这笔交易, * 它由支付订单API支付成功时返回的数据里面获取到。建议优先使用 * @param outTradeNo * 【商品订单编号】商户系统内部的订单号,transaction_id * 、out_trade_no二选一,如果同时存在优先级:transaction_id>out_trade_no * @param outRefundNo * 【退款编号】商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔 * 订单总金额,单位为分 * @param refundFee * 退款总金额,单位为分,可以做部分退款 * @return */ public static boolean refundForWxpay(Integer apptype, String transactionID, String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee, String pay_type) { Map<String, Object> map = new HashMap<String, Object>(); try { // 构建接口请求参数 com.tencent.protocol.RefundReqData refundReqData = new com.tencent.protocol.RefundReqData(transactionID, outTradeNo, outRefundNo, totalFee, refundFee, pay_type); // 请求接口返回结果 String result = requestRefundService(apptype, refundReqData); System.out.println("微信退款返回内容:" + result); // 获取预支付接口返回参数 map = XMLParser.getMapFromXML(result); System.out.println("微信退款返回参数:" + map); // 退款成功处理 if ("SUCCESS".equals(map.get("result_code"))) { return true; } } catch (Exception e) { e.printStackTrace(); return false; } return false; } /** * 获取支付宝 * * @param request * @return * @throws Exception */ private Paylog getPayLog_alipay(HttpServletRequest request) throws IOException { //////// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//////// // 商户订单号 String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8"); // 支付宝交易号 String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8"); // 交易状态 String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8"); // 支付者唯一Id String buyer_id = new String(request.getParameter("buyer_id").getBytes("ISO-8859-1"), "UTF-8"); // 支付帐号 String buyer_email = ""; if (SinataUtil.isNotEmpty(request.getParameter("buyer_logon_id"))) { buyer_email = new String(request.getParameter("buyer_logon_id").getBytes("ISO-8859-1"), "UTF-8"); } // 支付金额 String total_fee = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"); // 支付时间 String notify_time = new String(request.getParameter("notify_time").getBytes("ISO-8859-1"), "UTF-8"); //////// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//////// Paylog paylog = new Paylog(); paylog.setOutTradeNo(out_trade_no); paylog.setPayType(1); paylog.setBuyerId(buyer_id); paylog.setTradeNo(trade_no); paylog.setPayMoney(Double.parseDouble(total_fee)); paylog.setState(1); paylog.setAddTime(LocalDateTime.now()); paylog.setTradeStatus(trade_status.toString()); iPaylogService.save(paylog); return paylog; } public boolean judgeContainsStr(String cardNum) { String regex=".*[a-zA-Z]+.*"; Matcher m= Pattern.compile(regex).matcher(cardNum); return m.matches(); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/OrderAuctionBond.java
@@ -73,6 +73,11 @@ @ApiModelProperty(value = "删除标志(0代表存在 1代表删除)") @TableLogic private Integer delFlag; @ApiModelProperty(value = "支付方式 1=微信 2=支付宝") private Integer paymentMethod; @ApiModelProperty(value = "保证金订单编号") private String orderNo; } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderAuctionBondService.java
@@ -1,8 +1,10 @@ package com.ruoyi.order.service; import com.ruoyi.common.core.domain.R; import com.ruoyi.order.domain.pojo.OrderAuctionBond; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO; import org.apache.poi.ss.formula.functions.T; import org.springframework.web.bind.annotation.RequestBody; /** @@ -14,6 +16,6 @@ * @since 2024-05-16 */ public interface IOrderAuctionBondService extends IService<OrderAuctionBond> { void getOrderAuctionBond( OrderAuctionBondDTO orderAuctionBondDTO); R<T> getOrderAuctionBond(OrderAuctionBondDTO orderAuctionBondDTO); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IPaylogService.java
@@ -1,7 +1,21 @@ package com.ruoyi.order.service; import com.ruoyi.common.core.domain.R; import com.ruoyi.order.domain.pojo.Paylog; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.order.util.tencent.common.Signature; import com.ruoyi.order.util.tencent.common.XMLParser; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * <p> @@ -13,4 +27,25 @@ */ public interface IPaylogService extends IService<Paylog> { R<Map<String, Object>> getPayInfo(Integer uid, Integer type, String subject, String body, String orderID, HttpServletRequest request); /** * 服务器异步通知处理支付宝 * * @param request * @param res */ @RequestMapping("/alipay/notify") public void notifyUrl(HttpServletRequest request, HttpServletResponse res); /////////////////////////////////////////////////////////////////////////////////////////////////// /** * 微信支付回调(参考财付通回调接口) * * @param request * @param response */ void wxnotify(HttpServletRequest request, HttpServletResponse response); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderAuctionBondServiceImpl.java
@@ -2,11 +2,16 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.core.domain.R; import com.ruoyi.order.domain.pojo.OrderAuctionBond; import com.ruoyi.order.domain.pojo.Paylog; import com.ruoyi.order.mapper.OrderAuctionBondMapper; import com.ruoyi.order.service.IOrderAuctionBondService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.order.service.IPaylogService; import com.ruoyi.order.util.SinataUtil; import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO; import org.apache.poi.ss.formula.functions.T; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -26,16 +31,45 @@ @Resource private IOrderAuctionBondService iOrderAuctionBondService; @Override public void getOrderAuctionBond( OrderAuctionBondDTO orderAuctionBondDTO) { LambdaQueryWrapper<OrderAuctionBond> wrapper= Wrappers.lambdaQuery(); wrapper.notIn(OrderAuctionBond::getMemberId,orderAuctionBondDTO.getUserList()); wrapper.eq(OrderAuctionBond::getDelFlag,0); wrapper.eq(OrderAuctionBond::getAuctionSalesroomId,orderAuctionBondDTO.getAuctionSalesroomId()); List<OrderAuctionBond> orderAuctionBondList=iOrderAuctionBondService.list(wrapper); for (OrderAuctionBond orderAuctionBond:orderAuctionBondList){ @Resource private IPaylogService iPaylogService; @Resource private PaylogServiceImpl paylogServiceImpl; @Override public R<T> getOrderAuctionBond(OrderAuctionBondDTO orderAuctionBondDTO) { LambdaQueryWrapper<OrderAuctionBond> wrapper = Wrappers.lambdaQuery(); wrapper.notIn(OrderAuctionBond::getMemberId, orderAuctionBondDTO.getUserList()); wrapper.eq(OrderAuctionBond::getDelFlag, 0); wrapper.eq(OrderAuctionBond::getAuctionSalesroomId, orderAuctionBondDTO.getAuctionSalesroomId()); List<OrderAuctionBond> orderAuctionBondList = iOrderAuctionBondService.list(wrapper); for (OrderAuctionBond orderAuctionBond : orderAuctionBondList) { LambdaQueryWrapper<Paylog> wrapper1 = Wrappers.lambdaQuery(); wrapper1.notIn(Paylog::getOutTradeNo, orderAuctionBond.getOrderNo()); wrapper1.last("limit 1"); Paylog paylog = iPaylogService.getOne(wrapper1); if (paylog.getPayType() == 1) {//支付宝 boolean bo = paylogServiceImpl.refundForAlipay(paylog.getOutTradeNo(), paylog.getTradeNo(), orderAuctionBond.getBond().doubleValue()); if (!bo) { return R.fail("支付宝退款失败!"); } } else {//微信 String refundMoney = SinataUtil.doubleRetainTwo(orderAuctionBond.getBond().doubleValue() * 100d); Integer refundFee = Integer.parseInt(refundMoney.substring(0, refundMoney.length() - 3)); String money = SinataUtil.doubleRetainTwo(paylog.getPayMoney() * 100d); Integer totalFee = Integer.parseInt(money.substring(0, money.length() - 3)); boolean bo = paylogServiceImpl.refundForWxpay(1, paylog.getTradeNo(), paylog.getOutTradeNo(), orderAuctionBond.getOrderNo(), totalFee, refundFee, "2"); if (!bo) { return R.fail("微信退款失败!"); } } } return R.ok(); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/PaylogServiceImpl.java
@@ -1,10 +1,40 @@ package com.ruoyi.order.service.impl; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.response.AlipayTradeRefundResponse; import com.ruoyi.common.core.domain.R; import com.ruoyi.order.domain.pojo.Paylog; import com.ruoyi.order.mapper.PaylogMapper; import com.ruoyi.order.service.IPaylogService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.order.util.SinataUtil; import com.ruoyi.order.util.alipay.config.AlipayConfig; import com.ruoyi.order.util.alipay.util.PayDemoActivity; import com.ruoyi.order.util.tencent.common.Configure; import com.ruoyi.order.util.tencent.common.Signature; import com.ruoyi.order.util.tencent.common.XMLParser; import com.ruoyi.order.util.tencent.protocol.AppPayReqData; import com.ruoyi.order.util.tencent.protocol.UnifiedorderReqData; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.ruoyi.order.util.tencent.WXPay.requestRefundService; import static com.ruoyi.order.util.tencent.WXPay.requestUnifiedorderService; /** * <p> @@ -17,4 +47,388 @@ @Service public class PaylogServiceImpl extends ServiceImpl<PaylogMapper, Paylog> implements IPaylogService { @Resource private PaylogServiceImpl paylogServiceImpl; @Resource private IPaylogService iPaylogService; @Override public R<Map<String, Object>> getPayInfo(Integer uid, Integer type, String subject, String body, String orderID, HttpServletRequest request) { Double price = 0.0; try { if(judgeContainsStr(orderID)){ price= Double.valueOf(1); body = "商品支付"; subject = "商品支付"; Map<String, Object> map = new HashMap<String, Object>(); if (type == 1) { // 支付宝预下单 return paylogServiceImpl.alipay("1", subject, body, price, request); } else { // 微信预下单 return wxpay(1, "1", body, price, request); } } } catch (Exception e) { e.printStackTrace(); } return R.fail("获取异常"); } /** * 服务器异步通知处理支付宝 * * @param request * @param res */ @Override public void notifyUrl(HttpServletRequest request, HttpServletResponse res) { HttpServletResponse response = (HttpServletResponse) res; response.setContentType("text/html;charset=UTF-8"); PrintWriter out; try { out = response.getWriter(); // 获取支付宝POST过来反馈信息 Map<String, String> params = new HashMap<String, String>(); Map requestParams = request.getParameterMap(); log.debug("AlipayController.notifyUrl__requestParams:\n" + requestParams); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i < values.length; i++) { valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ","; } // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); params.put(name, valueStr); } Paylog paylog = getPayLog_alipay(request); // 验证成功 if ("TRADE_FINISHED".equals(paylog.getTradeStatus())) { System.out.println("AlipayController.notifyUrl__验证成功:success"); // 支付失败 } else if ("TRADE_SUCCESS".equals(paylog.getTradeStatus())) { // 支付成功 try { if(judgeContainsStr(paylog.getOutTradeNo())){ } // ——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— log.debug("AlipayController.notifyUrl__回调处理:success"); out.println("success"); // 请不要修改或删除 // ——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— log.debug("AlipayController.notifyUrl__回调处理:success"); out.println("success"); // 请不要修改或删除 } catch (Exception e) { log.debug("AlipayController.notifyUrl__回调逻辑代码处理异常!fail"); // 返回失败 out.println("fail"); e.printStackTrace(); } // //////////////////////////////////////////////////////////////////////////////////////// } else {// 验证失败 log.debug("AlipayController.notifyUrl__回调处理失败!fail"); out.println("fail"); } } catch ( IOException e) { log.debug("AlipayController.notifyUrl__支付宝服务器异步通知数据处理失败!"); e.printStackTrace(); } } /////////////////////////////////////////////////////////////////////////////////////////////////// /** * 微信支付回调(参考财付通回调接口) * * @param request * @param response */ @Override public void wxnotify(HttpServletRequest request, HttpServletResponse response) { try { System.out.println("微信支付回调!!!!!!!!!!!!!!!!!!!!!!!!!"); // 异步通知返回报文 StringBuffer notityXml = new StringBuffer(); String inputLine; while ((inputLine = request.getReader().readLine()) != null) { notityXml.append(inputLine); } request.getReader().close(); // log.debug("WxpayController.notify__notityXml:\n" + notityXml); System.out.println("WxpayController.notify__notityXml:\n" + notityXml); // 验证签名 if (Signature.checkIsSignValidFromResponseString(1, notityXml.toString()) || Signature.checkIsSignValidFromResponseString(2, notityXml.toString())) { Map<String, Object> map = XMLParser.getMapFromXML(notityXml.toString()); // log.debug("WxpayController.notify__map:\n" + map); // 接口返回状态 String result_code = (String) map.get("result_code"); if ("SUCCESS".equals(result_code)) { // // 商户订单号 String out_trade_no = (String) map.get("out_trade_no"); // // 微信支付交易号 String trade_no = (String) map.get("transaction_id"); // // 金额,以分为单位 String total_fee = (String) map.get("total_fee"); // // 优惠金额 // String discount = (String) map.get("discount"); // // 支付完成时间 String time_end = (String) map.get("time_end"); // // 支付者唯一Id(对应买家账号的一个加密串 ) String buyer_id = (String) map.get("buyer_id"); ///////////////////////////// 这里程序处理支付回调逻辑 ///////////////////////////// //////////////////// Paylog paylog = new Paylog(); paylog.setOutTradeNo(out_trade_no); paylog.setPayType(2); paylog.setBuyerId(buyer_id); paylog.setTradeNo(trade_no); paylog.setPayMoney(Double.parseDouble(total_fee) / 100); paylog.setState(1); System.out.println("支付完成时间" + time_end); paylog.setAddTime(LocalDateTime.now()); iPaylogService.save(paylog); if (judgeContainsStr(paylog.getOutTradeNo())) { log.debug("WxpayController.notify__回调处理成功:SUCCESS"); response.getOutputStream().print("success"); } log.debug("WxpayController.notify__回调处理成功:SUCCESS"); response.getOutputStream().print("success"); } else { log.debug("WxpayController.notify__回调处理:验证状态错误!" + result_code); System.out.println("验证状态错误!" + result_code); } } else { log.debug("WxpayController.notify__回调处理:通知签名验证失败!"); System.out.println("通知签名验证失败!"); } } catch (Exception e) { e.printStackTrace(); } } /** * 支付宝订单退款 * * @author tzj * @param out_trade_no * 商品订单号 * @param trade_no * 支付宝交易号 * @param refund_amount * 退款金额 * @return */ public boolean refundForAlipay(String out_trade_no, String trade_no, Double refund_amount) { try { // 实例化客户端 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.input_charset, AlipayConfig.ali_public_key,"RSA2"); // 实例化具体API对应的request类,类名称和接口名称对应 AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); // SDK已经封装掉了公共参数,这里只需要传入业务参数 // 此次只是参数展示,未进行字符串转义,实际情况下请转义 request.setBizContent("{" + "\"out_trade_no\":\"" + out_trade_no + "\", " + "\"trade_no\":\"" + trade_no + "\", " + "\"refund_amount\":" + refund_amount + ", " + "\"refund_reason\":\"正常退款\"," + "\"out_request_no\":\"HZ01RF001\"" + "}"); AlipayTradeRefundResponse response = alipayClient.execute(request); // 调用成功,则处理业务逻辑 if (response.isSuccess()) { return true; } } catch (Exception e) { e.printStackTrace(); return false; } return false; } /** * 获取支付信息支付(签约app支付2.0) * * @param subject * @param body * @param price * @param request * @return */ public R<Map<String, Object>> alipay(String orderNo, String subject, String body, Double price, HttpServletRequest request) { try { // 接口封装支付宝请求参数 // Map<String, Object> mData = new HashMap<String, Object>(); // 构建请求支付签名参数 Map<String, Object> pay = PayDemoActivity.appPay(subject, body, price, orderNo); /* * Set<Entry<String, String>> entrySet = pay.entrySet(); * Iterator<Entry<String, String>> iterator = entrySet.iterator(); * while (iterator.hasNext()) { Entry<String, String> next = * iterator.next(); mData.put(next.getKey(), next.getValue()); } */ return R.ok(pay); } catch (Exception e) { e.printStackTrace(); return R.fail("支付异常!"); } } /** * 统一下单 * * @param apptype * @param outTradeNo * @param body * @param price * @param request * @return */ public static R<Map<String, Object>> wxpay(Integer apptype, String outTradeNo, String body, Double price, HttpServletRequest request) { // 获取预支付接口返回参数 Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> appPayMap = new HashMap<String, Object>(); try { // 构建接口请求参数 UnifiedorderReqData unifiedorderReqData = new UnifiedorderReqData(apptype, outTradeNo, body, price, Configure.wx_notify_url); // 请求接口获取返回接口 String result = requestUnifiedorderService(apptype, unifiedorderReqData); System.out.println(result); System.out.println("WxpayController.createOrder__result:\n" + result); // 获取预支付接口返回参数 map = XMLParser.getMapFromXML(result); System.out.println("WxpayController.createOrder__result:\n" + result); // 捕获预支付接口错误提示 if ("FAIL".equals(map.get("result_code")) || "FAIL".equals(map.get("return_code"))) { return R.fail(String.valueOf(map.get("return_msg"))); } // 对获取预支付返回接口参数进行封装(生成支付订单接口数据) AppPayReqData appPay = new AppPayReqData(apptype, (String) map.get("appid"), (String) map.get("mch_id"), (String) map.get("prepay_id"), unifiedorderReqData.getNonce_str()); // 对获取预支付返回接口参数进行封装(生成支付订单接口数据) appPayMap.put("appid", appPay.getAppid());// 公众账号ID appPayMap.put("nonceStr", appPay.getNoncestr());// 随机字符串(32位) appPayMap.put("package", appPay.get_package());// 扩展字段(暂填写固定值Sign=WXPay) appPayMap.put("partnerId", appPay.getPartnerid());// 商户号 appPayMap.put("prepayId", appPay.getPrepayid());// 预支付编号(微信返回的支付交易会话ID) appPayMap.put("timeStamp", appPay.getTimestamp());// 时间戳 appPayMap.put("sign", appPay.getSign());// 根据API给的签名规则进行签名 return R.ok(appPayMap); } catch (Exception e) { System.out.println("统一下单_API_处理异常!"); e.printStackTrace(); } return R.fail("统一下单失败"); } /** * 微信退款 * * @param transactionID * 【支付交易号】是微信系统为每一笔支付交易分配的订单号,通过这个订单号可以标识这笔交易, * 它由支付订单API支付成功时返回的数据里面获取到。建议优先使用 * @param outTradeNo * 【商品订单编号】商户系统内部的订单号,transaction_id * 、out_trade_no二选一,如果同时存在优先级:transaction_id>out_trade_no * @param outRefundNo * 【退款编号】商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔 * 订单总金额,单位为分 * @param refundFee * 退款总金额,单位为分,可以做部分退款 * @return */ public static boolean refundForWxpay(Integer apptype, String transactionID, String outTradeNo, String outRefundNo, Integer totalFee, Integer refundFee, String pay_type) { Map<String, Object> map = new HashMap<String, Object>(); try { // 构建接口请求参数 com.tencent.protocol.RefundReqData refundReqData = new com.tencent.protocol.RefundReqData(transactionID, outTradeNo, outRefundNo, totalFee, refundFee, pay_type); // 请求接口返回结果 String result = requestRefundService(apptype, refundReqData); System.out.println("微信退款返回内容:" + result); // 获取预支付接口返回参数 map = XMLParser.getMapFromXML(result); System.out.println("微信退款返回参数:" + map); // 退款成功处理 if ("SUCCESS".equals(map.get("result_code"))) { return true; } } catch (Exception e) { e.printStackTrace(); return false; } return false; } /** * 获取支付宝 * * @param request * @return * @throws Exception */ private Paylog getPayLog_alipay(HttpServletRequest request) throws IOException { //////// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//////// // 商户订单号 String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8"); // 支付宝交易号 String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8"); // 交易状态 String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8"); // 支付者唯一Id String buyer_id = new String(request.getParameter("buyer_id").getBytes("ISO-8859-1"), "UTF-8"); // 支付帐号 String buyer_email = ""; if (SinataUtil.isNotEmpty(request.getParameter("buyer_logon_id"))) { buyer_email = new String(request.getParameter("buyer_logon_id").getBytes("ISO-8859-1"), "UTF-8"); } // 支付金额 String total_fee = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"); // 支付时间 String notify_time = new String(request.getParameter("notify_time").getBytes("ISO-8859-1"), "UTF-8"); //////// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//////// Paylog paylog = new Paylog(); paylog.setOutTradeNo(out_trade_no); paylog.setPayType(1); paylog.setBuyerId(buyer_id); paylog.setTradeNo(trade_no); paylog.setPayMoney(Double.parseDouble(total_fee)); paylog.setState(1); paylog.setAddTime(LocalDateTime.now()); paylog.setTradeStatus(trade_status.toString()); iPaylogService.save(paylog); return paylog; } public boolean judgeContainsStr(String cardNum) { String regex=".*[a-zA-Z]+.*"; Matcher m= Pattern.compile(regex).matcher(cardNum); return m.matches(); } }