微信支付返回签名接口

4 篇文章 0 订阅

在这里插入图片描述

pom文件

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

controller.java

package com.youruan.education.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.github.wxpay.sdk.WXPayUtil;
import com.youruan.education.util.HttpRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping("/pay")
public class SendPay {

    private Logger logger = Logger.getLogger("SendPay.java");

    @Value("${pay.wxpay.appId}")
    public String APPID;    //平台ID
    @Value("${pay.wxpay.appSecret}")
    public String APPSECRET;   //平台密钥
    @Value("${pay.wxpay.mchID}")
    public String MCHID;   //商家ID
    @Value("${pay.wxpay.paternerKEY}")
    public String PATERNERKEY; //商家密钥

    /**
     * @Description 微信浏览器内微信支付/公众号支付(JSAPI)
     * @param request
     * @return Map
     */
    @RequestMapping(value = "orders")
    public @ResponseBody Map<String, String> orders(String openId,String money,HttpServletRequest request, HttpServletResponse response) {
        try {

            logger.info("进入支付接口了");
            logger.info("openId=="+openId+"====money=="+money);

            // 拼接统一下单地址参数
            Map<String, String> paraMap = new HashMap<String, String>();
            // 获取请求ip地址
            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.getRemoteAddr();
            }
            if (ip.indexOf(",") != -1) {
                String[] ips = ip.split(",");
                ip = ips[0].trim();
            }

            paraMap.put("appid", APPID); // 商家平台ID
            paraMap.put("body", "纯情小店铺-薯条"); // 商家名称-销售商品类目、String(128)
            paraMap.put("mch_id", MCHID); // 商户ID
            paraMap.put("nonce_str", WXPayUtil.generateNonceStr()); // UUID
            paraMap.put("openid", openId);
            paraMap.put("out_trade_no", UUID.randomUUID().toString().replaceAll("-", ""));// 订单号,每次都不同
            paraMap.put("spbill_create_ip", ip);
            paraMap.put("total_fee", money); // 支付金额,单位分
            paraMap.put("trade_type", "JSAPI"); // 支付类型
            paraMap.put("notify_url", "用户支付完成后,你想微信调你的哪个接口");// 此路径是微信服务器调用支付结果通知路径随意写
            String sign = WXPayUtil.generateSignature(paraMap, PATERNERKEY);
            paraMap.put("sign", sign);
            String xml = WXPayUtil.mapToXml(paraMap);// 将所有参数(map)转xml格式

            // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
            String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

            System.out.println("xml为:" + xml);

            // String xmlStr = HttpRequest.sendPost(unifiedorder_url,
            // xml);//发送post请求"统一下单接口"返回预支付id:prepay_id

            String xmlStr = HttpRequest.httpsRequest(unifiedorder_url, "POST", xml);

            System.out.println("xmlStr为:" + xmlStr);

            // 以下内容是返回前端页面的json数据
            String prepay_id = "";// 预支付id
            if (xmlStr.indexOf("SUCCESS") != -1) {
                Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
                prepay_id = (String) map.get("prepay_id");
            }

            Map<String, String> payMap = new HashMap<String, String>();
            payMap.put("appId", APPID);
            payMap.put("timeStamp", new Timestamp(System.currentTimeMillis()) + "");
            payMap.put("nonceStr", WXPayUtil.generateNonceStr());
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id=" + prepay_id);
            String paySign = WXPayUtil.generateSignature(payMap, PATERNERKEY);
            payMap.put("paySign", paySign);
            //将这个6个参数传给前端
            return payMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Title: callBack
     * @Description: 支付完成的回调函数
     * @param:
     * @return:
     */
    @RequestMapping("/notify")
    public String callBack(HttpServletRequest request, HttpServletResponse response) {
        // System.out.println("微信支付成功,微信发送的callback信息,请注意修改订单信息");
        InputStream is = null;
        try {

            is = request.getInputStream();// 获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)
            String xml = InputStream2String(is);
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);// 将微信发的xml转map

            System.out.println("微信返回给回调函数的信息为:"+xml);

            if (notifyMap.get("result_code").equals("SUCCESS")) {
                String ordersSn = notifyMap.get("out_trade_no");// 商户订单号
                String amountpaid = notifyMap.get("total_fee");// 实际支付的订单金额:单位 分
                BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal("100"))).setScale(2);// 将分转换成元-实际支付金额:元

				/*
				 * 以下是自己的业务处理------仅做参考 更新order对应字段/已支付金额/状态码
				 */
                System.out.println("===notify===回调方法已经被调!!!");

            }

            // 告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可
            response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    public static String InputStream2String(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = is.read(buffer)) != -1) {
            baos.write(buffer, 0, len);
        }
        baos.close();
        is.close();

        byte[] lens = baos.toByteArray();
        String result = new String(lens,"UTF-8");//内容乱码处理

        return result;

    }

}



微信支付工具类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.github.wxpay.sdk;

import com.github.wxpay.sdk.WXPayConstants.SignType;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class WXPayUtil {
    public WXPayUtil() {
    }

    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        Map<String, String> data = new HashMap();
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
        Document doc = documentBuilder.parse(stream);
        doc.getDocumentElement().normalize();
        NodeList nodeList = doc.getDocumentElement().getChildNodes();

        for(int idx = 0; idx < nodeList.getLength(); ++idx) {
            Node node = nodeList.item(idx);
            if (node.getNodeType() == 1) {
                Element element = (Element)node;
                data.put(element.getNodeName(), element.getTextContent());
            }
        }

        try {
            stream.close();
        } catch (Exception var10) {
            ;
        }

        return data;
    }

    public static String mapToXml(Map<String, String> data) throws Exception {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.newDocument();
        Element root = document.createElement("xml");
        document.appendChild(root);
        Iterator var5 = data.keySet().iterator();

        while(var5.hasNext()) {
            String key = (String)var5.next();
            String value = (String)data.get(key);
            if (value == null) {
                value = "";
            }

            value = value.trim();
            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("encoding", "UTF-8");
        transformer.setOutputProperty("indent", "yes");
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        transformer.transform(source, result);
        String output = writer.getBuffer().toString();

        try {
            writer.close();
        } catch (Exception var12) {
            ;
        }

        return output;
    }

    public static String generateSignedXml(Map<String, String> data, String key) throws Exception {
        return generateSignedXml(data, key, SignType.MD5);
    }

    public static String generateSignedXml(Map<String, String> data, String key, SignType signType) throws Exception {
        String sign = generateSignature(data, key, signType);
        data.put("sign", sign);
        return mapToXml(data);
    }

    public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
        Map<String, String> data = xmlToMap(xmlStr);
        if (!data.containsKey("sign")) {
            return false;
        } else {
            String sign = (String)data.get("sign");
            return generateSignature(data, key).equals(sign);
        }
    }

    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
        return isSignatureValid(data, key, SignType.MD5);
    }

    public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception {
        if (!data.containsKey("sign")) {
            return false;
        } else {
            String sign = (String)data.get("sign");
            return generateSignature(data, key, signType).equals(sign);
        }
    }

    public static String generateSignature(Map<String, String> data, String key) throws Exception {
        return generateSignature(data, key, SignType.MD5);
    }

    public static String generateSignature(Map<String, String> data, String key, SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = (String[])keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        String[] var6 = keyArray;
        int var7 = keyArray.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            String k = var6[var8];
            if (!k.equals("sign") && ((String)data.get(k)).trim().length() > 0) {
                sb.append(k).append("=").append(((String)data.get(k)).trim()).append("&");
            }
        }

        sb.append("key=").append(key);
        if (SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        } else if (SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        } else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }

    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }

    public static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        byte[] var4 = array;
        int var5 = array.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            byte item = var4[var6];
            sb.append(Integer.toHexString(item & 255 | 256).substring(1, 3));
        }

        return sb.toString().toUpperCase();
    }

    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();
        byte[] var6 = array;
        int var7 = array.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            byte item = var6[var8];
            sb.append(Integer.toHexString(item & 255 | 256).substring(1, 3));
        }

        return sb.toString().toUpperCase();
    }
}

接口文档:

在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Java中实现H5微信支付,可以使用微信官方提供的支付API,具体步骤如下: 1. 注册微信支付服务号,并开通支付功能。 2. 在Java中调用微信支付API,生成预支付订单,获取预支付订单号。 3. 根据预支付订单号生成支付链接,返回给前端。 4. 前端通过支付链接跳转至微信支付页面进行支付。 以下是Java代码示例: 1. 生成预支付订单: ```java public String createPrepayOrder(String body, String outTradeNo, int totalFee, String spbillCreateIp, String notifyUrl) throws Exception { // 构造请求参数 SortedMap<String, String> params = new TreeMap<>(); params.put("appid", "微信公众号appid"); params.put("mch_id", "商户号"); params.put("nonce_str", WXPayUtil.generateNonceStr()); params.put("body", body); params.put("out_trade_no", outTradeNo); params.put("total_fee", totalFee + ""); params.put("spbill_create_ip", spbillCreateIp); params.put("notify_url", notifyUrl); params.put("trade_type", "MWEB"); String sign = WXPayUtil.generateSignature(params, "商户密钥"); params.put("sign", sign); String xml = WXPayUtil.mapToXml(params); String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String result = HttpUtil.postXml(url, xml); Map<String, String> resultMap = WXPayUtil.xmlToMap(result); return resultMap.get("prepay_id"); } ``` 2. 生成支付链接: ```java public String createPayUrl(String prepayId) throws Exception { SortedMap<String, String> params = new TreeMap<>(); params.put("prepay_id", prepayId); params.put("mweb_url", "微信支付回调地址"); params.put("nonce_str", WXPayUtil.generateNonceStr()); params.put("timestamp", System.currentTimeMillis() / 1000 + ""); params.put("sign_type", "MD5"); String sign = WXPayUtil.generateSignature(params, "商户密钥"); params.put("sign", sign); String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String param = WXPayUtil.mapToXml(params); String result = HttpUtil.postXml(url, param); Map<String, String> resultMap = WXPayUtil.xmlToMap(result); return resultMap.get("mweb_url"); } ``` 以上是Java实现H5微信支付的基本步骤,需要注意的是,生成预支付订单和生成支付链接时,需要按照微信官方文档提供的参数规则进行构造,才能正确生成订单和支付链接。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值