微信JSAPI支付签名算法(附通用代码)

签名算法

签名生成的通用步骤如下:

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

◆ key设置路径:微信商户平台(pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置

举例:

假设传送的参数如下:

appid: wxd930ea5d5a258f4f

mch_id: 10000100

device_info: 1000

body: test

nonce_str: ibuaiVcKdpRxkhJA

第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:

stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";

第二步:拼接API密钥:

stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d"  # 注:key为商户平台设置的密钥key

sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7"  # 注:MD5签名方式

最终得到最终发送的数据:

<xml>

<appid>wxd930ea5d5a258f4f</appid>

<mch_id>10000100</mch_id>

<device_info>1000</device_info>

<body>test</body>

<nonce_str>ibuaiVcKdpRxkhJA</nonce_str>

<sign>9A0A8659F005D6984697E2CA0A9CF3B7</sign>

</xml>

贴上我的通用代码:

不管是验证调用返回或微信主动通知签名时,只要将所有发送或者接收到的数据传入函数(当然接收到的签名(sign)不能传入),即可得到签名.同时当微信接口可能增加字段时,完美支持增加的扩展字段.

from hashlib import md5, sha1
def get_sign(kwargs, sign_type='MD5', pay_sign_key=None, is_upper=True):
    """
    微信签名参数组装
    @param: kwargs  参与签名的参数  dict类型
    @param: sign_type 签名类型
    @param: pay_sign_key 是否需要支付密钥
    @return: sign, sign_type
    """
    # 根据ascii码进行排序
    params = list(kwargs.items())
    params.sort()
    # url拼接
    string = "&".join(["%s=%s" % (str(p[0]), str(p[1])) for p in params])
    if pay_sign_key:
        string += "&key=%s" % pay_sign_key

    string = bytes(string, "UTF-8")
    # 生成签名 Point: 这里签名时间戳,必须与wxconfig中得时间戳一致
    sign = ""
    if sign_type == "MD5":
        sign = md5(string).hexdigest().upper() if is_upper else md5(string).hexdigest()
    if sign_type == "SHA1":
        sign = sha1(string).hexdigest().upper() if is_upper else sha1(string).hexdigest()
    # sign为签名,sign_type为签名类型
    return sign, sign_type
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是Java SpringBoot发起微信JSAPI支付使用V2密钥的代码示例: 1. 首先,在SpringBoot的配置文件中添加微信支付的相关配置信息: ```yaml wxpay: app-id: YOUR_APP_ID mch-id: YOUR_MCH_ID v2-key: YOUR_V2_KEY notify-url: YOUR_NOTIFY_URL ``` 2. 然后,在SpringBoot中定义微信支付的服务类: ```java @Service public class WxPayService { @Autowired private WxPayProperties wxPayProperties; public Map<String, String> createOrder(String openid, String outTradeNo, int totalFee, String body, String ipAddress) throws Exception { // 构造请求参数 Map<String, String> data = new HashMap<>(); data.put("appid", wxPayProperties.getAppId()); data.put("mch_id", wxPayProperties.getMchId()); data.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", "")); data.put("body", body); data.put("out_trade_no", outTradeNo); data.put("total_fee", String.valueOf(totalFee)); data.put("spbill_create_ip", ipAddress); data.put("notify_url", wxPayProperties.getNotifyUrl()); data.put("trade_type", "JSAPI"); data.put("openid", openid); // 生成签名 String sign = WxPayUtil.generateSignature(data, wxPayProperties.getV2Key()); data.put("sign", sign); // 发起统一下单请求 String unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String result = HttpUtil.post(unifiedOrderUrl, WxPayUtil.toXml(data)); Map<String, String> resultMap = WxPayUtil.xmlToMap(result); // 判断下单是否成功 if ("SUCCESS".equals(resultMap.get("return_code")) && "SUCCESS".equals(resultMap.get("result_code"))) { // 构造JSAPI支付参数 Map<String, String> payData = new HashMap<>(); payData.put("appId", wxPayProperties.getAppId()); payData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); payData.put("nonceStr", UUID.randomUUID().toString().replaceAll("-", "")); payData.put("package", "prepay_id=" + resultMap.get("prepay_id")); payData.put("signType", "MD5"); // 生成签名 String paySign = WxPayUtil.generateSignature(payData, wxPayProperties.getV2Key()); payData.put("paySign", paySign); return payData; } else { throw new Exception(resultMap.get("return_msg")); } } } ``` 3. 最后,在Controller层调用微信支付服务类: ```java @RestController @RequestMapping("/wxpay") public class WxPayController { @Autowired private WxPayService wxPayService; @PostMapping("/createOrder") public Map<String, String> createOrder(@RequestParam String openid, @RequestParam String outTradeNo, @RequestParam int totalFee, @RequestParam String body, HttpServletRequest request) throws Exception { String ipAddress = HttpUtil.getIpAddress(request); return wxPayService.createOrder(openid, outTradeNo, totalFee, body, ipAddress); } } ``` 其中,HttpUtil是一个工具类,用于发送HTTP请求。WxPayUtil是一个微信支付的工具类,用于生成签名、XML转换等操作。以上代码示例中,仅提供了微信支付的主要逻辑。具体实现中,还需要根据实际情况,添加异常处理、日志记录等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值