【网站支付PHP篇】thinkPHP集成支付宝支付(担保交易)
目錄
系列說明
開發環境
部署支付寶
支付請求
支付寶返回處理
系列說明
最近在幫朋友的系統安裝支付模塊(兌換網站積分),現在總結一些開發心得,希望對大家有用。這個系列會講以下第三方支付平臺的集成:
支付寶 https://www.alipay.com/
匯潮支付 http://www.ecpss.cn/new/index.htm
智付支付 http://www.dinpay.com/
環迅支付 http://www.ips.com/Default.aspx
以后有更新其他平臺也會寫出來。
這次的支付系統是用來網站的積分充值。為了簡化,這里采用的是1元RMB=1個網站積分的兌換。
這里,不會描述怎么申請支付平臺的收款帳號。
開發環境
ThinkPHP 3.1.2 (我用的是標準版)
win7 + Apache2
mysql 5.1
這里說一下數據庫的設計。
部署支付寶
我用的是支付寶擔保交易(即時到賬的門檻有點高=.=).先從支付寶網站下載擔保交易的demo(要注意編碼,我用的是utf-8)。
前往ThinkPHP目錄下的Extend,找到Vendor目錄(這個目錄是第三方類庫的存放目錄,如果沒有,手動創建一個,要標準版本里面是沒有的),然后在Vendor下創建Alipay目錄存在支付寶相關的文件。目錄結構如下:
接著修改 alipay.config.php 文件:
支付請求
配置好支付寶后,就可以進行支付請求了。支付寶的示例代碼很是詳細,很多可以直接用。
首先,創建OrderAction.class.php 來處理訂單相關的業務操作。
定義pay方法:
/**
* 支付訂單
*/
public function pay(){
$this->checkLogin();
header('Content-type: text/html; charset=utf-8');
$id = args("id", 0);
$DAO = new OrderModel();
$order = $DAO->where("id=".$id)->find();
$error = "";
if(!isset($order)){
$error = "訂單不存在";
}else if($order['status'] == 1){
$error = "此訂單已經完成,無需再次支付!";
} else if($order['status'] == 2){
$error = "此訂單已經取消,無法支付,請重新下單!";
}
if($error != ""){
$this->_FAIL("系統錯誤",$error,$this->getErrorLinks());
return ;
}
//支付寶
if($order['payment'] == 'alipay'){
$this->payWithAlipay($order);
}
else if($order['payment'] == 'ecpss'){
$this->payWithEcpss($order);
}
else if($order['payment'] == 'dinpay'){
$this->payWithDinpay($order);
}
}
然后再定義 payWithAlipay($order) 方法(根據具體情況修改相關的參數即可):
/**
* 以支付寶形式支付
* @param unknown_type $order
*/
private function payWithAlipay($order){
//引入支付寶相關的文件
require_once(VENDOR_PATH."Alipay/alipay.config.php");
require_once(VENDOR_PATH."Alipay/lib/alipay_submit.class.php");
//支付類型
$payment_type = "1";
//必填,不能修改
//服務器異步通知頁面路徑
$notify_url = C("HOST")."index.php/Order/notifyOnAlipay";
//頁面跳轉同步通知頁面路徑
$return_url = C("HOST")."index.php/Order";
//賣家支付寶帳戶
$seller_email = $alipay_config['seller_email'];
//必填
//商戶訂單號, 從訂單對象中獲取
$out_trade_no = $order['tradeNo'];
//商戶網站訂單系統中唯一訂單號,必填
//訂單名稱
$subject = $order['subject'];
//必填
//付款金額
$price = $order['price'];
//必填
$body = $order['subject'];
//商品展示地址
$show_url = C('HOST');
//構造要請求的參數數組,無需改動
$parameter = array(
"service" => "create_partner_trade_by_buyer",
"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,
"price"=> $price,
"quantity"=> "1",
"logistics_fee"=> "0.00",
"logistics_type"=> "EXPRESS",
"logistics_payment"=> "SELLER_PAY",
"body"=> $body,
"show_url"=> $show_url,
"receive_name"=> "",
"receive_address"=> "",
"receive_zip"=> "",
"receive_phone"=> "",
"receive_mobile"=> "",
"_input_charset"=> trim(strtolower($alipay_config['input_charset']))
);
//建立請求
$alipaySubmit = new AlipaySubmit($alipay_config);
$html_text = $alipaySubmit->buildRequestForm($parameter,"get", "去支付");
echo $html_text;
}
支付寶返回處理
最后是支付寶異步通知的處理函數(這里,我只對異步返回作處理):
/**
* 支付寶異步通知
*/
public function notifyOnAlipay(){
require_once(VENDOR_PATH."Alipay/alipay.config.php");
require_once(VENDOR_PATH."Alipay/lib/alipay_notify.class.php");
$orderLogDao = new OrderLogModel();
//計算得出通知驗證結果
$alipayNotify = new AlipayNotify($alipay_config);
$verify_result = $alipayNotify->verifyNotify();
if($verify_result) {//驗證成功
//商戶訂單號
$out_trade_no = $_POST['out_trade_no'];
//支付寶交易號
$trade_no = $_POST['trade_no'];
//根據訂單號獲取訂單
$DAO = new OrderModel();
$order = $DAO->where("tradeNo='".$out_trade_no."'")->find();
//如果訂單不存在,設置為0
if(!isset($order)){
$orderId = 0;
}
else{
$orderId = $order['id'];
}
//交易狀態
$trade_status = $_POST['trade_status'];
$log = "notify from Alipay, trade_status=".$trade_status." alipay sign=".$_POST['sign'];
$orderLog['order_id'] = $orderId;
$orderLog['addDate'] = sqlDate();
if($_POST['trade_status'] == 'WAIT_BUYER_PAY') {
//該判斷表示買家已在支付寶交易管理中產生了交易記錄,但沒有付款
}
/*
* 成功付款后,進行積分操作
*/
else if($_POST['trade_status'] == 'WAIT_SELLER_SEND_GOODS') {
//該判斷表示買家已在支付寶交易管理中產生了交易記錄且付款成功,但賣家沒有發貨
if(isset($order) && $order['status'] == 0){
$resultInfo = $this->doAfterPaySuccess($DAO, $order);
$log.= $resultInfo;
}
}
else if($_POST['trade_status'] == 'WAIT_BUYER_CONFIRM_GOODS') {
//該判斷表示賣家已經發了貨,但買家還沒有做確認收貨的操作
}
else if($_POST['trade_status'] == 'TRADE_FINISHED') {
//該判斷表示買家已經確認收貨,這筆交易完成
}
else {
}
/*
* 保存orderlog
*/
$orderLog['log'] = $log;
$orderLogDao->add($orderLog);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
echo "success"; //返回成功標記給支付寶
}
else {
//驗證不通過時,也記錄下來
$orderLog['log'] = "notify from Alipay, 但是驗證不通過,sign=".$_POST['sign'];
$orderLog['order_id'] = -1;
$orderLog['addDate'] = sqlDate();
$orderLogDao->add($orderLog);
//驗證失敗
echo "fail";
}
}
測試一筆,得到如下的結果:
總結
支付寶的集成還是比較簡單的,官方的教程很詳細。
這里要注意的是,
1、alipay.config.php 下的 cacert.pem 文件的路徑一定要對,之前我沒注意這點,結果出來以下的錯誤:
2、在notify_url中,一定只能返回 "success"或者"fail",也不能對這個url作登錄驗證的處理。
3、還要注意對網站訂單的反重復處理
總結
以上是生活随笔為你收集整理的【网站支付PHP篇】thinkPHP集成支付宝支付(担保交易)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qt程序卡死 linux,QtCreat
- 下一篇: WBS 与 甘特图