1、导入maven依赖

<dependency>
   <groupId>com.github.wxpay</groupId>
   <artifactId>wxpay-sdk</artifactId>
   <version>0.0.3</version>
</dependency>

2、调用官方SDK获取预支付订单等参数(注意生签名的参数顺序不能乱,如果生成的签名对但是报签名错误可以把密钥全改为大写试试。

public Result unifiedOrder(Map<String,Object> param, HttpServletRequest request) {

        Map<String, String> returnMap = new HashMap<>();
        Map<String, String> responseMap = new HashMap<>();
        Map<String, String> data = new HashMap<>();
        String orderNo = param.get("orderNo").toString();
        try {
                //支付参数
                WXPay wxpay = new WXPay(wxPayAppConfig);
                data.put("appid", wxPayAppConfig.getAppID());
                data.put("body", "订单支付");
                data.put("mch_id", wxPayAppConfig.getMchID());
                data.put("notify_url", wxPayAppConfig.getPayNotifyUrl());//异步通知地址(请注意必须是外网)
                data.put("out_trade_no", orderNo);
                data.put("spbill_create_ip", getIpAddress(request)); //自己的服务器IP地址
                Double amount = Double.parseDouble(param.get("amount").toString());
                data.put("total_fee", String.valueOf((int) (amount * 100)));
                data.put("trade_type", "APP");//交易类型
                String s = WXPayUtil.generateSignature(data, wxPayAppConfig.getKey());  //签名
                data.put("sign", s);//签名
                //使用官方API请求预付订单
                Map<String, String> resultMap = wxpay.unifiedOrder(data);
                //获取返回码
                String returnCode = resultMap.get("return_code");
                //若返回码为SUCCESS,则会返回一个result_code,再对该result_code进行判断
                if ("SUCCESS".equals(returnCode)) {
                    String resultCode = resultMap.get("result_code");
                    if ("SUCCESS".equals(resultCode)) {
                        responseMap = resultMap;
                    }
                }
                if (responseMap == null || responseMap.isEmpty()) {
                    return ResultUtil.error("获取预支付交易会话标识失败");
                }
                // 3、签名生成算法
                Long time = System.currentTimeMillis() / 1000;
                String timestamp = time.toString();
                returnMap.put("appid", wxPayAppConfig.getAppID());
                returnMap.put("partnerid", wxPayAppConfig.getMchID());
                returnMap.put("prepayid", responseMap.get("prepay_id"));
                returnMap.put("noncestr", responseMap.get("nonce_str"));
                returnMap.put("timestamp", timestamp);
                returnMap.put("package", "Sign=WXPay");
                returnMap.put("sign", WXPayUtil.generateSignature(returnMap, wxPayAppConfig.getKey()));//微信支付签名
            
                return ResultUtil.success(returnMap);
        } catch (Exception e) {
            logger.error("订单号:{},错误信息:{}", orderNo, e.getStackTrace());
            return ResultUtil.error("微信支付统一下单失败");
        }
    }

3、回调(注:如果回调成功就不会再次回调,否则会进行多次回调)

@RequestMapping(value = "/notify")
    @ResponseBody
    public String payNotify(HttpServletRequest request, HttpServletResponse response) {

        InputStream is = null;
        String xmlBack = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
        try {
            is = request.getInputStream();
            // 将InputStream转换成String
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            xmlBack = wxPayService.payBack(sb.toString());
            // 告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可
            response.getWriter().write(xmlBack);
        } catch (Exception e) {
            logger.error("微信手机支付回调通知失败:", e);
        }
        finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
	/**
     * @param notifyData 异步通知后的XML数据
     * @return
     */
    public String payBack(String notifyData) {
        WXPay wxpay = new WXPay(wxPayAppConfig);
        String xmlBack = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
        Map<String, String> notifyMap = new HashMap<>();
        try {
            notifyMap = WXPayUtil.xmlToMap(notifyData);         // 调用官方SDK转换成map类型数据
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//验证签名是否有效,有效则进一步处理

                String return_code = notifyMap.get("return_code");//状态
                String out_trade_no = notifyMap.get("out_trade_no");//商户订单号
                String total_fee = notifyMap.get("total_fee");//订单总金额,单位为分
                if (return_code.equals("SUCCESS")) {
                    //业务代码
                }
                return xmlBack;
            } else {
                // 签名错误,如果数据里没有sign字段,也认为是签名错误
                //失败的数据要不要存储?
                logger.error("手机支付回调通知签名错误");
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return xmlBack;
            }
        } catch (Exception e) {
            logger.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }

其他配置信息 

#微信APP支付参数
#wxpayconfig:
#商户应用appId
wxpayconfig.appid= 
#商户ID
wxpayconfig.mchid= 
#商户key:api秘钥(32位)
wxpayconfig.key= 
#回调接口
wxpayconfig.payNotifyUrl=
/**
 * 获取服务器IP工具类
 */

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();
        }
        return ip;
    }
/**
 * 微信参数配置
 */
package com.test.service.pay;
import com.github.wxpay.sdk.WXPayConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.InputStream;

@Component
@ConfigurationProperties(prefix = "wxpayconfig")
public class WxPayAppConfig implements WXPayConfig {
    /**
     * appID
     */
    private String appID;

    /**
     * 商户号
     */
    private String mchID;

    /**
     * API 密钥
     */
    private String key;

    /**
     * API证书绝对路径 (本项目放在了 resources/cert/wxpay/apiclient_cert.p12")
     */
    private String certPath;

    /**
     * HTTP(S) 连接超时时间,单位毫秒
     */
    private int httpConnectTimeoutMs = 8000;

    /**
     * HTTP(S) 读数据超时时间,单位毫秒
     */
    private int httpReadTimeoutMs = 10000;

    /**
     * 微信支付异步通知地址
     */
    private String payNotifyUrl;

    /**
     * 微信退款异步通知地址
     */
    private String refundNotifyUrl;

    /**
     * 获取商户证书内容(这里证书需要到微信商户平台进行下载)
     *
     * @return 商户证书内容
     */
    @Override
    public InputStream getCertStream() {
        InputStream certStream  =getClass().getClassLoader().getResourceAsStream(certPath);
        return certStream;
    }

    public String getAppID() {
        return appID;
    }

    public void setAppID(String appID) {
        this.appID = appID;
    }

    public String getMchID() {
        return mchID;
    }

    public void setMchID(String mchID) {
        this.mchID = mchID;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getCertPath() {
        return certPath;
    }

    public void setCertPath(String certPath) {
        this.certPath = certPath;
    }

    public int getHttpConnectTimeoutMs() {
        return httpConnectTimeoutMs;
    }

    public void setHttpConnectTimeoutMs(int httpConnectTimeoutMs) {
        this.httpConnectTimeoutMs = httpConnectTimeoutMs;
    }

    public int getHttpReadTimeoutMs() {
        return httpReadTimeoutMs;
    }

    public void setHttpReadTimeoutMs(int httpReadTimeoutMs) {
        this.httpReadTimeoutMs = httpReadTimeoutMs;
    }

    public String getPayNotifyUrl() {
        return payNotifyUrl;
    }

    public void setPayNotifyUrl(String payNotifyUrl) {
        this.payNotifyUrl = payNotifyUrl;
    }

    public String getRefundNotifyUrl() {
        return refundNotifyUrl;
    }

    public void setRefundNotifyUrl(String refundNotifyUrl) {
        this.refundNotifyUrl = refundNotifyUrl;
    }

}