360 lines
13 KiB
PHP
360 lines
13 KiB
PHP
<?php
|
||
/**
|
||
* SAAS应用系统 --- 十年开发经验汇集巨献!
|
||
* ==========================================================
|
||
* Copy right 2020-2050 成都众联思索科技有限公司,保留所有权利。
|
||
* ----------------------------------------------------------
|
||
* 官方网址: https://www.zoomtk.com
|
||
* 这不是自由软件!未经允许不得用于商业目或程序代码摘取及修改。
|
||
* 任何企业和个人未经允许对程序代码以任何形式任何目的再发布传播。
|
||
* 唯一发布渠道www.zoomtk.com;非官方渠道统一视为侵权行为。
|
||
* ==========================================================
|
||
*/
|
||
|
||
namespace addon\aliapp\model;
|
||
use addon\alipay\data\sdk\AopCertClient;
|
||
use addon\alipay\data\sdk\AopClient;
|
||
use addon\alipay\data\sdk\request\AlipayTradeRefundRequest;
|
||
use addon\alipay\model\Config;
|
||
use app\exception\ApiException;
|
||
use app\model\system\Pay as PayCommon;
|
||
use think\Exception;
|
||
use think\facade\Db;
|
||
class CloudPay
|
||
{
|
||
public $aop;
|
||
function __construct()
|
||
{
|
||
try {
|
||
$config_info = config('alipay.cloudAlipay');
|
||
// 获取支付宝支付参数(统一支付到平台账户)
|
||
$this->aop = new AopClient();
|
||
$this->aop->alipayrsaPublicKey = $config_info['public_key'] ?? "";
|
||
$this->aop->alipayPublicKey = $config_info['alipay_public_key'] ?? "";
|
||
$this->aop->isv_app_id = $config_info["isv_app_id"] ?? "";
|
||
$this->aop->rsaPrivateKey = $config_info['private_key'] ?? "";
|
||
$this->aop->gatewayUrl = 'https://apigw.alipay-eco.com';
|
||
$this->aop->alipaySdkVersion = "alipay-sdk-php-20200415";
|
||
$this->aop->apiVersion = '1.0';
|
||
$this->aop->signType = 'RSA2';
|
||
$this->aop->postCharset = 'UTF-8';
|
||
$this->aop->format = 'json';
|
||
} catch (\Exception $e) {
|
||
throw new ApiException(-1, '支付宝配置错误');
|
||
}
|
||
}
|
||
public function payNotify($data)
|
||
{
|
||
if ($this->rsaCheckV($data)) {
|
||
switch ($data['service']) {
|
||
case 'spi.fitness.merchant.syncStatus'://商户状态
|
||
file_put_contents(__DIR__.'/pay/'.date('YmdHis').'syncStatus.txt',json_encode($_POST));
|
||
$biz_content = json_decode($_POST['biz_content'], true);
|
||
$res = $this->syncStatus($biz_content);
|
||
break;
|
||
case 'spi.fitness.subscription.syncSubscription':
|
||
file_put_contents(__DIR__.'/pay/'.date('YmdHis').'syncSubscription.txt',json_encode($_POST));
|
||
$biz_content = json_decode($_POST['biz_content'], true);
|
||
$res = $this->syncSubscription($biz_content);
|
||
break;
|
||
case 'spi.fitness.order.syncOrder':
|
||
file_put_contents(__DIR__.'/pay/'.date('YmdHis').'syncOrder.txt',json_encode($_POST));
|
||
$biz_content = json_decode($_POST['biz_content'], true);
|
||
$res = $this->syncOrder($biz_content);
|
||
break;
|
||
}
|
||
} else {
|
||
echo "fail";
|
||
}
|
||
}
|
||
|
||
|
||
/***
|
||
* 商户状态
|
||
* @param $data
|
||
*/
|
||
public function syncStatus($data)
|
||
{
|
||
echo "success";
|
||
}
|
||
/***
|
||
* 订单回调
|
||
* @param $data
|
||
* @throws \Exception
|
||
*/
|
||
public function syncSubscription($data)
|
||
{
|
||
$out_trade_no = $data['outSubscriptionNo'];
|
||
// 支付宝交易号
|
||
$trade_no = $data['subscriptionNo'];
|
||
// 交易状态
|
||
$trade_status = $data['subscriptionStatus'];
|
||
if ($trade_status == "NORMAL") {
|
||
switch ($trade_status){
|
||
case 'NORMAL': //正常
|
||
$pay_common = new PayCommon();
|
||
$retval = $pay_common->onlinePay($out_trade_no, "zmalipay", $trade_no, "aliapp");
|
||
// 发送 服务开通成功提醒
|
||
$orderInfo = Db::name('order')->where('out_trade_no',$out_trade_no)->find();
|
||
if(!is_array($orderInfo)) $orderInfo = $orderInfo->toArray();
|
||
$memberGoodsCard = Db::name('member_goods_card')->where('order_id',$orderInfo['order_id'])->find();
|
||
if(!is_array($memberGoodsCard)) $memberGoodsCard = $memberGoodsCard->toArray();
|
||
$nickname = Db::name('member')->where('member_id',$orderInfo['member_id'])->value('nickname');
|
||
$res = (new AliPayMessage($orderInfo['site_id']))->sendMessage($orderInfo['member_id'],'SERVICE_OPENED_SUCCESS',[
|
||
'end_time' => date('Y年m月d日',$memberGoodsCard['end_time']),// 到期时间 日期:2022年1月18日
|
||
'nickname' => $nickname,// 姓名
|
||
'start_time' => date('Y年m月d日',$memberGoodsCard['create_time']),// 开通时间 日期:2022年1月18日
|
||
'content' => $memberGoodsCard['goods_name'],// 服务项目
|
||
]);
|
||
|
||
|
||
break;
|
||
case 'PAUSE': //订单暂停
|
||
break;
|
||
case "SURRENDER": //解约
|
||
break;
|
||
case "END": //订单结束
|
||
break;
|
||
case "DEFAULT_CANCEL": //违约取消
|
||
break;
|
||
case "CANCEL": //超时取消
|
||
break;
|
||
}
|
||
}
|
||
echo "success";
|
||
}
|
||
|
||
|
||
/***
|
||
* 订单同步状态
|
||
* @param $data
|
||
*/
|
||
public function syncOrder($data)
|
||
{
|
||
|
||
$out_trade_no = $data['outSubscriptionNo']; //平台交易号
|
||
|
||
// 支付宝交易号
|
||
$trade_no = $data['subscriptionNo'];
|
||
|
||
$third_order_no = $data['orderNo'];
|
||
// 交易状态
|
||
$trade_status = $data['orderStatus'];
|
||
$where=[
|
||
'out_trade_no'=>$out_trade_no,
|
||
'third_order_no'=>$third_order_no
|
||
];
|
||
$orderInfo = model('order')->getInfo([[ 'out_trade_no', '=', $out_trade_no ]],'order_id,member_id');
|
||
$zmOrder=Db::name('zm_order')->where($where)->find();
|
||
if(empty($zmOrder)){
|
||
$insdata=[
|
||
'merchantPid'=>$data['merchantPid'],
|
||
'userid'=>$data['userId'],
|
||
'order_id'=>$orderInfo['order_id'],
|
||
'uid'=>$orderInfo['member_id'],
|
||
'trade_no'=>$trade_no,
|
||
'out_trade_no'=>$out_trade_no,
|
||
'third_order_no'=>$third_order_no,
|
||
'create_time'=>strtotime($data['orderDate']),
|
||
'plan_time'=>strtotime($data['planDeductionTime']??''),
|
||
'period'=>$data['period'],
|
||
'order_status'=>$trade_status,
|
||
'amount'=>$data['deductionAmount']
|
||
];
|
||
Db::name('zm_order')->insert($insdata);
|
||
}else{
|
||
$updata=[
|
||
'period'=>$data['period'],
|
||
'order_status'=>$trade_status,
|
||
];
|
||
if($trade_status=='PAID'){
|
||
$updata['pay_time']=strtotime($data['actualDeductionTime']);
|
||
}
|
||
if($trade_status=='PAYING'){
|
||
try{
|
||
event('AliVerify',$zmOrder);
|
||
}catch(Exception $exception){
|
||
trace($exception,'核销失败');
|
||
}
|
||
}
|
||
Db::name('zm_order')->where($where)->update($updata);
|
||
}
|
||
echo "success";
|
||
}
|
||
|
||
|
||
/***
|
||
* 退款
|
||
*/
|
||
public function refund($param){
|
||
$pay_info=$param['pay_info'];
|
||
$bizContent=[
|
||
'merchantPid'=>'2088420482043304',
|
||
'subscriptionNo'=>$pay_info['trade_no'],
|
||
'orderNo'=>$pay_info['order_no']
|
||
];
|
||
//其他参数
|
||
$params["charset"] = "UTF-8";
|
||
$params["isv_app_id"]= $this->aop->isv_app_id;
|
||
$params["utc_timestamp"]=$this->msectime();
|
||
//指定需要调用的service接口
|
||
$params["service"] = "api.fitness.orderRefund";
|
||
$params["request_id"] =$this->uuid();
|
||
$params["biz_content"] = json_encode($bizContent);
|
||
$params["version"] = "1.0";
|
||
$params["sign"] = $this->aop->generateSign($params, "RSA2");
|
||
$params["sign_type"] = 'RSA2';
|
||
// 调用ECOAPI
|
||
$result = $this->aop->call($params);
|
||
return $result;
|
||
}
|
||
|
||
|
||
/***
|
||
* 新增或者修改商户
|
||
* @param $param
|
||
* @return false|mixed
|
||
*/
|
||
public function upAlipayUser($param,$settleAccountList=''){
|
||
$bizContent=[
|
||
'merchantPid'=>$param['smid'],
|
||
'smid'=>$param['smid'],
|
||
'merchantAppId'=>$param['merchantAppId'],
|
||
'merchantLoginName'=>$param['merchantLoginName'],
|
||
'merchantName'=>$param['merchantName'],
|
||
'separateLedgerRate'=>$param['separateLedgerRate'],
|
||
'phone'=>$param['phone'],
|
||
];
|
||
if($settleAccountList){
|
||
$bizContent['settleAccountList']=array_values($settleAccountList);
|
||
}
|
||
//其他参数
|
||
$params["charset"] = "UTF-8";
|
||
$params["isv_app_id"]= $this->aop->isv_app_id;
|
||
$params["utc_timestamp"]=$this->msectime();
|
||
//指定需要调用的service接口
|
||
$params["service"] = "api.fitness.newSaveOrUpdate";
|
||
$params["request_id"] =$this->uuid();
|
||
$params["biz_content"] = json_encode($bizContent);
|
||
$params["version"] = "1.0";
|
||
$params["sign"] = $this->aop->generateSign($params, "RSA2");
|
||
$params["sign_type"] = 'RSA2';
|
||
// 调用ECOAPI
|
||
$result = $this->aop->call($params);
|
||
return $result['response'];
|
||
}
|
||
|
||
/***
|
||
* 商户解约
|
||
* @param $param
|
||
* @return false|mixed
|
||
*/
|
||
public function Surrender($param,$type='NORMAL'){
|
||
$pay_info=$param['pay_info'];
|
||
$bizContent=[
|
||
'subscriptionNo'=>$pay_info['trade_no'],
|
||
'subscriptionCancelType'=>$type //NORMAL 正常 DEFAULT违约
|
||
];
|
||
//其他参数
|
||
$params["charset"] = "UTF-8";
|
||
$params["isv_app_id"]= $this->aop->isv_app_id;
|
||
$params["utc_timestamp"]=$this->msectime();
|
||
//指定需要调用的service接口
|
||
$params["service"] = "api.fitness.subscriptionSurrender";
|
||
$params["request_id"] =$this->uuid();
|
||
$params["biz_content"] = json_encode($bizContent);
|
||
$params["version"] = "1.0";
|
||
$params["sign"] = $this->aop->generateSign($params, "RSA2");
|
||
$params["sign_type"] = 'RSA2';
|
||
// 调用ECOAPI
|
||
$result = $this->aop->call($params);
|
||
return $result;
|
||
}
|
||
|
||
|
||
/***
|
||
* 核销
|
||
* @param $orderNo
|
||
* @return false|mixed
|
||
*/
|
||
public function verify($orderNo,$verificationCode){
|
||
$bizContent=[
|
||
// 'orderNo'=>$orderNo,
|
||
'verificationCode'=>$verificationCode
|
||
];
|
||
//其他参数
|
||
$params["charset"] = "UTF-8";
|
||
$params["isv_app_id"]= $this->aop->isv_app_id;
|
||
$params["utc_timestamp"]=$this->msectime();
|
||
//指定需要调用的service接口
|
||
$params["service"] = "api.fitness.verification";
|
||
$params["request_id"] =$this->uuid();
|
||
$params["biz_content"] = json_encode($bizContent);
|
||
$params["version"] = "1.0";
|
||
$params["sign"] = $this->aop->generateSign($params, "RSA2");
|
||
$params["sign_type"] = 'RSA2';
|
||
// 调用ECOAPI
|
||
$result = $this->aop->call($params);
|
||
return $result;
|
||
}
|
||
|
||
/***
|
||
* 订单查询
|
||
* @param $subscriptionNo
|
||
* @param $orderNo
|
||
* @return false|mixed
|
||
*/
|
||
public function orderQuery($subscriptionNo = '',$orderNo = ''){
|
||
$bizContent=[
|
||
'subscriptionNo'=>$subscriptionNo,
|
||
'orderNo'=>$orderNo,
|
||
];
|
||
//其他参数
|
||
$params["charset"] = "UTF-8";
|
||
$params["isv_app_id"]= $this->aop->isv_app_id;
|
||
$params["utc_timestamp"]=$this->msectime();
|
||
//指定需要调用的service接口
|
||
$params["service"] = "api.fitness.orderQuery";
|
||
$params["request_id"] =$this->uuid();
|
||
$params["biz_content"] = json_encode($bizContent);
|
||
$params["version"] = "1.0";
|
||
$params["sign"] = $this->aop->generateSign($params, "RSA2");
|
||
$params["sign_type"] = 'RSA2';
|
||
// 调用ECOAPI
|
||
$result = $this->aop->call($params);
|
||
return $result;
|
||
}
|
||
|
||
/***
|
||
* 验证签名
|
||
* @param $data
|
||
* @return bool|void
|
||
*/
|
||
public function rsaCheckV($data)
|
||
{
|
||
$res = $this->aop->rsaCheckV2($data, $this->aop->alipayrsaPublicKey, 'RSA2');
|
||
return $res;
|
||
}
|
||
|
||
/**
|
||
* 返回当前的毫秒时间戳
|
||
*/
|
||
public function msectime()
|
||
{
|
||
list($s1, $s2) = explode(' ', microtime());
|
||
return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
|
||
}
|
||
/**
|
||
* 生成UUID
|
||
*/
|
||
public function uuid()
|
||
{
|
||
$chars = md5(uniqid(mt_rand(), true));
|
||
$uuid = substr($chars, 0, 8) . '-'
|
||
. substr($chars, 8, 4) . '-'
|
||
. substr($chars, 12, 4) . '-'
|
||
. substr($chars, 16, 4) . '-'
|
||
. substr($chars, 20, 12);
|
||
return $uuid;
|
||
}
|
||
} |