支付宝电脑网站版支付

电脑网站支付封装。以下是alipay.php的内容

<?php
/**
* @user : wy
* @date : 2018年7月23日
* @desc : 支付宝支付对接
**/
namespace Alipay;
use think\Exception;

class Alipay {
	private $_config = [];
	public function __construct(){
		require_once 'config.php';
		$this->_config = $config;
		//注册自动加载方法
		spl_autoload_register([__CLASS__,'loadFile']);
	}
	/**
	 * @param unknown $className
	 * @return boolean
	 * @desc:自动加载类文件
	 */
	private function loadFile($className){
		$fileName = $className.'.php';
		$currentPath = dirname(__FILE__).'/';
		$pagepayPath = $currentPath.'./pagepay/';
		$buildermodelPath = $currentPath.'pagepay/buildermodel/';
		$servicePath = $currentPath.'pagepay/service/';
		if(file_exists($pagepayPath.$fileName)){
			require_once $pagepayPath.$fileName;
		}elseif (file_exists($buildermodelPath.$fileName)){
			require_once $buildermodelPath.$fileName;
		}elseif (file_exists($servicePath.$fileName)){
			require_once $servicePath.$fileName;
		}else{
			return false;
		} 
		return true;
	}
	/**
	 * @param unknown $data
	 * 参数名|是否必填|描述
	 * out_trade_no|是|支付单号
	 * subject|是|订单名称
	 * total|是|支付金额
	 * body|否|商品描述
	 * 
	 * @desc:
	 */
	public function unifiedOrder($data){
		$this->setLog($data,'undifiedOrder-param:');
		//商户订单号,商户网站订单系统中唯一支付单号,必填
		$outTradeNo = trim($data['out_trade_no']);
		
		//订单名称,必填
		$subject = trim($data['subject']);
		
		//付款金额,必填
		$totalAmount = trim($data['total']);
		
		//商品描述,可空
		$body = isset($data['body'])?trim($data['body']):'';
		
		//构造参数
		$payRequestBuilder = new \AlipayTradePagePayContentBuilder();
		$payRequestBuilder->setBody($body);
		$payRequestBuilder->setSubject($subject);
		$payRequestBuilder->setTotalAmount($totalAmount);
		$payRequestBuilder->setOutTradeNo($outTradeNo);
		$aop = new \AlipayTradeService($this->_config);
		/**
		 * pagePay 电脑网站支付请求
		 * @param $builder 业务参数,使用buildmodel中的对象生成。
		 * @param $return_url 同步跳转地址,公网可以访问
		 * @param $notify_url 异步通知地址,公网可以访问
		 * @return $response 支付宝返回的信息
		 */
		$response = $aop->pagePay($payRequestBuilder,$this->_config['return_url'],$this->_config['notify_url']);
	}
	/**
	 * @param unknown $data
	 * @param boolean $sign 是否验签
	 * @throws Exception
	 * @return 
	 * @desc:支付宝回调数据检测
	 */
	public function notify($data,$sign = false){
		try {
			if($sign){
				//验证签名
				$alipay = new \AlipayTradeService($this->_config);
				$result = $alipay->check($data);
				if(!$result) throw new Exception('验签失败');
			}
			//验证接口调用的app_id是否一致
			$appid = $data['app_id'];
			if($appid != $this->_config['app_id']){
				throw new Exception('app_id不一致');
			}
			//订单查询支付结果
			$queryData = ['transaction_id'=>$data['trade_no'],'out_trade_no'=>$data['out_trade_no']];
			$result = $this->orderQuery($queryData);
			if(!$result['state']) throw new Exception('订单查询结果:'.$result['msg']);
			if($result['data']['total_amount'] != $data['total_amount']) throw new Exception('回调金额与订单查询金额不等');
			return callback(true);
		} catch (Exception $e) {
			return callback(false,$e->getMessage());
		}
	}
	/**
	 * 订单查询-支付宝
	 * @param unknown $data
	 *  参数名|是否必填|描述
	 * transaction_id|二选一|支付宝交易号
	 * out_trade_no|二选一|商户支付单号
	 * @desc:
	 */
	public function orderQuery($data){
		try {
			$this->setLog($data,'orderQuery-param:');
			if(empty($data)) throw new Exception('参数为空');
			//构造参数
			$RequestBuilder = new \AlipayTradeQueryContentBuilder();
			if(isset($data['transaction_id']) && !empty($data['transaction_id'])){
				//支付宝交易号
				$RequestBuilder->setTradeNo($data['transaction_id']);
			}elseif(isset($data['out_trade_no']) && !empty($data['out_trade_no'])){
				$RequestBuilder->setOutTradeNo($out_trade_no);
			}else{
				throw new Exception('交易单号与支付单号不能同时为空');
			}
			$aop = new \AlipayTradeService($this->_config);
			/**
			 * alipay.trade.query (统一收单线下交易查询)
			 * @param $builder 业务参数,使用buildmodel中的对象生成。
			 * @return $response 支付宝返回的信息
			 */
			$response = $aop->Query($RequestBuilder);
			$response = json_decode(json_encode($response),true);
			$this->setLog($response,'orderQuery-response:');
			if($response['code'] != '10000'){
				throw new Exception($response['msg']);
			}
			return callback(true,'',$response);
		} catch (Exception $e) {
			$this->setLog($e->getMessage(),'orderQuery-error:');
			return callback(false,$e->getMessage());
		}
		
	}
	/**
	 * @param unknown $data
	 *  参数名|是否必填|描述
	 * transaction_id|二选一|支付宝交易号
	 * out_trade_no|二选一|商户支付单号
     * refund_fee|是|退款总额,单位元
     * out_refund_no|是|平台退款单号,
     * @return 退款返回结果
       {
	    "code": "10000",
	    "msg": "Success",
	    "buyer_logon_id": "nqy***@sandbox.com",
	    "buyer_user_id": "2088102175437002",
	    "fund_change": "N",
	    "gmt_refund_pay": "2018-07-24 16:22:23",
	    "out_trade_no": "610585760482976360",
	    "refund_fee": "30.00",
	    "send_back_fee": "0.00",
	    "trade_no": "2018072421001004000200631548"
	  }
	 * @desc:退款
	 */
	public function refund($data){
		try {
			$this->setLog($data,'refund-param:');
			//参数构造
			$RequestBuilder = new \AlipayTradeRefundContentBuilder();
			if(isset($data['transaction_id']) && !empty($data['transaction_id'])){
				$RequestBuilder->setTradeNo($data['transaction_id']);
			}elseif(isset($data['out_trade_no']) && !empty($data['out_trade_no'])){
				$RequestBuilder->setOutTradeNo($data['out_trade_no']);
			}else{
				throw new Exception('支付单号和支付宝交易号不能同时为空');
			}
			//退款总额,单位元
			$RequestBuilder->setRefundAmount($data['refund_fee']);
			//退款单号
			$RequestBuilder->setOutRequestNo($data['out_refund_no']);
			$aop = new \AlipayTradeService($this->_config);
			$response = $aop->Refund($RequestBuilder);
			$this->setLog($response,'refund-response:');
			$response = json_decode(json_encode($response),true);
			if($response['code'] != '10000'){
				throw new Exception($response['msg']);
			}
			return callback(true,'退款申请成功',$response);
		} catch (Exception $e) {
			$this->setLog($e->getMessage(),'refund-error:');
			return callback(false,$e->getMessage());
		}
	}
	/**
	 * @param unknown $data
	 * 参数|是否必填|描述
	 * transaction_id|二选一|支付宝交易号
	 * out_trade_no|二选一|商户支付单号
     * out_refund_no|是|平台退款单号,
     * @return
     * 返回参数
       {
	    "code": "10000",
	    "msg": "Success",
	    "out_request_no": "2018072421001004000200631548",
	    "out_trade_no": "610585760482976360",
	    "refund_amount": "30.00",
	    "total_amount": "30.00",
	    "trade_no": "2018072421001004000200631548"
	 	 }
	 * @desc:退款查询
	 */
	public function refundQuery($data){
		try {
			$this->setLog($data,'refundQuery-param:');
			$RequestBuilder = new \AlipayTradeFastpayRefundQueryContentBuilder();
			if(isset($data['transaction_id']) && !empty($data['transaction_id'])){
				$RequestBuilder->setTradeNo($data['transaction_id']);
			}elseif(isset($data['out_trade_no']) && !empty($data['out_trade_no'])){
				$RequestBuilder->setOutTradeNo($data['out_trade_no']);
			}else{
				throw new Exception('支付单号和支付宝交易号不能同时为空');
			}
			$RequestBuilder->setOutRequestNo($data['out_refund_no']);
			$aop = new \AlipayTradeService($this->_config);
			$response = $aop->refundQuery($RequestBuilder);
			$this->setLog($response,'refundQuery-response:');
			$response = json_decode(json_encode($response),true);
			if($response['alipay_trade_fastpay_refund_query_response']['code'] != '10000'){
				throw new Exception($response['alipay_trade_fastpay_refund_query_response']['msg']);
			}
			return callback(true,'',$response['alipay_trade_fastpay_refund_query_response']);
		} catch (Exception $e) {
			$this->setLog($e->getMessage(),'refundQuery-error:');
			return callback(false,$e->getMessage());
		}
	}
	/**
	 * @param unknown $content
	 * @param string $prefix
	 * @desc:记录日志
	 */
	public function setLog($contents,$prefix = ""){
		$path = RUNTIME_PATH.'/log/alipay/';
		setLog($contents,$prefix,$path);
	}
}

以下是notify.php中的异步通知处理

/**
	 *
	 * @desc:支付宝支付结果同步回调
	 */
	public function alipayReturn(){
		$param = $this->request->param();
		$result = $this->dealNotify($param,false,1);
		if($result['state']){
			//支付成功
			$this->redirect(url('index/buy/payok',['pay_sn'=>$param['out_trade_no']]));
		}else{
			//支付失败
			$this->redirect(url(''));
		}
	}
	/**
	 * @param unknown $data
	 * @param boolean $sign 是否验签
	 * @param boolean $type 1-同步处理 2-异步处理
	 * @desc:处理支付宝同步通知和异步通知数据
	 */
	private function dealNotify($data,$sign = false,$type = '2'){
		try {
			$typeDesc = ($type == 1)?'return':'notify';
			$prefix = 'alipay-'.$typeDesc;
			$alipay = new Alipay();
			$alipay->setLog($data,$prefix."-param:");
			//1-alipay数据验证
			$result = $alipay->notify($data,$sign);
			if(!$result['state']) throw new Exception($result['msg']);
			//2-检测支付金额是否一致
			$pay = new Pay();
			$result = $pay->checkPayTotal($data['out_trade_no'], $data['total_amount']);
			$alipay->setLog('账单实际金额:'.$result['data']['total'].",实际支付金额:".$data['total_amount']);
			if(!$result['state']) throw new Exception($result['msg']);
			//修改订单相关数据
			$this->purOrderUpdate($data['out_trade_no'], $data['trade_no'],$data['total_amount']);
			$alipay->setLog('success',$prefix."-end:");
			return callback(true);
		} catch (Exception $e) {
			$alipay->setLog($e->getMessage(),$prefix."-end-error:");
			return callback(false,$e->getMessage());
		}
	}
	/**
	 * 
	 * @desc:支付宝支付结果异步回调(包括部分退款异步通知。全额退款没有异步通知)
	 */
	public function alipayNotify(){
		try {
			if(!$this->request->isPost()) throw new Exception('非法请求');
			$param = $this->request->param();
			if(isset($param['refund_fee'])){
				$alipay = new Alipay();
				$alipay->setLog($param,'refund-notify:param:');
				//退款状态修改
				$this->_updateRefund($param['out_biz_no'],1);
				$alipay->setLog('success','refund-notify-end:');
			}else{
				//支付结果异步通知
				$result = $this->dealNotify($param);
				if(!$result['state']) throw new Exception($result['msg']);
			}
			return 'success';
		} catch (Exception $e) {
			$alipay->setLog($e->getMessage(),'notify-end-error:');
			return 'fail';
		}
	}

注意:申请退款后,部分退款才会有异步通知,全额退款不会触发退款结果的异步通知。退款结果的异步通知路径跟支付结果异步回调地址一致。退款回调参数中多refund_fee这个参数。退款回调参数如下:

{
	"gmt_create": "2018-07-26 09:45:05",
	"charset": "UTF-8",
	"gmt_payment": "2018-07-26 09:45:24",
	"notify_time": "2018-07-26 09:47:37",
	"subject": "",
	"gmt_refund": "2018-07-26 09:47:36.849",
	"sign": "drGhgTe9Ly60hN0fgXlrcu+xSH5+cx3ZJsNDKyCFDsRhHhD2eqANbaqXKgPMOBdUon3aYWa7Akv55lel2AZWSPDpJsDeG04V2Xd7Dr4GB\/dtIDAcrZ6Bb7a3+HZFnc8q+VxKZAJmEMKgMNX86Evv55FxtsGByqi53UASa4OQ2\/yhayjPBlcujUXhzLBb1sVDttGS5UZx7pDGYPlOpUaLnymxAcbPCHcOZY1Gt0MjYd4m\/AUKs1gByyaJdrX34++gi7chlSUruSFzwlRmVyI2eLEdb23tISvOox21wCMq6YdBYcUNlmZ2Mt6itaEItGWx8D9\/VJYdj1bLjnCSKn8f1A==",
	"out_biz_no": "R201807260946373238851",
	"buyer_id": "2088102175437002",
	"version": "1.0",
	"notify_id": "00a13b3a2640169502675254b25572ag02",
	"notify_type": "trade_status_sync",
	"out_trade_no": "",
	"total_amount": "340.00",
	"trade_status": "TRADE_SUCCESS",
	"refund_fee": "240.00",
	"trade_no": "2018072621001004000200641757",
	"auth_app_id": "",
	"app_id": "",
	"sign_type": "RSA2",
	"seller_id": ""
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值