PHP實現支付寶手機WAP支付接入說明
阿新 • • 發佈:2019-01-06
因為專案原因,最近剛在專案中接入了支付寶的支付,故將支付過程記錄下來以備檢視。
專案背景:該專案為手機WAP專案,所以接入的是支付寶的手機網站支付型別。
首先,在支付寶官方下載SDK和DEMO:
https://docs.open.alipay.com/203/105910/
在pay.php中引入相關類檔案和配置,如下,同時提交相關訂單資訊
個人在測試中發現DEMO中有坑,需對AlipayTradeService.php做以下修改:<?php /* * * 功能:支付寶手機網站支付介面(alipay.trade.wap.pay)介面除錯入口頁面 * 版本:2.0 * 修改日期:2016-11-01 * 說明: * 以下程式碼只是為了方便商戶測試而提供的樣例程式碼,商戶可以根據自己網站的需要,按照技術文件編寫,並非一定要使用該程式碼。 請確保專案檔案有可寫許可權,不然列印不了日誌。 */ header("Content-type: text/html; charset=utf-8"); include_once("../../../include/config.inc.php"); require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'service/AlipayTradeService.php'; require_once dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'buildermodel/AlipayTradeWapPayContentBuilder.php'; require dirname ( __FILE__ ).DIRECTORY_SEPARATOR.'./../config.php'; //接收支付資料 $order_data = trim(get_param("orderDa")); //訂單資料 if($order_data == "" ){ $mssage = "資料不能為空"; showinfo($mssage,'' ,3); exit; } $result_order = json_decode(uc_authcode(base64_decode($order_data), 'DECODE', ADMIN_KEY),true); //商戶訂單號,商戶網站訂單系統中唯一訂單號,必填 $out_trade_no = $result_order['WIDout_trade_no']; //訂單名稱,必填 $subject = $result_order['WIDsubject']; //付款金額,必填 $total_amount = $result_order['WIDtotal_amount']; //商品描述,可空 $body = $result_order['WIDbody']; //超時時間 $timeout_express="1m"; //驗證資料 $pay_md5 = $result_order['infoPy']; //訂單驗證 if($out_trade_no==''){ $mssage = "訂單號不能為空"; showinfo($mssage,'' ,3); exit; } if($total_amount=='' || $total_amount==0){ $mssage = "訂單金額不能為空"; showinfo($mssage,'' ,3); exit; } //購買商品 if($result_order['flag']=='paycard'){ //檢測是否有訂單號 $where = " and o_orderid = '".$out_trade_no."' and o_totalprice='".$total_amount."' and o_status=4 "; $info = get_info($GLOBALS["conn"],"game_order",array(),$where); if( empty($info) ){ $mssage = "沒有此訂單!"; showinfo($mssage,'' ,3); exit; } //驗證資料 $p_arr = array( 'uid'=>$info['o_playerid'], 'uorder'=>$info['o_orderid'], 'uprice'=>$info['o_totalprice'],); $p_time = $info['o_addtime']; $p_key = ADMIN_KEY; $p_md5 = md5($p_arr.$p_time.$p_key); if( $p_md5 != $pay_md5 ){ $mssage = "請勿非法操作!"; showinfo($mssage,'' ,3); exit; } } //申請還款 if($result_order['flag']=='repayment'){ //檢測是否有訂單號 $where = " and l_orderid = '".$out_trade_no."' and l_returnnum='".$total_amount."' and l_status=3 "; $info = get_info($GLOBALS["conn"],"game_loan_order",array(),$where); if( empty($info) ){ $mssage = "沒有此訂單!"; showinfo($mssage,'' ,3); exit; } //驗證資料 $p_arr = array( 'uid'=>$info['l_playerid'], 'uorder'=>$info['l_orderid'], 'uprice'=>$info['l_returnnum']); $p_time = $info['l_addtime']; $p_key = ADMIN_KEY; $p_md5 = md5($p_arr.$p_time.$p_key); if( $p_md5 != $pay_md5 ){ $mssage = "請勿非法操作!"; showinfo($mssage,'' ,3); exit; } } //記錄要提交的訂單資訊到日誌 $log_msg = "訂單內容:" . json_encode($result_order); sys_log_write_content( $log_msg.__FILE__.__LINE__ ,"pay_log","jsapi"); //傳送支付指令 $payRequestBuilder = new AlipayTradeWapPayContentBuilder(); $payRequestBuilder->setBody($body); $payRequestBuilder->setSubject($subject); $payRequestBuilder->setOutTradeNo($out_trade_no); $payRequestBuilder->setTotalAmount($total_amount); $payRequestBuilder->setTimeExpress($timeout_express); $payResponse = new AlipayTradeService($config); $result=$payResponse->wapPay($payRequestBuilder,$config['return_url'],$config['notify_url']); return ; ?>
在此之前要根據註釋在config.php中填入自己的引數
後臺通知中根據DEMO中註釋修改即可,本人實際測試發現無需驗證sell_id
notify_url.php
<?php /* * * 功能:支付寶伺服器非同步通知頁面 * 版本:2.0 * 修改日期:2016-11-01 * 說明: * 以下程式碼只是為了方便商戶測試而提供的樣例程式碼,商戶可以根據自己網站的需要,按照技術文件編寫,並非一定要使用該程式碼。 *************************頁面功能說明************************* * 建立該頁面檔案時,請留心該頁面檔案中無任何HTML程式碼及空格。 * 該頁面不能在本機電腦測試,請到伺服器上做測試。請確保外部可以訪問該頁面。 * 如果沒有收到該頁面返回的 success 資訊,支付寶會在24小時內按一定的時間策略重發通知 */ include_once("../../include/config.inc.php"); require_once("config.php"); require_once 'wappay/service/AlipayTradeService.php'; $arr=$_POST; $alipaySevice = new AlipayTradeService($config); $alipaySevice->writeLog(var_export($_POST,true)); $result = $alipaySevice->check($arr); /* 實際驗證過程建議商戶新增以下校驗。 1、商戶需要驗證該通知資料中的out_trade_no是否為商戶系統中建立的訂單號, 2、判斷total_amount是否確實為該訂單的實際金額(即商戶訂單建立時的金額), 3、校驗通知中的seller_id(或者seller_email) 是否為out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id/seller_email) 4、驗證app_id是否為該商戶本身。 */ if($result) {//驗證成功 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //請在這裡加上商戶的業務邏輯程式代 //——請根據您的業務邏輯來編寫程式(以下程式碼僅作參考)—— //獲取支付寶的通知返回引數,可參考技術文件中伺服器非同步通知引數列表 //商戶訂單號 $out_trade_no = $_POST['out_trade_no']; //支付寶交易號 $trade_no = $_POST['trade_no']; //交易狀態 $trade_status = $_POST['trade_status']; //訂單金額 $total_amount = $_POST['total_amount']; //sell_id //$sell_id = $_POST['seller_id']; //app_id $app_id = $_POST['app_id']; //判斷支付型別(提現還是借貸) $type = substr($out_trade_no,0,2); //獲取對應訂單資訊 if($type=='tx'){ $order_info = get_order_info($out_trade_no); //驗證訂單資料 if(empty($order_info)){ echo 'fail';exit; } if($total_amount != $order_info['o_totalprice']){ echo 'fali';exit; } } if($type=='jd'){ $order_info = get_loan_order_info($out_trade_no); //驗證訂單資料 if(empty($order_info)){ echo 'fail';exit; } if($total_amount != $order_info['l_returnnum']){ echo 'fali';exit; } } /*if($sell_id!=$config['sell_id']){ echo 'fali';exit; }*/ if($app_id!=$config['app_id']){ echo 'fali';exit; } if($_POST['trade_status'] == 'TRADE_FINISHED') { //判斷該筆訂單是否在商戶網站中已經做過處理 //如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程式 //請務必判斷請求時的total_amount與通知時獲取的total_fee為一致的 //如果有做過處理,不執行商戶的業務程式 //注意: //退款日期超過可退款期限後(如三個月可退款),支付寶系統傳送該交易狀態通知 if($type=='tx'){ if($order_info['o_status']==4){ //執行業務處理 //取出禮包碼 $sql = "select sysid,gc_code from ".get_table("game_gift_code")." where gc_status=1 limit 1"; $query = $GLOBALS["conn"]->Query($sql); $value = $GLOBALS['conn']->FetchArray($query); $up_arr = array( 'o_status' => 1, 'o_trade_no' => $trade_no, 'o_giftcode' => $value['gc_code'] ); $up_where = " and o_orderid='".$out_trade_no."'"; $row = update_record($GLOBALS["conn"],'game_order',$up_arr,array(),$up_where);//更新訂單資料 if($row>0){ $msg = "訂單 ".$out_trade_no." 已支付"; $log_msg = "call back:" . $msg; sys_log_write_content( $log_msg.__FILE__.__LINE__ ,"pay_log","notify_order_success"); //更新禮包碼狀態 $up_gift = array( 'gc_status'=>2, 'gc_time' => THIS_DATETIME, 'gc_orderid' => $out_trade_no ); $gift_where = " and sysid=".$value['sysid']; update_record($GLOBALS["conn"],'game_gift_code',$up_gift,array(),$gift_where); //更新商品出售數量 /*$where = " and og_sysid='".$out_trade_no."'"; $garr = get_info($GLOBALS['conn'],"game_order_goods",array('og_goodsid'),$where,'',true); foreach($garr as $k=>$v){ $up_num = array( 'g_sellnum' => 'g_sellnum'+1 ); $num_where = " and g_id='".$v."'"; update_record($GLOBALS['conn'],"game_goods",$up_num,array(),$num_where);//更新商品出售 }*/ //新增使用者訊息 $title = '付款成功,請試用後儘快退款';//標題 $content = '您的訂單['.$out_trade_no.']已經付款成功,<br>道具試用後可申請退款退回繫結借記卡,適合現金緊缺的玩家!系統贈送您的遊戲兌換碼:'.$value['gc_code'].',可以在您的遊戲中進行使用,感謝您的支援!<br>如需幫助,請點選左上角【幫助】找到您的問題或者聯絡客服進行人工服務,QQ:2013609564'; add_player_msg($order_info['o_playerid'],$title,$content); } } } if($type=='jd'){ if($order_info['l_status']==3){ //執行業務處理 $up_arr = array( 'l_status' => 4, 'l_trade_no' => $trade_no, 'l_returntime' => THIS_DATETIME ); $up_where = " and l_orderid='".$out_trade_no."'"; $row = update_record($GLOBALS["conn"],'game_loan_order',$up_arr,array(),$up_where);//更新訂單資料 if($row>0){ $msg = "訂單 ".$out_trade_no." 已支付"; $log_msg = "call back:" . $msg; sys_log_write_content( $log_msg.__FILE__.__LINE__ ,"pay_log","notify_order_success"); } } } } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { //判斷該筆訂單是否在商戶網站中已經做過處理 //如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程式 //請務必判斷請求時的total_amount與通知時獲取的total_fee為一致的 //如果有做過處理,不執行商戶的業務程式 //注意: //付款完成後,支付寶系統傳送該交易狀態通知 if($type=='tx'){ if($order_info['o_status']==4){ //執行業務處理 //取出禮包碼 $sql = "select sysid,gc_code from ".get_table("game_gift_code")." where gc_status=1 limit 1"; $query = $GLOBALS["conn"]->Query($sql); $value = $GLOBALS['conn']->FetchArray($query); $up_arr = array( 'o_status' => 1, 'o_trade_no' => $trade_no, 'o_giftcode' => $value['gc_code'] ); $up_where = " and o_orderid='".$out_trade_no."'"; $row = update_record($GLOBALS["conn"],'game_order',$up_arr,array(),$up_where);//更新訂單資料 if($row>0){ $msg = "訂單 ".$out_trade_no." 已支付"; $log_msg = "call back:" . $msg; sys_log_write_content( $log_msg.__FILE__.__LINE__ ,"pay_log","notify_order_success"); //更新禮包碼狀態 $up_gift = array( 'gc_status'=>2, 'gc_time' => THIS_DATETIME, 'gc_orderid' => $out_trade_no ); $gift_where = " and sysid=".$value['sysid']; update_record($GLOBALS["conn"],'game_gift_code',$up_gift,array(),$gift_where); //更新商品出售數量 /*$where = " and og_sysid='".$out_trade_no."'"; $garr = get_info($GLOBALS['conn'],"game_order_goods",array('og_goodsid'),$where,'',true); foreach($garr as $k=>$v){ $up_num = array( 'g_sellnum' => 'g_sellnum'+1 ); $num_where = " and g_id='".$v."'"; update_record($GLOBALS['conn'],"game_goods",$up_num,array(),$num_where);//更新商品出售 }*/ //新增使用者訊息 $title = '付款成功,請試用後儘快退款';//標題 $content = '您的訂單['.$out_trade_no.']已經付款成功,<br>道具試用後可申請退款退回繫結借記卡,適合現金緊缺的玩家!系統贈送您的遊戲兌換碼:'.$value['gc_code'].',可以在您的遊戲中進行使用,感謝您的支援!<br>如需幫助,請點選左上角【幫助】找到您的問題或者聯絡客服進行人工服務,QQ:2013609564'; add_player_msg($order_info['o_playerid'],$title,$content); } } } if($type=='jd'){ if($order_info['l_status']==3){ //執行業務處理 $up_arr = array( 'l_status' => 4, 'l_trade_no' => $trade_no, 'l_returntime' => THIS_DATETIME ); $up_where = " and l_orderid='".$out_trade_no."'"; $row = update_record($GLOBALS["conn"],'game_loan_order',$up_arr,array(),$up_where);//更新訂單資料 if($row>0){ $msg = "訂單 ".$out_trade_no." 已支付"; $log_msg = "call back:" . $msg; sys_log_write_content( $log_msg.__FILE__.__LINE__ ,"pay_log","notify_order_success"); } } } } //——請根據您的業務邏輯來編寫程式(以上程式碼僅作參考)—— echo "success"; //請不要修改或刪除 }else { //驗證失敗 echo "fail"; //請不要修改或刪除 } ?>