From 1b8de36a8d467408d9a892039e9b02ad9df3bc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=9D=99?= Date: Tue, 4 Jan 2022 19:39:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=AE=9D=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Http/Controllers/AlipayController.php | 78 ++++++++++++++++++- app/Endpoint/Callback/routes.php | 2 +- app/Services/AlipayService.php | 32 +++++--- 3 files changed, 98 insertions(+), 14 deletions(-) diff --git a/app/Endpoint/Callback/Http/Controllers/AlipayController.php b/app/Endpoint/Callback/Http/Controllers/AlipayController.php index 721cf2d7..0b06d545 100644 --- a/app/Endpoint/Callback/Http/Controllers/AlipayController.php +++ b/app/Endpoint/Callback/Http/Controllers/AlipayController.php @@ -2,20 +2,90 @@ namespace App\Endpoint\Callback\Http\Controllers; +use App\Events\OrderPaid; +use App\Exceptions\BizException; +use App\Models\Order; +use App\Services\AlipayService; +use App\Services\PayService; use Illuminate\Http\Request; +use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; +use Throwable; class AlipayController extends Controller { /** - * 支付通知 + * 通知 * - * @param Request $request + * @param \Illuminate\Http\Request $request + * @param \App\Services\AlipayService $alipayService * @return \Illuminate\Http\Response */ - public function paidNotify(Request $request) + public function __invoke(Request $request, AlipayService $alipayService) { - $this->log('paid notify', $request->all()); + $this->log('notify', $request->all()); + + if (! $alipayService->verifyNotify($request->all())) { + throw new BizException('签名校验失败'); + } + + if ($request->filled('out_biz_no')) { + return $this->refundedNotify($request); + } + + return $this->paidNotify($request); + } + + /** + * 付款通知 + * + * @param Request $request + * @return void + */ + protected function paidNotify(Request $request) + { + $input = $request->all(); + + try { + $payLog = DB::transaction(function () use ($input) { + $tradeStatus = data_get($input, 'trade_status'); + + if (in_array($tradeStatus, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) { + (new PayService())->handleSuccessByPaySerialNumber($input['out_trade_no'], [ + 'out_trade_no' => $input['trade_no'], + 'pay_at' => Carbon::parse($input['gmt_payment']), + ]); + } elseif ($tradeStatus === 'TRADE_CLOSED') { + (new PayService())->handleFailedByPaySerialNumber($input['out_trade_no'], [ + 'out_trade_no' => $input['trade_no'] ?? null, + 'failed_reason' => '未付款交易超时关闭', + ]); + } + }); + + $payable = $payLog?->payable; + + if ($payable instanceof Order) { + OrderPaid::dispatchIf($payable->isPaid(), $payable); + } + } catch (BizException $e) { + } catch (Throwable $e) { + throw $e; + } + + return 'success'; + } + + /** + * 退款通知 + * + * @param Request $request + * @return void + */ + protected function refundedNotify(Request $request) + { + return 'success'; } /** diff --git a/app/Endpoint/Callback/routes.php b/app/Endpoint/Callback/routes.php index 5118f7c7..cf361084 100644 --- a/app/Endpoint/Callback/routes.php +++ b/app/Endpoint/Callback/routes.php @@ -11,4 +11,4 @@ Route::post('kuaidi100', [Kuaidi100Controller::class, 'notify']); Route::post('wxpay/paid-notify', [WeChatPayController::class, 'paidNotify'])->name('wxpay.paid_notify'); Route::post('wxpay/order-refund-notify', [WeChatPayController::class, 'orderRefundedNotify'])->name('wxpay.order_refund_notify'); -Route::post('alipay/paid-notify', [AlipayController::class, 'paidNotify'])->name('alipay.paid_notify'); +Route::post('alipay', AlipayController::class)->name('alipay.notify'); diff --git a/app/Services/AlipayService.php b/app/Services/AlipayService.php index 35b9cd02..d0667cd4 100644 --- a/app/Services/AlipayService.php +++ b/app/Services/AlipayService.php @@ -2,10 +2,11 @@ namespace App\Services; -use AlibabaCloud\Client\Config\Config; use Alipay\EasySDK\Kernel\CertEnvironment; +use Alipay\EasySDK\Kernel\Config; use Alipay\EasySDK\Kernel\EasySDKKernel; use Alipay\EasySDK\Payment\App\Client as AppClient; +use Alipay\EasySDK\Payment\Common\Client as CommonClient; class AlipayService { @@ -17,7 +18,9 @@ class AlipayService */ public function pay(array $params) { - $result = $this->app()->pay( + $kernel = $this->getKernel(); + + $result = (new AppClient($kernel))->pay( $params['subject'], $params['out_trade_no'], $params['total_amount'], @@ -28,22 +31,33 @@ class AlipayService ]; } + /** + * 验证回调通知 + * + * @param array $parameters + * @return bool + */ + public function verifyNotify(array $parameters = []): bool + { + $client = new CommonClient($this->getKernel()); + + return $client->verifyNotify($parameters); + } + /** * App 支付客户端 * - * @return AppClient + * @return EasySDKKernel */ - protected function app(): AppClient + public function getKernel(): EasySDKKernel { - $kernel = new EasySDKKernel($this->getConfig()); - - return new AppClient($kernel); + return new EasySDKKernel($this->getConfig()); } /** * 获取支付宝配置信息 * - * @return \AlibabaCloud\Client\Config\Config + * @return \Alipay\EasySDK\Kernel\Config */ protected function getConfig(): Config { @@ -58,7 +72,7 @@ class AlipayService $cfg->merchantCertPath = $configs['app_public_cert_path']; $cfg->alipayCertPath = $configs['public_cert_path']; $cfg->alipayRootCertPath = $configs['root_cert_path']; - $cfg->notifyUrl = $configs['notify_url'] ?? url(route('alipay.paid_notify', [], false), [], true); + $cfg->notifyUrl = $configs['notify_url'] ?? url(route('alipay.notify', [], false), [], true); $certEnvironment = new CertEnvironment(); $certEnvironment->certEnvironment(