鍍金池/ 問答/HTML/ 微信支付-支付驗(yàn)收指引里的【驗(yàn)收簽名】如何獲取?

微信支付-支付驗(yàn)收指引里的【驗(yàn)收簽名】如何獲?。?/h1>

最近在做App的微信支付的驗(yàn)收,請問驗(yàn)收的簽名,是需要單獨(dú)寫一端代碼來獲取然后在整個(gè)驗(yàn)收期間都不變,還是需要在支付驗(yàn)收環(huán)節(jié)里每次都動(dòng)態(tài)獲取,直到驗(yàn)收完成,再換成自己的原來的API密鑰???這里實(shí)在不明白,網(wǎng)上搜了好久也沒有相關(guān)信息。

我自己寫了個(gè)小的程序用curl來模擬post行為,始終獲取失敗

<?php

    $xml = '<xml><appid>開放平臺(tái)的AppID</appid><mch_id>商戶號</mch_id><nonce_str>32位隨機(jī)數(shù)</nonce_str><sign>微信支付API的密鑰</sign></xml>';
    $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey';
    $header[] = "Content-type: text/xml;charset=UTF-8";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

    $a = curl_exec($ch);
    echo $a;

    curl_close($ch);  
    
?>

獲取的始終是:

<xml>
  <return_code><!--[CDATA[FAIL]]--></return_code>
  <return_msg><!--[CDATA[獲取沙箱密鑰失敗,確認(rèn)交易密鑰是否正確]]--></return_msg>
</xml>

以下是官網(wǎng)的資料:

https://pay.weixin.qq.com/wik... 這里看到了獲取的說明,但是沒說是怎么獲?????

獲取驗(yàn)簽秘鑰API:
請求Url https://api.mch.weixin.qq.com...
是否需要證書 否
請求方式 POST

請求參數(shù):
字段名 字段 必填 示例值 類型 說明
商戶號 mch_id 是 1305638280 String(32) 微信支付分配的微信商戶號
隨機(jī)字符串 nonce_str 是 5K8264ILTKCH16CQ2502SI8ZNMTM67VS String(32) 隨機(jī)字符串,不長于32位
簽名 sign 是 5K8264ILTKCH16CQ2502SI8ZNMTM67VS String(32) 簽名值


回答
編輯回答
薄荷糖

網(wǎng)上查了好多帖子,終于搞定了,以饗后來者~
PS.如果確認(rèn)自己各項(xiàng)參數(shù)都對,但是還是提示簽名錯(cuò)誤,更新一下API密鑰,然后就ok了,微信那邊好像有緩存

創(chuàng)建一個(gè)沙箱驗(yàn)收的類,擴(kuò)展自WxPayDataBase

class Sandbox extends WxPayDataBase{

    //設(shè)置對象的屬性
    public function s_setValues($k, $v){
        $this->values[$k] = $v;
    }

    //讀取對象的屬性
    public function s_getValues($k){
        return $this->values[$k];
    }
    
    //獲取密鑰API
    public static function getSignKey($input, $mch_key){

        console_log( '1:'.json_encode($input->values) );
        
        //提交業(yè)務(wù)
        $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey';
        
        //生成簽名
        $input->setSign($mch_key);
        console_log( '2:'.json_encode($input->values) );
        
        //$values = $input->GetValues();
        //console_log( '3:'.json_encode($values) );
        
        $xml = $input->array2xml();
        console_log( '4:'.$xml );

        //向微信請求接口
        $result = self::postXmlCurl($xml, $url);
        console_log( json_encode($result) );

        $result = $input->xml2array($result);
        console_log( json_encode($result) );

        return $result;
    }

    

    /**
     * 
     * 產(chǎn)生隨機(jī)字符串,不長于32位
     * @param int $length
     * @return 產(chǎn)生的隨機(jī)字符串
     */
    public static function getNonceStr($length = 32) 
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {  
            $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
        } 
        return $str;
    }


    /**
     * 以post方式提交xml到對應(yīng)的接口url
     * 
     * @param string $xml  需要post的xml數(shù)據(jù)
     * @param string $url  url
     * @param bool $useCert 是否需要證書,默認(rèn)不需要
     * @param int $second   url執(zhí)行超時(shí)時(shí)間,默認(rèn)30s
     * @throws WxPayException
     */
    private static function postXmlCurl($xml, $url, $useCert = false, $second = 30)
    {    
        $ch = curl_init();
        
        //設(shè)置超時(shí)
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);

        //設(shè)置訪問的網(wǎng)址
        curl_setopt($ch, CURLOPT_URL, $url);
        
        //skysowe_modifid
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        
        //設(shè)置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        
        //要求結(jié)果為字符串且輸出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        console_log( 'cert:'.$useCert );
        if($useCert == true){
            //設(shè)置證書
            //使用證書:cert 與 key 分別屬于兩個(gè).pem文件
            curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);
            curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
            curl_setopt($ch,CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);
        }
        
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //console_log( 'xml:'.json_encode($xml) );

        //運(yùn)行curl
        $data = curl_exec($ch);
        //console_log( 'curl_result:'.json_encode($data) );
        
        //返回結(jié)果
        if($data){
            curl_close($ch);
            return $data;
        } else { 
            $error = curl_errno($ch);
            curl_close($ch);
            throw new WxPayException("curl出錯(cuò),錯(cuò)誤碼:$error");
            //console_log( 'curl_error:'.$error );
        }
    }


    /**
     * 輸出xml字符
     * @throws WxPayException
    **/
    public function array2xml()
    {
        if(!is_array($this->values) 
            || count($this->values) <= 0)
        {
            throw new WxPayException("數(shù)組數(shù)據(jù)異常!");
        }
        
        $xml = "<xml>";
        foreach ($this->values as $key=>$val)
        {
            if (is_numeric($val) || $key=="nonce_str" || $key=="sign" ){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml; 
    }

    /**
     * 將xml轉(zhuǎn)為array
     * @param string $xml
     * @throws WxPayException
     */
    public function xml2array($xml)
    {    
        if(!$xml){
            throw new WxPayException("xml數(shù)據(jù)異常!");
        }
        //將XML轉(zhuǎn)為array
        //禁止引用外部xml實(shí)體
        libxml_disable_entity_loader(true);
        $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);        
        return $this->values;
    }

}

然后獲取sandbox_signkey

    //沙箱用例:0 獲取驗(yàn)簽秘鑰
    $sandbox_test = new Sandbox();

    $sandbox_test->s_setValues('mch_id', WxPayConfig::MCHID);
    $sandbox_test->s_setValues('nonce_str', $sandbox_test->getNonceStr());

    //debug
    console_log( $sandbox_test->s_getValues('mch_id') );
    console_log( $sandbox_test->s_getValues('nonce_str') );
    console_log( WxPayConfig::KEY );

    $rs = Sandbox::getSignKey($sandbox_test, WxPayConfig::KEY);

    //debug
    echo json_encode($rs);
    echo $rs['sandbox_signkey'];

    exit;
2017年7月19日 09:36