php 微信支付企业付款
1.所需参数
| 字段名 | 变量名 | 必填 | 示例值 | 类型 | 描述 | |
|---|---|---|---|---|---|---|
| 公众账号appid | mch_appid | 是 | wx8888888888888888 | String | 公众号的appId | |
| 商户号 | mchid | 是 | 1900000109 | String(32) | 微信支付平台商户号 就是平台账号 |
|
| 随机字符串 | nonce_str | 是 | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | String(32) | 随机字符串,随便随机个什么<32位 | |
| 商户订单号 | partner_trade_no | 是 | 10000098201411111234567890 | String | 订单号,保持唯一性,自定义一个随机订单号 | |
| 用户 openid |
openid | 是 | oxTWIuGaIt6gTKsQRLau2M0yL16E | String | 商户appid下,某用户的openid | |
| 校验用户姓名选项 | check_name | 是 | NO_CHECK 不检验 (小额推荐) FORCE_CHEC 强制检验 OPTION_CHECK 自动检验 |
String | NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功) |
|
| 收款用户姓名 | re_user_name | 可选 | 马花花 (如果上一个参数为强制检验此为必填项) |
String | 收款用户真实姓名。 如果check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名 |
|
| 金额 | amount | 是 | 100 单位为分 100就是100分. |
int | 企业付款金额,单位为分 | |
| 企业付款描述信息 | desc | 是 | 奖金啊,提现成功啊 退款成功啊什么的 |
String | 企业付款操作说明信息。必填。 | |
| Ip地址 | spbill_create_ip | 是 | 192.168.0.1 | String(32) | 调用接口的机器Ip地址服务器ip | |
|
支付密钥
|
key
|
是
|
F5YguNW77Ao4N5yu5wZ8Lb00NKO987ks
|
String(32)
|
设置在商户平台上的支付密钥 | |
|
签名
|
sign
|
|
C380BEC2BFD727A4B6845133519F3AD6
|
String(32)
|
上面的内容的一个综合的加密结果
|
2.还需要支付时使用的证书
3.签名的规则
意思就是将上述的除了支付秘钥和签名的9-10项(因为收款用户姓名是根据验证选项而决定是否需要的)
按照ASCII的从小到大排序之后的字符串
例如:$str = "amount=100&check_name=NO_CHECK&desc=奖金啊,提现成功啊 退款成功啊什么的&mch_appid=wx8888888888888888&mchid=1900000109&nonce_str=5K8264ILTKCH16CQ2502SI8ZNMTM67VS&openid=oxTWIuGaIt6gTKsQRLau2M0yL16E&partner_trade_no=10000098201411111234567890&spbill_create_ip=192.168.0.1";
- 签名是不是一直变动的呢?是的 每一个签名都是不一样的,别想着存起来一直用!怎么算呢?官方有一个文档,对于会的人来说就是废话,对于不会的来说就是天书。总的来说分为3部,官方有一个签名生成工具https://pay.weixin.qq.com/wiki/tools/signverify/。
- 将你本次请求的所有参数(当然除了签名),按照一定的顺序排序成一个字符串,顺序一会再说,先说格式,比如本次的这次请求有9个参数:
$str = "amount=100&check_name=NO_CHECK&desc=奖金啊,提现成功啊 退款成功啊什么的&mch_appid=wx8888888888888888&mchid=1900000109&nonce_str=5K8264ILTKCH16CQ2502SI8ZNMTM67VS&openid=oxTWIuGaIt6gTKsQRLau2M0yL16E&partner_trade_no=10000098201411111234567890&spbill_create_ip=192.168.0.1";
仔细观察不难发现,字符串排列是有顺序的 为键值首字母的排列顺序。而官方为了听起来霸气,讲的是根据 参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式排序吓的我一哆嗦啊! 不就字母顺序表么!不过仔细一看发现不对了,比如 mchid和 mch_appid这尼玛前三个字母一样啊,一位一位排序下来出现一个 i 和 _怎么办呢? 这时候就用到ASCII码表了,不过看官也不用去查了 上面的可以直接粘去用了 而ASCII码表的顺序呢就是按照0123456789:;< = > ? @ ABCDEFGHIJKLMNOPQRSTUVWXYZ [ \ ] ^ _ ` abcdefghijklmnopqrstuvwxyz { | }~的顺序排列 那么我门就知道mch_appid应该在 mchid 前面了。
- 排序完这9个参数 之后再用&加上特殊参数 微信支付平台上设置的支付密钥就是
$str = "amount=100&check_name=NO_CHECK&desc=奖金啊,提现成功啊 退款成功啊什么的&mch_appid=wx8888888888888888&mchid=1900000109&nonce_str=5K8264ILTKCH16CQ2502SI8ZNMTM67VS&openid=oxTWIuGaIt6gTKsQRLau2M0yL16E&partner_trade_no=10000098201411111234567890&spbill_create_ip=192.168.0.1&key=F5YguNW77Ao4N5yu5wZ8Lb00NKO987ks"
- 之后就简单了先md5加密下然后转为大写 签名就OK了
$sign = strtoupper(md5($str));
然后我们就要将这些参数填充到xml格式的字符串中去了
4.开始撸码吧
/**
* 格式化参数格式化成url参数
*/
public function ToUrl($arr)
{
$buff = "";
foreach ($arr as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
//将乱序的数组
public function ToSign($arr,$key)
{
//签名步骤一:按字典序排序参数
ksort($arr);
$string = ToUrl($arr);
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$key;
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
// $result1 = strtoupper($string);
return $string;
}
/**
* 输出xml字符
* @throws WxPayException
**/
public static function ToXml($arr)
{
if(!is_array($arr) || count($arr) <= 0)
{
echo '数据异常';
}
$xml = "<xml>";
foreach ($arr as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
/**
* zll 生成唯一订单号
*/
public function order_sn(){
$str = "qyfk".uniqid();
return $str;
}
/**
* zll 将信息提交到微信服务器,发起企业付款
*/
public function qyzf_post($url,$xml,$config,$second=30){
$ch = curl_init();
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
// curl_setopt($ch,CURLOPT_SSLCERT,"/home/lizi/addons/grow/template/mobile/cash/apiclient_cert.pem");
// curl_setopt($ch,CURLOPT_SSLKEY,"/home/lizi/addons/grow/template/mobile/cash/apiclient_key.pem");
$str = 'D:/www/';//证书必须使用绝对路径,否则报错,错误貌似是52什么的
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT,$str.trim($config['apiclient_cert'],'.'));
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,$str.trim($config['apiclient_key'],'.'));
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
$data = curl_exec($ch);
if($data){
curl_close($ch);
return $data;
}else{
$error = curl_errno($ch);
echo "call faild, errorCode:$error\n";
curl_close($ch);
return false;
}
}
/**
* zll 企业付款
*/
public function qiyezhifu($data){
//解释amount为付款金额,单位分,貌似最低1元,desc为付款的描述(必填),ip就是服务器ip必填
//$data = array('wxappid'=>14,'openid'=>'oRyzq0LrtuqKqQdH-FubBqcMuTi8-','amount'=>100,'desc'=>'提现奖励','ip'=>'123.207.19.254'); //获取数据库的支付配置信息
$config = get_pay_conf($data['wxappid']);
if($config){
//对必备参数进行有效性判断
if(empty($config['appid']) || empty($config['shh']) || empty($config['partnerkey']) || empty($data['amount']) || empty($config['apiclient_cert']) || empty($config['apiclient_key'])){
throw new Exception("支付配置中的appid或商户号或支付秘钥不能为空,或支付金额不能为空");
}else{
$da['mch_appid'] = $config['appid']; //appid
$da['mchid'] = $config['shh']; //商户号
$da['nonce_str'] = $this->getStr(32); //随机字符串
$da['partner_trade_no'] = $this->order_sn(); //订单号,保持唯一性即可
$da['openid'] = $data['openid']; //粉丝的openid
$da['check_name'] = "NO_CHECK"; //NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
//$da['re_user_name'] = ""; //收款用户真实姓名。 如果check_name设置为FORCE_CHECK或OPTION_CHECK,则必填用户真实姓名
$da['amount'] = $data['amount']; //付款金额,单位分
$da['desc'] = $data['desc'] ? $data['desc']:"提现奖励"; //企业付款描述信息
$da['spbill_create_ip'] = $data['ip'] ? $data['ip'] : "123.207.19.254"; //服务器ip
$da['sign'] = $this->ToSign($da, $config['partnerkey']);//生成签名
//$da['key'] = $config['partnerkey']; //支付秘钥 //将数组转为xml
$xml = $this->ToXml($da);
$url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
$this->qyzf_post($url,$xml,$config);
}
}else{
return false;
}
}
上面的代码我是在thinkphp3.2框架里面写的,所以方法之间的调用用的是$this->XXX();
其他的框架或原生的php可以进行修改方法调用方式即可
php 微信支付企业付款的更多相关文章
- 微信分账功能与微信支付企业付款相关内容详解(payjs版)
PAYJS开通微信分账功能以来,有很多同学咨询相关情况.很多同学关心有没有什么办法,可以让自己的商户号快速开通企业付款功能.这里就介绍下微信分账的具体相关内容,可以完美解决问题. 一.什么是微信分账? ...
- JAVA微信支付——企业付款(企业向微信用户个人付款、转账)
本地开发环境支付回调调试方法可以参考:https://www.cnblogs.com/pxblog/p/11623053.html 需要自行引入相关依赖 官方文档地址:https://pay.weix ...
- php微信支付企业付款到零钱报错call faild, errorCode:58
这个报错一般是自己证书目录不是绝对目录,正确的目录结构应该是网站根目录下的:“C:\PHPWAMP_IN1\wwwroot\XXXX\XXXX.pem”. 还要注意的是文件夹命名一定 ...
- PHP微信商户支付 - 企业付款到零钱功能(即提现)技术资料汇总
PHP实现微信开发中提现功能(企业付款到用户零钱) 一.实现该功能目的 这几天在小程序里要实现用户从系统中提现到零钱的功能,查了一下文档可以使用 企业付款到用户零钱 来实现: 官方文档:https:/ ...
- PHP实现微信商户支付企业付款到零钱功能代码实例
本文为大家分享了PHP实现微信商户支付企业付款到零钱的具体代码,供大家参考,具体内容如下 微信支付开发文档 一.开通条件 企业付款为企业提供付款至用户零钱的能力,支持通过API接口付款,或通过微信支付 ...
- PHP微信商户支付企业付款到零钱功能
一 开通条件,就是首先要在微信平台设置好. 以下微信文档里有的,我这里大概掠几项比较重要的. 付款资金 企业付款到零钱资金使用商户号余额资金. 根据商户号的账户开通情况,实际出款账户有做区别: ◆ 默 ...
- PHP实现微信企业付款到个人零钱步骤
微信支付企业付款到零钱功能应用广泛,比如微信红包奖励,业务结算等.通过企业向个人付款,付款资金将直接进入用户微信零钱. 一 开通条件 付款资金 企业付款到零钱资金使用商户号余额资金. 根据商户号的 ...
- 为产品接入微信支付解决方案(公司&个人)
微信支付个人及公司的区别 H5支付:主要实现的效果是在非微信内网页中点击支付,拉起微信APP内的微信支付进行付款. APP支付:主要实现的效果是在APP内部点击支付,拉起微信APP内的微信支付进行付款 ...
- 微信支付之扫码支付、公众号支付、H5支付、小程序支付相关业务流程分析总结
前言 很久以来,一直想写一篇微信支付有关的总结文档:一方面是总结自己的一些心得,另一方面也可以帮助别人,但是因种种原因未能完全理解透彻微信支付的几大支付方式,今天有幸做一些总结上的文章,也趁此机会,将 ...
随机推荐
- Webservice银行报文接口设计
Preface: 合理的软件架构设计其好处是不言而喻的,系统具有清晰的软件结构,良好的可扩展性,类的职能单一明确,系统的复杂度底.此前的一个实际项目中总结了些关于OO设计的实际应用,主要是围绕'高 ...
- elasticsearch java 客户端之action简介
上一篇介绍了elasticsearch的client结构,client只是一个门面,在每个方法后面都有一个action来承接相应的功能.但是action也并非是真正的功能实现者,它只是一个代理,它的真 ...
- 使用缓存Memcache存储更新微信access token
关键字:Memcache access_token 更新 存储 7200 本文介绍如何使用缓存Memcache存储及更新 access token的方法. 一.Access Token access_ ...
- Android 用Socket实现PC和手机的文件传输
PC服务器端代码: /* * PC与<a href="http://lib.csdn.net/base/android" class='replace_word' title ...
- HDU 2281 Square Number Pell方程
http://acm.hdu.edu.cn/showproblem.php?pid=2281 又是一道Pell方程 化简构造以后的Pell方程为 求出其前15个解,但这些解不一定满足等式,判断后只有5 ...
- LAN8720A网络模块的使用问题
一.LAN8720A模块驱动电路 最近在调试STM32F4驱动LAN8720A网络模块,在做方案前参考是正点原子的LAN8720A的驱动电路方案,但是从网上买回来的LAN8720A模块用正点原子的例程 ...
- 洛谷 P2655 2038年问题
P2655 2038年问题 题目描述 网络时代,机会与危机共存.“千年虫”解决之后,会不会有新的“虫”出现?回答是肯定的,“2038年”就是一个新的关卡. 也许大家都已经知道计算机的2000年问题是什 ...
- [Javascript AST] 3. Continue: Write ESLint rule
The rule we want to write is show warning if user using console method: // valid foo.console() conso ...
- js数组遍历和对象遍历小结
数组的遍历 for循环 for(var j = 0,len = arr.length; j < len; j++){ console.log(arr[j]); } forEach,性能比for还 ...
- web前端背景介绍
Internet:是一个全球性的计算机互联网络,中文名称“因特网”.“国际互联网”.“网际网”等等: Internet提供的服务:http.ftp.Telnet.email.www.bbs等等: 基本 ...