-──────
代碼文件結構
───────
create_direct_pay_by_user-php-UTF-8
│
├lib┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈類文件夾
│ │
│ ├alipay_core.function.php ┈┈┈┈┈┈支付寶接口公用函數文件
│ │
│ ├alipay_notify.class.php┈┈┈┈┈┈┈支付寶通知處理類文件
│ │
│ ├alipay_submit.class.php┈┈┈┈┈┈┈支付寶各接口請求提交類文件
│ │
│ └alipay_md5.function.php┈┈┈┈┈┈┈支付寶接口MD5函數文件
│
├log.txt┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈日誌文件
│
├alipay.config.php┈┈┈┈┈┈┈┈┈┈┈┈基礎配置類文件
│
├alipayapi.php┈┈┈┈┈┈┈┈┈┈┈┈┈┈支付寶接口入口文件
│
├notify_url.php ┈┈┈┈┈┈┈┈┈┈┈┈┈服務器異步通知頁面文件
│
├return_url.php ┈┈┈┈┈┈┈┈┈┈┈┈┈頁面跳轉同步通知文件
│
├cacert.pem ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈用於CURL中校驗SSL的CA證書文件
│
└readme.txt ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈使用說明文本php
※注意※
一、必須開啓curl服務
(1)使用Crul須要修改服務器中php.ini文件的設置,找到php_curl.dll去掉前面的";"便可
(2)文件夾中cacert.pem文件請務必放置到商戶網站平臺中(如:服務器上),而且保證其路徑有效,提供的代碼demo中的默認路徑是當前文件夾下——getcwd().'\\cacert.pem'
二、須要配置的文件是:
alipay.config.php
alipayapi.phphtml
1:from表單數據提交 node
<!-- 支付寶支付頁面 --> <form name=alipayment action="<?php echo Yii::app()->request->baseUrl ?>/index.php/Payment/alipayapi" method=post target="_blank"> <div style="display: none;"><input size="30" name="WIDseller_email" value="XXXXX.com" /> <input size="30" name="WIDout_trade_no" value="<?php echo @$OrderInfo['PayNumber']?>" /> <input size="30" name="WIDsubject" value="<?php echo @XUtils::cutstr($OrderInfo['OrderName'],30)?>" /> <input size="30" name="WIDtotal_fee" value="<?php echo @$OrderInfo['TotalMoney']?>" /> <input size="30" name="WIDbody" /> <input size="30" name="WIDshow_url" /></div> <li> <div class="pay_boxin pay_curr"> <span class="left"><img src="<?php echo Yii::app()->request->baseUrl ?>/assets/default/images/alipay.png" height="30px"></span> <span class="pay_money right"> <p>支付<strong><?php echo @sprintf('%0.2f',$OrderInfo['TotalMoney'])?></strong>元</p> </span> <span class="pay_liji pay_disno"><img src="<?php echo Yii::app()->request->baseUrl ?>/assets/default/images/pay_liji.png"></span> </div> <input type="submit" style="width:220px; height:50px; border:0px; margin:30px 0 0 500px; background: url(<?php echo Yii::app()->request->baseUrl ?>/assets/default/images/pay_quite.png) center no-repeat; cursor:pointer;" value="" > </li> </form>
2:控制器頁面跳轉數據庫
3:alipayapi.php 接口文件 構造請求參api
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>支付寶即時到帳交易接口</title> </head> <?php /* * * 功能:即時到帳交易接口接入頁 * 版本:3.3 * 修改日期:2012-07-23 * 說明: * 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。 *************************注意************************* * 若是您在接口集成過程當中遇到問題,能夠按照下面的途徑來解決 * 一、商戶服務中心(https://b.alipay.com/support/helperApply.htm?action=consultationApply),提交申請集成協助,咱們會有專業的技術工程師主動聯繫您協助解決 * 二、商戶幫助中心(http://help.alipay.com/support/232511-16307/0-16307.htm?sh=Y&info_type=9) * 三、支付寶論壇(http://club.alipay.com/read-htm-tid-8681712.html) * 若是不想使用擴展功能請把擴展功能參數賦空值。 */ require_once("alipay.config.php"); require_once("lib/alipay_submit.class.php"); /**************************請求參數**************************/ //支付類型 $payment_type = "1"; //必填,不能修改 //服務器異步通知頁面路徑 $notify_url = "http://www.XXX.com".$this->createUrl('Payment/Notify'); //需http://格式的完整路徑,不能加?id=123這類自定義參數 //頁面跳轉同步通知頁面路徑 $return_url = "http://www.XXX.com".$this->createUrl('Payment/Return'); //需http://格式的完整路徑,不能加?id=123這類自定義參數,不能寫成http://localhost/ //賣家支付寶賬戶 $seller_email = 'XXXX@XXXX.com';//$_POST['WIDseller_email']; //必填 //商戶訂單號 $out_trade_no = $_POST['WIDout_trade_no']; //商戶網站訂單系統中惟一訂單號,必填 //訂單名稱 $subject = $_POST['WIDsubject']; //必填 //付款金額 $total_fee = $_POST['WIDtotal_fee']; //必填 //訂單描述 $body = $_POST['WIDbody']; //商品展現地址 $show_url = $_POST['WIDshow_url']; //需以http://開頭的完整路徑,例如:http://www.商戶網址.com/myorder.html //防釣魚時間戳 $anti_phishing_key = ""; //若要使用請調用類文件submit中的query_timestamp函數 //客戶端的IP地址 $exter_invoke_ip = ""; //非局域網的外網IP地址,如:221.0.0.1 /************************************************************/ //構造要請求的參數數組,無需改動 $parameter = array( "service" => "create_direct_pay_by_user", "partner" => trim($alipay_config['partner']), "payment_type" => $payment_type, "notify_url" => $notify_url, "return_url" => $return_url, "seller_email" => $seller_email, "out_trade_no" => $out_trade_no, "subject" => $subject, "total_fee" => $total_fee, "body" => '',//$body, "show_url" => $show_url, "anti_phishing_key" => $anti_phishing_key, "exter_invoke_ip" => $exter_invoke_ip, "_input_charset" => trim(strtolower($alipay_config['input_charset'])) ); //創建請求 $alipaySubmit = new AlipaySubmit($alipay_config); $html_text = $alipaySubmit->buildRequestForm($parameter,"get", "確認"); echo $html_text; ?> </body> </html>
4:notify_url.php 服務器異步通知頁面文件數組
<?php /* * * 功能:支付寶服務器異步通知頁面 * 版本:3.3 * 日期:2012-07-23 * 說明: * 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。 *************************頁面功能說明************************* * 建立該頁面文件時,請留心該頁面文件中無任何HTML代碼及空格。 * 該頁面不能在本機電腦測試,請到服務器上作測試。請確保外部能夠訪問該頁面。 * 該頁面調試工具請使用寫文本函數logResult,該函數已被默認關閉,見alipay_notify_class.php中的函數verifyNotify * 若是沒有收到該頁面返回的 success 信息,支付寶會在24小時內按必定的時間策略重發通知 */ require_once("alipay.config.php"); require_once("lib/alipay_notify.class.php"); //計算得出通知驗證結果 $alipayNotify = new AlipayNotify($alipay_config); $verify_result = $alipayNotify->verifyNotify(); if($verify_result) {//驗證成功 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //請在這裏加上商戶的業務邏輯程序代 //——請根據您的業務邏輯來編寫程序(如下代碼僅做參考)—— //獲取支付寶的通知返回參數,可參考技術文檔中服務器異步通知參數列表 //商戶訂單號 $out_trade_no = $_POST['out_trade_no']; //支付寶交易號 $trade_no = $_POST['trade_no']; //交易狀態 $trade_status = $_POST['trade_status']; if($_POST['trade_status'] == 'TRADE_FINISHED') { //判斷該筆訂單是否在商戶網站中已經作過處理 //若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 //若是有作過處理,不執行商戶的業務程序 //注意: //該種交易狀態只在兩種狀況下出現 //一、開通了普通即時到帳,買家付款成功後。 //二、開通了高級即時到帳,從該筆交易成功時間算起,過了簽約時的可退款時限(如:三個月之內可退款、一年之內可退款等)後。 //調試用,寫文本函數記錄程序運行狀況是否正常 //logResult("這裏寫入想要調試的代碼變量值,或其餘運行的結果記錄"); } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { //判斷該筆訂單是否在商戶網站中已經作過處理 //若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 //若是有作過處理,不執行商戶的業務程序 //注意: //該種交易狀態只在一種狀況下出現——開通了高級即時到帳,買家付款成功後。 //調試用,寫文本函數記錄程序運行狀況是否正常 //logResult("這裏寫入想要調試的代碼變量值,或其餘運行的結果記錄"); } //——請根據您的業務邏輯來編寫程序(以上代碼僅做參考)—— echo "success"; //請不要修改或刪除 $this->actionSetPayN($out_trade_no,1); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } else { //驗證失敗 echo "fail"; //調試用,寫文本函數記錄程序運行狀況是否正常 //logResult("這裏寫入想要調試的代碼變量值,或其餘運行的結果記錄"); } ?>
5:return_url.php 支付寶跳轉會商戶通知信息安全
<?php /* * * 功能:支付寶頁面跳轉同步通知頁面 * 版本:3.3 * 日期:2012-07-23 * 說明: * 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。 *************************頁面功能說明************************* * 該頁面可在本機電腦測試 * 可放入HTML等美化頁面的代碼、商戶業務邏輯程序代碼 * 該頁面能夠使用PHP開發工具調試,也能夠使用寫文本函數logResult,該函數已被默認關閉,見alipay_notify_class.php中的函數verifyReturn */ require_once("alipay.config.php"); require_once("lib/alipay_notify.class.php"); ?> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <?php //計算得出通知驗證結果 $alipayNotify = new AlipayNotify($alipay_config); $verify_result = $alipayNotify->verifyReturn(); if($verify_result) {//驗證成功 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //請在這裏加上商戶的業務邏輯程序代碼 //——請根據您的業務邏輯來編寫程序(如下代碼僅做參考)—— //獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表 //商戶訂單號 $out_trade_no = $_GET['out_trade_no']; //支付寶交易號 $trade_no = $_GET['trade_no']; //交易狀態 $trade_status = $_GET['trade_status']; if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') { //判斷該筆訂單是否在商戶網站中已經作過處理 //若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 //若是有作過處理,不執行商戶的業務程序 } else { echo "trade_status=".$_GET['trade_status']; } $this->actionSetPayN($out_trade_no,1); $this->redirect(array('/UserCenter')); //——請根據您的業務邏輯來編寫程序(以上代碼僅做參考)—— ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } else { //驗證失敗 //如要調試,請看alipay_notify.php頁面的verifyReturn函數 echo "驗證失敗"; } ?> <title>支付寶即時到帳交易接口</title> </head> <body> </body> </html>
6:config基礎配置文件服務器
<?PHP //↓↓↓↓↓↓↓↓↓↓請在這裏配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ //合做身份者id,以2088開頭的16位純數字 $alipay_config['partner'] = ''; //安全檢驗碼,以數字和字母組成的32位字符 $alipay_config['key'] = ''; //↑↑↑↑↑↑↑↑↑↑請在這裏配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ //簽名方式 不需修改 $alipay_config['sign_type'] = strtoupper('MD5'); //字符編碼格式 目前支持 gbk 或 utf-8 $alipay_config['input_charset']= strtolower('utf-8'); //ca證書路徑地址,用於curl中ssl校驗 //請保證cacert.pem文件在當前文件夾目錄中 $alipay_config['cacert'] = getcwd().'\\cacert.pem'; //訪問模式,根據本身的服務器是否支持ssl訪問,若支持請選擇https;若不支持請選擇http $alipay_config['transport'] = 'http'; ?>
7:─────────
lib 類文件函數結構
─────────
alipay_core.function.php
function createLinkstring($para)
功能:把數組全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串
輸入:Array $para 須要拼接的數組
輸出:String 拼接完成之後的字符串
function createLinkstringUrlencode($para)
功能:把數組全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串,並對參數值urlencode
輸入:Array $para 須要拼接的數組
輸出:String 拼接完成之後的字符串
function paraFilter($para)
功能:除去數組中的空值和簽名參數
輸入:Array $para 簽名參數組
輸出:Array 去掉空值與簽名參數後的新簽名參數組
function argSort($para)
功能:對數組排序
輸入:Array $para 排序前的數組
輸出:Array 排序後的數組
function logResult($word='')
功能:寫日誌,方便測試(看網站需求,也能夠改爲存入數據庫)
輸入:String $word 要寫入日誌裏的文本內容 默認值:空值
function getHttpResponsePOST($url, $cacert_url, $para, $input_charset = '')
功能:遠程獲取數據,POST模式
輸入:String $url 指定URL完整路徑地址
String $cacert_url 指定當前工做目錄絕對路徑
Array $para 請求的數據
String $input_charset 編碼格式。默認值:空值
輸出:String 遠程輸出的數據
function getHttpResponseGET($url, $cacert_url)
功能:遠程獲取數據,GET模式
輸入:String $url 指定URL完整路徑地址
String $cacert_url 指定當前工做目錄絕對路徑
輸出:String 遠程輸出的數據
function charsetEncode($input,$_output_charset ,$_input_charset)
功能:實現多種字符編碼方式
輸入:String $input 須要編碼的字符串
String $_output_charset 輸出的編碼格式
String $_input_charset 輸入的編碼格式
輸出:String 編碼後的字符串
function charsetDecode($input,$_input_charset ,$_output_charset)
功能:實現多種字符解碼方式
輸入:String $input 須要解碼的字符串
String $_output_charset 輸出的解碼格式
String $_input_charset 輸入的解碼格式
輸出:String 解碼後的字符串app
<?php /* * * 支付寶接口公用函數 * 詳細:該類是請求、通知返回兩個文件所調用的公用函數核心處理文件 * 版本:3.3 * 日期:2012-07-19 * 說明: * 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。 */ /** * 把數組全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串 * @param $para 須要拼接的數組 * return 拼接完成之後的字符串 */ function createLinkstring($para) { $arg = ""; while (list ($key, $val) = each ($para)) { $arg.=$key."=".$val."&"; } //去掉最後一個&字符 $arg = substr($arg,0,count($arg)-2); //若是存在轉義字符,那麼去掉轉義 if(get_magic_quotes_gpc()){$arg = stripslashes($arg);} return $arg; } /** * 把數組全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串,並對字符串作urlencode編碼 * @param $para 須要拼接的數組 * return 拼接完成之後的字符串 */ function createLinkstringUrlencode($para) { $arg = ""; while (list ($key, $val) = each ($para)) { $arg.=$key."=".urlencode($val)."&"; } //去掉最後一個&字符 $arg = substr($arg,0,count($arg)-2); //若是存在轉義字符,那麼去掉轉義 if(get_magic_quotes_gpc()){$arg = stripslashes($arg);} return $arg; } /** * 除去數組中的空值和簽名參數 * @param $para 簽名參數組 * return 去掉空值與簽名參數後的新簽名參數組 */ function paraFilter($para) { $para_filter = array(); while (list ($key, $val) = each ($para)) { if($key == "sign" || $key == "sign_type" || $val == "")continue; else $para_filter[$key] = $para[$key]; } return $para_filter; } /** * 對數組排序 * @param $para 排序前的數組 * return 排序後的數組 */ function argSort($para) { ksort($para); reset($para); return $para; } /** * 寫日誌,方便測試(看網站需求,也能夠改爲把記錄存入數據庫) * 注意:服務器須要開通fopen配置 * @param $word 要寫入日誌裏的文本內容 默認值:空值 */ function logResult($word='') { $fp = fopen("log.txt","a"); flock($fp, LOCK_EX) ; fwrite($fp,"執行日期:".strftime("%Y%m%d%H%M%S",time())."\n".$word."\n"); flock($fp, LOCK_UN); fclose($fp); } /** * 遠程獲取數據,POST模式 * 注意: * 1.使用Crul須要修改服務器中php.ini文件的設置,找到php_curl.dll去掉前面的";"就好了 * 2.文件夾中cacert.pem是SSL證書請保證其路徑有效,目前默認路徑是:getcwd().'\\cacert.pem' * @param $url 指定URL完整路徑地址 * @param $cacert_url 指定當前工做目錄絕對路徑 * @param $para 請求的數據 * @param $input_charset 編碼格式。默認值:空值 * return 遠程輸出的數據 */ function getHttpResponsePOST($url, $cacert_url, $para, $input_charset = '') { if (trim($input_charset) != '') { $url = $url."_input_charset=".$input_charset; } $curl = curl_init($url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL證書認證 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//嚴格認證 curl_setopt($curl, CURLOPT_CAINFO,$cacert_url);//證書地址 curl_setopt($curl, CURLOPT_HEADER, 0 ); // 過濾HTTP頭 curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);// 顯示輸出結果 curl_setopt($curl,CURLOPT_POST,true); // post傳輸數據 curl_setopt($curl,CURLOPT_POSTFIELDS,$para);// post傳輸數據 $responseText = curl_exec($curl); //var_dump( curl_error($curl) );//若是執行curl過程當中出現異常,可打開此開關,以便查看異常內容 curl_close($curl); return $responseText; } /** * 遠程獲取數據,GET模式 * 注意: * 1.使用Crul須要修改服務器中php.ini文件的設置,找到php_curl.dll去掉前面的";"就好了 * 2.文件夾中cacert.pem是SSL證書請保證其路徑有效,目前默認路徑是:getcwd().'\\cacert.pem' * @param $url 指定URL完整路徑地址 * @param $cacert_url 指定當前工做目錄絕對路徑 * return 遠程輸出的數據 */ function getHttpResponseGET($url,$cacert_url) { $curl = curl_init($url); curl_setopt($curl, CURLOPT_HEADER, 0 ); // 過濾HTTP頭 curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);// 顯示輸出結果 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL證書認證 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//嚴格認證 curl_setopt($curl, CURLOPT_CAINFO,$cacert_url);//證書地址 $responseText = curl_exec($curl); //var_dump( curl_error($curl) );//若是執行curl過程當中出現異常,可打開此開關,以便查看異常內容 curl_close($curl); return $responseText; } /** * 實現多種字符編碼方式 * @param $input 須要編碼的字符串 * @param $_output_charset 輸出的編碼格式 * @param $_input_charset 輸入的編碼格式 * return 編碼後的字符串 */ function charsetEncode($input,$_output_charset ,$_input_charset) { $output = ""; if(!isset($_output_charset) )$_output_charset = $_input_charset; if($_input_charset == $_output_charset || $input ==null ) { $output = $input; } elseif (function_exists("mb_convert_encoding")) { $output = mb_convert_encoding($input,$_output_charset,$_input_charset); } elseif(function_exists("iconv")) { $output = iconv($_input_charset,$_output_charset,$input); } else die("sorry, you have no libs support for charset change."); return $output; } /** * 實現多種字符解碼方式 * @param $input 須要解碼的字符串 * @param $_output_charset 輸出的解碼格式 * @param $_input_charset 輸入的解碼格式 * return 解碼後的字符串 */ function charsetDecode($input,$_input_charset ,$_output_charset) { $output = ""; if(!isset($_input_charset) )$_input_charset = $_input_charset ; if($_input_charset == $_output_charset || $input ==null ) { $output = $input; } elseif (function_exists("mb_convert_encoding")) { $output = mb_convert_encoding($input,$_output_charset,$_input_charset); } elseif(function_exists("iconv")) { $output = iconv($_input_charset,$_output_charset,$input); } else die("sorry, you have no libs support for charset changes."); return $output; } ?>
┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉
function md5Sign($prestr, $key)
功能:MD5簽名
輸入:String $prestr 待簽名數據
String $key 私鑰
輸出:String 簽名結果
function md5Verify($prestr, $sign, $key)
功能:MD5驗籤
輸入:String $data 待簽名數據
String $sign 簽名結果
String $key 私鑰
輸出:bool 驗證結果curl
<?php /* * * MD5 * 詳細:MD5加密 * 版本:3.3 * 日期:2012-07-19 * 說明: * 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。 */ /** * 簽名字符串 * @param $prestr 須要簽名的字符串 * @param $key 私鑰 * return 簽名結果 */ function md5Sign($prestr, $key) { $prestr = $prestr . $key; return md5($prestr); } /** * 驗證簽名 * @param $prestr 須要簽名的字符串 * @param $sign 簽名結果 * @param $key 私鑰 * return 簽名結果 */ function md5Verify($prestr, $sign, $key) { $prestr = $prestr . $key; $mysgin = md5($prestr); if($mysgin == $sign) { return true; } else { return false; } } ?>
┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉
alipay_notify.class.php
function verifyNotify()
功能:對notify_url的認證
輸出:Bool 驗證結果:true/false
function verifyReturn()
功能:對return_url的認證
輸出:Bool 驗證結果:true/false
function getSignVeryfy($para_temp, $sign)
功能:獲取返回時的簽名驗證結果
輸入:Array $para_temp 通知返回來的參數數組
String $sign 支付寶返回的簽名結果
輸出:Bool 得到簽名驗證結果
function getResponse($notify_id)
功能:獲取遠程服務器ATN結果,驗證返回URL
輸入:String $notify_id 通知校驗ID
輸出:String 服務器ATN結果
<?php /* * * 類名:AlipayNotify * 功能:支付寶通知處理類 * 詳細:處理支付寶各接口通知返回 * 版本:3.2 * 日期:2011-03-25 * 說明: * 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考 *************************注意************************* * 調試通知返回時,可查看或改寫log日誌的寫入TXT裏的數據,來檢查通知返回是否正常 */ require_once("alipay_core.function.php"); require_once("alipay_md5.function.php"); class AlipayNotify { /** * HTTPS形式消息驗證地址 */ var $https_verify_url = 'https://mapi.alipay.com/gateway.do?service=notify_verify&'; /** * HTTP形式消息驗證地址 */ var $http_verify_url = 'http://notify.alipay.com/trade/notify_query.do?'; var $alipay_config; function __construct($alipay_config){ $this->alipay_config = $alipay_config; } function AlipayNotify($alipay_config) { $this->__construct($alipay_config); } /** * 針對notify_url驗證消息是不是支付寶發出的合法消息 * @return 驗證結果 */ function verifyNotify(){ if(empty($_POST)) {//判斷POST來的數組是否爲空 return false; } else { //生成簽名結果 $isSign = $this->getSignVeryfy($_POST, $_POST["sign"]); //獲取支付寶遠程服務器ATN結果(驗證是不是支付寶發來的消息) $responseTxt = 'true'; if (! empty($_POST["notify_id"])) {$responseTxt = $this->getResponse($_POST["notify_id"]);} //寫日誌記錄 //if ($isSign) { // $isSignStr = 'true'; //} //else { // $isSignStr = 'false'; //} //$log_text = "responseTxt=".$responseTxt."\n notify_url_log:isSign=".$isSignStr.","; //$log_text = $log_text.createLinkString($_POST); //logResult($log_text); //驗證 //$responsetTxt的結果不是true,與服務器設置問題、合做身份者ID、notify_id一分鐘失效有關 //isSign的結果不是true,與安全校驗碼、請求時的參數格式(如:帶自定義參數等)、編碼格式有關 if (preg_match("/true$/i",$responseTxt) && $isSign) { return true; } else { return false; } } } /** * 針對return_url驗證消息是不是支付寶發出的合法消息 * @return 驗證結果 */ function verifyReturn(){ if(empty($_GET)) {//判斷POST來的數組是否爲空 return false; } else { //生成簽名結果 $isSign = $this->getSignVeryfy($_GET, $_GET["sign"]); //獲取支付寶遠程服務器ATN結果(驗證是不是支付寶發來的消息) $responseTxt = 'true'; if (! empty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);} //寫日誌記錄 //if ($isSign) { // $isSignStr = 'true'; //} //else { // $isSignStr = 'false'; //} //$log_text = "responseTxt=".$responseTxt."\n return_url_log:isSign=".$isSignStr.","; //$log_text = $log_text.createLinkString($_GET); //logResult($log_text); //驗證 //$responsetTxt的結果不是true,與服務器設置問題、合做身份者ID、notify_id一分鐘失效有關 //isSign的結果不是true,與安全校驗碼、請求時的參數格式(如:帶自定義參數等)、編碼格式有關 if (preg_match("/true$/i",$responseTxt) && $isSign) { return true; } else { return false; } } } /** * 獲取返回時的簽名驗證結果 * @param $para_temp 通知返回來的參數數組 * @param $sign 返回的簽名結果 * @return 簽名驗證結果 */ function getSignVeryfy($para_temp, $sign) { //除去待簽名參數數組中的空值和簽名參數 $para_filter = paraFilter($para_temp); //對待簽名參數數組排序 $para_sort = argSort($para_filter); //把數組全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串 $prestr = createLinkstring($para_sort); $isSgin = false; switch (strtoupper(trim($this->alipay_config['sign_type']))) { case "MD5" : $isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']); break; default : $isSgin = false; } return $isSgin; } /** * 獲取遠程服務器ATN結果,驗證返回URL * @param $notify_id 通知校驗ID * @return 服務器ATN結果 * 驗證結果集: * invalid命令參數不對 出現這個錯誤,請檢測返回處理中partner和key是否爲空 * true 返回正確信息 * false 請檢查防火牆或者是服務器阻止端口問題以及驗證時間是否超過一分鐘 */ function getResponse($notify_id) { $transport = strtolower(trim($this->alipay_config['transport'])); $partner = trim($this->alipay_config['partner']); $veryfy_url = ''; if($transport == 'https') { $veryfy_url = $this->https_verify_url; } else { $veryfy_url = $this->http_verify_url; } $veryfy_url = $veryfy_url."partner=" . $partner . "¬ify_id=" . $notify_id; $responseTxt = getHttpResponseGET($veryfy_url, $this->alipay_config['cacert']); return $responseTxt; } } ?>
┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉
alipay_submit.class.php
function buildRequestMysign($para_sort)
功能:生成要請求給支付寶的參數數組
輸入:Array $para_sort 已排序要簽名的數組
輸出:String 簽名結果
function buildRequestPara($para_temp)
功能:根據反饋回來的信息,生成簽名結果
輸入:Array $para_temp 請求前的參數數組
輸出:String 要請求的參數數組
function buildRequestParaToString($para_temp)
功能:根據反饋回來的信息,生成簽名結果
輸入:Array $para_temp 請求前的參數數組
輸出:String 要請求的參數數組字符串
function buildRequestForm($para_temp, $method, $button_name)
功能:創建請求,以表單HTML形式構造(默認)
輸入:Array $para_temp 請求前的參數數組
String $method 提交方式。兩個值可選:post、get
String $button_name 確認按鈕顯示文字
輸出:String 提交表單HTML文本
function buildRequestHttp($para_temp)
功能:創建請求,以模擬遠程HTTP的POST請求方式構造並獲取支付寶的處理結果
輸入:Array $para_temp 請求前的參數數組
輸出:String 支付寶處理結果
function buildRequestHttpInFile($para_temp, $file_para_name, $file_name)
功能:創建請求,以模擬遠程HTTP的POST請求方式構造並獲取支付寶的處理結果,帶文件上傳功能
輸入:Array $para_temp 請求參數數組
String $file_para_name 文件類型的參數名
String $file_name 文件完整絕對路徑
輸出:String 支付寶返回處理結果
function query_timestamp()
功能:用於防釣魚,調用接口query_timestamp來獲取時間戳的處理函數
輸出:String 時間戳字符串
<?php /* * * 類名:AlipaySubmit * 功能:支付寶各接口請求提交類 * 詳細:構造支付寶各接口表單HTML文本,獲取遠程HTTP數據 * 版本:3.3 * 日期:2012-07-23 * 說明: * 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 * 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。 */ require_once("alipay_core.function.php"); require_once("alipay_md5.function.php"); class AlipaySubmit { var $alipay_config; /** *支付寶網關地址(新) */ var $alipay_gateway_new = 'https://mapi.alipay.com/gateway.do?'; function __construct($alipay_config){ $this->alipay_config = $alipay_config; } function AlipaySubmit($alipay_config) { $this->__construct($alipay_config); } /** * 生成簽名結果 * @param $para_sort 已排序要簽名的數組 * return 簽名結果字符串 */ function buildRequestMysign($para_sort) { //把數組全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串 $prestr = createLinkstring($para_sort); $mysign = ""; switch (strtoupper(trim($this->alipay_config['sign_type']))) { case "MD5" : $mysign = md5Sign($prestr, $this->alipay_config['key']); break; default : $mysign = ""; } return $mysign; } /** * 生成要請求給支付寶的參數數組 * @param $para_temp 請求前的參數數組 * @return 要請求的參數數組 */ function buildRequestPara($para_temp) { //除去待簽名參數數組中的空值和簽名參數 $para_filter = paraFilter($para_temp); //對待簽名參數數組排序 $para_sort = argSort($para_filter); //生成簽名結果 $mysign = $this->buildRequestMysign($para_sort); //簽名結果與簽名方式加入請求提交參數組中 $para_sort['sign'] = $mysign; $para_sort['sign_type'] = strtoupper(trim($this->alipay_config['sign_type'])); return $para_sort; } /** * 生成要請求給支付寶的參數數組 * @param $para_temp 請求前的參數數組 * @return 要請求的參數數組字符串 */ function buildRequestParaToString($para_temp) { //待請求參數數組 $para = $this->buildRequestPara($para_temp); //把參數組中全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串,並對字符串作urlencode編碼 $request_data = createLinkstringUrlencode($para); return $request_data; } /** * 創建請求,以表單HTML形式構造(默認) * @param $para_temp 請求參數數組 * @param $method 提交方式。兩個值可選:post、get * @param $button_name 確認按鈕顯示文字 * @return 提交表單HTML文本 */ function buildRequestForm($para_temp, $method, $button_name) { //待請求參數數組 $para = $this->buildRequestPara($para_temp); $sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".$this->alipay_gateway_new."_input_charset=".trim(strtolower($this->alipay_config['input_charset']))."' method='".$method."'>"; while (list ($key, $val) = each ($para)) { $sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>"; } //submit按鈕控件請不要含有name屬性 //$sHtml = $sHtml."<input type='submit' value='".$button_name."'></form>"; $sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>"; return $sHtml; } /** * 創建請求,以模擬遠程HTTP的POST請求方式構造並獲取支付寶的處理結果 * @param $para_temp 請求參數數組 * @return 支付寶處理結果 */ function buildRequestHttp($para_temp) { $sResult = ''; //待請求參數數組字符串 $request_data = $this->buildRequestPara($para_temp); //遠程獲取數據 $sResult = getHttpResponsePOST($this->alipay_gateway_new, $this->alipay_config['cacert'],$request_data,trim(strtolower($this->alipay_config['input_charset']))); return $sResult; } /** * 創建請求,以模擬遠程HTTP的POST請求方式構造並獲取支付寶的處理結果,帶文件上傳功能 * @param $para_temp 請求參數數組 * @param $file_para_name 文件類型的參數名 * @param $file_name 文件完整絕對路徑 * @return 支付寶返回處理結果 */ function buildRequestHttpInFile($para_temp, $file_para_name, $file_name) { //待請求參數數組 $para = $this->buildRequestPara($para_temp); $para[$file_para_name] = "@".$file_name; //遠程獲取數據 $sResult = getHttpResponsePOST($this->alipay_gateway_new, $this->alipay_config['cacert'],$para,trim(strtolower($this->alipay_config['input_charset']))); return $sResult; } /** * 用於防釣魚,調用接口query_timestamp來獲取時間戳的處理函數 * 注意:該功能PHP5環境及以上支持,所以必須服務器、本地電腦中裝有支持DOMDocument、SSL的PHP配置環境。建議本地調試時使用PHP開發軟件 * return 時間戳字符串 */ function query_timestamp() { $url = $this->alipay_gateway_new."service=query_timestamp&partner=".trim(strtolower($this->alipay_config['partner']))."&_input_charset=".trim(strtolower($this->alipay_config['input_charset'])); $encrypt_key = ""; $doc = new DOMDocument(); $doc->load($url); $itemEncrypt_key = $doc->getElementsByTagName( "encrypt_key" ); $encrypt_key = $itemEncrypt_key->item(0)->nodeValue; return $encrypt_key; } } ?>