From 40ede165cdc64ab19d7056ec92f7be5e7f53e2ad Mon Sep 17 00:00:00 2001 From: edmondlang Date: Sun, 19 Sep 2021 17:06:13 +0800 Subject: [PATCH 01/10] online-payment-ui --- .../BookingPaymentQuotationComponent.vue | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index 9909ae8e..9efbe54c 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -169,6 +169,15 @@ +
+
+
+
+
Online Transfer
+
+
+
+
@@ -190,6 +199,38 @@ + +
+
+ +
+
+
+
+
+ + Maybank2u +
+
+
+
+
+ +
+
+
+
+
+ + Cimb +
+
+
+
+
+ +
+
@@ -197,7 +238,7 @@
- +
@@ -311,6 +352,11 @@ id: 'cash', status: false }, + onlinePayment: { + bankName: '', + id: '', + status: false + }, amount: (Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100).toFixed(2), calculation: null } @@ -331,6 +377,14 @@ status: false, } + }, + selectOnlinePaymentBank(bankName){ + this.onlinePayment = { + bankName: bankName.bankName, + id: bankName.id, + status: true, + } + }, submitForm(){ this.parameters = { From cc93b5f03e7986e672323ad10ff17b877d51a618 Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Mon, 27 Sep 2021 11:00:34 +0800 Subject: [PATCH 02/10] create billplz create bill api --- .env.example | 7 ++- .../CreateBillplzBillLogic.php | 56 +++++++++++++++++++ .../Billplzs/Services/CreatesBillplzBill.php | 39 +++++++++++++ .../Billplzs/CreateBillplzBillController.php | 20 +++++++ config/billplz.php | 10 ++++ routes/api.php | 2 + routes/billplz.php | 9 +++ 7 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php create mode 100644 app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php create mode 100644 app/Http/Controllers/Billplzs/CreateBillplzBillController.php create mode 100644 config/billplz.php create mode 100644 routes/billplz.php diff --git a/.env.example b/.env.example index 47a20e74..5bf2187f 100644 --- a/.env.example +++ b/.env.example @@ -50,4 +50,9 @@ FILESYSTEM_DRIVER="documents" JWT_SECRET= JWT_TTL=1440 -IS_PRODUCTION=false \ No newline at end of file +IS_PRODUCTION=false + +BILLPLZ_BASE_URL="https://www.billplz-sandbox.com" +BILLPLZ_API_KEY="0fa4c710-761b-4a7a-a501-c2c2d02643d5" +BILLPLZ_COLLECTION_ID="hev2wdjy" +BILLPLZ_CALLBACK_URL="localhost:9003" \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php new file mode 100644 index 00000000..b1333cf6 --- /dev/null +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php @@ -0,0 +1,56 @@ + 'Created Billplz Bill', + 'message' => 'You have successfully created a new Bill' + ]; + } + + /** @var CreatesBillplzBill */ + private $createsBillplzBill; + + /** + * CreateBookingLogic constructor. + * @param CreatesBillplzBill $createsBillplzBill + */ + public function __construct(CreatesBillplzBill $createsBillplzBill) + { + $this->createsBillplzBill = $createsBillplzBill; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $billPlz = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, $request->input('billNumber'), 200, $request->input('bankName')); + + if(!$billPlz) throw new MalformedRequestException('Unable to get correct response from billplz server.'); + + return $this->response(['data' => $billPlz]); + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php new file mode 100644 index 00000000..0bab471f --- /dev/null +++ b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php @@ -0,0 +1,39 @@ +post(config('billplz.base_url').'/api/v3/bills', [ + 'collection_id' => config('billplz.collection_id'), + 'name' => $name, + 'email' => $email, + 'description' => $description, + 'amount' => $amount, + 'callback_url' => config('billplz.callback_url'), + 'reference_1_label' => 'Bank Code', + 'reference_1' => config('billplz.'.strtolower($bank_code)) + ]); + + if($response->successful()){ + $data = $response->json(); + + $data['url'] = $data['url'].'?auto_submit=true'; + + return $data; + }else{ + return null; + } + }catch(\Exception $exception){ + throw new MalformedRequestException('Unable to get correct response from billplz server'); + } + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Billplzs/CreateBillplzBillController.php b/app/Http/Controllers/Billplzs/CreateBillplzBillController.php new file mode 100644 index 00000000..cd62cfec --- /dev/null +++ b/app/Http/Controllers/Billplzs/CreateBillplzBillController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/config/billplz.php b/config/billplz.php new file mode 100644 index 00000000..5166a59e --- /dev/null +++ b/config/billplz.php @@ -0,0 +1,10 @@ + env('BILLPLZ_BASE_URL', 'https://www.billplz-sandbox.com'), + 'api_key' => env('BILLPLZ_API_KEY', '0fa4c710-761b-4a7a-a501-c2c2d02643d5'), + 'collection_id' => env('BILLPLZ_COLLECTION_ID', 'hev2wdjy'), + 'callback_url' => env('BILLPLZ_CALLBACK_URL', 'localhost'), + 'maybank' => 'MB2U0227', + 'cimb' => 'BCBB0235' +]; \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 146d519a..08c0231d 100644 --- a/routes/api.php +++ b/routes/api.php @@ -47,6 +47,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function require __DIR__ . '/announcement.php'; + require __DIR__ . '/billplz.php'; + // require __DIR__ . '/wallet.php'; // require __DIR__ . '/rate.php'; // require __DIR__ . '/receipt.php'; diff --git a/routes/billplz.php b/routes/billplz.php new file mode 100644 index 00000000..cee3c778 --- /dev/null +++ b/routes/billplz.php @@ -0,0 +1,9 @@ + 'billplz', 'as' => 'billplz.', 'namespace' => 'Billplzs'], function () { + Route::group(['prefix' => 'bill', 'as' => 'bill.'], function () { + Route::post('/create', 'CreateBillplzBillController@create')->name('create'); + }); +}); \ No newline at end of file From 5a65aa51f425af346c6c5ccf09faf0dcadd075da Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Wed, 29 Sep 2021 09:29:22 +0800 Subject: [PATCH 03/10] update input in CreateBillplzBillLogic --- .../Billplzs/ControllersLogic/CreateBillplzBillLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php index b1333cf6..7aabd468 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CreateBillplzBillLogic.php @@ -46,7 +46,7 @@ class CreateBillplzBillLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { - $billPlz = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, $request->input('billNumber'), 200, $request->input('bankName')); + $billPlz = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, $request->input('description'), 200, $request->input('bankName')); if(!$billPlz) throw new MalformedRequestException('Unable to get correct response from billplz server.'); From fb84e47d432446cb4a3bdfb88af9cb5fc8a75878 Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Mon, 4 Oct 2021 15:09:36 +0800 Subject: [PATCH 04/10] integrate create billplz bill with create booking payment, and a new billplz callback url --- .env.example | 4 +- .../Eloquent/Filters/PaymentReference.php | 20 +++++ .../ControllersLogic/CallbackBillplzLogic.php | 71 +++++++++++++++ .../BillplzXSignatureObject.php | 88 +++++++++++++++++++ .../Billplzs/Services/CreatesBillplzBill.php | 9 +- .../Billplzs/Services/GetBillplzBill.php | 28 ++++++ .../CreateBookingPaymentLogic.php | 19 +++- .../Billplzs/CallbackBillplzController.php | 20 +++++ app/Http/Resources/BookingResource.php | 1 + config/billplz.php | 2 + routes/api.php | 6 ++ 11 files changed, 262 insertions(+), 6 deletions(-) create mode 100644 app/Classes/General/Eloquent/Filters/PaymentReference.php create mode 100644 app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php create mode 100644 app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php create mode 100644 app/Classes/Modules/Billplzs/Services/GetBillplzBill.php create mode 100644 app/Http/Controllers/Billplzs/CallbackBillplzController.php diff --git a/.env.example b/.env.example index 5bf2187f..f9a5dde4 100644 --- a/.env.example +++ b/.env.example @@ -54,5 +54,7 @@ IS_PRODUCTION=false BILLPLZ_BASE_URL="https://www.billplz-sandbox.com" BILLPLZ_API_KEY="0fa4c710-761b-4a7a-a501-c2c2d02643d5" +BILLPLZ_X_SIGNATURE_KEY="S-pbNVthVRsvnPfZlgLwqqOg" BILLPLZ_COLLECTION_ID="hev2wdjy" -BILLPLZ_CALLBACK_URL="localhost:9003" \ No newline at end of file +BILLPLZ_REDIRECT_URL="localhost:9003" +BILLPLZ_CALLBACK_URL="localhost:9003/api/v1/billplz/callback" \ No newline at end of file diff --git a/app/Classes/General/Eloquent/Filters/PaymentReference.php b/app/Classes/General/Eloquent/Filters/PaymentReference.php new file mode 100644 index 00000000..10c1fa49 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/PaymentReference.php @@ -0,0 +1,20 @@ +where('payment_reference', $value); + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php new file mode 100644 index 00000000..bce275a3 --- /dev/null +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -0,0 +1,71 @@ + 'Callback Billplz', + 'message' => 'You have successfully receive Billplz callback' + ]; + } + + /** @var GetBillplzBill */ + private $getBillplzBill; + + /** @var UpdatesTransactionStatus */ + private $updatesTransactionStatus; + + + /** + * CreateBookingLogic constructor. + * @param CreateGetBillplzBillsBillplzBill $getBillplzBill + * @param UpdatesTransactionStatus $updatesTransactionStatus + */ + public function __construct(GetBillplzBill $getBillplzBill, UpdatesTransactionStatus $updatesTransactionStatus) + { + $this->getBillplzBill = $getBillplzBill; + $this->updatesTransactionStatus = $updatesTransactionStatus; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $billplzXSignatureObject = new BillplzXSignatureObject($request); + + if(!$billplzXSignatureObject->isValidSignature()) throw new MalformedRequestException('Unable to get correct response from billplz server.'); + + $billPlz = $this->getBillplzBill->execute($request->input('id')); + + if(!$billPlz) throw new MalformedRequestException('Unable to get correct response from billplz server.'); + + if($billPlz->state == 'paid') $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); + + return $this->response(['data' => $billPlz]); + + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php b/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php new file mode 100644 index 00000000..ac3f178c --- /dev/null +++ b/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php @@ -0,0 +1,88 @@ +request = $request; + + $this->_constructBillplzArray()->_natSortBillplzArray()->_constructBillplzString()->_computeBillplzXSignature(); + } + + private function _constructBillplzArray(){ + foreach($this->request->all() as $key => $value){ + if($key != 'x_signature'){ + $this->billPlzConstructArray[] = $key.$value; + } + } + return $this; + } + + private function _natCaseSortBillplzArray(){ + natcasesort($this->billPlzConstructArray); + return $this; + } + + private function _natSortBillplzArray(){ + natsort($this->billPlzConstructArray); + return $this; + } + + private function _constructBillplzString(){ + $this->billPlzConstructString = implode('|', $this->billPlzConstructArray); + return $this; + } + + private function _computeBillplzXSignature(){ + $this->billPlzComputedXSignature = hash_hmac('sha256', $this->billPlzConstructString, config('billplz.x_signature_key')); + return $this; + } + + /** + * @return array + */ + public function getBillPlzConstructArray(): array + { + return $this->billPlzConstructArray; + } + + /** + * @return string + */ + public function getBillPlzConstructString(): string + { + return $this->billPlzConstructString; + } + + /** + * @return string + */ + public function getBillPlzComputedXSignature(): string + { + return $this->billPlzComputedXSignature; + } + + public function isValidSignature(): bool + { + return $this->billPlzComputedXSignature == $this->request->x_signature ? true : false; + } + +} \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php index 0bab471f..4a70e06e 100644 --- a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php +++ b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php @@ -10,7 +10,7 @@ class CreatesBillplzBill * @return \Illuminate\Database\Eloquent\Model * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(string $name, string $email, string $description, float $amount, string $bank_code) { + public function execute(string $name, string $email, string $description, float $amount, string $bankCode, string $billNumber) { try{ $response = Http::withBasicAuth(config('billplz.api_key').':', '')->post(config('billplz.base_url').'/api/v3/bills', [ 'collection_id' => config('billplz.collection_id'), @@ -18,9 +18,12 @@ class CreatesBillplzBill 'email' => $email, 'description' => $description, 'amount' => $amount, + 'redirect_url' => config('billplz.redirect_url'), 'callback_url' => config('billplz.callback_url'), 'reference_1_label' => 'Bank Code', - 'reference_1' => config('billplz.'.strtolower($bank_code)) + 'reference_1' => $bankCode, + 'reference_2_label' => 'Bill Number', + 'reference_2' => $billNumber ]); if($response->successful()){ @@ -28,7 +31,7 @@ class CreatesBillplzBill $data['url'] = $data['url'].'?auto_submit=true'; - return $data; + return (object) $data; }else{ return null; } diff --git a/app/Classes/Modules/Billplzs/Services/GetBillplzBill.php b/app/Classes/Modules/Billplzs/Services/GetBillplzBill.php new file mode 100644 index 00000000..ff7c129f --- /dev/null +++ b/app/Classes/Modules/Billplzs/Services/GetBillplzBill.php @@ -0,0 +1,28 @@ +get(config('billplz.base_url').'/api/v3/bills/'.$billPlzId); + + if($response->successful()){ + $data = $response->json(); + + return (object) $data; + }else{ + return null; + } + }catch(\Exception $exception){ + throw new MalformedRequestException('Unable to get correct response from billplz server'); + } + } +} \ No newline at end of file diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php index b2a0732a..87f32666 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php @@ -11,7 +11,9 @@ use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\Services\CreatesTransaction; +use App\Classes\Modules\Transactions\Services\UpdatesTransaction; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; +use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\TransactionType; @@ -46,9 +48,15 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic /** @var CreatesTransaction */ private $createsTransaction; + /** @var UpdatesTransaction */ + private $updatesTransaction; + /** @var CalculatesBookingOutstanding */ private $calculatesBookingOutstanding; + /** @var CreatesBillplzBill */ + private $createsBillplzBill; + /** * CreateBookingPaymentLogic constructor. * @param FetchesBookingQuotation $fetchBookingQuotation @@ -56,14 +64,17 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic * @param GeneratesTransactionBillNumber $generatesTransactionBillNumber * @param CreatesTransaction $createsTransaction * @param CalculatesBookingOutstanding $calculatesBookingOutstanding + * @param CreatesBillplzBill $createsBillplzBill */ - public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding) + public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, UpdatesTransaction $updatesTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill) { $this->fetchBookingQuotation = $fetchBookingQuotation; $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit; $this->generatesTransactionBillNumber = $generatesTransactionBillNumber; $this->createsTransaction = $createsTransaction; + $this->updatesTransaction = $updatesTransaction; $this->calculatesBookingOutstanding = $calculatesBookingOutstanding; + $this->createsBillplzBill = $createsBillplzBill; } /** @@ -88,11 +99,15 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); + if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){ + $billPlzBill = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, 'This payment is made on behave '.$booking->company->name, $configurations->getTotal(), $request->input('bank_code'), $billNumber); + } + $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, $configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(), $configurations->getTotal(), $configurations->getForeignTotal(), 1, $configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(), - $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION); + $configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], isset($billPlzBill) ? $billPlzBill->id : NULL); $transaction = $this->createsTransaction->execute($booking, $object); diff --git a/app/Http/Controllers/Billplzs/CallbackBillplzController.php b/app/Http/Controllers/Billplzs/CallbackBillplzController.php new file mode 100644 index 00000000..33525632 --- /dev/null +++ b/app/Http/Controllers/Billplzs/CallbackBillplzController.php @@ -0,0 +1,20 @@ +execute($request); + } + +} \ No newline at end of file diff --git a/app/Http/Resources/BookingResource.php b/app/Http/Resources/BookingResource.php index cc5f0dca..865ace28 100644 --- a/app/Http/Resources/BookingResource.php +++ b/app/Http/Resources/BookingResource.php @@ -23,6 +23,7 @@ class BookingResource extends JsonResource */ public function toArray($request) { + // dd($this->service); return [ 'id' => $this->id, 'company' => new CompanyResource($this->company), diff --git a/config/billplz.php b/config/billplz.php index 5166a59e..ac5b3a75 100644 --- a/config/billplz.php +++ b/config/billplz.php @@ -3,7 +3,9 @@ return [ 'base_url' => env('BILLPLZ_BASE_URL', 'https://www.billplz-sandbox.com'), 'api_key' => env('BILLPLZ_API_KEY', '0fa4c710-761b-4a7a-a501-c2c2d02643d5'), + 'x_signature_key' => env('BILLPLZ_X_SIGNATURE_KEY', 'S-pbNVthVRsvnPfZlgLwqqOg'), 'collection_id' => env('BILLPLZ_COLLECTION_ID', 'hev2wdjy'), + 'redirect_url' => env('BILLPLZ_REDIRECT_URL', 'localhost'), 'callback_url' => env('BILLPLZ_CALLBACK_URL', 'localhost'), 'maybank' => 'MB2U0227', 'cimb' => 'BCBB0235' diff --git a/routes/api.php b/routes/api.php index 08c0231d..3bae2eea 100644 --- a/routes/api.php +++ b/routes/api.php @@ -23,6 +23,12 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function Route::get('countries/list', 'Services\CountriesListController@index')->name('list.countries'); }); + Route::group(['prefix' => 'billplz', 'as' => 'billplz.', 'namespace' => 'Billplzs'], function () { + Route::group(['prefix' => 'bill', 'as' => 'bill.'], function () { + Route::post('/callback', 'CallbackBillplzController@callback')->name('callback'); + }); + }); + Route::group(['middleware' => 'valid.token'], function () { From 9861c62c141b351a0e999159d98d0535c868e3e6 Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Thu, 7 Oct 2021 10:49:54 +0800 Subject: [PATCH 05/10] integrate create billplz bill with create booking payment, and a new billplz callback url --- .../ControllersLogic/CallbackBillplzLogic.php | 13 ++++++++++-- .../BillplzXSignatureObject.php | 20 +++++++++++++++++-- .../Billplzs/Services/CreatesBillplzBill.php | 4 ++-- routes/web.php | 4 ++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index bce275a3..eb472ce5 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -12,6 +12,7 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\Modules\Billplzs\Services\GetBillplzBill; use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject; use App\Classes\General\Abstracts\AbstractControllerLogic; +use App\Classes\Modules\Transactions\Services\FetchesTransaction; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; class CallbackBillplzLogic extends AbstractControllerLogic @@ -30,6 +31,9 @@ class CallbackBillplzLogic extends AbstractControllerLogic /** @var GetBillplzBill */ private $getBillplzBill; + /** @var FetchesTransaction */ + private $fetchesTransaction; + /** @var UpdatesTransactionStatus */ private $updatesTransactionStatus; @@ -37,11 +41,13 @@ class CallbackBillplzLogic extends AbstractControllerLogic /** * CreateBookingLogic constructor. * @param CreateGetBillplzBillsBillplzBill $getBillplzBill + * @param FetchesTransaction $fetchesTransaction * @param UpdatesTransactionStatus $updatesTransactionStatus */ - public function __construct(GetBillplzBill $getBillplzBill, UpdatesTransactionStatus $updatesTransactionStatus) + public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus) { $this->getBillplzBill = $getBillplzBill; + $this->fetchesTransaction = $fetchesTransaction; $this->updatesTransactionStatus = $updatesTransactionStatus; } @@ -55,14 +61,17 @@ class CallbackBillplzLogic extends AbstractControllerLogic */ public function logic(Request $request) : JsonResponse { + $billplzXSignatureObject = new BillplzXSignatureObject($request); if(!$billplzXSignatureObject->isValidSignature()) throw new MalformedRequestException('Unable to get correct response from billplz server.'); - $billPlz = $this->getBillplzBill->execute($request->input('id')); + $billPlz = $this->getBillplzBill->execute($billplzXSignatureObject->getBillPlzId()); if(!$billPlz) throw new MalformedRequestException('Unable to get correct response from billplz server.'); + $transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]); + if($billPlz->state == 'paid') $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); return $this->response(['data' => $billPlz]); diff --git a/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php b/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php index ac3f178c..db3e3ad6 100644 --- a/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php +++ b/app/Classes/Modules/Billplzs/DataTransferObjects/BillplzXSignatureObject.php @@ -8,6 +8,9 @@ use App\Classes\General\Interfaces\DataTransferObject; class BillplzXSignatureObject implements DataTransferObject { + /** @var string */ + private $billPlzId; + /** @var array */ private $billPlzConstructArray; @@ -20,16 +23,24 @@ class BillplzXSignatureObject implements DataTransferObject /** @var Request */ private $request; + /** @var string */ + private $requestXSignature; + public function __construct(Request $request) { $this->request = $request; + $this->billPlzId = $request->id ? $request->id : $request->{'billplz[id]'}; + + $this->requestXSignature = $request->x_signature ? $request->x_signature : $request->{'billplz[x_signature]'}; + $this->_constructBillplzArray()->_natSortBillplzArray()->_constructBillplzString()->_computeBillplzXSignature(); } private function _constructBillplzArray(){ foreach($this->request->all() as $key => $value){ - if($key != 'x_signature'){ + if($key != 'x_signature' && $key != 'billplz[x_signature]'){ + $key = str_replace(']', '', str_replace('[', '', $key)); $this->billPlzConstructArray[] = $key.$value; } } @@ -56,6 +67,11 @@ class BillplzXSignatureObject implements DataTransferObject return $this; } + public function getBillPlzId(): string + { + return $this->billPlzId; + } + /** * @return array */ @@ -82,7 +98,7 @@ class BillplzXSignatureObject implements DataTransferObject public function isValidSignature(): bool { - return $this->billPlzComputedXSignature == $this->request->x_signature ? true : false; + return $this->billPlzComputedXSignature == $this->requestXSignature ? true : false; } } \ No newline at end of file diff --git a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php index 4a70e06e..bd97728e 100644 --- a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php +++ b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php @@ -10,7 +10,7 @@ class CreatesBillplzBill * @return \Illuminate\Database\Eloquent\Model * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(string $name, string $email, string $description, float $amount, string $bankCode, string $billNumber) { + public function execute(string $name, string $email, string $description, float $amount, string $billNumber, string $bankCode = '') { try{ $response = Http::withBasicAuth(config('billplz.api_key').':', '')->post(config('billplz.base_url').'/api/v3/bills', [ 'collection_id' => config('billplz.collection_id'), @@ -21,7 +21,7 @@ class CreatesBillplzBill 'redirect_url' => config('billplz.redirect_url'), 'callback_url' => config('billplz.callback_url'), 'reference_1_label' => 'Bank Code', - 'reference_1' => $bankCode, + 'reference_1' => $bankCode ? $bankCode : config('billplz.maybank'), 'reference_2_label' => 'Bill Number', 'reference_2' => $billNumber ]); diff --git a/routes/web.php b/routes/web.php index 1578a131..09c802af 100644 --- a/routes/web.php +++ b/routes/web.php @@ -69,6 +69,10 @@ Route::get('/transfer/merge/{marking}', function ($marking) { return view('pages.booking_merge', ['marking' => $marking]); })->name('booking.merge'); +Route::get('/bookings/billplz', function () { + return view('pages.billplz_redirect'); +})->name('bookings.billplz'); + Route::get('/export/customers/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@export'); Route::get('/export/transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@transactions'); From ab534ea8ed3f86d33e5eb57d3bf25ce853cdfe98 Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Thu, 7 Oct 2021 10:59:43 +0800 Subject: [PATCH 06/10] integrate create billplz bill with create booking payment, and a new billplz callback url --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index f9a5dde4..6367c9b8 100644 --- a/.env.example +++ b/.env.example @@ -56,5 +56,5 @@ BILLPLZ_BASE_URL="https://www.billplz-sandbox.com" BILLPLZ_API_KEY="0fa4c710-761b-4a7a-a501-c2c2d02643d5" BILLPLZ_X_SIGNATURE_KEY="S-pbNVthVRsvnPfZlgLwqqOg" BILLPLZ_COLLECTION_ID="hev2wdjy" -BILLPLZ_REDIRECT_URL="localhost:9003" +BILLPLZ_REDIRECT_URL="http://localhost:9003/bookings/billplz" BILLPLZ_CALLBACK_URL="localhost:9003/api/v1/billplz/callback" \ No newline at end of file From 223caa2c3307cd0c02ca0bca6d7fe1627fbb4eb3 Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Thu, 7 Oct 2021 11:00:50 +0800 Subject: [PATCH 07/10] integrate create billplz bill with create booking payment, and a new billplz callback url --- .../Bookings/ControllersLogic/CreateBookingPaymentLogic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php index 87f32666..f0958c14 100644 --- a/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php +++ b/app/Classes/Modules/Bookings/ControllersLogic/CreateBookingPaymentLogic.php @@ -100,7 +100,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic $billNumber = $this->generatesTransactionBillNumber->execute('PYMT-'); if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){ - $billPlzBill = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, 'This payment is made on behave '.$booking->company->name, $configurations->getTotal(), $request->input('bank_code'), $billNumber); + $billPlzBill = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, 'This payment is made on behave '.$booking->company->name, $configurations->getTotal(), $billNumber, $request->input('bank_code')); } $object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id, From 7dbe51bda91d370bcda8e070c01437bb1c66aad1 Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Fri, 8 Oct 2021 10:31:23 +0800 Subject: [PATCH 08/10] integrate create billplz bill with create booking payment, and a new billplz callback url --- .../Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php | 2 +- app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php | 2 +- .../bookings/forms/BookingPaymentQuotationComponent.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php index eb472ce5..8dece746 100644 --- a/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php +++ b/app/Classes/Modules/Billplzs/ControllersLogic/CallbackBillplzLogic.php @@ -72,7 +72,7 @@ class CallbackBillplzLogic extends AbstractControllerLogic $transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]); - if($billPlz->state == 'paid') $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::PENDING_VERIFICATION); + if($billPlz->state == 'paid') $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED); return $this->response(['data' => $billPlz]); diff --git a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php index bd97728e..7cf4bdef 100644 --- a/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php +++ b/app/Classes/Modules/Billplzs/Services/CreatesBillplzBill.php @@ -10,7 +10,7 @@ class CreatesBillplzBill * @return \Illuminate\Database\Eloquent\Model * @throws \App\Classes\Exceptions\MalformedRequestException */ - public function execute(string $name, string $email, string $description, float $amount, string $billNumber, string $bankCode = '') { + public function execute(string $name, string $email, string $description, float $amount, string $billNumber, ?string $bankCode = null) { try{ $response = Http::withBasicAuth(config('billplz.api_key').':', '')->post(config('billplz.base_url').'/api/v3/bills', [ 'collection_id' => config('billplz.collection_id'), diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index 9efbe54c..b98d2762 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -169,7 +169,7 @@ -
+
From 13c948d40e01365097e875c91b7d461a5af10881 Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Fri, 8 Oct 2021 10:32:55 +0800 Subject: [PATCH 09/10] integrate create billplz bill with create booking payment, and a new billplz callback url --- .../bookings/forms/BookingPaymentQuotationComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue index b98d2762..9efbe54c 100644 --- a/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue +++ b/resources/assets/vue/components/bookings/forms/BookingPaymentQuotationComponent.vue @@ -169,7 +169,7 @@
-
+
From 5e0799687f18942a0727abefeca9e4bd3dd033ce Mon Sep 17 00:00:00 2001 From: ahmedsophyudden Date: Fri, 15 Oct 2021 19:20:55 +0800 Subject: [PATCH 10/10] added billplz_redirect.blade sample page --- .../views/pages/billplz_redirect.blade.php | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 resources/views/pages/billplz_redirect.blade.php diff --git a/resources/views/pages/billplz_redirect.blade.php b/resources/views/pages/billplz_redirect.blade.php new file mode 100644 index 00000000..a2e924a4 --- /dev/null +++ b/resources/views/pages/billplz_redirect.blade.php @@ -0,0 +1,33 @@ + + \ No newline at end of file