微信企業支付開發文檔:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
企業付款業務是基於微信支付商戶平台的資金管理能力,為了協助商戶方便地實現企業向個人付款,針對部分有開發能力的商戶,提供通過API完成企業付款的功能。
比如目前的保險行業向客戶退保、給付、理賠。
企業付款將使用商戶的可用余額,需確保可用余額充足。查看可用余額、充值、提現請登錄商戶平台“資金管理”進行操作。
下面是微信企業付款接口THINKPHP控制器,
C('WX_APPID'),C('WX_MCHID'),C('WX_KEYC') 這三項我已事先寫在配置文件中了
<?php /** * 微信企業付款接口 */ namespace Admin\Controller; use Think\Controller; class CompayController extends Controller { protected $payurl = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //這里的路徑很重要 一定要寫相對路徑 protected $cacab = array( 'api_cert'=>'weixin/cert/apiclient_cert.pem', 'api_key'=>'weixin/cert/apiclient_key.pem', 'api_ca'=>'weixin/cert/rootca.pem', ); //$data 要傳遞的參數, $wxchat微信企業支付等信息 /** $data 格式如下 * $data = array( 'userid' //申請退款者ID 'openid' //退款者openid 'refundid' //退款申請ID 'money' //退款金額 'desc' //退款描述 ); * */ public function wxbuild($data, $wxchat){ //判斷有沒有CA證書及支付信息 if(empty($wxchat['api_cert']) || empty($wxchat['api_key']) || empty($wxchat['api_ca']) || empty($wxchat['appid']) || empty($wxchat['mchid'])){ $wxchat['appid'] = C('WX_APPID'); //appid $wxchat['mchid'] = C('WX_MCHID'); //商戶號 $wxchat['api_cert'] = $this->cacab['api_cert']; $wxchat['api_key'] = $this->cacab['api_key']; $wxchat['api_ca'] = $this->cacab['api_ca']; } $webdata = array( 'mch_appid' => $wxchat['appid'], 'mchid' => $wxchat['mchid'], 'nonce_str' => md5(time()), //'device_info' => '1000', 'partner_trade_no' => $data['bpno'], //商戶訂單號,需要唯一 'openid' => $data['openid'], 'check_name'=> 'NO_CHECK', //OPTION_CHECK不強制校驗真實姓名, FORCE_CHECK:強制 NO_CHECK: //'re_user_name' => 'jorsh', //收款人用戶姓名 'amount' => $data['money'] * 100, //付款金額單位為分 'desc' => empty($data['desc'])? '微信提現' : $data['desc'], 'spbill_create_ip' => $this->getip(), ); $sig = $this->makeSign($webdata); foreach ($webdata as $k => $v) { $tarr[] =$k.'='.$v; } sort($tarr); $sign = implode($tarr, '&'); $sign .= '&key='.C('WX_KEYC'); //支付密鑰 //$webdata['sign']=strtoupper(md5($sign)); $webdata['sign']= $sig; $wget = $this->array2xml($webdata); $content = $this->curl_post_ssl($this->payurl, $wget, $wxchat); if(!$content){ return array('status'=>1, 'msg'=>"Can't connect the server" ); } return $this->xmlToArray($content); } public function getip() { static $ip = ''; $ip = $_SERVER['REMOTE_ADDR']; if(isset($_SERVER['HTTP_CDN_SRC_IP'])) { $ip = $_SERVER['HTTP_CDN_SRC_IP']; } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) { foreach ($matches[0] AS $xip) { if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) { $ip = $xip; break; } } } return $ip; } /** * 將一個數組轉換為 XML 結構的字符串 * @param array $arr 要轉換的數組 * @param int $level 節點層級, 1 為 Root. * @return string XML 結構的字符串 */ public function array2xml($arr, $level = 1) { $s = $level == 1 ? "<xml>" : ''; foreach($arr as $tagname => $value) { if (is_numeric($tagname)) { $tagname = $value['TagName']; unset($value['TagName']); } if(!is_array($value)) { $s .= "<{$tagname}>".(!is_numeric($value) ? '<![CDATA[' : '').$value.(!is_numeric($value) ? ']]>' : '')."</{$tagname}>"; } else { $s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>"; } } $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s); return $level == 1 ? $s."</xml>" : $s; } /** * 微信支付發起請求 */ protected function curl_post_ssl($url, $xmldata,$wxchat, $second=30,$aHeader=array()){ $ch = curl_init(); //超時時間 curl_setopt($ch,CURLOPT_TIMEOUT,$second); curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); //這里設置代理,如果有的話 //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98'); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,0); curl_setopt($ch, CURLOPT_SSLVERSION, 1); //默認格式為PEM,可以注釋 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT,$wxchat['api_cert']); //默認格式為PEM,可以注釋 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY,$wxchat['api_key']); //curl_setopt($ch,CURLOPT_CAINFO,$config['rootca']); if( count($aHeader) >= 1 ){ curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader); } curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); $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; } } //將XML轉為array public function xmlToArray($xml) { //禁止引用外部xml實體 libxml_disable_entity_loader(true); $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $values; } /** * 生成簽名 * @return 簽名,本函數不覆蓋sign成員變量 */ public function makeSign($data){ //獲取微信支付秘鑰 vendor('WxPayPubHelper.WxPayJsApiPay'); $key = \WxPayConfig::KEY; // 去空 $data=array_filter($data); //簽名步驟一:按字典序排序參數 ksort($data); $string_a=http_build_query($data); $string_a=urldecode($string_a); //簽名步驟二:在string后加入KEY //$config=$this->config; $string_sign_temp=$string_a."&key=".$key; //簽名步驟三:MD5加密 $sign = md5($string_sign_temp); // 簽名步驟四:所有字符轉為大寫 $result=strtoupper($sign); return $result; } //企業付款測試 public function test(){ $bpid = session('dpid'); //通過bpid查詢提現信息 $balance = M('balance')->where('bpid ='.$bpid)->find(); //通過用戶ID獲取OPENID $openid = M('userinfo')->where('uid ='.$balance['uid'])->getField('openid'); $username = M('userinfo')->where('uid ='.$balance['uid'])->getField('username'); $data = array( 'userid' => $balance['uid'], //用戶ID 做更新狀態使用 'openid' => $openid, //收錢的人微信 OPENID 'refundid' => $balance['bpid'], //提現申請IDbpno 'bpno' => $balance['bpno'], //提現申請ID 'money' => $balance['dzprice'], //金額 'desc' => '微信提現', ); //var_dump($data);die; $res = $this->wxbuild($data); if ($res['result_code'] == "SUCCESS") { //微信提現成功 $time = date("Y-m-d H:i:s"); $cltime = time(); M('balance')->where('bpid='.$bpid)->setField(array('isverified'=>'1','remarks'=>$time." 微信提現成功!",'cltime'=>$cltime));//1是同意 session('bpid',NULL); $this->ajaxReturn("success"); }else{ $this->ajaxReturn("error"); } } }