DiverseYouthNightSchool/application/api/controller/school/Pay.php

247 lines
8.1 KiB
PHP
Raw Permalink Normal View History

2024-11-08 18:18:06 +08:00
<?php
namespace app\api\controller\school;
use addons\epay\library\Service;
use addons\third\model\Third;
use app\common\model\school\classes\order\Order as OrderModel;
use Exception;
use think\Log;
/**
* 课程支付接口
*/
class Pay extends Base
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
protected $model = null;
/**
* 初始化操作
* @access protected
*/
protected function _initialize()
{
$this->model = new OrderModel;
parent::_initialize();
//判断登录用户是否是员工
}
/**
* @ApiTitle( 课程第三方支付)
* @ApiSummary(课程第三方支付(微信等支付))
* @ApiRoute(/api/school/pay/payment)
* @ApiMethod(POST)
* @ApiParams(name = "order_no", type = "string",required=true,description = "订单id或订单号")
* @ApiParams(name = "type", type = "string",required=true,description = "服务商:alipay=支付宝,wechat=微信")
* @ApiParams(name = "platform", type = "string",required=true,description = "平台:web=PC网页支付,wap=H5手机网页支付,app=APP支付,scan=扫码支付,mp=微信公众号支付,miniapp=微信小程序支付")
* @ApiParams(name = "openid", type = "string",required=false,description = "用户openid(非必填)")
* @ApiReturn({
*
*})
*/
public function payment()
{
$order_no = $this->request->post('order_no/s');
$type = $this->request->post('type/s');
$method = $this->request->post('platform/s');
$openid = $this->request->post('openid/s', "");
$platform = $method;
try {
//订单支付前校验
$this->model->checkPay($order_no,$type);
$order = OrderModel::where('order_no', $order_no)->find();
$amount = $order["totalprice"];
} catch (\Exception $e) {
$this->error($e->getMessage());
}
if (!$amount || $amount < 0) {
$this->error("支付金额必须大于0");
}
if (!$type || !in_array($type, ['alipay', 'wechat'])) {
$this->error("支付类型不能为空");
}
if (in_array($method, ['miniapp', 'mp']) && !$openid) {
// 微信公众号,小程序支付,必须有 openid
if (isset($openid) && $openid) {
// 如果传的有 openid
} else {
// 没有 openid 默认拿下单人的 openid
$oauth = Third::where([
'user_id' => $order->user_id,
'platform' => $type,
'apptype' => $platform
])->find();
$openid = $oauth ? $oauth->openid : '';
}
if (!$openid) {
// 缺少 openid
$this->error("授权过期,请您重新授权登录");
}
}
//订单号
$out_trade_no = $order_no;
//订单标题
$title = '课程订单['.$out_trade_no."]支付";
//回调链接
$notifyurl = $this->request->root(true) . '/api/school/pay/notifyx/paytype/' . $type. '/platform/' . $method;
$returnurl = $this->request->root(true) . '/api/school/pay/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;
$response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method, $openid);
$this->success('查询成功', ["paydata"=>$response]);
// return $response;
2024-11-08 18:18:06 +08:00
}
/**
* @ApiTitle( 第三方支付支付成功回调)
* @ApiSummary(第三方支付成功回调)
* @ApiRoute(/api/school/pay/notifyx)
* @ApiMethod(GET)
* @ApiReturn({
*
*})
*/
public function notifyx()
{
$paytype = $this->request->param('paytype');
$platform = $this->request->param('platform');
$pay = Service::checkNotify($paytype);
if (!$pay) {
return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
}
$payment = $paytype;
// 获取回调数据V3和V2的回调接收不同
$data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
Log::write('notifyx-result:'. json_encode($data));
$out_trade_no = $data['out_trade_no'];
$out_refund_no = $data['out_biz_no'] ?? '';
// 判断是否是支付宝退款(支付宝退款成功会通知该接口)
if ($paytype == 'alipay' // 支付宝支付
&& $data['notify_type'] == 'trade_status_sync' // 同步交易状态
&& $data['trade_status'] == 'TRADE_CLOSED' // 交易关闭
&& $out_refund_no // 退款单号
) {
// 退款回调
// $this->refundFinish($out_trade_no, $out_refund_no,$platform);
return $pay->success()->send();
}
// 判断支付宝微信是否是支付成功状态,如果不是,直接返回响应
if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') {
// 不是交易成功的通知,直接返回成功
return $pay->success()->send();
}
if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) {
// 微信交易未成功,返回 false让微信再次通知
return false;
}
try {
//微信支付V3返回和V2不同
if (Service::isVersionV3() && $paytype === 'wechat') {
$data = $data['resource']['ciphertext'];
$data['total_fee'] = $data['amount']['total'];
}
\think\Log::record($data);
$payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
$out_trade_no = $data['out_trade_no'];
\think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}");
//你可以在此编写订单逻辑
// 支付成功流程
//获取支付金额、订单号
$pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
//你可以在此编写订单逻辑
$order = OrderModel::getNopayOrder($out_trade_no);
if (!$order || $order["status"] != '0') {
// 订单不存在,或者订单已支付
return $pay->success()->send();
}
$notify = [
'order_no' => $data['out_trade_no'],
'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'],
'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])),
'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'],
'payment_json' => json_encode($data->all()),
'pay_fee' => $pay_fee,
'pay_type' => $payment, // 支付方式
'platform' => $platform,
];
$this->model->paySuccess($order['order_no'],$notify,$pay_fee,true,true);
2024-11-08 18:18:06 +08:00
} catch (Exception $e) {
\think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
}
//下面这句必须要执行,且在此之前不能有任何输出
if (Service::isVersionV3()) {
return $pay->success()->getBody()->getContents();
} else {
return $pay->success()->send();
}
}
/**
* 支付返回,网页支付版本(小程序忽略)
*/
public function returnx()
{
$paytype = $this->request->param('paytype');
$out_trade_no = $this->request->param('out_trade_no');
$pay = Service::checkReturn($paytype);
if (!$pay) {
$this->error('签名错误', '');
}
//你可以在这里定义你的提示信息,但切记不可在此编写逻辑
$this->success("请返回网站查看支付结果", addon_url("epay/index/index"));
}
}