微信支付生成sign签名(MD5格式) 校验sign

本文深入探讨了微信支付中签名算法的实现与验证过程,详细解释了如何通过MD5算法生成签名,以及如何校验微信返回的数据签名一致性,确保交易的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



import com.aui.stock.controller.mini.config.WxSPConfig;
import com.aui.stock.util.wx.xml.XmlUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 *      * 签名算法
 *      * 
 *      * @param o 要参与签名的数据对象
 *      * @return 签名
 *      * @throws IllegalAccessException
 *      
 */
public class Signature {

    private static Logger logger = LoggerFactory.getLogger(Signature.class);

    /**
     * 检验微信返回的数据并校验签名是否一致
     *
     * @param xmlResponse
     * @return Boolean
     */
    public static Boolean validateResponseXmlToMap(String xmlResponse) {
        Boolean  flag=false;
        if (StringUtils.isEmpty(xmlResponse)) {
            throw new RuntimeException("传入请求微信支付返回的数据为空");
        }
        // 处理微信返回的数据进行验证
        Map<String, String> xmlToMap = XmlUtil.xmlToMap(xmlResponse);
        logger.info("请求微信支付,返回的数据转换成Map" + xmlToMap);
        // 1.判断返回值是否成功 return_code 此值返回成功并不代表成功
        String return_code = xmlToMap.get("return_code");
        String return_msg = xmlToMap.get("return_msg");
        logger.info("微信支付,返回的通信标识" + return_code);
        logger.info("微信支付,返回的信息" + return_msg);
        if (StringUtils.isNotEmpty(return_code) && return_code.equals("SUCCESS")) {
            // 需要判断此值
            String result_code = xmlToMap.get("result_code");
            logger.info("微信支付,返回的成功标识" + result_code);
            if (StringUtils.isNotEmpty(result_code) && result_code.equals("SUCCESS")) {
                // 校验返回的sign是否一致
                validateSign(xmlToMap, WxSPConfig.MCH_KEY);
                flag=true;
                return flag;
            }
        }
        return flag;
    }

    /**
     * 校验微信支付的sign
     *
     * @param parameterMap
     * @param key          void
     */
    public static boolean validateSign(Map<String, String> parameterMap, String key) {
        String sign = parameterMap.get("sign");
        logger.info("微信支付,传入的sign进行校验" + sign);
        if (StringUtils.isEmpty(sign)) {
            logger.info("微信支付,sign参数为空!");
            return false;
        }
        String md5Hex = getSign(parameterMap, key);
        if (!md5Hex.equals(sign.toUpperCase())) {
            logger.info("微信支付,签名错误");
            return false;
        }
        return true;
    }



    /**
     * 获取sign值
     *
     * @param parameterMap
     * @param key
     * @return String
     */
    public static String getSign(Map<String, String> parameterMap, String key) {
        // 将Map转换为TreeMap
        Set<Map.Entry<String, String>> parameterMapSet = parameterMap.entrySet();
        Iterator<Map.Entry<String, String>> hashMapIterator = parameterMapSet.iterator();

        Map<String, String> treeMap = new TreeMap<String, String>();
        while (hashMapIterator.hasNext()) {
            Map.Entry<String, String> param = hashMapIterator.next();
            if (!"sign".equals(param.getKey())) {
                treeMap.put(param.getKey(), param.getValue());
            }
        }
        // 拼接字符串
        StringBuffer sb = new StringBuffer();
        Set<Map.Entry<String, String>> treeMapSet = treeMap.entrySet();
        Iterator<Map.Entry<String, String>> treeMapIterator = treeMapSet.iterator();
        while (treeMapIterator.hasNext()) {
            Map.Entry<String, String> param = treeMapIterator.next();
            // 校验空值
            if (StringUtils.isEmpty(param.getValue())) {
                if (treeMapIterator.hasNext()) {
                } else {
                    sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                }
                continue;
            }
            sb.append(param.getKey());
            sb.append("=");
            sb.append(param.getValue());
            if (treeMapIterator.hasNext()) {
                sb.append("&");
            }
        }
        if (StringUtils.isEmpty(sb.toString())) {
            throw new RuntimeException("传入的参数为空");
        }
        // 拼接key
        sb.append("&key=").append(key);
        logger.info("微信支付,检验的拼接的字符串=" + sb.toString());
        String md5Hex = DigestUtils.md5Hex(sb.toString()).toUpperCase();
        return md5Hex;
    }


}

 

在PHP中使用微信支付V3生成签名的过程需要以下几个步骤: 1. **初始化配置**: 首先,确保你已经有了商户号、AppID、商户密钥(SecretKey)以及开放平台API证书(如需)。 2. **构建请求数据**: 创建一个包含交易相关的字段数组,例如: - `nonce_str`: 非对称加密随机字符串 - `timestamp`: 当前时间戳 - `package`: 支付请求的统一封装,如`prepay_id` 或 `jsapi_ticket` - `sign_type`: 签名类型,通常为`MD5` 或 `SHA256` - 其他根据支付场景所需的字段(如商品信息、用户信息等) 3. **设置数组排序**: 得到的请求参数需要按照指定的键字典序进行排序,保证每次请求参数的一致性。 4. **拼接字符串**: 将排序后的参数以"&"连接,并移除所有空值键值对。 5. **签名计算**: 使用商户密钥对上述拼接后的字符串进行哈希处理,生成签名。如果是MD5签名,使用`md5($string . "&key=" . $secretKey)`;如果是SHA256签名,可以使用`sha256($string . "&key=" . $secretKey)`。 6. **签名结果验证**: 在发送至微信服务器之前,将生成签名和原始请求数据一起发送,微信校验其真实性。 ```php // 示例代码片段 $param = [ 'appid' => 'your_appid', // ... 其他参数 'nonce_str' => uniqid(), // ... 排序并拼接参数 ]; ksort($param); $string_to_sign = ''; foreach ($param as $k => $v) { if (!empty($v)) { $string_to_sign .= $k . '=' . $v . '&'; } } // 移除最后一个 & $string_to_sign = rtrim($string_to_sign, '&'); $signature = hash('sha256', $string_to_sign . "&key={$your_secret_key}"); // 发送请求之前,将签名放入请求体或头部 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值