112 lines
3.6 KiB
PHP
112 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Endpoint\Callback\Http\Controllers;
|
|
|
|
use App\Events\OrderPaid;
|
|
use App\Exceptions\BizException;
|
|
use App\Models\Order;
|
|
use App\Models\OrderRefundLog;
|
|
use App\Services\Payment\WxpayService;
|
|
use App\Services\PayService;
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Throwable;
|
|
|
|
class WxpayController extends Controller
|
|
{
|
|
/**
|
|
* 支付结果通知
|
|
*
|
|
* @param \App\Services\Payment\WxpayService $wxpayService
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function paidNotify(WxpayService $wxpayService, Request $request)
|
|
{
|
|
return $wxpayService->payment()->handlePaidNotify(function ($message, $fail) use ($request) {
|
|
$this->log('paid notify--------'.$request->url(), $message);
|
|
|
|
// 通信失败
|
|
if (data_get($message, 'return_code') !== 'SUCCESS') {
|
|
return $fail('通信失败');
|
|
}
|
|
|
|
try {
|
|
$payLog = DB::transaction(function () use ($message) {
|
|
$payService = new PayService();
|
|
|
|
if (data_get($message, 'result_code') === 'SUCCESS') {
|
|
return $payService->handleSuccessByPaySerialNumber($message['out_trade_no'], [
|
|
'out_trade_no' => $message['transaction_id'],
|
|
'pay_at' => Carbon::parse($message['time_end']),
|
|
]);
|
|
} elseif (data_get($message, 'result_code') === 'FAIL') {
|
|
return $payService->handleFailedByPaySerialNumber($message['out_trade_no'], [
|
|
'out_trade_no' => $message['transaction_id'] ?? null,
|
|
'failed_reason' => '['.$message['err_code'].']'.$message['err_code_des'],
|
|
]);
|
|
}
|
|
});
|
|
|
|
$payable = $payLog?->payable;
|
|
|
|
if ($payable instanceof Order) {
|
|
OrderPaid::dispatchIf($payable->isPaid(), $payable);
|
|
}
|
|
} catch (ModelNotFoundException | BizException $e) {
|
|
} catch (Throwable $e) {
|
|
throw $e;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 订单退款结果通知
|
|
*
|
|
* @param \App\Services\Payment\WxpayService $wxpayService
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function orderRefundedNotify(WxpayService $wxpayService)
|
|
{
|
|
return $wxpayService->payment()->handleRefundedNotify(function ($message, $reqInfo, $fail) {
|
|
$this->log('refund notify', $reqInfo);
|
|
|
|
// 通信失败
|
|
if (data_get($message, 'return_code') !== 'SUCCESS') {
|
|
return $fail('通信失败');
|
|
}
|
|
|
|
// 退款失败
|
|
if ($reqInfo['refund_status'] !== 'SUCCESS') {
|
|
$log = OrderRefundLog::where('sn', $reqInfo['out_refund_no'])->first();
|
|
|
|
$log?->update([
|
|
'status' => OrderRefundLog::STATUS_FAILED,
|
|
'failed_reason' => $reqInfo['refund_status'] === 'CHANGE' ? '退款异常' : '退款关闭',
|
|
]);
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 微信回调日志
|
|
*
|
|
* @param string $message
|
|
* @param array $context
|
|
* @return void
|
|
*/
|
|
protected function log(string $message, array $context = [])
|
|
{
|
|
return Log::build([
|
|
'driver' => 'daily',
|
|
'path' => storage_path('logs/wxpay-notify.log'),
|
|
])->info($message, $context);
|
|
}
|
|
}
|