123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- package com.example.controller;
- import com.alibaba.fastjson.JSON;
- import com.example.base.*;
- import com.example.entity.OmsOrder;
- import com.example.entity.RefundOrder;
- import com.example.entity.WxPayFrom;
- import com.example.enums.PayStatusEnum;
- import com.example.enums.ResultEnum;
- import com.example.util.GeneratorIdUtils;
- import com.example.util.RedisUtil;
- import com.example.util.UUIDUtils;
- import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
- import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
- import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
- import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
- import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
- import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
- import com.github.binarywang.wxpay.constant.WxPayConstants;
- import com.github.binarywang.wxpay.exception.WxPayException;
- import com.github.binarywang.wxpay.service.WxPayService;
- import io.swagger.annotations.Api;
- import io.swagger.annotations.ApiOperation;
- import lombok.extern.slf4j.Slf4j;
- import me.chanjar.weixin.common.bean.WxJsapiSignature;
- import me.chanjar.weixin.common.error.WxErrorException;
- import me.chanjar.weixin.mp.api.WxMpService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.web.bind.annotation.*;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.PrintWriter;
- import java.math.BigDecimal;
- @Slf4j
- @RestController
- @Api(tags = "公众号支付", description = "WechatH5PayController")
- @RequestMapping("/app")
- public class WechatH5PayController extends BaseController {
- private final static String OMSORDER = "oms_order_";
- @Value("${wx.pay.wxpayAppcallbackurl}")
- private String wxpayCallbackUrl;
- @Value("${wx.pay.wxpayRefundCallBackUrl}")
- private String wxpayRefundCallBackUrl;
- @Autowired
- private WxPayService wxPayService;
- @Autowired
- private RedisUtil redisUtil;
- @PostMapping("/pay")
- public ResponseBase pay(@RequestBody WxPayFrom wxPayFrom, HttpServletRequest request) {
- String orderId = wxPayFrom.getOrderId();
- String openid = wxPayFrom.getOpenid();
- String tradeType = wxPayFrom.getTradeType();
- OmsOrder omsOrder = JSON.parseObject(redisUtil.get(OMSORDER + orderId).toString(), OmsOrder.class);
- Integer status = omsOrder.getStatus();
- //查询订单是否支付
- if (status.equals(PayStatusEnum.SUCCESS.getIndex())) {
- throw new RuntimeException("订单已支付");
- }
- WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
- //随机字符串
- String s = UUIDUtils.randomUUID();
- orderRequest.setNonceStr(s);
- //商品描述
- String productName = omsOrder.getProductName();
- orderRequest.setBody(productName);
- //商户订单号(支付编号)
- // GeneratorIdUtils generatorIdUtils = new GeneratorIdUtils();
- // String orderNum = generatorIdUtils.nextId();
- // log.info("orderNum:" + orderNum);
- //设置商户订单号
- orderRequest.setOutTradeNo(orderId);
- //设置金额
- //data.getTotalPrice();
- BigDecimal money = omsOrder.getPayAmount();
- //元转成分
- money = money.multiply(new BigDecimal(100));
- int i = money.intValue();
- if ("test".equals(tradeType)) {
- //测试环境一分钱
- orderRequest.setTotalFee(1);
- } else {
- orderRequest.setTotalFee(i);
- }
- //终端ip
- String ipAddress = getIpAddress(request);
- orderRequest.setSpbillCreateIp(ipAddress);
- // 通知地址 支付成功后回调地址
- log.info("wxpayCallbackUrl=================>{}", wxpayCallbackUrl);
- orderRequest.setNotifyUrl(wxpayCallbackUrl);
- //交易类型
- orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);
- //用户标识 获取用户openid
- orderRequest.setOpenid(openid);
- // 这个可能是偏向原生一点的统一下单,返回的参数有很多没用的 或者null值 建议使用 createOrder下单
- Object unOrder = null;
- try {
- unOrder = wxPayService.createOrder(orderRequest);
- } catch (WxPayException e) {
- //e.printStackTrace();
- log.error(e.getMessage());
- //签名完成新增支付订单
- return responseError(500, "微信支付失败");
- }
- //更新本地订单支付id
- //orderClient.update(data);
- //签名完成新增支付订单
- return responseSuccess(new ResultVO(ResultEnum.SUCCESS, unOrder));
- }
- @Autowired
- private WxMpService wxMpService;
- /*微信js签名接口*/
- @GetMapping("/getJsapiTicket")
- public ResponseBase getJsapiTicket(String url) {
- WxJsapiSignature jsapiSignature = null;
- try {
- jsapiSignature = wxMpService.createJsapiSignature(url);
- } catch (WxErrorException e) {
- e.printStackTrace();
- System.err.print(e.getError());
- }
- return responseSuccess(new ResultVO(ResultEnum.SUCCESS, jsapiSignature));
- }
- /**
- * wx支付成功回调接口
- *
- * @param request
- * @param response
- * @throws IOException
- */
- @RequestMapping("/payResult")
- @ApiOperation("微信支付返回通知")
- public void payResult(HttpServletRequest request, HttpServletResponse response) throws IOException {
- log.info("微信支付返回通知函数开始---------------------");
- InputStream inStream = request.getInputStream();
- ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = inStream.read(buffer)) != -1) {
- outSteam.write(buffer, 0, len);
- }
- outSteam.close();
- inStream.close();
- String result = new String(outSteam.toByteArray(), "utf-8");
- boolean isPayOk = false;
- WxPayOrderNotifyResult wxPayOrderNotifyResult = null;
- // 此处调用订单查询接口验证是否交易成功
- try {
- wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(result);
- if ("SUCCESS".equals(wxPayOrderNotifyResult.getResultCode())) {
- isPayOk = true;
- }
- log.info("解析数据:" + wxPayOrderNotifyResult.toString());
- } catch (WxPayException e) {
- e.printStackTrace();
- }
- String noticeStr = "";
- // 支付成功,商户处理后同步返回给微信参数
- PrintWriter writer = response.getWriter();
- if (isPayOk) {
- //建议在这里处理付款完成的业务(虽然前端也可以处理后续业务,但是前端处理并不安全,例如:客户突然关闭浏览器了等情况,付款成功后续的业务将中断)
- //支付订单支付编号
- System.out.println("===============付款成功,业务开始处理==============");
- String orderNum = wxPayOrderNotifyResult.getOutTradeNo();
- log.info("orderNum:" + orderNum);
- //将订单更新为支付
- OmsOrder omsOrder = JSON.parseObject(redisUtil.get(OMSORDER + orderNum).toString(), OmsOrder.class);
- omsOrder.setStatus(PayStatusEnum.SUCCESS.getIndex());
- redisUtil.set(OMSORDER + omsOrder.getOrderId(), omsOrder);
- /**
- * 自己的业务
- */
- System.out.println("===============付款成功,业务处理完毕==============");
- // 通知微信已经收到消息,不要再给我发消息了,否则微信会8连击调用本接口
- noticeStr = setXML("SUCCESS", "OK");
- log.info("收到通知返回给微信api信息:-----------" + noticeStr);
- writer.write(noticeStr);
- writer.flush();
- } else {
- // 支付失败, 记录流水失败
- noticeStr = setXML("FAIL", "");
- writer.write(noticeStr);
- writer.flush();
- System.out.println("===============支付失败==============");
- }
- }
- public static String setXML(String return_code, String return_msg) {
- return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
- }
- public static String getIpAddress(HttpServletRequest request) {
- String ip = request.getHeader("x-forwarded-for");
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("Proxy-Client-IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("WL-Proxy-Client-IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("HTTP_CLIENT_IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getHeader("HTTP_X_FORWARDED_FOR");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
- ip = request.getRemoteAddr();
- }
- String[] split = ip.split(",");
- ip = split[0];
- return ip;
- }
- @GetMapping("/order/{orderId}")
- @ApiOperation("查询订单状态")
- public ResponseBase queryOrder(@PathVariable(value = "orderId") String orderId) {
- try {
- WxPayOrderQueryResult orderQueryResult = wxPayService.queryOrder(null, orderId);
- return responseSuccess(new ResultVO(ResultEnum.SUCCESS, orderQueryResult));
- } catch (WxPayException e) {
- e.printStackTrace();
- return responseError(500, "查询订单异常");
- }
- }
- @PostMapping("/order/refund")
- @ApiOperation("申请退款")
- public ResponseBase refundOrder(@RequestBody RefundOrder refundOrder) {
- WxPayRefundRequest refundRequest = new WxPayRefundRequest();
- try {
- OmsOrder omsOrder = JSON.parseObject(redisUtil.get(OMSORDER + refundOrder.getOrderId()).toString(), OmsOrder.class);
- refundRequest.setOutTradeNo(refundOrder.getOrderId());
- GeneratorIdUtils generatorIdUtils = new GeneratorIdUtils();
- String refundNo = generatorIdUtils.nextId();
- refundRequest.setOutRefundNo(refundNo);
- refundRequest.setRefundDesc(refundOrder.getRefundDesc());
- refundRequest.setTotalFee(omsOrder.getTotalAmount().intValue());
- refundRequest.setRefundFee(refundRequest.getTotalFee());
- refundRequest.setOpUserId(refundRequest.getMchId());
- refundRequest.setNotifyUrl(wxpayRefundCallBackUrl);
- wxPayService.refund(refundRequest);
- } catch (WxPayException e) {
- e.printStackTrace();
- return responseError(500, "申请退款异常");
- }
- return responseSuccess(new ResultVO());
- }
- @RequestMapping("/refundResult")
- @ApiOperation("退款回调")
- public void refundResult(HttpServletRequest request, HttpServletResponse response) throws IOException {
- log.info("微信退款回调通知函数开始---------------------");
- InputStream inStream = request.getInputStream();
- ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = inStream.read(buffer)) != -1) {
- outSteam.write(buffer, 0, len);
- }
- outSteam.close();
- inStream.close();
- String result = new String(outSteam.toByteArray(), "utf-8");
- boolean refundOk = false;
- WxPayRefundNotifyResult wxPayRefundNotifyResult = null;
- try {
- wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(result);
- if ("SUCCESS".equals(wxPayRefundNotifyResult.getReturnCode())) {
- refundOk = true;
- }
- log.info("解析数据:" + wxPayRefundNotifyResult.toString());
- } catch (WxPayException e) {
- e.printStackTrace();
- }
- String noticeStr = "";
- // 支付成功,商户处理后同步返回给微信参数
- PrintWriter writer = response.getWriter();
- if (refundOk) {
- //建议在这里处理付款完成的业务(虽然前端也可以处理后续业务,但是前端处理并不安全,例如:客户突然关闭浏览器了等情况,付款成功后续的业务将中断)
- //支付订单支付编号
- System.out.println("===============退款成功,业务开始处理==============");
- String refundNo = wxPayRefundNotifyResult.getReqInfo().getOutRefundNo();
- log.info("refundNo:" + refundNo);
- //将订单更新已退款
- /**
- * 自己的业务
- */
- System.out.println("===============退款成功,业务处理完毕==============");
- //todo:关闭订单
- noticeStr = setXML("SUCCESS", "OK");
- log.info("收到通知返回给微信api信息:-----------" + noticeStr);
- writer.write(noticeStr);
- writer.flush();
- } else {
- // 支付失败, 记录流水失败
- noticeStr = setXML("FAIL", "");
- writer.write(noticeStr);
- writer.flush();
- System.out.println("===============退款失败==============");
- }
- }
- @ApiOperation("退款订单查询")
- @GetMapping("/order/refund/{orderId}")
- public ResponseBase refundQuery(@PathVariable(value = "orderId") String orderId) {
- try {
- WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery(null, orderId, null, null);
- } catch (WxPayException e) {
- e.printStackTrace();
- return responseError(500, "查询退款异常");
- }
- return responseSuccess(new ResultVO());
- }
- }
|