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

245 lines
8.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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);
return $response;
}
/**
* @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_sn'],$notify,$pay_fee,true,true);
} 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"));
}
}