springboot微信支付

先用图理一下我的代码思路:
在这里插入图片描述
代码如下:

1,引入依赖

<dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.50</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.1.0</version>
        </dependency>

2,WXPayConfig类

// 设置具体参数实现微信接口
import com.github.wxpay.sdk.WXPayConfig;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class WXConfigUtil implements WXPayConfig {
    private byte[] certData;

    public static final String APP_ID = "xx";

    public static final String KEY = "xx";

    public static final String MCH_ID = "xx";

    public WXConfigUtil() throws Exception {
//        String certPath = ClassUtils.getDefaultClassLoader().getResource("").getPath()+"/weixin/apiclient_cert.p12";//从微信商户平台下载的安全证书存放的路径
        String certPath = "/var/www/service/weixin/apiclient_cert.p12";//从微信商户平台下载的安全证书存放的路径
        File file = new File(certPath);
        InputStream certStream = new FileInputStream(file);
        this.certData = new byte[(int) file.length()];
        certStream.read(this.certData);
        certStream.close();
    }

    @Override
    public String getAppID() {
        return APP_ID;
    }

    //parnerid,商户号
    @Override
    public String getMchID() {
        return MCH_ID;
    }

    @Override
    public String getKey() {
        return KEY;
    }

    @Override
    public InputStream getCertStream() {
        ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

    @Override
    public int getHttpConnectTimeoutMs() {
        return 8000;
    }

    @Override
    public int getHttpReadTimeoutMs() {
        return 10000;
    }
}


3,WXminiConfig类

/**
 * @author linan
 */
public class WXminiConfig {
    /**
     * 微信appId
     */
    public static final String WECHAT_APPID = "xx";

    /**
     * 微信商户号
     */
    public static final String WECHAT_MACH_ID = "xx";

    /**
     * key
     */
    public static final String WECHAT_key = "xx";

    /**
     * 支付类型,小程序用:JSAPI
     */
    public static final String tradeType = "JSAPI";

    /**
     * 回掉地址
     */
    public static final String NOTIFYURL = "https://xx:8082/user/weixin/notify";

    /**
     * 统一下单地址
     */
    public static final String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    /**
     * 微信小程序密钥
     */
    public static final String WECHAT_APP_SECRET = "xx";
}

4,WeChatPayUtil工具类

import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.common.collect.Maps;
import com.smxy.config.WXminiConfig;
import com.smxy.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

import static com.github.wxpay.sdk.WXPayUtil.*;
import static com.smxy.util.HttpUtils.getCurrentTimestamp;


@Slf4j
@Component
public class WeChatPayUtil {

    public Map<String, String> getPrePayInfo(HttpServletRequest request, Order order, String openId) throws Exception {
        Map<String, String> map = Maps.newHashMap();
        map.put("appid", WXminiConfig.WECHAT_APPID);
        map.put("mch_id", WXminiConfig.WECHAT_MACH_ID);
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        map.put("body", "xx");
        map.put("out_trade_no", order.getTrade());
        map.put("total_fee", Integer.parseInt(order.getPrice())*100+"");
        map.put("spbill_create_ip", request.getRemoteAddr());
        map.put("trade_type", WXminiConfig.tradeType);
        map.put("notify_url", WXminiConfig.NOTIFYURL);
        map.put("openid", openId);
        String unifiedorderUrl = WXminiConfig.UNIFIED_ORDER_URL; // 微信统一下单URL
        String sign = WXPayUtil.generateSignature(map, WXminiConfig.WECHAT_key, WXPayConstants.SignType.MD5);
//        String sign = generateSignature(map, WXminiConfig.WECHAT_key);// 生成签名 PAY_API_SECRET=微信支付相关API调用时使用的秘钥
        map.put("sign", sign);  // 参数配置 我直接写成"sign"
//        System.out.println(WXminiConfig.WECHAT_key);
//        map.put("sign", WXPayUtil.generateSignature(map, WXminiConfig.WECHAT_key,
//                WXPayConstants.SignType.MD5));
        //请求微信统一下单接口
        String xml = mapToXml(map);
        String xmlStr = HttpUtils.httpRequest(unifiedorderUrl, "POST",xml);

        Map map1 = HttpUtils.doXMLParse(xmlStr);
        String return_code = (String) map1.get("return_code");//返回状态码
        String result_code = (String) map1.get("result_code");//返回状态码
        String err_code = (String) map1.get("err_code");//返回状态码
        String err_code_des = (String) map1.get("err_code_des");//返回状态码
        log.info(xmlStr);
        if (return_code.equals("SUCCESS") || return_code.equals(result_code)) {
            // 业务结果
            String prepay_id = (String) map1.get("prepay_id");//返回的预付单信息
            Map<String, String> payMap = new HashMap<>();
            payMap.put("appId", WXminiConfig.WECHAT_APPID);  // 参数配置
            payMap.put("timeStamp", getCurrentTimestamp() + "");  //时间
            payMap.put("nonceStr", generateNonceStr());  // 获取随机字符串
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id=" + prepay_id);
            String paySign = generateSignature(payMap, WXminiConfig.WECHAT_key); //第二次生成签名
            payMap.put("paySign", paySign);
            payMap.put("prepayId", prepay_id);
            return payMap;   //返回给前端,让前端去调支付 ,完成后你去调支付查询接口,看支付结果,处理业务。
        } else {
            System.out.println("下单失败");
            return null;
            //打印失败日志
        }


    }

    /**
     * 获取当前机器的ip
     *
     * @return String
     */
    public static String getLocalIp() {
        InetAddress ia = null;
        String localip = null;
        try {
            ia = InetAddress.getLocalHost();
            localip = ia.getHostAddress();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return localip;

    }
}

5,WechatUtil工具类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.smxy.config.WXminiConfig;
import org.apache.shiro.codec.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


public class WechatUtil {
    public static JSONObject getSessionKeyOrOpenId(String code) {
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, String> requestUrlParam = new HashMap<>();
        // https://mp.weixin.qq.com/wxopen/devprofile?action=get_profile&token=164113089&lang=zh_CN
        //小程序appId
        requestUrlParam.put("appid", WXminiConfig.WECHAT_APPID);
        //小程序secret
        requestUrlParam.put("secret", WXminiConfig.WECHAT_APP_SECRET);
        //小程序端返回的code
        requestUrlParam.put("js_code", code);
        //默认参数
        requestUrlParam.put("grant_type", "authorization_code");
        //发送post请求读取调用微信接口获取openid用户唯一标识
        JSONObject jsonObject = JSON.parseObject(HttpClientUtil.doPost(requestUrl, requestUrlParam));
        return jsonObject;
    }

    public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv) {
        // 被加密的数据
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decode(sessionKey);
        // 偏移量
        byte[] ivByte = Base64.decode(iv);
        try {
            // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSON.parseObject(result);
            }
        } catch (Exception e) {
        }
        return null;
    }
}

6,HttpClientUtil

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {

    public static String doGet(String url, Map<String, String> param) {

        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);

            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doGet(String url) {
        return doGet(url, null);
    }

    public static String doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }

    public static String doPost(String url) {
        return doPost(url, null);
    }

    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }
}

7,HttpUtils

import com.github.wxpay.sdk.WXPayConstants;
import lombok.extern.slf4j.Slf4j;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.util.*;

import static com.github.wxpay.sdk.WXPayUtil.MD5;

/**
 * @Created by Wu Chenxuan
 * @Description
 */
@Slf4j
public class HttpUtils {
    private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private static final Random RANDOM = new SecureRandom();

    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }


    /**
     * 生成签名
     *
     * @param data 待签名数据
     * @param key  API密钥
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key) throws Exception {
        return generateSignature(data, key, WXPayConstants.SignType.MD5);  //MD5是常量 不想写常量可以直接写成"MD5"
    }

    /**
     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
     *
     * @param data     待签名数据
     * @param key      API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {   // FIELD_SIGN = sign
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
            {
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
            }
        }
        sb.append("key=").append(key);
        if (WXPayConstants.SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        } else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {  //HMACSHA256常量 可以直接写成 "HMACSHA256"
            return HMACSHA256(sb.toString(), key);
        } else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }

    /**
     * 生成 HMACSHA256
     *
     * @param data 待处理数据
     * @param key  密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }


    /**
     * 将Map转换为XML格式的字符串
     *
     * @param data Map类型数据
     * @return XML格式的字符串
     * @throws Exception
     */
    public static String mapToXml(Map<String, String> data) throws Exception {
     /*   org.w3c.dom.Document document = WXPayXmlUtil.newDocument();
        org.w3c.dom.Element root = document.createElement("xml");
        document.appendChild(root);
        for (String key: data.keySet()) {
            String value = data.get(key);
            if (value == null) {
                value = "";
            }
            value = value.trim();
            org.w3c.dom.Element filed = document.createElement(key);
            filed.appendChild(document.createTextNode(value));
            root.appendChild(filed);
        }*/
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        // DOMSource source = new DOMSource(document);
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        //  transformer.transform(source, result);
        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
        try {
            writer.close();
        } catch (Exception ex) {
        }
        return output;
    }

    /**
     * 发送https post请求。
     *
     * @param requestUrl 请求的url(https://xxx.com)
     * @param postData   post传输的数据。
     * @return 请求成功返回请求内容,请求失败直接返回null。
     */
    public static String httpsPost(String requestUrl, String postData) {
        return httpsRequest2(requestUrl, "POST", postData);
    }


    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     *
     * @param strxml
     * @return
     * @throws
     * @throws IOException
     */
    public static Map doXMLParse(String strxml) throws Exception {
        if (null == strxml || "".equals(strxml)) {
            return null;
        }

        Map m = new HashMap();
        InputStream in = String2Inputstream(strxml);
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }

            m.put(k, v);
        }

        //关闭流
        in.close();

        return m;
    }

    public static InputStream String2Inputstream(String str) {
        return new ByteArrayInputStream(str.getBytes());
    }

    /**
     * 获取子结点的xml
     *
     * @param children
     * @return String
     */
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if (!children.isEmpty()) {
            Iterator it = children.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if (!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }

        return sb.toString();
    }


    public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
        // 创建SSLContext
        StringBuffer buffer = null;
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(requestMethod);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.connect();
            //往服务器端写内容
            if (null != outputStr) {
                OutputStream os = conn.getOutputStream();
                os.write(outputStr.getBytes("utf-8"));
                os.close();
            }
            // 读取服务器端返回的内容
            InputStream is = conn.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            BufferedReader br = new BufferedReader(isr);
            buffer = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }


    /**
     * 发送https请求,请求成功返回请求内容,请求失败直接返回空串。
     *
     * @param requestUrl 请求的url(https://xxx.com)
     * @param method     请求方法,一般有GET和POST方法。
     * @param outputStr  请求时附带的数据。
     * @return 请求成功返回请求内容,请求失败直接返回null。
     */
    public static String httpsRequest2(String requestUrl, String method, String outputStr) {
        HttpsURLConnection conn = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = null;
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);

            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            conn.setRequestMethod(method);

            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                conn.setDoOutput(true);
                outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 从输入流读取返回内容
            inputStream = conn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            return buffer.toString();
        } catch (ConnectException ce) {
            log.error("连接超时:{}", ce);
        } catch (Exception e) {
            log.error("https请求异常:{}", e);
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (IOException e) {
                log.warn(e.getLocalizedMessage(), e);
            }
        }

        return null;
    }


    /**
     * 获取当前时间戳,单位秒
     *
     * @return
     */
    public static long getCurrentTimestamp() {
        return System.currentTimeMillis() / 1000;
    }


}

8,Impl实现类

@Override
    public Map miniAppPay(HttpServletRequest request, String trade, String openId) throws Exception {
        Order order = orderMapper.getOrderByTrade(trade);
        WeChatPayUtil weChatPayUtil = new WeChatPayUtil();
        Map<String, String> prePayInfo = null;
        try {
            prePayInfo = weChatPayUtil.getPrePayInfo(request, order, openId);
            return prePayInfo;
        } catch (Exception e){
            e.printStackTrace();
            throw  new Exception("生成支付预订单时失败");
        }

    }

9,Controller类使用

@PostMapping("/weixin/miniAppPay")
    @ApiOperation("微信小程序支付")
    public Map miniAppPay(HttpServletRequest request, @RequestParam String trade, @RequestParam String code){
        JSONObject sessionKeyOrOpenId = WechatUtil.getSessionKeyOrOpenId(code);
        String openid = sessionKeyOrOpenId.getString("openid");
        Map map = null;
        try {
            map = userService.miniAppPay(request, trade, openid);
        } catch (Exception e) {
            System.out.println(e);
        }
        return map;
    }
@PostMapping("/weixin/notify")
    public String wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        String notityXml = sb.toString();
        String xmlBack = "";
        Map<String, String> resultMap = WXPayUtil.xmlToMap(notityXml);
        String returnCode = (String) resultMap.get("return_code");//业务结果
        String orderNo = resultMap.get("out_trade_no");//订单号
        String sign = resultMap.get("sign");//获取微信签名
        resultMap.remove("sign");//去除签名字段
        String signNew = WXPayUtil.generateSignature(resultMap, WXminiConfig.WECHAT_key); //重新签名
        if (signNew.equals(sign)) {
            if ("SUCCESS".equals(returnCode)) {
                if (orderNo != null) {
                    Order order = orderMapper.getOrderByTrade(orderNo);
                    order.setStatus(1);
                    int i = orderMapper.UpdateOrder(order);
                    if (order.getSuperior() != null && !order.getSuperior().equals(" ")){
                        int commission = Integer.parseInt(order.getCommission());
                        commission = commission * order.getNumber();
                        User user = userMapper.getUserByUsername(order.getSuperior());
                        user.setAccount(Integer.parseInt(user.getAccount()) + commission + "").setInviteNumber(user.getInviteNumber()+1);
                        userService.updateUser(user);
                    }
                    String username = order.getUsername();
                    User user1 = userMapper.getUserByUsername(username);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    if (user1.getIsVip() == 0){
                        user1.setIsVip(1);
                        Calendar nowTime = Calendar.getInstance();
                        nowTime.setTime(new Date());
                        String endTime = "";
                        if (order.getVipLevel() == 1) {
                            nowTime.add(Calendar.MONTH, order.getNumber());
                            endTime = sdf.format(nowTime.getTime());
                        } else if(order.getVipLevel() == 2) {
                            nowTime.add(Calendar.DAY_OF_YEAR, order.getNumber()*7);
                            endTime = sdf.format(nowTime.getTime());
                            user1.setIsFirst(1);
                        } else {
                            nowTime.add(Calendar.YEAR, order.getNumber());
                            endTime = sdf.format(nowTime.getTime());
                        }
                        user1.setTime(endTime);
                        user1.setLevel( order.getVipLevel() );

                    }else {
                        String endTime1 = user1.getTime();
                        Date date = sdf.parse(endTime1);
                        Calendar endTime = Calendar.getInstance();
                        endTime.setTime(date);
                        if (order.getVipLevel() == 1) {
                            endTime.add(Calendar.MONTH, order.getNumber());
                        } else if(order.getVipLevel() == 2) {
                            endTime.add(Calendar.DAY_OF_YEAR, order.getNumber());
                        } else {
                            endTime.add(Calendar.YEAR, order.getNumber());
                        }
                        user1.setTime(sdf.format(endTime.getTime()));
                    }
                    userMapper.updateUser(user1);
                    if (i > 0) {
                        System.err.println("微信手机支付回调成功订单号:{}");
                        System.err.println(orderNo);
                        xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    } else {
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }
                } else {
                    System.err.println("微信手机支付回调失败订单号:{}");
                    System.err.println(orderNo);
                    xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                }
            } else {
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[交易失败]]></return_msg>" + "</xml> ";
            }
        } else {
            System.err.println("手机支付回调通知签名错误");
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
SpringBoot是一个开源的Java应用程序框架,用于快速构建独立的、基于生产级别的Java应用程序。它提供了许多功能和工具,可以简化开发过程并提高开发效率。而H5微信支付是指在移动端网页上使用微信支付的一种方式。下面是使用SpringBoot来实现H5微信支付的步骤: 1. 准备工作:首先,您需要拥有微信公众号或小程序账号,并开通支付功能。您还需要有自己的服务器,以接收微信支付的通知。同时,确保您已经使用了Java SpringBoot框架。 2. 配置微信支付参数:在SpringBoot项目的配置文件中,添加微信支付所需的配置参数,包括AppID、商户号、支付密钥等。这些参数可以在微信开放平台上获取。 3. 引入相关依赖:在项目的构建文件中,添加微信支付相关的依赖项,如微信支付SDK或其他相关库。这些依赖项将帮助您在代码中调用微信支付接口。 4. 创建统一下单接口:使用SpringBoot框架创建一个用于接收支付请求的接口。在该接口中,您需要获取用户的支付信息,并调用微信支付统一下单接口生成预支付订单。 5. 处理支付结果通知:创建一个用于接收微信支付结果通知的接口。在该接口中,您需要验证支付结果的合法性,并处理相应的业务逻辑。 6. 前端页面开发:在前端页面中添加微信支付的相关逻辑,包括调用微信支付接口、展示支付结果等。 总结起来,要使用SpringBoot来实现H5微信支付,您需要进行准备工作,配置微信支付参数,引入相关依赖,创建统一下单接口,处理支付结果通知,以及在前端页面中添加支付逻辑。这样就可以实现使用SpringBoot进行H5微信支付了。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I'm 程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值