diff --git a/CHANGELOG.md b/CHANGELOG.md index f62bb49..0cb3eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Tất cả lịch sử tiến trình phát triển thư viện +### 1.1.0 + ++ Thêm lớp đối tượng `PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware` giảm nghiệp vụ xác minh tính hợp lệ của +complete purchase request. + + ### 1.0.1 + Hổ trợ Laravel 6 & 7. diff --git a/docs/VNPay.md b/docs/VNPay.md index 50ee43a..05a8cfe 100644 --- a/docs/VNPay.md +++ b/docs/VNPay.md @@ -47,6 +47,9 @@ if ($response->isSuccessful()) { } ``` +Hoặc bạn có thể sử dụng `PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware` để giảm bớt nghiệp vụ xử lý kiểm tra tính hợp lệ +của request, xem thêm tại [đây](common/CompletePurchaseMiddleware.md). + Kham khảo thêm các tham trị khi VNPay trả về tại [đây](https://sandbox.vnpayment.vn/apis/docs/huong-dan-tich-hop/#code-returnurl). ### Kiểm tra thông tin `IPN` do VNPay gửi sang: diff --git a/docs/VTCPay.md b/docs/VTCPay.md index 09d9652..05882f1 100644 --- a/docs/VTCPay.md +++ b/docs/VTCPay.md @@ -45,6 +45,9 @@ if ($response->isSuccessful()) { } ``` +Hoặc bạn có thể sử dụng `PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware` để giảm bớt nghiệp vụ xử lý kiểm tra tính hợp lệ +của request, xem thêm tại [đây](common/CompletePurchaseMiddleware.md). + Kham khảo thêm các tham trị khi VTCPay trả về tại [đây](https://vtcpay.vn/tai-lieu-tich-hop-website). diff --git a/docs/common/CompletePurchaseMiddleware.md b/docs/common/CompletePurchaseMiddleware.md new file mode 100644 index 0000000..f39e4ea --- /dev/null +++ b/docs/common/CompletePurchaseMiddleware.md @@ -0,0 +1,37 @@ +Complete purchase middleware +================================================== + +Lớp `PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware` là một [route middleware](https://laravel.com/docs/7.x/middleware#assigning-middleware-to-routes) giúp bạn +giảm bớt nghiệp vụ xác thực phiên giao dịch của khách có thành công hay không hay có phải là do nhà cung cấp dịch vụ gửi về hay không, thay vào đó bạn chỉ cần tập trung vào xử lý +nghiệp vụ khi thanh toán thành công hoặc thất bại. + +Để sử dụng middleware này thì bạn cần khai báo nó vào `routeMiddleware`: + +```php +// Within App\Http\Kernel Class... + + protected $routeMiddleware = [ + 'completePurchase' => \PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware::class + ]; +``` + +Và gắn nó vào route đảm nhiệm nghiệp vụ khi nhà cung cấp dịch vụ redirect khách về site của bạn +ví dụ: + +```php + Route::get('/complete-purchase', function (\Illuminate\Http\Request $request) { + /** @var \Omnipay\Common\Message\ResponseInterface $completePurchaseResponse */ + $completePurchaseResponse = $request->attributes->get('completePurchaseResponse'); + + if ($completePurchaseResponse->isSuccessful()) { + // xử lý logic thanh toán thành công. + } elseif ($completePurchaseResponse->isCancelled()) { + // khi khách hủy giao dịch. + } else { + // các trường hợp khác + } + + })->middleware('completePurchase:MoMoAIO'); +``` + +Parameter truyền vào middleware chính là gateway name của bạn ở ví dụ trên nó là `MoMoAIO` gateway. diff --git a/docs/momo/AllInOne.md b/docs/momo/AllInOne.md index 5ce0dd1..491503b 100644 --- a/docs/momo/AllInOne.md +++ b/docs/momo/AllInOne.md @@ -44,6 +44,9 @@ if ($response->isSuccessful()) { } ``` +Hoặc bạn có thể sử dụng `PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware` để giảm bớt nghiệp vụ xử lý kiểm tra tính hợp lệ +của request, xem thêm tại [đây](../common/CompletePurchaseMiddleware.md). + Kham khảo thêm các tham trị khi MoMo trả về tại [đây](https://developers.momo.vn/#/docs/aio/?id=th%c3%b4ng-tin-tham-s%e1%bb%91). ### Kiểm tra thông tin `notifyUrl` do MoMo gửi sang: diff --git a/docs/onepay/Domestic.md b/docs/onepay/Domestic.md index 315cacd..bdc381a 100644 --- a/docs/onepay/Domestic.md +++ b/docs/onepay/Domestic.md @@ -44,6 +44,9 @@ if ($response->isSuccessful()) { } ``` +Hoặc bạn có thể sử dụng `PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware` để giảm bớt nghiệp vụ xử lý kiểm tra tính hợp lệ +của request, xem thêm tại [đây](../common/CompletePurchaseMiddleware.md). + Kham khảo thêm các tham trị khi OnePay trả về tại [đây](https://mtf.onepay.vn/developer/resource/documents/docx/quy_trinh_tich_hop-noidia.pdf). ### Kiểm tra thông tin `IPN` do OnePay gửi sang: diff --git a/docs/onepay/International.md b/docs/onepay/International.md index 973366d..22f5037 100644 --- a/docs/onepay/International.md +++ b/docs/onepay/International.md @@ -44,6 +44,9 @@ if ($response->isSuccessful()) { } ``` +Hoặc bạn có thể sử dụng `PHPViet\Laravel\Omnipay\Middleware\CompletePurchaseMiddleware` để giảm bớt nghiệp vụ xử lý kiểm tra tính hợp lệ +của request, xem thêm tại [đây](../common/CompletePurchaseMiddleware.md). + Kham khảo thêm các tham trị khi OnePay trả về tại [đây](https://mtf.onepay.vn/developer/resource/documents/docx/quy_trinh_tich_hop-noidia.pdf). ### Kiểm tra thông tin `IPN` do OnePay gửi sang: diff --git a/src/Middleware/CompletePurchaseMiddleware.php b/src/Middleware/CompletePurchaseMiddleware.php new file mode 100644 index 0000000..126f2c7 --- /dev/null +++ b/src/Middleware/CompletePurchaseMiddleware.php @@ -0,0 +1,46 @@ + + * @since 1.1.0 + */ +class CompletePurchaseMiddleware +{ + /** + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return mixed + */ + public function handle($request, Closure $next, string $gateway) + { + /** @var AbstractGateway $gateway */ + $gateway = app('omnipay')->gateway($gateway); + + if (! $gateway->supportsCompletePurchase()) { + throw new \InvalidArgumentException('Gateway configured not support complete purchase method!'); + } + + try { + $response = $gateway->completePurchase()->send(); + } catch (OmnipayException $e) { + throw new BadRequestHttpException($e->getMessage()); + } + + $request->attributes->set('completePurchaseResponse', $response); + + return $next($request); + } +} diff --git a/tests/Middleware/CompletePurchaseMiddlewareTest.php b/tests/Middleware/CompletePurchaseMiddlewareTest.php new file mode 100644 index 0000000..933830b --- /dev/null +++ b/tests/Middleware/CompletePurchaseMiddlewareTest.php @@ -0,0 +1,70 @@ + + * @since 1.0.0 + */ +class CompletePurchaseMiddlewareTest extends TestCase +{ + public function getEnvironmentSetUp($app): void + { + $_GET['partnerCode'] = 'test'; + $_GET['accessKey'] = 'test'; + $_GET['requestId'] = 'test'; + $_GET['amount'] = 'test'; + $_GET['orderId'] = 'test'; + $_GET['orderInfo'] = 'test'; + $_GET['orderType'] = 'test'; + $_GET['transId'] = 'test'; + $_GET['message'] = 'test'; + $_GET['localMessage'] = 'test'; + $_GET['responseTime'] = 'test'; + $_GET['errorCode'] = 'test'; + $_GET['extraData'] = 'test'; + $_GET['signature'] = 'test'; + $_GET['payType'] = 'test'; + + parent::getEnvironmentSetUp($app); + + $router = $app->get('router'); + $router->middleware(CompletePurchaseMiddleware::class); + $router->aliasMiddleware('completePurchase', CompletePurchaseMiddleware::class); + $router->get( + '/test', + function (Request $request) { + $completePurchaseResponse = $request->attributes->get('completePurchaseResponse'); + + $this->assertInstanceOf(ResponseInterface::class, $completePurchaseResponse); + + return new Response('ok', 200); + } + )->middleware('completePurchase:MoMoAIO'); + } + + public function testCanGetResponse() + { + $response = $this->get('/test'); + $response->assertOk(); + } + + public function testMissingRequestQueryParam() + { + unset($_GET['signature']); + $response = $this->get('/test'); + $response->assertStatus(400); + } +}