|  | @@ -0,0 +1,197 @@
 | 
	
		
			
				|  |  | +package com.hwrj.cloud.portal.controller;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
 | 
	
		
			
				|  |  | +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
 | 
	
		
			
				|  |  | +import com.github.binarywang.wxpay.constant.WxPayConstants;
 | 
	
		
			
				|  |  | +import com.github.binarywang.wxpay.exception.WxPayException;
 | 
	
		
			
				|  |  | +import com.github.binarywang.wxpay.service.WxPayService;
 | 
	
		
			
				|  |  | +import com.hwrj.cloud.common.api.CommonResult;
 | 
	
		
			
				|  |  | +import com.hwrj.cloud.portal.util.GeneratorIdUtils;
 | 
	
		
			
				|  |  | +import com.hwrj.cloud.portal.util.UUIDUtils;
 | 
	
		
			
				|  |  | +import com.hwrj.cloud.portal.wxfrom.WxPayFrom;
 | 
	
		
			
				|  |  | +import io.swagger.annotations.Api;
 | 
	
		
			
				|  |  | +import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.annotation.Value;
 | 
	
		
			
				|  |  | +import org.springframework.stereotype.Controller;
 | 
	
		
			
				|  |  | +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
 | 
	
		
			
				|  |  | +@Controller
 | 
	
		
			
				|  |  | +@Api(tags = "AppPayController", description = "支付")
 | 
	
		
			
				|  |  | +@RequestMapping("/app")
 | 
	
		
			
				|  |  | +public class AppPayController {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Value("${wx.pay.wxpayAppcallbackurl}")
 | 
	
		
			
				|  |  | +    private String wxpayCallbackUrl;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private WxPayService wxPayService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @GetMapping("/pay")
 | 
	
		
			
				|  |  | +    @ResponseBody
 | 
	
		
			
				|  |  | +    public CommonResult pay(WxPayFrom wxPayFrom, HttpServletRequest request) {
 | 
	
		
			
				|  |  | +        String orderId = wxPayFrom.getOrderId();
 | 
	
		
			
				|  |  | +        String openid = wxPayFrom.getOpenid();
 | 
	
		
			
				|  |  | +        String tradeType = wxPayFrom.getTradeType();
 | 
	
		
			
				|  |  | +        //查询订单是否支付
 | 
	
		
			
				|  |  | +        int enable = 0;
 | 
	
		
			
				|  |  | +        if(1==enable){
 | 
	
		
			
				|  |  | +            throw new RuntimeException("订单已支付");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
 | 
	
		
			
				|  |  | +        //随机字符串
 | 
	
		
			
				|  |  | +        String s = UUIDUtils.randomUUID();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        orderRequest.setNonceStr(s);
 | 
	
		
			
				|  |  | +        //商品描述
 | 
	
		
			
				|  |  | +        orderRequest.setBody("碳汇扶贫!");
 | 
	
		
			
				|  |  | +        //商户订单号(支付编号)
 | 
	
		
			
				|  |  | +        GeneratorIdUtils generatorIdUtils = new GeneratorIdUtils();
 | 
	
		
			
				|  |  | +        String orderNum = generatorIdUtils.nextId();
 | 
	
		
			
				|  |  | +        log.info("orderNum:" + orderNum);
 | 
	
		
			
				|  |  | +        //设置商户订单号
 | 
	
		
			
				|  |  | +        orderRequest.setOutTradeNo(orderNum);
 | 
	
		
			
				|  |  | +        //设置支付id
 | 
	
		
			
				|  |  | +        //设置金额
 | 
	
		
			
				|  |  | +        //data.getTotalPrice();
 | 
	
		
			
				|  |  | +        BigDecimal money = new BigDecimal("0.1");
 | 
	
		
			
				|  |  | +        //元转成分
 | 
	
		
			
				|  |  | +        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.APP);
 | 
	
		
			
				|  |  | +        //用户标识 获取用户openid
 | 
	
		
			
				|  |  | +        orderRequest.setOpenid(openid);
 | 
	
		
			
				|  |  | +        // 这个可能是偏向原生一点的统一下单,返回的参数有很多没用的 或者null值 建议使用 createOrder下单
 | 
	
		
			
				|  |  | +        Object unOrder = null;
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            unOrder = wxPayService.createOrder(orderRequest);
 | 
	
		
			
				|  |  | +        } catch (WxPayException e) {
 | 
	
		
			
				|  |  | +            //e.printStackTrace();
 | 
	
		
			
				|  |  | +            log.error(e.getMessage());
 | 
	
		
			
				|  |  | +            //签名完成新增支付订单
 | 
	
		
			
				|  |  | +            return CommonResult.failed("微信支付失败");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //更新本地订单支付id
 | 
	
		
			
				|  |  | +        //orderClient.update(data);
 | 
	
		
			
				|  |  | +        //签名完成新增支付订单
 | 
	
		
			
				|  |  | +        return CommonResult.failed("微信支付成功");
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * wx支付成功回调接口
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param request
 | 
	
		
			
				|  |  | +     * @param response
 | 
	
		
			
				|  |  | +     * @throws IOException
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    @RequestMapping("payResult")
 | 
	
		
			
				|  |  | +    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);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//            Order order=new Order();
 | 
	
		
			
				|  |  | +//            order.setTransId(orderNum);
 | 
	
		
			
				|  |  | +//            //将订单更新为支付
 | 
	
		
			
				|  |  | +//            orderClient.payment(order);
 | 
	
		
			
				|  |  | +            /**
 | 
	
		
			
				|  |  | +             * 自己的业务
 | 
	
		
			
				|  |  | +             */
 | 
	
		
			
				|  |  | +            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;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |