前提声明
该功能已经不可开通,以往已开通的商户不受影响 否则报错如下 <err_code_des><![CDATA[你的商户号未开通该产品权限,请联系管理员到产品中心开通。开通路径:产品中心-产品大全-企业微信 -向员工付款-申请开通]]></err_code_des>
大概流程如下
验证签名是否正确 (https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1) 这里的api密钥用的是 APIv2 密钥,记得不要申请错了,不然会报错,提示签名错误 http 请求的是 xml,返回的也是 xml
源码(访问 paywwsptrans2pocket )
import time
import xml
from hashlib import md5
from xml.dom.minidom import parseString
import xml.etree.ElementTree as ET
import requests
import randomdef payForEmployee(xml_data, cert_path, key_path):url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/paywwsptrans2pocket"resp = requests.post(url=url, data=xml_data.encode(encoding="utf-8"), cert=(cert_path, key_path))print(resp.text)def getNonceStr():data = "123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP"nonce_str = ''.join(random.sample(data, 30))return nonce_strdef dict_to_xml(d):root = ET.Element("xml")for key, value in d.items():child = ET.Element(key)child.text = str(value)root.append(child)xml_str = ET.tostring(root, encoding='utf-8').decode()dom = xml.dom.minidom.parseString(xml_str)xml_str_formatted = dom.toprettyxml(indent=" ")xml_lines = xml_str_formatted.split("\n")xml_lines = [line for line in xml_lines if not line.strip().startswith("<?xml")]xml_str_formatted = "\n".join(xml_lines)return xml_str_formatteddef getWxSign(data_dict, api_secret, sign_type="微信支付"):""":param data_dict: {"appid": ''}:param api_secret: "xxxx":param sign_type: 微信支付 | 企业微信 :return:"""data_dict = {k: data_dict[k] for k in sorted(data_dict)}data = "&".join([f"{key}={value}" for key, value in data_dict.items()])data += "&key=" + api_secret.strip()m = md5()m.update(data.encode())result = m.hexdigest().upper()print(data_dict)print(dict_to_xml(data_dict))print("sign ======= %s" % result, data)if sign_type == "微信支付":data_dict.update({"sign": result})data_dict = {k: data_dict[k] for k in sorted(data_dict)}return dict_to_xml(data_dict)else:return resultif __name__ == '__main__':appid = 'wx095123456748f4c' # 服务号 小程序 企业微信 mchid = '1612345294' # 商户号openid = 'ocsgO5WTmiVuV_vAlv1234TeXETc' # 选定appid 下的openid, 同一用户在不同的appid下的openid 不同# ●通过该命令得到 `openssl x509 -in apiclient_cert.pem -noout -serial`serial_no = '40B5F411111121222162B39AD54A29C' # 从证书得到的证书编号api_key = 'za21231112312aaa22600b3255' # 商户密钥 keymethod = "POST"spbill_create_ip = "11.1.1.1"timestamp = str(int(time.time()))nonce_str = getNonceStr()amount = 100desc = "测试企业付款"partner_trade_no = time.strftime("%Y%m%d%H%M%S000000") + str(int(random.uniform(1000, 9999))) + "1"ww_msg_type = "NORMAL_MSG"act_name = "产品部门报销"cert_path = "apiclient_cert.pem" # 证书公钥key_path = "apiclient_key.pem" # 证书私钥# 加密企业微信 算法workwx_sign = getWxSign({"appid": appid, "mch_id": mchid, "nonce_str": nonce_str,"partner_trade_no": partner_trade_no, "openid": openid, "amount": amount, "desc": desc,"ww_msg_type": ww_msg_type,}, api_secret=api_key, sign_type="企业微信 ")print(workwx_sign)wx_sign = getWxSign({"appid": appid, "mch_id": mchid, "nonce_str": nonce_str,"partner_trade_no": partner_trade_no, "openid": openid,"check_name": "NO_CHECK", "amount": amount, "desc": desc,"spbill_create_ip": spbill_create_ip, "ww_msg_type": ww_msg_type, "workwx_sign": workwx_sign,"act_name": act_name}, api_secret=api_key)print("wx_sign", wx_sign)payForEmployee(wx_sign, cert_path, key_path)