namespace payment;
use \think\Db;
/**
* @author mselect <445712421@qq.com>
*
* @DateTime 2018-11-16 10:43:44
* 支付宝支付类
*/
class Alipay {
//是否沙盒环境
public $is_sandbox = false;
//沙盒地址
private $sandurl = '/';
//正式地址
private $url = '/';
//appid
private $appid ;
//sand appid
private $sandappid = '沙盒appid';
//回调前缀
private $notify_url;
//商户应用私钥
private $rsaPrivateKey = '正式应用私钥';
//支付宝公钥 验签使用
private $alipayPublicKey= '正式支付宝公钥';
//沙盒应用私钥
private $sandrsaPrivateKey = '沙盒应用私钥';
private $sandalipayPublicKey = '沙盒支付宝公钥';
public function __construct(){
$payment = Db::name('payment')->where('id', 2)->find();
$json = json_decode($payment['json'], true);
$this->appid = $json['appid'];
$this->notify_url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
if(!is_dir('static/logs')){
mkdir('static/logs', 0777);
}
}
/**
* @author mselect <445712421@qq.com>
*
* @DateTime 2018-11-16 10:57:51
* 当面付
*/
public function pay($order_id){}
/**
* @author mselect <445712421@qq.com>
*
* @DateTime 2018-11-19 15:03:28
* PC网站支付
*/
public function pagepay($order_id){}
/**
* @author mselect <445712421@qq.com>
*
* @DateTime 2018-12-21 16:10:11
* app支付
*
* @param <intval> order_id 订单ID
*/
public function apppay($orderid){
//支付宝APP支付, 支付接口组合数据
$time = time();
$order = Db::name('order')->where('id', $orderid)->find();
$notify_url = $this->notify_url . '回调地址';
if($this->is_sandbox){
$this->url = $this->sandurl;
$this->appid = $this->sandappid;
$this->rsaPrivateKey = $this->sandrsaPrivateKey;
$this->alipayPublicKey = $this->sandalipayPublicKey;
}
//业务参数
$biz_content = array(
'subject' => 'XXXX',
'out_trade_no' => $order['order_unique'],
'total_amount' => $order['real_total_money'],
'product_code' => 'QUICK_MSECURITY_PAY',
);
import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
import('AlipayTradeAppPayRequest', EXTEND_PATH . 'payment/alipay/aop/request');
$aop = new \AopClient;
$aop->gatewayUrl = $this->url;
$aop->appId = $this->appid;
$aop->rsaPrivateKey = $this->rsaPrivateKey;
$aop->format = "json";
$aop->charset = "UTF-8";
$aop->signType = "RSA2";
$aop->alipayrsaPublicKey =$this->alipayPublicKey;
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:
$request = new \AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数
$request->setNotifyUrl($notify_url);
$request->setBizContent(json_encode($biz_content));
//这里和普通的接口调用不同,使用的是sdkExecute
$response = $aop->sdkExecute($request);
//htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题
$return = $response;//就是orderString 可以直接给客户端请求,无需再做处理。
return $return;
}
/**
* @author mselect <445712421@qq.com>
*
* @DateTime 2018-11-16 13:36:17 { function_description }
* 支付宝支付通知
*
* @param <type> $data 异步通知返回的所有数据
*/
public function notify($data){
if($this->is_sandbox){
$this->alipayPublicKey = $this->sandalipayPublicKey;
}
import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
$aop = new \AopClient;
$aop->alipayrsaPublicKey = $this->alipayPublicKey;
$flag = $aop->rsaCheckV1($data, NULL, "RSA2");
$order = Db::name("order")->where('order_unique', $data['out_trade_no'])->where('status', -1)->find();
if($order['real_total_money'] != $data['total_amount']){
file_put_contents('static/logs/', '异步返回订单金额不正确, 时间:' . date("Y-m-d H:i:s") . "\r\n", FILE_APPEND);exit;
}
$rst = $this->orderquery($order, 'TRADE_SUCCESS');
if($rst){
$time = time();
Db::startTrans();
try {
//TODO... 数据库操作
Db::commit();
}catch(\Exception $e){
Db::rollback();
file_put_contents('static/logs/', '修改数据库失败,失败信息:' . $e->getMessage() . ",记录时间:" . date('Y-m-d H:i:s') . "\r\n", FILE_APPEND);exit;
}
echo 'success';exit;
}else {
file_put_contents('static/log/', "查询订单状态错误时间:" .date("Y-m-d H:i:s"). "\r\n", FILE_APPEND);
exit;
}
}
/**
* @author mselect <445712421@qq.com>
*
* @DateTime 2018-11-16 13:39:15
* 支付查询接口
*
* @param order 订单数据
* @param status 要验证的状态 WAIT_BUYER_PAY-交易创建等待买家付款 TRADE_CLOSED-未付款交易超时关闭或支付完成后全额退款 TRADE_SUCCESS-交易支付成功 TRADE_FINISHED-交易结束不可退款
*/
public function orderquery($order , $status){
//是否沙盒环境
if($this->is_sandbox){
$this->url = $this->sandurl;
$this->appid = $this->sandappid;
$this->rsaPrivateKey = $this->sandrsaPrivateKey;
$this->alipayPublicKey = $this->sandalipayPublicKey;
}
$biz_content = [
'out_trade_no' => $order['order_unique'],
'trade_no' => $order['trade_no'],
];
import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
import('AlipayTradeQueryRequest', EXTEND_PATH . 'payment/alipay/aop/request');
$aop = new \AopClient;
$aop->gatewayUrl = $this->url; //'/';
$aop->appId = $this->appid; // 'your app_id';
$aop->rsaPrivateKey = $this->rsaPrivateKey; //'请填写开发者私钥去头去尾去回车,一行字符串';
$aop->alipayrsaPublicKey= $this->alipayPublicKey; //'请填写支付宝公钥,一行字符串';
$aop->apiVersion = '1.0';
$aop->signType = 'RSA2';
$aop->postCharset='UTF-8';
$aop->format='json';
$request = new \AlipayTradeQueryRequest;
$request->setBizContent(json_encode($biz_content));
$result = $aop->execute ( $request);
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if(!empty($resultCode)&&$resultCode == 10000){
return true;
} else {
return false;
}
}
/**
* @author mselect <445712421@qq.com>
*
* @DateTime 2018-12-26 15:39:57
* 交易关闭接口
*
* @param <intval> order_id 订单ID
*/
public function trade_close($order_id){
$order = Db::name('order')->where('id', $order_id)->find();
if($this->is_sandbox){
$this->url = $this->sandurl;
$this->appid = $this->sandappid;
$this->rsaPrivateKey = $this->sandrsaPrivateKey;
$this->alipayPublicKey = $this->sandalipayPublicKey;
}
//请求参数
$biz_content = array(
'out_trade_no' => $order['order_unique'],
);
import('AopClient', EXTEND_PATH . 'payment/alipay/aop');
import('AlipayTradeCloseRequest', EXTEND_PATH . 'payment/alipay/aop/request');
$aop = new \AopClient ();
$aop->gatewayUrl = $this->url;
$aop->appId = $this->appid;
$aop->rsaPrivateKey = $this->rsaPrivateKey; //'请填写开发者私钥去头去尾去回车,一行字符串';
$aop->alipayrsaPublicKey= $this->alipayPublicKey; //'请填写支付宝公钥,一行字符串';
$aop->apiVersion = '1.0';
$aop->signType = 'RSA2';
$aop->postCharset='UTF-8';
$aop->format='json';
$request = new \AlipayTradeCloseRequest;
$request->setBizContent(json_encode($biz_content));
$result = $aop->execute ( $request);
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if( (!empty($resultCode)&&$resultCode == 10000 ) || (!empty($resultCode)&&$resultCode == 40004) ){
return true;
} else {
file_put_contents('static/logs/', '关闭订单失败, 失败码:'. $result->$responseNode->code . ", 失败原因:". $result->$responseNode->msg . "\r\n", FILE_APPEND);
return false;
}
}
}