mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
integrate create billplz bill with create booking payment, and a new billplz callback url
This commit is contained in:
+3
-1
@@ -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"
|
||||
BILLPLZ_REDIRECT_URL="localhost:9003"
|
||||
BILLPLZ_CALLBACK_URL="localhost:9003/api/v1/billplz/callback"
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class PaymentReference implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('payment_reference', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Billplzs\ControllersLogic;
|
||||
|
||||
use ErrorException;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
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\UpdatesTransactionStatus;
|
||||
|
||||
class CallbackBillplzLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => '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]);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Billplzs\DataTransferObjects;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class BillplzXSignatureObject implements DataTransferObject
|
||||
{
|
||||
|
||||
/** @var array */
|
||||
private $billPlzConstructArray;
|
||||
|
||||
/** @var string */
|
||||
private $billPlzConstructString;
|
||||
|
||||
/** @var string */
|
||||
private $billPlzComputedXSignature;
|
||||
|
||||
/** @var Request */
|
||||
private $request;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Billplzs\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class GetBillplzBill
|
||||
{
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(string $billPlzId) {
|
||||
try{
|
||||
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Billplzs;
|
||||
|
||||
use App\Classes\Modules\Billplzs\ControllersLogic\CallbackBillplzLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CallbackBillplzController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param BillplzBillLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function callback(Request $request, CallbackBillplzLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ class BookingResource extends JsonResource
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
// dd($this->service);
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'company' => new CompanyResource($this->company),
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
Reference in New Issue
Block a user