ThinkPHP整合支付宝担保交易
ThinkPHP整合支付宝担保交易
本代码参考大神 http://www.thinkphp.cn/code/240.html 的思路
1.登陆支付宝后台,下载担保交易的集成包。
2.下载完成后的文件说明:
纯担保交易接口-create_partner_trade_by_buyer(20151015)
确认发货接口-send_goods_confirm_by_platform(20150312)
根据自己需要去选择,需要说明下,先担保整合完成后才回去处理确认发货,因为确认发货时需要担保交易的支付宝交易编号
对应的代码文件结构───────<br>
create_partner_trade_by_buyer-php-UTF-8<br>
│<br>
├lib┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈类文件夹<br>
│ │<br>
│ ├alipay_core.function.php ┈┈┈┈┈┈支付宝接口公用函数文件<br>
│ │<br>
│ ├alipay_notify.class.php┈┈┈┈┈┈┈支付宝通知处理类文件<br>
│ │<br>
│ ├alipay_submit.class.php┈┈┈┈┈┈┈支付宝各接口请求提交类文件<br>
│ │<br>
│ └alipay_md5.function.php┈┈┈┈┈┈┈支付宝接口MD5函数文件<br>
│<br>
├log.txt┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈日志文件<br>
│<br>
├alipay.config.php┈┈┈┈┈┈┈┈┈┈┈┈基础配置类文件<br>
│<br>
├alipayapi.php┈┈┈┈┈┈┈┈┈┈┈┈┈┈支付宝接口入口文件<br>
│<br>
├notify_url.php ┈┈┈┈┈┈┈┈┈┈┈┈┈服务器异步通知页面文件<br>
│<br>
├return_url.php ┈┈┈┈┈┈┈┈┈┈┈┈┈页面跳转同步通知文件<br>
│<br>
├cacert.pem ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈用于CURL中校验SSL的CA证书文件<br>
│<br>
└readme.txt ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈使用说明文本
这里我们先处理代码
3.核心处理代码
把lib目录文件下的4个核心文件放入 ThinkPHP/Library/Vendor/Alipay 下
修改文件名为:alipay_core.function.php -> Corefunction.php<br>
alipay_notify.class.php -> Notify.php<br>
alipay_submit.class.php -> Submit.php<br>
alipay_md5.function.php -> Md5function.php<br>
其中 Notify.php 和 Md5function.php 需要删除前面引入的两行代码
require_once("alipay_core.function.php");
require_once("alipay_md5.function.php");
因为在使用TP第三方扩展类的时候会自动引入他需要的这两个文件
核心框架整合完成之后我们来整理逻辑代码。
4.逻辑代码整理
首先我们把 签名文件 cacert.pem 放在网站的跟目录,其他目录也行,不过需要有访问权限的
然后在公共配置文件conf.php中添加 支付宝配置 //支付宝配置参数<br>
'alipay_config'=>array(<br>
'partner' =>'2088**********************', //这里是你在成功申请支付宝接口后获取到的PID;<br>
'key'=>'ob4x7k0*************************',//这里是你在成功申请支付宝接口后获取到的Key<br>
'sign_type'=>strtoupper('MD5'),<br>
'input_charset'=> strtolower('utf-8'),<br>
'cacert'=> getcwd().'\\cacert.pem',//liunx这里需要注意 \\ 和 / 在liunx的区别<br>
'transport'=> 'http',<br>
'seller_email'=>'775919499@qq.com',// 这里是你的收款账号,<br>
),<br>
//以上配置项,是从接口包中alipay.config.php 文件中复制过来,进行配置;<br>
'alipay' =>array(<br>
//这里是异步通知页面url,提交到项目的Pay控制器的notifyurl方法;<br>
'notify_url'=>'http://www.loveteemo.com/Pay/notifyurl', <br>
//这里是页面跳转通知url,提交到项目的Pay控制器的returnurl方法;<br>
'return_url'=>'http://www.loveteemo.com/Pay/returnurl',<br>
),
然后去创建一个 Key 控制器,然后处理代码:<?php <br />
namespace Home\Controller;<br>
use Think\Controller;<br>
class KeyController extends Controller {<br>
//利用构造函数引入核心文件<br>
public function _initialize() {<br>
vendor('Alipay.Corefunction');<br>
vendor('Alipay.Md5function');<br>
vendor('Alipay.Notify');<br>
vendor('Alipay.Submit'); <br>
}<br>
//首页,用来展示商品页<br>
public function index(){<br>
$this->display();<br>
}<br>
//订单页,我写死了的,可以根据自己需要进行修改<br>
public function order(){<br>
$type = I('get.type');<br>
if($type==1){<br>
$date = array('type'=>1,"price"=>'0.01',"name"=>"《火星救援》");<br>
}elseif($type==2){<br>
$date = array('type'=>2,"price"=>'0.01',"name"=>"《死神的精确度》");<br>
}elseif($type==3){<br>
$date = array('type'=>3,"price"=>'0.01',"name"=>"《寂寞是毒,也是解药》");<br>
}elseif($type==4){<br>
$date = array('type'=>4,"price"=>'0.01',"name"=>"《只要不忘了回家的路》");<br>
}elseif($type==5){<br>
$date = array('type'=>5,"price"=>'0.01',"name"=>"《异想星球 hello,我是托比小黑》");<br>
}elseif($type==6){<br>
$date = array('type'=>6,"price"=>'0.01',"name"=>"《张鸣说历史:大国的虚与实》");<br>
}<br>
$this->time = time();<br>
$this->assign("data",$date);<br>
$this->display();<br>
}<br>
//订单页点击提交,传递必要参数后开始支付,可自行修改<br>
public function payorder(){<br>
//传递数组配置<br>
$alipay_config=C('alipay_config');<br>
/**************************请求参数**************************/<br>
//支付类型<br>
$payment_type = "1"; //必填,不能修改<br>
//服务器异步通知页面路径<br>
$notify_url = C('alipay.notify_url'); //需http://格式的完整路径,不能加?id=123这类自定义参数<br>
//页面跳转同步通知页面路径<br>
$return_url = C('alipay.return_url'); //需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/<br>
//商户订单号<br>
$out_trade_no = $_POST['orderid']; //商户网站订单系统中唯一订单号,必填<br>
//订单名称<br>
$subject = $_POST['ordername']; //必填<br>
//付款金额<br>
$price = $_POST['orderprice']; //必填<br>
//商品数量<br>
$quantity = "1"; //必填,建议默认为1,不改变值,把一次交易看成是一次下订单而非购买一件商品<br>
//物流费用<br>
$logistics_fee = "0.00"; //必填,即运费<br>
//物流类型<br>
$logistics_type = "EXPRESS"; //必填,三个值可选:EXPRESS(快递)、POST(平邮)、EMS(EMS)<br>
//物流支付方式<br>
$logistics_payment = "SELLER_PAY"; //必填,两个值可选:SELLER_PAY(卖家承担运费)、BUYER_PAY(买家承担运费)<br>
//订单描述<br>
$body = $_POST['orderbody'];<br>
//商品展示地址<br>
$show_url = $_POST['ordershow']; //需以http://开头的完整路径,如:http://www.商户网站.com/myorder.html<br>
//收货人姓名<br>
$receive_name = $_POST['user_name']; //如:张三<br>
//收货人地址<br>
$receive_address = $_POST['user_address']; //如:XX省XXX市XXX区XXX路XXX小区XXX栋XXX单元XXX号<br>
//收货人邮编<br>
$receive_zip = $_POST['user_zip']; //如:123456<br>
//收货人电话号码<br>
$receive_phone = $_POST['user_phone']; //如:0571-88158090<br>
//收货人手机号码<br>
$receive_mobile = $_POST['user_mobile']; //如:13312341234<br>
/************************************************************/<br>
<br>
//构造要请求的参数数组,无需改动<br>
$parameter = array(<br>
"service" => "create_partner_trade_by_buyer",<br>
"partner" => trim($alipay_config['partner']),<br>
"seller_email" => trim($alipay_config['seller_email']),<br>
"payment_type"=> $payment_type,<br>
"notify_url"=> $notify_url,<br>
"return_url"=> $return_url,<br>
"out_trade_no"=> $out_trade_no,<br>
"subject"=> $subject,<br>
"price"=> $price,<br>
"quantity"=> $quantity,<br>
"logistics_fee"=> $logistics_fee,<br>
"logistics_type"=> $logistics_type,<br>
"logistics_payment"=> $logistics_payment,<br>
"body"=> $body,<br>
"show_url"=> $show_url,<br>
"receive_name"=> $receive_name,<br>
"receive_address"=> $receive_address,<br>
"receive_zip"=> $receive_zip,<br>
"receive_phone"=> $receive_phone,<br>
"receive_mobile"=> $receive_mobile,<br>
"_input_charset"=> trim(strtolower($alipay_config['input_charset']))<br>
);<br>
//存入数据库订单信息 static为99是无效订单<br>
M('test')->add(array("orderid"=>$out_trade_no,"addtime"=>time(),"ordername"=>$subject,"orderprice"=>$price,"static"=>99));<br>
//建立请求<br>
$alipaySubmit = new \AlipaySubmit($alipay_config);<br>
//dump($alipaySubmit);die;<br>
$html_text = $alipaySubmit->buildRequestForm($parameter,"get", "确认");<br>
echo $html_text;<br>
}<br>
/****************************** 服务器异步通知页面方法 *******************************/<br>
public function notifyurl(){<br>
//防止乱码<br>
header("Content-Type:text/html;charset=utf-8");<br>
//计算得出通知验证结果<br>
$alipay_config=C('alipay_config');<br>
$alipayNotify = new \AlipayNotify($alipay_config);<br>
$verify_result = $alipayNotify->verifyNotify();<br>
if($verify_result) {//验证成功<br>
//商户订单号<br>
logResult("订单编号:".$_POST['out_trade_no'].",状态".$_POST['trade_status']."");<br>
$out_trade_no = $_POST['out_trade_no'];<br>
//支付宝交易号<br>
$trade_no = $_POST['trade_no'];<br>
//交易状态<br>
$trade_status = $_POST['trade_status'];<br>
if($_POST['trade_status'] == 'WAIT_BUYER_PAY') {<br>
//该判断表示买家已在支付宝交易管理中产生了交易记录,但没有付款<br>
//判断该笔订单是否在商户网站中已经做过处理<br>
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序<br>
//如果有做过处理,不执行商户的业务程序<br>
echo "success";//请不要修改或删除<br>
//调试用,写文本函数记录程序运行情况是否正常<br>
//获取支付宝的订单号后写入数据库,修改订单状态为0 待支付<br>
M('test')->where(array("orderid"=>$out_trade_no))->save(array("static"=>0,"lasttime"=>time(),'payid'=>$trade_no));<br>
//文本日志文件,这里的日志文件会在网站根目录生成一个log.txt文件<br>
logResult("这里是等待付款");<br>
}<br>
else if($_POST['trade_status'] == 'WAIT_SELLER_SEND_GOODS') {<br>
//该判断表示买家已在支付宝交易管理中产生了交易记录且付款成功,但卖家没有发货<br>
//判断该笔订单是否在商户网站中已经做过处理<br>
//买家支付后,修改状态为已支付代发货<br>
M('test')->where(array("orderid"=>$out_trade_no))->save(array("static"=>1,"lasttime"=>time()));<br>
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序<br>
//如果有做过处理,不执行商户的业务程序<br>
echo "success";//请不要修改或删除<br>
//调试用,写文本函数记录程序运行情况是否正常<br>
logResult("支付完成!订单编号:".$out_trade_no.",状态".$_POST['trade_status']."");<br>
}<br>
else if($_POST['trade_status'] == 'WAIT_BUYER_CONFIRM_GOODS') {<br>
//该判断表示卖家已经发了货,但买家还没有做确认收货的操作<br>
//判断该笔订单是否在商户网站中已经做过处理<br>
//发货完成后会修改状态<br>
M('test')->where(array("orderid"=>$out_trade_no))->save(array("static"=>2,"lasttime"=>time()));<br>
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序<br>
//如果有做过处理,不执行商户的业务程序<br>
echo "success";//请不要修改或删除<br>
//调试用,写文本函数记录程序运行情况是否正常<br>
logResult("发货完成,等待买家收货");<br>
}<br>
else if($_POST['trade_status'] == 'TRADE_FINISHED') {<br>
//该判断表示买家已经确认收货,这笔交易完成<br>
//判断该笔订单是否在商户网站中已经做过处理<br>
//买家收货后订单完成<br>
M('test')->where(array("orderid"=>$out_trade_no))->save(array("static"=>3,"lasttime"=>time()));<br>
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序<br>
//如果有做过处理,不执行商户的业务程序<br>
echo "success";//请不要修改或删除<br>
//调试用,写文本函数记录程序运行情况是否正常<br>
logResult("交易完成!");<br>
}<br>
else {<br>
//其他状态判断<br>
echo "success";<br>
//调试用,写文本函数记录程序运行情况是否正常<br>
logResult ("错误");<br>
}<br>
}<br>
else {<br>
//验证失败<br>
echo "fail";<br>
//调试用,写文本函数记录程序运行情况是否正常<br>
logResult("验证失败");<br>
}<br>
}<br>
<br>
/* 页面跳转处理方法; */<br>
public function returnurl(){<br>
$alipay_config=C('alipay_config');<br>
//计算得出通知验证结果<br>
$alipayNotify = new \AlipayNotify($alipay_config);<br>
$verify_result = $alipayNotify->verifyReturn();<br>
if($verify_result) {//验证成功<br>
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——<br>
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表<br>
//商户订单号<br>
$out_trade_no = $_GET['out_trade_no'];<br>
//支付宝交易号<br>
$trade_no = $_GET['trade_no'];<br>
//交易状态<br>
$trade_status = $_GET['trade_status'];<br>
if($_GET['trade_status'] == 'WAIT_SELLER_SEND_GOODS') {<br>
//判断该笔订单是否在商户网站中已经做过处理<br>
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序<br>
//如果有做过处理,不执行商户的业务程序<br>
}<br>
//<br>
else {<br>
echo "trade_status=".$_GET['trade_status'];<br>
}<br>
$this->assign("payid",$trade_no);<br>
}<br>
else {<br>
//验证失败<br>
//如要调试,请看alipay_notify.php页面的verifyReturn函数<br>
echo "验证失败";<br>
}<br>
$this->display();<br>
}<br>
//自动发货 利用隐藏表单传递必须数据过来<br>
public function sendgoods(){<br>
$alipay_config=C('alipay_config');<br>
/**************************请求参数**************************/<br>
//支付宝交易号<br>
$trade_no = $_POST['WIDtrade_no'];<br>
//必填<br>
//物流公司名称<br>
$logistics_name = $_POST['WIDlogistics_name'];<br>
//必填<br>
//物流发货单号<br>
$invoice_no = $_POST['WIDinvoice_no'];<br>
//物流运输类型<br>
$transport_type = $_POST['WIDtransport_type'];<br>
//三个值可选:POST(平邮)、EXPRESS(快递)、EMS(EMS)<br>
/************************************************************/<br>
//构造要请求的参数数组,无需改动<br>
$parameter = array(<br>
"service" => "send_goods_confirm_by_platform",<br>
"partner" => trim($alipay_config['partner']),<br>
"trade_no"=> $trade_no,<br>
"logistics_name"=> $logistics_name,<br>
"invoice_no"=> $invoice_no,<br>
"transport_type"=> $transport_type,<br>
"_input_charset"=> trim(strtolower($alipay_config['input_charset']))<br>
);<br>
//建立请求<br>
$alipaySubmit = new \AlipaySubmit($alipay_config);<br>
$html_text = $alipaySubmit->buildRequestHttp($parameter);<br>
//解析XML<br>
//注意:该功能PHP5环境及以上支持,需开通curl、SSL等PHP配置环境。建议本地调试时使用PHP开发软件<br>
$doc = new \DOMDocument();<br>
$doc->loadXML($html_text);<br>
//请在这里加上商户的业务逻辑程序代码<br>
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——<br>
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表<br>
//解析XML<br>
if( ! empty($doc->getElementsByTagName( "alipay" )->item(0)->nodeValue) ) {<br>
$alipay = $doc->getElementsByTagName( "alipay" )->item(0)->nodeValue;<br>
//echo $alipay;<br>
//M('test')->where(array("orderid"=>$out_trade_no))->save(array("static"=>2,"lasttime"=>time()));<br>
$this->success("自动发货完成!","/Home/Key/lists");<br>
}<br>
}<br>
//筛选无效订单后展示<br>
public function lists(){<br>
$lists = M('test')->where("static != 99")->limit(20)->order("id desc")->select();<br>
$this->assign("lists",$lists);<br>
$this->display();<br>
}<br>
}[code]到这里基本的业务逻辑就完成了,附带测试的数据库给大家分享下[code]CREATE TABLE `web_test` (<br>
`id` int(11) NOT NULL AUTO_INCREMENT,<br>
`orderid` varchar(16) NOT NULL,<br>
`ordername` varchar(128) NOT NULL,<br>
`orderprice` varchar(16) NOT NULL,<br>
`static` int(11) NOT NULL COMMENT '0为未支付,1为已支付未发货,2为发货为确认收,3为确认收,4为取消',<br>
`addtime` int(11) NOT NULL,<br>
`lasttime` int(11) NOT NULL,<br>
`payid` varchar(32) NOT NULL,<br>
PRIMARY KEY (`id`),<br>
UNIQUE KEY `orderid` (`orderid`)<br>
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
5.需要注意的地方:
签名的目录,上面有说过,签名的目录在liunx和windows是有区别的,liunx需要改成 'cacert'=> getcwd().'/cacert.pem',
不然会报错说签名没找到
在部署完成后测试的时候会遇到有些浏览器乱码,谷歌正常
这里需要注意的是TP在异步的时候会出现,在urldecode的时候中文出现乱码,所以在这里我在前面加一行代码防止乱码header("Content-Type:text/html;charset=utf-8");
本地测试异步中写操作数据库是没任何意义的
因为异步需要服务器上测试才行的。
打个广告
个人博客 青春博客 www.loveteemo.com 欢迎大家来访
原本链接:http://loveteemo.com/article-130.html
AD:真正免费,域名+虚机+企业邮箱=0元

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

了解Python程式設計的入門程式碼範例Python是一種簡單易學,功能強大的程式語言。對於初學者來說,了解Python程式設計的入門級程式碼範例是非常重要的。本文將為您提供一些具體的程式碼範例,幫助您快速入門。列印HelloWorldprint("HelloWorld")這是Python中最簡單的程式碼範例。 print()函數用於將指定的內容輸出

PHP變數儲存程式運行期間的值,對於建立動態且互動的WEB應用程式至關重要。本文將深入探討php變量,並透過10個真實的範例展示它們的實際應用。 1.儲存使用者輸入$username=$_POST["username"];$passWord=$_POST["password"];此範例從表單提交中提取使用者名稱和密碼,並將其儲存在變數中以供進一步處理。 2.設定配置值$database_host="localhost";$database_username="username";$database_pa

《Go語言程式設計實例:Web開發中的程式碼範例》隨著網路的快速發展,Web開發已成為各行業中不可或缺的一部分。作為一門功能強大且效能優越的程式語言,Go語言在Web開發中越來越受到開發者們的青睞。本文將透過具體的程式碼範例,介紹如何利用Go語言進行Web開發,讓讀者更能理解並運用Go語言來建立自己的Web應用。 1.簡單的HTTP伺服器首先,讓我們從一個

Java冒泡排序最簡單的程式碼範例冒泡排序是一種常見的排序演算法,它的基本想法是透過相鄰元素的比較和交換來將待排序序列逐步調整為有序序列。以下是一個簡單的Java程式碼範例,示範如何實作冒泡排序:publicclassBubbleSort{publicstaticvoidbubbleSort(int[]arr){int

如何使用PHP編寫庫存管理系統中的庫存分倉管理功能碼庫存管理是許多企業中不可或缺的一部分。對於擁有多個倉庫的企業來說,庫存分倉管理功能尤其重要。透過合理管理和追蹤庫存,企業可以實現不同倉庫之間的庫存調撥,優化營運成本,改善協同效率。本文將介紹如何使用PHP編寫庫存分倉管理功能的程式碼,並為您提供相關的程式碼範例。一、建立資料庫在開始編寫庫存分倉管理功能的程式碼之

華為雲端邊緣運算對接指南:Java程式碼範例快速實現介面隨著物聯網技術的快速發展和邊緣運算的興起,越來越多的企業開始關注邊緣運算的應用。華為雲端提供了邊緣運算服務,為企業提供了高可靠的運算資源和便利的開發環境,使得邊緣運算應用更容易實現。本文將介紹如何透過Java程式碼快速實現華為雲端邊緣運算的介面。首先,我們需要準備好開發環境。確保你已經安裝了Java開發工具包(

標題:從入門到精通:Go語言中常用資料結構的程式碼實作資料結構在程式設計中起著至關重要的作用,它是程式設計的基礎。在Go語言中,有許多常用的資料結構,掌握這些資料結構的實作方式對於成為優秀的程式設計師至關重要。本文將介紹Go語言中常用的資料結構,並給出對應的程式碼範例,幫助讀者從入門到精通這些資料結構。 1.數組(Array)數組是一種基本的資料結構,是一組相同類型

Java選擇排序法程式碼編寫指南及範例選擇排序是一種簡單直觀的排序演算法,其想法是每次從未排序的元素中選擇最小(或最大)的元素進行交換,直到所有元素排序完成。本文將提供選擇排序的程式碼編寫指南,並附上具體的Java範例程式碼。演算法原理選擇排序的基本原理是將待排序數組分為已排序和未排序兩部分,每次從未排序部分選擇最小(或最大)的元素,將其放到已排序部分的末尾。重複上述
