微信企業付款到我的

提早說一個重要的坑,不注意掉進去,會浪費一些時間。
php

  1. 用戶付款到商戶平臺的帳戶 與 商戶付款到我的的帳戶是相互獨立的 意思是商戶要付款到我的必須用本身充值到商戶平臺帳戶的錢
  2. 企業付款到我的必須開通此功能 以後纔可使用
  3. 須要到商戶平臺下載支付證書 在使用時不要用官方的demo(2014年的 不怕死的用起來),在引用時直接把文件存放在服務器上的絕對路徑寫到函數裏(相對於服務器的絕對路徑)
  4. 在算簽名的時候注意 ASCII的順序  大寫字母 < _ < 小寫字母 (噁心的我夠嗆)
  5. 支付金額必須大於100 單位分

直接上代碼 提現類 並無作驗證明現了功能 代碼後面有詳細的流程介紹!!
算法

<?php
/*
微信企業 支付到我的
*/
class cash
{

/**
     *  array轉xml
     */
public function arrayToXml($arr)
{
  $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; } //使用證書,以post方式提交xml到對應的接口url /** * 做用:使用證書,以post方式提交xml到對應的接口url */ function curl_post_ssl($url, $vars, $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");   curl_setopt($ch,CURLOPT_POST, 1);   curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);   $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;   }
}
//企業向我的付款 public function payToUser($openid='oJZJ0w_N_LlTo4AHLnN-cGGtJSeM',$desc='提現成功',$amount='102') {   //微信付款到我的的接口   $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';   $params["mch_appid"] = ''; //公衆帳號appid   $params["mchid"] = ''; //商戶號 微信支付平臺帳號   $params["nonce_str"] = 'longdongzhiye99'.mt_rand(100,999); //隨機字符串   $params["partner_trade_no"] = mt_rand(10000000,99999999); //商戶訂單號   $params["amount"] = $amount; //金額   $params["desc"] = $desc; //企業付款描述   $params["openid"] = $openid; //用戶openid   $params["check_name"] = 'NO_CHECK'; //不檢驗用戶姓名   $params['spbill_create_ip'] = '123.56.48.18'; //獲取IP //生成簽名(簽名算法後面詳細介紹)   $str = 'amount='.$params["amount"].'&check_name='.$params["check_name"].'&desc='.$params["desc"].'&mch_appid='.$params["mch_appid"].'&mchid='.$params["mchid"].'&nonce_str='.$params["nonce_str"].'&openid='.$params["openid"].'&partner_trade_no='.$params["partner_trade_no"].'&spbill_create_ip='.$params['spbill_create_ip'].'&key=F5YguNW77Ao4N5yu5wZ8Lb00NKOg1Y04';   //md5加密 轉換成大寫   $sign = strtoupper(md5($str));   $params["sign"] = $sign;//簽名   $xml = $this->arrayToXml($params);   return $this->curl_post_ssl($url, $xml); } } /* $cash = new cash; $res = $cash -> payToUser(); var_dump($res); */

 

  1. 要支付必須先配置服務號與微信商戶平臺,這裏略。
  2. 登錄商戶平臺開通企業付款到我的
  3. 若是要實現自動付款
  4. 首先肯定一個方向 就是這是微信的一個接口 帶着參數post請求就行了
    1. $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //請求接口
    2. 參數(這個玩意能夠慢慢說了)
  5. 參數包含兩個部分 字符串部分 和 證書部分,到這時候你就不要想着跟別的接口似得馬馬虎虎拼拼就出來了,這個過程要慢慢來
            字符串部分須要 9個常規參數 + 1個簽名+1個支付密鑰,先說9個參數
字段名 變量名 必填 示例值 類型 描述
公衆帳號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)
這個噁心了
下面單獨解釋
  1. 簽名是否是一直變更的呢?是的 每個簽名都是不同的,別想着存起來一直用!怎麼算呢?官方有一個文檔,對於會的人來講就是廢話,對於不會的來講就是天書。總的來講分爲3部,官方有一個簽名生成工具https://pay.weixin.qq.com/wiki/tools/signverify/

    1. 將你本次請求的全部參數(固然除了簽名),按照必定的順序排序成一個字符串,順序一會再說,先說格式,好比本次的此次請求有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 前面了。
    2. 排序完這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"
    3. 以後就簡單了先md5加密下而後轉爲大寫 簽名就OK了

      $sign = strtoupper(md5($str));
           

        而後咱們就要將這些參數填充到xml格式的字符串中去了api

官方示例爲數組

<xml>

<mch_appid>wxe062425f740c30d8</mch_appid>

<mchid>10000098</mchid>

<nonce_str>3PG2J4ILTKCH16CQ2502SI8ZNMTM67VS</nonce_str>

<partner_trade_no>100000982014120919616</partner_trade_no>

<openid>ohO4Gt7wVPxIT1A9GjFaMYMiZY1s</openid>

<check_name>OPTION_CHECK</check_name>

<re_user_name>張三</re_user_name>

<amount>100</amount>

<desc>節日快樂!</desc>

<spbill_create_ip>10.2.3.10</spbill_create_ip>

<sign>C97BDBACF37622775366F38B629F45E3</sign>

</xml>

 

我我的仍是覺的將參數都存到數組裏,而後遍歷拼接出來比較好例如:

服務器

$params["mch_appid"]        = '';   //公衆帳號appid
$params["mchid"]            = '';   //商戶號 微信支付平臺帳號
$params["nonce_str"]        = 'longdongzhiye99'.mt_rand(100,999);   //隨機字符串
$params["partner_trade_no"] = mt_rand(10000000,99999999);           //商戶訂單號
$params["amount"]           = $amount;          //金額
$params["desc"]             = $desc;            //企業付款描述
$params["openid"]           = $openid;          //用戶openid
$params["check_name"]       = 'NO_CHECK';       //不檢驗用戶姓名
$params['spbill_create_ip'] = '123.56.48.18';   //獲取IP

//生成簽名(簽名算法後面詳細介紹)
$str = 'amount='.$params["amount"].'&check_name='.$params["check_name"].'&desc='.$params["desc"].'&mch_appid='.$params["mch_appid"].'&mchid='.$params["mchid"].'&nonce_str='.$params["nonce_str"].'&openid='.$params["openid"].'&partner_trade_no='.$params["partner_trade_no"].'&spbill_create_ip='.$params['spbill_create_ip'].'&key=F5YguNW77Ao4N5yu5wZ8Lb00NKOg1Y04';
//md5加密 轉換成大寫
$sign = strtoupper(md5($str));

$params["sign"] = $sign;//簽名

 

而後拼接微信

$xml = "<xml>";
foreach ($paramsas $key => $val) {
if (is_numeric($val)) {
  $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else{
  $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
$xml .= "</xml>";

 

獲得$xml。app

到此字符傳參數部分完成了,而後還沒完呢!還有證書部分

以後用curl函數檢測證書 以後頁要用curl發送請求 直接貼代碼解釋
 
 
 
 
/**
     *   做用:使用證書,以post方式提交xml到對應的接口url
     */
function curl_post_ssl($url, $xml, $second=30)
{
  $ch = curl_init();
  //超時時間
  curl_setopt($ch,CURLOPT_TIMEOUT,$second);
  //將curl_exec()獲取的信息以文件流的形式返回,而不是直接輸出。
  curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);


  curl_setopt($ch,CURLOPT_URL,$url);

  //根據curl版本有不一樣默認值 設置一下放心
  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");

  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;
  }
}

 

貼出成功以後返回碼
<xml>

<return_code><![CDATA[SUCCESS]]></return_code>

<return_msg><![CDATA[]]></return_msg>

<mch_appid><![CDATA[wxec38b8ff840bd989]]></mch_appid>

<mchid><![CDATA[10013274]]></mchid>

<device_info><![CDATA[]]></device_info>

<nonce_str><![CDATA[lxuDzMnRjpcXzxLx0q]]></nonce_str>

<result_code><![CDATA[SUCCESS]]></result_code>

<partner_trade_no><![CDATA[10013574201505191526582441]]></partner_trade_no>

<payment_no><![CDATA[1000018301201505190181489473]]></payment_no>

<payment_time><![CDATA[2015-05-19 15:26:59]]></payment_time>

</xml>

 


失敗的返回碼會提示錯誤信息 就不作介紹了。curl

相關文章
相關標籤/搜索