php微信支付v3版簽名生成(php 微信支付流程)

  • 1、如何利用PHP實現 APP端微信支付功能
  • 2、用PHP做微信支付簽名錯誤,請教一下這個是什麼原因
  • 3、如何用PHP實現微信支付,求教。新手!說明詳細點
  • 4、微信網頁支付V3版js_api_call.php從訂單跳轉到微信支付提示缺少統一支付接口必填參數out_trade_no!
  • 5、如何用PHP實現微信支付?
  • 6、微信支付遇到簽名驗證失敗的解決方法

一丶 PHP後台後台生成預支付交易單,返回正確的預支付交易回話標識後再在APP裡面調起支付!官方文檔:

根據文檔拼接微信需要的參數,這裡需要幾個方法,直接上代碼!

傳輸給微信的參數要組裝成xml格式發送,傳如參數數組!

public function ToXml($data=array())

    {

        if(!is_array($data) || count($data) = 0)

        {

           return ‘數組異常’;

        }

        $xml = “”;

        foreach ($data as $key=$val)

        {

            if (is_numeric($val)){

                $xml.=””.$key.””.$val.””;

            }else{

                $xml.=””.$key.””;

            }

        }

        $xml.=””;

        return $xml;

    }

2.生成隨機字符串,微信所需參數! 這裡方法很多,看自己愛好都行!

function rand_code(){

        $str = ‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;//62個字符

        $str = str_shuffle($str);

        $str = substr($str,0,32);

        return  $str;

}

3.這裡是微信比較重要的一步了,這個方法會多次用到!生成簽名

private function getSign($params) {

        ksort($params);        //將參數數組按照參數名ASCII碼從小到大排序

        foreach ($params as $key = $item) {

            if (!empty($item)) {         //剔除參數值為空的參數

                $newArr[] = $key.’=’.$item;     // 整合新的參數數組

            }

        }

        $stringA = implode(“”, $newArr);         //使用  符號連接參數

        $stringSignTemp = $stringA.”key=”.”************************”;        //拼接key

        // key是在商戶平台API安全里自己設置的

        $stringSignTemp = MD5($stringSignTemp);       //將字符串進行MD5加密

        $sign = strtoupper($stringSignTemp);      //將所有字符轉換為大寫

        return $sign;

    }

4.傳遞參數給微信,生成預支付訂單! 接收微信返回的數據,在反給APP端,APP端調用支付接口,完成支付 ! APP端所需參數見微信文檔:;index=2

public function wx_pay() {

        $nonce_str = $this-rand_code();        //調用隨機字符串生成方法獲取隨機字符串

        $data[‘appid’] =’wxdbc5dc*******’;   //appid

        $data[‘mch_id’] = ‘1493*****’ ;        //商戶號

        $data[‘body’] = “APP支付測試”;

        $data[‘spbill_create_ip’] = $_SERVER[‘HTTP_HOST’];   //ip地址

        $data[‘total_fee’] = 1;                         //金額

        $data[‘out_trade_no’] = time().mt_rand(10000,99999);    //商戶訂單號,不能重複

        $data[‘nonce_str’] = $nonce_str;                   //隨機字符串

        $data[‘notify_url’] = ”; 接收支付後的通知,必須為能直接訪問的網址,不能跟參數

        $data[‘trade_type’] = ‘APP’;      //支付方式

        //將參與簽名的數據保存到數組  注意:以上幾個參數是追加到$data中的,$data中應該同時包含開發文檔中要求必填的剔除sign以外的所有數據

        $data[‘sign’] = $this-getSign($data);        //獲取簽名

        $xml = $this-ToXml($data);            //數組轉xml

        //curl 傳遞給微信方

        $url = “”;

        //header(“Content-type:text/xml”);

        $ch = curl_init();

        curl_setopt($ch,CURLOPT_URL, $url);

        if(stripos($url,”https://”)!==FALSE){

            curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

        }    else    {

            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);

            curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//嚴格校驗

        }

        //設置header

        curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

        curl_setopt($ch, CURLOPT_HEADER, FALSE);

        //要求結果為字符串且輸出到屏幕上

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        //設置超時

        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch, CURLOPT_POST, TRUE);

        //傳輸文件

        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

        //運行curl

        $data = curl_exec($ch);

        //返回結果

        if($data){

            curl_close($ch);

            //返回成功,將xml數據轉換為數組.

            $re = $this-FromXml($data);

            if($re[‘return_code’] != ‘SUCCESS’){

                json(“201”,’簽名失敗’);

            }

            else{

            //接收微信返回的數據,傳給APP!

                $arr =array(

                    ‘prepayid’ =$re[‘prepay_id’],

                    ‘appid’ = ‘wxdbc5dc*****’,

                    ‘partnerid’ = ‘14937****’,

                    ‘package’ = ‘Sign=WXPay’,

                    ‘noncestr’ = $nonce_str,

                    ‘timestamp’ =time(),

                );

                //第二次生成簽名

                $sign = $this-getSign($arr);

                $arr[‘sign’] = $sign;

                json(‘200′,’簽名成功’,$arr);

            }

        } else {

            $error = curl_errno($ch);

            curl_close($ch);

            json(‘201’,”curl出錯,錯誤碼:$error”);

        }

    }

5.將xml數據轉換為數組,接收微信返回數據時用到.

public function FromXml($xml)

    {

        if(!$xml){

            echo “xml數據異常!”;

        }

        //將XML轉為array

        //禁止引用外部xml實體

        libxml_disable_entity_loader(true);

        $data = json_decode(json_encode(simplexml_load_string($xml, ‘SimpleXMLElement’, LIBXML_NOCDATA)), true);

        return $data;

    }

二 .APP支付成功後,會調用你填寫的回調地址 . 返回參數詳見微信文檔:;index=3

// 微信支付回調

     function wx_notify(){

           //接收微信返回的數據數據,返回的xml格式

           $xmlData = file_get_contents(‘php://input’);

           //將xml格式轉換為數組

           $data = $this-FromXml($xmlData);

           //用日誌記錄檢查數據是否接受成功,驗證成功一次之後,可刪除。

           $file = fopen(‘./log.txt’, ‘a+’);

           fwrite($file,var_export($data,true));

           //為了防止假數據,驗證簽名是否和返回的一樣。

           //記錄一下,返回回來的簽名,生成簽名的時候,必須剔除sign字段。

           $sign = $data[‘sign’];

           unset($data[‘sign’]);

           if($sign == $this-getSign($data)){

            //簽名驗證成功後,判斷返回微信返回的

            if ($data[‘result_code’] == ‘SUCCESS’) {

                //根據返回的訂單號做業務邏輯

                $arr = array(

                       ‘pay_status’ = 1,

                    );

                $re = M(‘order’)-where([‘order_sn’=$data[‘out_trade_no’]])-save($arr);

                //處理完成之後,告訴微信成功結果!

                if($re){

                    echo ”;exit();

                }

            }

            //支付失敗,輸出錯誤信息

            else{

                $file = fopen(‘./log.txt’, ‘a+’);

           fwrite($file,”錯誤信息:”.$data[‘return_msg’].date(“Y-m-d H:i:s”),time().”\r\n”);    

            }

    }

    else{

                $file = fopen(‘./log.txt’, ‘a+’);

           fwrite($file,”錯誤信息:簽名驗證失敗”.date(“Y-m-d H:i:s”),time().”\r\n”);    

            }

}

在這裡,微信APP支付流程就成功走完了!謝謝支持!

———————

出現這種情況可能是您的網絡不好,或者是沒有遵循開發規範,導致數字簽名失敗

建議您更換更好的網絡,同時根據開發規範調整後台代碼。

微信公眾號JSAPI支付

一:配置參數

申請成功後,獲取接口文件, 將所有文件放入項目根目錄weixin下,在WxPay.ub.config.php中填入配置賬戶信息;

二:設置授權

開發者中心-網頁服務-網頁授權獲取用戶基本信息-修改;

“授權回調頁面域名修改成你的域名地址即可,須保證網頁授權已獲得,不然會報redirect_uri 參數錯誤;

三:網頁授權獲取用戶openid

js_api_call.php 請求文件中改動(所有傳給微信的參數都在入口文件中接收)

$out_trade_no = $_GET[‘out_trade_no’]; //商戶系統內部訂單號 32個字符內

$total_fee = $_GET[‘total_fee’]*100; //訂單總金額 單位為分,不能帶小數點,所以須把價格乘以100,

不然獲取prepay_id時會報錯誤(設置金額字段時最好設為小數點後2位)

$pay_status = get_pay_status($out_trade_no);//查看訂單支付狀態

$return_url = get_return_url($out_trade_no); //設置支付成功後跳轉頁面

//使用jsapi接口

$jsApi = new JsApi_pub();

//通過code獲得openid

if (!isset($_GET[‘code’])) { //觸發微信返回code碼

//設置redirect_uri參數,返回code碼地址,其實就是重定向到當前頁面,獲取用戶code碼參數

$url = WxPayConf_pub::JS_API_CALL_URL.”?showwxpaytitle=1out_trade_no=$out_trade_nototal_fee=$total_fee”;

$url = $jsApi-createOauthUrlForCode($url);

Header(“Location: $url”);

}else{ //獲取code碼,以獲取openid

$code = $_GET[‘code’];

$jsApi-setCode($code);

$openid = $jsApi-getOpenId(); //用戶標識

}

再就是WxPayHubHelper.php文件 JsApi_pub()類下createOauthUrlForCode($redirectUrl)方法, 第二個參數

改為 $urlObj[“redirect_uri”] = urlencode($redirectUrl); //對$url變量進行url編碼 不然header重定向時無法獲取訂單號和金額

四:設置統一支付接口參數,獲取prepay_id (預支付ID 微信生成的預支付 ID,用於後續接口調用中使用)

微信支付-開發配置-支付測試-測試授權目錄和測試白名單添加

(支付授權目錄需要精確到最細一級的目錄,且在使用時,目錄名稱後直接加文件名,如ccc.com/weixin/)

確保你 WxPayPubHelper.php文件里 UnifiedOrder_pub 這個類的getPrepayId這個方法能正常使用

這一步的調試在 getPrepayId()內 var_dump($this-result); 就能看到錯誤代碼;

posXml這個方法後調用了createXml這個方法

function postXml() {

$xml = $this-createXml();

//**在此處查看xml文件是否正常生成

include_once(“log_.php”);

$log = new Log_();

$log-log_result(“log.txt”,$xml);

//** 由於打印一些xml格式的文件只顯示字符長度,不顯示內容。於是用log的形式寫在服務器上調試

$this-response = $this-postXmlCurl($xml,$this-url,$this-curl_timeout);

return $this-response;

}

保證xml這個變量格式如下;

參數正確,postXmlCurl才能正確提交,提交後就能得到正確的prepay_id,就能彈出支付框了

五:使用jsapi調起支付

根據prepay_id生成jsapi支付參數

$jsApi-setPrepayId($prepay_id);

$jsApiParameters = $jsApi-getParameters();

//調用微信JS api 支付

function jsApiCall() {

WeixinJSBridge.invoke(

‘getBrandWCPayRequest’,

,

function(res){

WeixinJSBridge.log(res.err_msg);

if(res.err_msg == “get_brand_wcpay_request:ok”) { //支付成功後

window.location.href=”” //跳轉地址及訂單操作,在異步頁面也須處理訂單,防止同步時失敗

}else{

alert(“支付失敗”+res.err_code+res.err_desc+res.err_msg);

}

}

);

}(每次請求callpay方法時須判斷訂單狀態,防止重複提交)

六:通用通知接口 異步處理微信返回結果

支付完成後,notify.php中獲取微信的回調

$xml = $GLOBALS[‘HTTP_RAW_POST_DATA’];

//須驗證簽名,並回應微信。

if($notify-checkSign() == TRUE) //簽名驗證通過並更新訂單狀態後

$notify-setReturnParameter(“return_code”,”SUCCESS”); //設置返回碼,保證支付狀態改變後才返回成功

//對後台通知交互時,如果微信收到商戶的應答不是成功或超時,微信認為通知失敗,

//微信會通過一定的策略(如30分鐘共8次)定期重新發起通知,

$returnXml = $notify-returnXml();

echo $returnXml;(將xml數據返回微信 當return_code為SUCCESS時,不會再通知)

//當收到通知進行處理時,首先檢查對應業務數據的狀態,判斷該通知是否已經處理過,如果沒有處理過再進行處理,

如果處理過直接返回結果成功。在對業務數據進行狀態檢查和處理之前,要採用數據鎖進行並發控制,

以避免函數重入造成的數據混亂.

//判斷是否在微信瀏覽器打開

function isWeiXin(){

var ua = window.navigator.userAgent.toLowerCase();

if(ua.match(/MicroMessenger/i) == ‘micromessenger’){

return true;

}else{

return false;

}

}

步驟夠詳細了吧,我自己實現過,所以寫了日誌,結合php版本的demo 大致弄得出來了,如果對整個流程不太清楚,仔細的看完微信公眾號支付接口文檔,你申請微信公眾號支付成功了就會有的,

這個out_trade_no你請求過去沒,

這個out_trade_no是你自己網站上的訂單號,流程是這樣的

用戶在你的網站支付,你自己的網站首先生成一個訂單號,比如1234,然後把相關的信息請求給微信,這個out_trade_no也就是你的訂單號(1234),然後微信那邊支付成功之後會回調,他會把這個out_trade_no依然給你,你可以通過這個來識別是誰支付成功了

你的圖片

看到沒,那是個例子,你依然把他注釋了,所以那個$out_trade_no是空的,

商戶支付的訂單號由商戶自定義生成,微信支付要求商戶訂單號保持唯一性(建議根據當前系統時間加隨機序列來生成訂單號)。重新發起一筆支付要使用原訂單號,避免重複支付;已支付過或已調用關單、撤銷(請見後文的API列表)的訂單號不能重新發起支付。

以PHP語言為例,對微信支付的開發流程進行一下說明:

1.獲取訂單信息。

2.根據訂單信息和支付相關的賬號生成sign,並且生成支付參數。

3.將支付參數信息POST到微信服務器,獲取返回信息。

4.根據返回信息生成相應的支付代碼(微信內部)或是支付二維碼(非微信內),完成支付。

1.下單的簽名方式使用MD5方式

2.利用下單獲取到的prepay_id,來進行調起支付階段的paySign的簽名

3.如果提示簽名驗證失敗:

        ①首先檢查你的5個參數是否完整:timeStamp,nonceStr,package,signType,paySign

        ②signType 必須是MD5,官方demo不是MD5,改為MD5,這也是大坑,當然我自己用python 寫的時候直接用的MD5

        ③在做paySign簽名的時候,需要6個參數,上述5個參數去掉paySign(不參與簽名),加上appId(注意是大寫I,這是個大坑,這個錯了那簽名必然失敗)和key

        ④如果上述步驟沒問題還是失敗,那麼去驗證以下你的簽名是否通過

        ⑤還有一點簽名的時候必須把所有英文全部轉為大寫

4.歡迎評論,多多交流

原創文章,作者:MEXDF,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/126284.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
MEXDF的頭像MEXDF
上一篇 2024-10-03 23:07
下一篇 2024-10-03 23:07

相關推薦

  • PHP和Python哪個好找工作?

    PHP和Python都是非常流行的編程語言,它們被廣泛應用於不同領域的開發中。但是,在考慮擇業方向的時候,很多人都會有一個問題:PHP和Python哪個好找工作?這篇文章將從多個方…

    編程 2025-04-29
  • PHP怎麼接幣

    想要在自己的網站或應用中接受比特幣等加密貨幣的支付,就需要對該加密貨幣擁有一定的了解,並使用對應的API進行開發。本文將從多個方面詳細闡述如何使用PHP接受加密貨幣的支付。 一、環…

    編程 2025-04-29
  • 使用PHP foreach遍歷有相同屬性的值

    本篇文章將介紹如何使用PHP foreach遍歷具有相同屬性的值,並給出相應的代碼示例。 一、基礎概念 在講解如何使用PHP foreach遍歷有相同屬性的值之前,我們需要先了解幾…

    編程 2025-04-28
  • PHP獲取301跳轉後的地址

    本文將為大家介紹如何使用PHP獲取301跳轉後的地址。301重定向是什麼呢?當我們訪問一個網頁A,但是它已經被遷移到了另一個地址B,此時若服務器端做了301重定向,那麼你的瀏覽器在…

    編程 2025-04-27
  • Python爬蟲流程用法介紹

    本文將介紹Python爬蟲的流程,包括數據採集、數據處理以及數據存儲等方面。如果想要使用Python爬取網站數據,本文將為您提供詳細的指導和實例。 一、數據採集 1、確定目標網站 …

    編程 2025-04-27
  • PHP登錄頁面代碼實現

    本文將從多個方面詳細闡述如何使用PHP編寫一個簡單的登錄頁面。 1. PHP登錄頁面基本架構 在PHP登錄頁面中,需要包含HTML表單,用戶在表單中輸入賬號密碼等信息,提交表單後服…

    編程 2025-04-27
  • Java項目Git發布流程規範

    本文旨在介紹Java項目在使用Git進行發布時的流程規範。Git作為一個版本控制工具,其功能十分強大,但是對於Java項目進行發布時,需要我們根據標準化的流程規範來執行操作,以確保…

    編程 2025-04-27
  • xmake qt:構建Qt應用的全流程解決方案

    本文將會詳細闡述xmake qt的使用方法以及其能夠解決的問題。針對Qt應用開發中的各種困境,xmake提供了一整套的解決方案,包括自動構建、依賴管理、部署打包等,極大地提高了開發…

    編程 2025-04-27
  • PHP與Python的比較

    本文將會對PHP與Python進行比較和對比分析,包括語法特性、優缺點等方面。幫助讀者更好地理解和使用這兩種語言。 一、語法特性 PHP語法特性: <?php // 簡單的P…

    編程 2025-04-27
  • Android Activity啟動流程

    一、Activity概述 Android應用程序是由許多Activity組成的。一個Activity代表一個屏幕上的窗口。用戶與應用程序交互時,Activity會接收用戶的輸入並處…

    編程 2025-04-25

發表回復

登錄後才能評論