tp5.1 集成支付宝支付方法(二)

引用:

https://blog.csdn.net/weixin_42122979/article/details/80899552

https://github.com/dream2023/ThinkPHP5-alipay

http://www.thinkphp.cn/code/3593.html

 

源码在上面中下载(原文是5.0以版本以前的用法,5.1版本用法需要修改才能用)

使用说明

  • 在默认配置情况下,将文件夹拷贝到根目录即可, 其中extend目录为支付扩展目录, application\extra\alipay.php为配置文件
  • 需要在配置文件application\extra\alipay.php中填写必要的参数(TP5.1版本,这个用法不行)

1.调用配置文件用法:

方法一:固定值法  并将上边代码复制进去,放到 /config/app.php文件中

tp5.1 集成支付宝支付方法(二)_第1张图片

    // +----------------------------------------------------------------------
    // | 支付宝支付参数
    // +----------------------------------------------------------------------
//	'alipay'=>[
//		//应用ID,您的APPID。
//		'app_id' => "2016090000241",
//
//		//商户私钥
//		'merchant_private_key' => "MIIEowIBAAKCAQEAsBUqNm8NAKnukhMSFNBUlogaiZxwbM3usQQQrnpcCPhmuwqdekjkSS7eBnql5K21N641uR05G+7M1teqz1nn39lPO1pmOQj21jxwEyIZvAFn+RJGQCO+C/853nOEQ7/WACg4FUplTHZukMZA9z438yomc2C+DqcUD/j9XgIC5W2ZdQfXy0elL4Ciq7IT0HYJojS0/Vk1Qf2kPDFCNcNOB1irNL99eZ1ENsuf82CCmw9tVrcWhZ5Jt6n7vyVOp8P5IIsamTk/KvG6Px/8iqccY83Fg0wvn2sWw49vB3YHD7lTQfwBnZHwQ4WmKh6j+na/MdmEat96StMjaylf4hF/TQIDAQABAoIBAGtWG4tfGqAC9qkY8va5IDc69GJaeLX6urwxbDHP6PaW5ZizGdgHQxHRfgqZDTNfKI6upZUYWU3LvhZhFYCcn5p3D7Nwocu2yTFDWlZvfRx8BvNvzl8e6qTJim8uH7xk3oDuA3IHDcUUlMWv9L5CsTyLvzCqEnFALByofVqnAzjzGHFO/PRWpGyPw6gvQyR1yrL8BMQOn+RIUGeJl25TuJzS+X6uOVbdO3I3WKyyyJ6tZbKAxlUY0H2XruPwH/cJZ0h8sLRihRn1ZDnzhJiKPvirwAoLvVU7KwmA5wikFbU7voTqCtxzrrR+zKLzjpu/qQbOQKBgG4iZDMngawdxr/FfNA2uPJKTOniF3TD6roGDjcCmR/Y/47r1CUpEaIOLwuG4GXyRnWT3Lo7a1ve4oTudUhGKtrjPlxPGFqC7MMabknREEDnfjAqLM0tPkhnb1qvRMltepe5fS0kEDEg5Qo9aktJd1wLJ09dWnv7ijh+Bc6l+gin",
//		
//		//异步通知地址
//		'notify_url' => "http://www.81.com/00/notify_url.php",
//		
//		//同步跳转
//		'return_url' => "http://www.81.com/00/return_url.php",
//
//		//编码格式
//		'charset' => "UTF-8",
//
//		//签名方式
//		'sign_type'=>"RSA2",
//
//		//支付宝网关
//		'gatewayUrl' => "https://openapi.alipaydev.com/gateway.do",
//
//		//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
//		'alipay_public_key' => "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QV6KrPDrmAPdFc1EqTsPO7kdlHhvs09noSEV4NUxO4XPyz5E62eJRxPlcBuSD1yzM84xBTNXo6WgTM6XuxvM74Bs6hXVm/WcZxSLIGAZ5N9tymx9+09fOMejOObydP/HIi6sfcyQeHBR7owHe9GP4fsSzMQIDAQAB",
//    ]

方法二:动态值法  就是把这些参数保存到数据库中,然后再读出来

在公共文件中读出(路径:/application/common.php),组成数组$config

tp5.1 集成支付宝支付方法(二)_第2张图片

//支付宝支付参数
function alipay_confing(){
	$config['app_id']='20100919000241';
	$config['merchant_private_key']='MIIEowIBAAKCAQEAsBUqNm8NAKnukhMSFNBUlogaiZxwbM3usQQQrnpcCPhmuwqdekjkSS7eBnql5K21N641uR05G+7M1teqz1ng5Qo9aktJd1wLJ09dWnv7ijh+Bc6l+gin';
	$config['notify_url']='';
	$config['return_url']='';
	$config['charset']='UTF-8';
	$config['sign_type']='RSA2';
	$config['gatewayUrl']='https://openapi.alipaydev.com/gateway.do';
	$config['alipay_public_key']='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QV6KrPDrmAPdFc1EqTsPO7kdlHhvs09noSEV4NUxO4XPyz5E62eJRxPlcBuSD1yzM84xBTNXo6WgTM6XuxvM74Bs6hXVm/WcZxSLIGAZ5N9tymx9+09fOMejOObydP/GOrEAV4KF5tB65+/aq4+rvp0w/QlhfmMHwjaazLXmdBjSzXj5x1v0Ep2uzPG4SgH+XCvM6SCN0mvSIKdZDPtIowPlpLXOqzMQIDAQAB';
	
	return $config;
	
}

调用:在\extend\alipay\Pagepay.php文件中调用

$config=alipay_confing();

tp5.1 集成支付宝支付方法(二)_第3张图片

 

 

注意

错误采用抛出异常的方式, 可根据自己的业务在统一接口进行修改

用法

电脑网站支付 Pagepay.php

调用 \alipay\Pagepay::pay($params) 即可

手机网站支付 Wappay.php

调用 \alipay\Wappay::pay($params) 即可

交易查询接口 Query.php

调用 \alipay\Query::exec($query_no) 即可

交易退款接口 Refund.php

调用 \alipay\Refund::exec($params) 即可

退款统一订单查询 RefundQuery.php

调用 \alipay\RefundQuery::exec($params) 即可

交易关闭接口 Close.php

调用 \alipay\Close::exec($query_no) 即可

查询账单下载地址接口 Datadownload.php

调用 \alipay\Datadownload::exec($bill_type, $bill_date) 即可

验签 Notify.php

调用 \alipay\Notify::check($params) 即可

通知处理步骤建议

  1. 验签
  2. 判断订单状态
  3. 进行业务操作

一下两个类仅为建议, 帮助理解, 可根据具体业务进行变更, 详细理解可参考官方文档和SDK

  • application\common\NotifyHandler.php 通知操作的处理类
  • application\example\Notify.php 具体实现

 

5.1版本需要修改,

5.1版取消了import()这种引入类方法

所以需要上面用到import()方法的,都要换成require

tp5.1 集成支付宝支付方法(二)_第4张图片

//Loader::import('alipay.pay.service.AlipayTradeService');
require '../extend/alipay/pay/service/AlipayTradeService.php';

 

 

调用:

class Notify extends NotifyHandler
{
    protected $params; // 订单信息
    
    public function index()
    {
        parent::init();
    }
	
    public function play()
    {
       $this->getorder();
        $ass =  \alipay\Pagepay::pay($this->params);
    }

    /**
     * 获取订单信息, 必须包含订单号和订单金额
     *
     * @return string $params['out_trade_no'] 商户订单
     * @return float  $params['total_amount'] 订单金额
     */
    public function getOrder()
    {
        // 以下仅示例
//      $out_trade_no = $_POST['out_trade_no'];
//      $order = Db::name('order')->where('out_trade_no', $out_trade_no)->find();
        $out_trade_no = time().rand(1000,9999);
//		$order = arrar(
//		   'out_trade_no' = $out_trade_no,
//		   'total_amount' = 0.1,
//		   'status' = 0,
//		   'id' = 1,
//		   'subject' = '测试',
//		);
        $params = [
            'out_trade_no' => $out_trade_no,
            'total_amount' => 0.1,
            'status'       => 0,
            'id'           => 1,
            'subject'      => '测试'
        ];

        $this->params = $params;
    }

    /**
     * 检查订单状态
     *
     * @return Boolean true表示已经处理过 false表示未处理过
     */
    public function checkOrderStatus()
    {
        // 以下仅示例
        if($this->params['status'] == 0) {
            // 表示未处理
            return false;
        } else {
            return true;
        }
    }

    /**
     * 业务处理
     * @return Boolean true表示业务处理成功 false表示处理失败
     */
    public function handle()
    {
        // 以下仅示例
        $result = Db::name('order')->where('id', $this->params['id'])->update(['status'=>1]);
        if($result) {
            return true;
        } else {
            return false;
        }
    }
}

 

 

例子:

1、把支付宝文件放到:\extend\alipay\里边

支付宝文件包在这里下载:https://download.csdn.net/download/haibo0668/10558364

2、在TP5.1控制器中代码

assign([            
           'number' => $number
        ]); 
		 
        return $this->fetch();
    }
	
	//支付
    public function payment()
    {
    	//$params=input('post.');
        $this->getOrder();
		//\alipay\Pagepay::pay($this->params);//支付宝电脑PC扫码支付
		\alipay\Wappay::pay($this->params);//支付宝移动支付

    }
	
     /**
     * 获取订单信息, 必须包含订单号和订单金额
     *
     * @return string $params['out_trade_no'] 商户订单
     * @return float  $params['total_amount'] 订单金额
     */
    public function getOrder()
    {
       
    	 $number=input('WIDout_trade_no');//订单号
		 $title=input('WIDsubject');//订单名称
		 $price=input('WIDtotal_amount');//总价格 如果购买多个商品,就是多个商品的总价
		 $state=0;//状态 0未支付 1已支付
		 $type=4;//支付类型 1=微信扫码  2=微信公众号 3=微信H5支付 4=支付宝PC电脑扫码 5=支付宝移动  6=银联 
		 $type_state=0;//订单类型 0单个购买 1购买多个商品
		 
	  	   $data['number']=$number;
	       $data['title']=$title;
		   $data['price']=$price;
	  	   $data['state']=$state;
		   $data['type']=$type;
		   $data['type_state']=$type_state;
		   
          //生成订单表
           if(!$number || !$price || !$title){
           	   $this->error('错误:订单号、价格、3标题不能为空!',url('index'));
           }

				$order_rs=db('order')->insert($data);	
				
				if($order_rs){
			          //传递参数到支付宝接口文件中
					  	   $params['out_trade_no']=$number;
					       $params['subject']=$title;
						   $params['total_amount']=$price;
				}else{//生成订单失败 返回错误信息
                           $this->error('生成订单表失败!',url('index'));
				}

   
        $this->params = $params;
    }
 
 
	/* *
	 * 功能:支付宝页面跳转同步通知页面
	 * 版本:2.0
	 * 修改日期:2017-05-01
	 * 说明:
	 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
	
	 *************************页面功能说明*************************
	 * 该页面可在本机电脑测试
	 * 可放入HTML等美化页面的代码、商户业务逻辑程序代码
	 */
    public function return_url()
    {  
    	    $params=input('get.');
			$result = \alipay\Notify::check($params);
			//$result = \alipay\Notify::check($this->params);
			if($result) {//验证成功

				//获取支付成功后支付宝返回的参数
	                $out_trade_no = htmlspecialchars(input('out_trade_no'));//商户订单号
					$total_amount=htmlspecialchars(input('total_amount'));//价格
					$app_id=htmlspecialchars(input('app_id'));//应用ID
					$trade_no = htmlspecialchars(input('trade_no'));//支付宝交易号
					
									
				
						   $data['state']=1;
					  	   $data['pay_number']=$trade_no;
						   $data['pay_time']=date("Y-m-d H:i:s",time());
						   						   
						   Db::name('order')->where('number', $out_trade_no)->update($data);
						   echo "支付成功!";
				
						
			
			} else {
			    //验证失败
			    echo "支付失败3";die;
			}
    }
	
	
	/* *
	 * 功能:支付宝服务器异步通知页面
	 * 版本:2.0
	 * 修改日期:2017-05-01
	 * 说明:
	 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
	
	 *************************页面功能说明*************************
	 * 创建该页面文件时,请留心该页面文件中无任何HTML代码及空格。
	 * 该页面不能在本机电脑测试,请到服务器上做测试。请确保外部可以访问该页面。
	 * 如果没有收到该页面返回的 success 信息,支付宝会在24小时内按一定的时间策略重发通知
	 * 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等;
	 * 支付宝是用POST方式发送通知信息,因此该页面中获取参数的方式,如:request.Form(“out_trade_no”)、$_POST[‘out_trade_no’];
	 * 支付宝主动发起通知,该方式才会被启用;
	 * 只有在支付宝的交易管理中存在该笔交易,且发生了交易状态的改变,支付宝才会通过该方式发起服务器通知(即时到账交易状态为“等待买家付款”的状态默认是不会发送通知的);
	 * 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的;
	 * 第一次交易状态改变(即时到账中此时交易状态是交易完成)时,不仅会返回同步处理结果,而且服务器异步通知页面也会收到支付宝发来的处理结果通知;
	 * 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);
	 * 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到success字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知;
	 * cookies、session等在此页面会失效,即无法获取这些数据;
	 * 该方式的调试与运行必须在服务器上,即互联网上能访问;
	 * 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理;
	 * 当商户收到服务器异步通知并打印出success时,服务器异步通知参数notify_id才会失效。也就是说在支付宝发送同一条异步通知时(包含商户并未成功打印出success导致支付宝重发数次通知),服务器异步通知参数notify_id是不变的。
	 * 
	 * 需要严格按照如下描述校验通知数据的正确性。

	 * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
	 * 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
	 * 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),
	 * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。
	 *状态TRADE_SUCCESS的通知触发条件是商户签约的产品支持退款功能的前提下,买家付款成功;
	 *交易状态TRADE_FINISHED的通知触发条件是商户签约的产品不支持退款功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。
	 */
    public function notify_url()
    {
//					//require_once 'config.php';
//					        //require_once 'pagepay/service/AlipayTradeService.php';
//					require '../extend/alipay/pay/service/AlipayTradeService.php';
//					
					//$params=input('');
//					$arr=input('post.');
//					$config=alipay_confing();//传入支付宝参数
//					$alipaySevice = new AlipayTradeService($config); 
//					$alipaySevice->writeLog(var_export($_POST,true));
                    $params=input('post.');
					$result = \alipay\Notify::check($params);
					//$result = \alipay\Notify::check($this->params);
					

					if($result) {//验证成功
					
							//获取支付成功后支付宝返回的参数
					                $out_trade_no = htmlspecialchars(input('out_trade_no'));//商户订单号
									$total_amount=htmlspecialchars(input('total_amount'));//价格
									$app_id=htmlspecialchars(input('app_id'));//应用ID
									$trade_no = htmlspecialchars(input('trade_no'));//支付宝交易号
									
									$trade_status = htmlspecialchars(input('trade_status'));//交易状态
									$out_biz_no = htmlspecialchars(input('out_biz_no'));//商户业务ID,主要是退款通知中返回退款申请的流水号
									$gmt_payment = htmlspecialchars(input('gmt_payment'));//交易付款时间
									$buyer_id = htmlspecialchars(input('buyer_id'));//买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字
									
									//判断转跳通知中是否成功记录
									$rs=db('order')->where('number', $out_trade_no)->where('pay_number',$trade_no)->find();
									if($rs['state']){//state=1 成功记录
													   $data['pay_time']=$gmt_payment;
													   $data['pay_biz']=$out_biz_no;
													   $data['pay_buyer_id']=$buyer_id;
													   Db::name('order')->where('number', $out_trade_no)->update($data);
													   
										     echo "success";	//请不要修改或删除
									}else{//转跳通知不成功记录  需要重新记录
									
											if($trade_status=="TRADE_SUCCESS" || $trade_status=="TRADE_FINISHED"){//支付成功
												
													   $data['state']=1;
												  	   //$data['pay_number']=$trade_no;
													   //$data['pay_time']=date("Y-m-d H:i:s",time());
													   $data['pay_time']=$gmt_payment;
													   $data['pay_biz']=$out_biz_no;
													   $data['pay_buyer_id']=$buyer_id;
													   Db::name('order')->where('number', $out_trade_no)->update($data);
													   
													 echo "success";	//请不要修改或删除
											}else{
												     echo "fail";
											}
									}
									

								
				

					}else {
					    //验证失败
					    echo "fail";
					
					}	
	}

}

公共文件的函数

//生成唯一订单号
function generate_order_number(){
	    return date('YmdHis').rand(100,999);
    //return date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}

 

模板:



	
	支付宝电脑网站支付
	



支付宝电脑网站支付体验入口页

付 款

商户订单号 :

订单名称 :

付款金额 :

商品描述:

如果您点击“付款”按钮,即表示您同意该次的执行操作。

 

你可能感兴趣的:(thinkphp5,支付宝)