From db75e7becd3f0a6070b584bc179ed03980205fee Mon Sep 17 00:00:00 2001 From: Ramon Gutierrez Date: Wed, 6 Sep 2023 04:05:15 +0800 Subject: [PATCH] Add insurance endpoints, insurance and paymongo connectors #761 --- config/routes/apiv2.yaml | 31 ++ config/routes/insurance.yaml | 12 +- config/routes/paymongo.yaml | 6 + config/services.yaml | 7 + .../CustomerAppAPI/InsuranceController.php | 291 ++++++++++++++++++ src/Controller/PayMongoController.php | 23 ++ src/Entity/CustomerVehicle.php | 18 ++ src/Entity/InsuranceApplication.php | 238 ++++++++++++++ src/Ramcar/InsuranceApplicationStatus.php | 16 + src/Ramcar/InsuranceClientType.php | 14 + src/Ramcar/InsuranceMVType.php | 32 ++ src/Ramcar/InsuranceVehicleLine.php | 18 ++ src/Service/InsuranceConnector.php | 123 +++++--- src/Service/PayMongoConnector.php | 122 ++++++++ 14 files changed, 904 insertions(+), 47 deletions(-) create mode 100644 config/routes/paymongo.yaml create mode 100644 src/Controller/CustomerAppAPI/InsuranceController.php create mode 100644 src/Controller/PayMongoController.php create mode 100644 src/Entity/InsuranceApplication.php create mode 100644 src/Ramcar/InsuranceApplicationStatus.php create mode 100644 src/Ramcar/InsuranceClientType.php create mode 100644 src/Ramcar/InsuranceMVType.php create mode 100644 src/Ramcar/InsuranceVehicleLine.php create mode 100644 src/Service/PayMongoConnector.php diff --git a/config/routes/apiv2.yaml b/config/routes/apiv2.yaml index af7d0084..8f781ca7 100644 --- a/config/routes/apiv2.yaml +++ b/config/routes/apiv2.yaml @@ -260,4 +260,35 @@ apiv2_account_delete_resend_code: apiv2_account_delete_code_validate: path: /apiv2/account_delete_code_validate controller: App\Controller\CustomerAppAPI\AccountController::validateDeleteCode + methods: [POST] + +# insurance +apiv2_insurance_vehicle_maker_list: + path: /apiv2/insurance/vehicles/makers + controller: App\Controller\CustomerAppAPI\InsuranceController::getVehicleMakers + methods: [GET] + +apiv2_insurance_vehicle_model_list: + path: /apiv2/insurance/vehicles/models/{maker_id} + controller: App\Controller\CustomerAppAPI\InsuranceController::getVehicleModels + methods: [GET] + +apiv2_insurance_vehicle_trim_list: + path: /apiv2/insurance/vehicles/trims/{model_id} + controller: App\Controller\CustomerAppAPI\InsuranceController::getVehicleTrims + methods: [GET] + +apiv2_insurance_vehicle_mv_type_list: + path: /apiv2/insurance/mvtypes + controller: App\Controller\CustomerAppAPI\InsuranceController::getMVTypes + methods: [GET] + +apiv2_insurance_vehicle_client_type_list: + path: /apiv2/insurance/clienttypes + controller: App\Controller\CustomerAppAPI\InsuranceController::getClientTypes + methods: [GET] + +apiv2_insurance_application_create: + path: /apiv2/insurance/application + controller: App\Controller\CustomerAppAPI\InsuranceController::createApplication methods: [POST] \ No newline at end of file diff --git a/config/routes/insurance.yaml b/config/routes/insurance.yaml index bf3e3814..cf8b2974 100644 --- a/config/routes/insurance.yaml +++ b/config/routes/insurance.yaml @@ -1,6 +1,16 @@ # insurance insurance_listener: - path: /api/insurance/listen + path: /insurance/listen controller: App\Controller\InsuranceController::listen methods: [POST] + +insurance_payment_success: + path: /insurance/payment/success + controller: App\Controller\InsuranceController::paymentSuccess + methods: [GET] + +insurance_payment_cancel: + path: /insurance/payment/cancel + controller: App\Controller\InsuranceController::paymentCancel + methods: [GET] \ No newline at end of file diff --git a/config/routes/paymongo.yaml b/config/routes/paymongo.yaml new file mode 100644 index 00000000..3cccfa97 --- /dev/null +++ b/config/routes/paymongo.yaml @@ -0,0 +1,6 @@ +# paymongo + +paymongo_listener: + path: /paymongo/listen + controller: App\Controller\PayMongoController::listen + methods: [POST] diff --git a/config/services.yaml b/config/services.yaml index b59e8008..a9e5b16e 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -216,6 +216,13 @@ services: $username: "%env(INSURANCE_USERNAME)%" $password: "%env(INSURANCE_PASSWORD)%" + # paymongo connector + App\Service\PayMongoConnector: + arguments: + $base_url: "%env(PAYMONGO_BASE_URL)%" + $public_key: "%env(PAYMONGO_PUBLIC_KEY)%" + $secret_key: "%env(PAYMONGO_SECRET_KEY)%" + # entity listener for customer vehicle warranty code history App\EntityListener\CustomerVehicleSerialListener: arguments: diff --git a/src/Controller/CustomerAppAPI/InsuranceController.php b/src/Controller/CustomerAppAPI/InsuranceController.php new file mode 100644 index 00000000..a32e67c0 --- /dev/null +++ b/src/Controller/CustomerAppAPI/InsuranceController.php @@ -0,0 +1,291 @@ +client = $client; + } + + public function createApplication(Request $req, PayMongoConnector $paymongo, UrlGeneratorInterface $router) + { + // validate params + $validity = $this->validateRequest($req, [ + // internal + 'customer_vehicle_id', + + // client info + 'client_type', + 'first_name', + //'middle_name', // not required + 'surname', + 'corporate_name', + + // client contact info + 'address_number', + //'address_street', // not required + //'address_building', // not required + 'address_barangay', + 'address_city', + 'address_province', + 'zipcode', + 'mobile_number', + 'email_address', + + // car info + 'make', + 'model', + 'series', + 'color', + //'plate_number', // NOTE: we get this from the internal cv record instead + 'mv_file_number', + 'motor_number', + 'serial_chasis', // NOTE: this is how it's spelled on their API + 'year_model', + 'mv_type_id', + 'body_type', + //'is_public', // not required, boolean, only show field if mv_type_id in [4, 13] + //'orcr_file', // this is a file + + // mv_type_id specific fields + 'vehicle_use_type', // accepted values are: 'commercial', 'private' + ]); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + // require the orcr file + if ($req->files->get('orcr_file') === null) { + return new ApiResponse(false, 'Missing required file: orcr_file'); + } + + // get our listener url + $notif_url = $router->generate('insurance_listener', [], UrlGeneratorInterface::ABSOLUTE_URL); + + // get customer and cv info + $cust = $this->session->getCustomer(); + $cv = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('customer_vehicle_id')); + if ($cv == null) { + return new ApiResponse(false, 'Invalid customer vehicle id.'); + } + + // confirm that customer vehicle belongs to customer + if ($cv->getCustomer()->getID() != $cust->getID()) { + return new ApiResponse(false, 'Vehicle does not belong to customer.'); + } + + // process all our inputs first + $input = $req->request->all(); + + if (!isset($input['is_public'])) { + $input['is_public'] = false; + } + + $input['line'] = $this->getLineType($input['mv_type_id'], $input['vehicle_use_type'], $input['is_public']); + + // submit insurance application + $result = $this->client->createApplication( + $cv, + $notif_url, + $input, + $req->files->get('orcr_file') + ); + if (!$result['success']) { + return new APIResponse(false, $result['error']['message']); + } + + // build checkout item and metadata + $items = [ + [ + 'name' => "Insurance Premium", + 'description' => "Premium fee for vehicle insurance", + 'quantity' => 1, + 'amount' => (int)bcmul($result['response']['premium'], 100), + 'currency' => 'PHP', + ], + ]; + + $metadata = [ + 'customer_id' => $cust->getID(), + 'customer_vehicle_id' => $cv->getID(), + ]; + + // create paymongo checkout resource + $checkout = $paymongo->createCheckout( + $cust, + $items, + implode("-", [$cust->getID(), $result['response']['id']]), + "Motolite RES-Q Vehicle Insurance", + $router->generate('insurance_payment_success', [], UrlGeneratorInterface::ABSOLUTE_URL), + $router->generate('insurance_payment_cancel', [], UrlGeneratorInterface::ABSOLUTE_URL), + $metadata, + ); + if (!$checkout['success']) { + return new APIResponse(false, $checkout['error']['message']); + } + + $checkout_url = $checkout['response']['data']['attributes']['checkout_url']; + + // store application in db + $app = new InsuranceApplication(); + $app->setDateSubmitted(new DateTime()); + $app->setCustomer($cust); + $app->setCustomerVehicle($cv); + $app->setTransactionID($result['response']['id']); + $app->setPremiumAmount($result['response']['premium']); + $app->setStatus(InsuranceApplicationStatus::CREATED); + $app->setCheckoutURL($checkout_url); + $app->setCheckoutID($checkout['response']['data']['id']); + $app->setMetadata($input); + $this->em->persist($app); + $this->em->flush(); + + // return + return new ApiResponse(true, '', [ + 'app_id' => $app->getID(), + 'checkout_url' => $checkout_url, + ]); + } + + public function getVehicleMakers(Request $req) + { + // validate params + $validity = $this->validateRequest($req); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + // get maker list + $result = $this->client->getVehicleMakers(); + if (!$result['success']) { + return new APIResponse(false, $result['error']['message']); + } + + return new ApiResponse(true, '', [ + 'makers' => $result['response']['data']['vehicleMakers'], + ]); + } + + public function getVehicleModels($maker_id, Request $req) + { + // validate params + $validity = $this->validateRequest($req); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + // get maker list + $result = $this->client->getVehicleModels($maker_id); + if (!$result['success']) { + return new APIResponse(false, $result['error']['message']); + } + + return new ApiResponse(true, '', [ + 'models' => $result['response']['data']['vehicleModels'], + ]); + } + + public function getVehicleTrims($model_id, Request $req) + { + // validate params + $validity = $this->validateRequest($req); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + // get maker list + $result = $this->client->getVehicleTrims($model_id); + if (!$result['success']) { + return new APIResponse(false, $result['error']['message']); + } + + return new ApiResponse(true, '', [ + 'trims' => $result['response']['data']['vehicleTrims'], + ]); + } + + public function getMVTypes(Request $req) + { + // validate params + $validity = $this->validateRequest($req); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + return new ApiResponse(true, '', [ + 'mv_types' => InsuranceMVType::getCollection(), + ]); + } + + public function getClientTypes(Request $req) + { + // validate params + $validity = $this->validateRequest($req); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + return new ApiResponse(true, '', [ + 'mv_types' => InsuranceClientType::getCollection(), + ]); + } + + protected function getLineType($mv_type_id, $vehicle_use_type, $is_public = false) + { + $line = ''; + + // NOTE: this is a bit of a hack since we're hardcoding values, but this is fine for now + switch ($mv_type_id) { + case '3': + $line = 'mcoc'; + break; + case '4': + case '13': + if ($is_public) { + $line = 'lcoc'; + } else { + $line = 'mcoc'; + } + break; + default: + if ($vehicle_use_type === 'commercial') { + $line = 'ccoc'; + } else { + $line = 'pcoc'; + } + break; + } + + return $line; + } +} diff --git a/src/Controller/PayMongoController.php b/src/Controller/PayMongoController.php new file mode 100644 index 00000000..052cc521 --- /dev/null +++ b/src/Controller/PayMongoController.php @@ -0,0 +1,23 @@ +request->all(); + error_log(print_r($payload, true)); + + return $this->json([ + 'success' => true, + 'payload' => $payload, + ]); + } +} diff --git a/src/Entity/CustomerVehicle.php b/src/Entity/CustomerVehicle.php index a5525a38..281d14db 100644 --- a/src/Entity/CustomerVehicle.php +++ b/src/Entity/CustomerVehicle.php @@ -114,6 +114,13 @@ class CustomerVehicle */ protected $flag_active; + // link to insurance + /** + * @ORM\OneToOne(targetEntity="InsuranceApplication", inversedBy="customer_vehicle") + * @ORM\JoinColumn(name="insurance_application_id", referencedColumnName="id", nullable=true) + */ + protected $insurance_application; + public function __construct() { $this->flag_active = true; @@ -282,4 +289,15 @@ class CustomerVehicle { return $this->flag_active; } + + public function setInsuranceApplication(InsuranceApplication $application) + { + $this->insurance_application = $application; + return $this; + } + + public function getInsuranceApplication() + { + return $this->insurance_application; + } } diff --git a/src/Entity/InsuranceApplication.php b/src/Entity/InsuranceApplication.php new file mode 100644 index 00000000..d08b5317 --- /dev/null +++ b/src/Entity/InsuranceApplication.php @@ -0,0 +1,238 @@ +date_submitted = new DateTime(); + $this->date_paid = null; + $this->date_completed = null; + $this->metadata = []; + } + + public function getID() + { + return $this->id; + } + + public function setCustomer(Customer $cust = null) + { + $this->customer = $cust; + return $this; + } + + public function getCustomer() + { + return $this->customer; + } + + public function setCustomerVehicle(CustomerVehicle $cv = null) + { + $this->customer_vehicle = $cv; + return $this; + } + + public function getCustomerVehicle() + { + return $this->customer_vehicle; + } + + public function setDateSubmitted(DateTime $date) + { + $this->date_submitted = $date; + return $this; + } + + public function getDateSubmitted() + { + return $this->date_submitted; + } + + public function setTransactionID($id) + { + return $this->transaction_id = $id; + } + + public function getTransactionID() + { + return $this->transaction_id; + } + + public function setPremiumAmount($amount) + { + return $this->premium_amount = $amount; + } + + public function getPremiumAmount() + { + return $this->premium_amount; + } + + public function setStatus($status) + { + return $this->status = $status; + } + + public function getStatus() + { + return $this->status; + } + + public function setCOC($url) + { + return $this->coc_url = $url; + } + + public function getCOC() + { + return $this->coc_url; + } + + public function setDatePaid(DateTime $date) + { + $this->date_paid = $date; + return $this; + } + + public function getDatePaid() + { + return $this->date_paid; + } + + public function setDateCompleted(DateTime $date) + { + $this->date_completed = $date; + return $this; + } + + public function getDateCompleted() + { + return $this->date_completed; + } + + public function setMetadata($metadata) + { + return $this->metadata = $metadata; + } + + public function getMetadata() + { + return $this->metadata; + } + + public function setCheckoutURL($url) + { + return $this->checkout_url = $url; + } + + public function getCheckoutURL() + { + return $this->checkout_url; + } + + public function setCheckoutID($id) + { + return $this->checkout_id = $id; + } + + public function getCheckoutID() + { + return $this->checkout_id; + } +} diff --git a/src/Ramcar/InsuranceApplicationStatus.php b/src/Ramcar/InsuranceApplicationStatus.php new file mode 100644 index 00000000..821615eb --- /dev/null +++ b/src/Ramcar/InsuranceApplicationStatus.php @@ -0,0 +1,16 @@ + 'Created', + 'paid' => 'Paid', + 'completed' => 'Completed', + ]; +} diff --git a/src/Ramcar/InsuranceClientType.php b/src/Ramcar/InsuranceClientType.php new file mode 100644 index 00000000..1532ef7b --- /dev/null +++ b/src/Ramcar/InsuranceClientType.php @@ -0,0 +1,14 @@ + 'Individual', + 'c' => 'Corporate', + ]; +} diff --git a/src/Ramcar/InsuranceMVType.php b/src/Ramcar/InsuranceMVType.php new file mode 100644 index 00000000..73755821 --- /dev/null +++ b/src/Ramcar/InsuranceMVType.php @@ -0,0 +1,32 @@ + "Car", + '2' => "Shuttle Bus", + '3' => "Motorcycle", + '4' => "Motorcycle with Sidecar", + '5' => "Non-Conventional MV", + '8' => "Sports Utility Vehicle", + '9' => "Truck", + '10' => "Trailer", + '11' => "UV Private", + '12' => "UV Commercial", + '13' => "Tricycle", + ]; +} diff --git a/src/Ramcar/InsuranceVehicleLine.php b/src/Ramcar/InsuranceVehicleLine.php new file mode 100644 index 00000000..7e66426d --- /dev/null +++ b/src/Ramcar/InsuranceVehicleLine.php @@ -0,0 +1,18 @@ + 'Private Car', + 'mcoc' => 'Motorcycle / Motorcycle with Sidecar / Tricycle (Private)', + 'ccoc' => 'Commercial Vehicle', + 'lcoc' => 'Motorcycle / Motorcycle with Sidecar / Tricycle (Public)', + ]; +} diff --git a/src/Service/InsuranceConnector.php b/src/Service/InsuranceConnector.php index e10066a2..adfcfaef 100644 --- a/src/Service/InsuranceConnector.php +++ b/src/Service/InsuranceConnector.php @@ -2,6 +2,11 @@ namespace App\Service; +use App\Entity\CustomerVehicle; +use GuzzleHttp\Client; +use GuzzleHttp\Psr7; +use GuzzleHttp\Exception\RequestException; + class InsuranceConnector { protected $base_url; @@ -17,37 +22,68 @@ class InsuranceConnector $this->hash = $this->generateHash(); } - public function createApplication($notif_url, $client_info, $client_contact_info, $car_info) + public function createApplication(CustomerVehicle $cv, $notif_url, $data, $orcr_file) { $body = [ 'notif_url' => $notif_url, - 'client_info' => $client_info, - 'client_contact_info' => $client_contact_info, - 'car_info' => $car_info, + 'client_info' => [ + 'client_type' => $data['client_type'], + 'first_name' => $data['first_name'], + 'middle_name' => $data['middle_name'] ?? null, + 'surname' => $data['surname'], + 'corporate_name' => $data['corporate_name'], + ], + 'client_contact_info' => [ + 'address_number' => $data['address_number'], + 'address_street' => $data['address_street'] ?? null, + 'address_building' => $data['address_building'] ?? null, + 'address_barangay' => $data['address_barangay'], + 'address_city' => $data['address_city'], + 'address_province' => $data['address_province'], + 'zipcode' => (int)$data['zipcode'], + 'mobile_number' => $data['mobile_number'], + 'email_address' => $data['email_address'], + ], + 'car_info' => [ + 'make' => $data['make'], + 'model' => $data['model'], + 'series' => $data['series'], + 'color' => $data['color'], + 'plate_number' => $cv->getPlateNumber(), + 'mv_file_number' => $data['mv_file_number'], + 'motor_number' => $data['motor_number'], + 'serial_chasis' => $data['serial_chasis'], + 'year_model' => (int)$data['year_model'], + 'mv_type_id' => (int)$data['mv_type_id'], + 'body_type' => $data['body_type'], + 'is_public' => (bool)$data['is_public'], + 'line' => $data['line'], + 'orcr_file' => base64_encode(file_get_contents($orcr_file->getPathname())), + ], ]; - return $this->doRequest('/api/v1/ctpl/applications', true, $body); + return $this->doRequest('/api/v1/ctpl/applications', 'POST', $body); } public function tagApplicationPaid($application_id) { $url = '/api/v1/ctpl/application/' . $application_id . '/paid'; - return $this->doRequest($url, true); + return $this->doRequest($url, 'POST'); } public function getVehicleMakers() { - return $this->doRequest('/api/v1/ctpl/vehicle-makers'); + return $this->doRequest('/api/v1/ctpl/vehicle-makers', 'GET'); } - public function getVehicleModels() + public function getVehicleModels($maker_id) { - return $this->doRequest('/api/v1/ctpl/vehicle-models'); + return $this->doRequest('/api/v1/ctpl/vehicle-models?maker_id='. $maker_id, 'GET'); } - public function getVehicleTrims() + public function getVehicleTrims($model_id) { - return $this->doRequest('/api/v1/ctpl/vehicle-trims'); + return $this->doRequest('/api/v1/ctpl/vehicle-trims?model_id='. $model_id, 'GET'); } protected function generateHash() @@ -55,46 +91,41 @@ class InsuranceConnector return base64_encode($this->username . ":" . $this->password); } - protected function doRequest($url, $is_post = false, $body = []) + protected function doRequest($url, $method, $body = []) { - $curl = curl_init(); - - $options = [ - CURLOPT_URL => $this->base_url . '/' . $url, - CURLOPT_POST => $is_post, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HTTPHEADER => [ - 'Content-Type: application/json', - 'Authorization: Basic ' . $this->hash, - ], + $client = new Client(); + $headers = [ + 'Content-Type' => 'application/json', + 'accept' => 'application/json', + 'authorization' => 'Basic '. $this->hash, ]; - // add post body if present - if (!empty($body)) { - $options[CURLOPT_POSTFIELDS] = json_encode($body); + try { + $response = $client->request($method, $this->base_url . '/' . $url, [ + 'json' => $body, + 'headers' => $headers, + ]); + } catch (RequestException $e) { + $error = ['message' => $e->getMessage()]; + + error_log("Insurance API Error: " . $error['message']); + error_log(Psr7\Message::toString($e->getRequest())); + + if ($e->hasResponse()) { + $error['response'] = Psr7\Message::toString($e->getResponse()); + } + + return [ + 'success' => false, + 'error' => $error, + ]; } - curl_setopt_array($curl, $options); - $res = curl_exec($curl); + //error_log(print_r(json_decode($response->getBody(), true), true)); - curl_close($curl); - - error_log('Insurance API connector'); - error_log(print_r($options, true)); - error_log($res); - - // response - return $this->handleResponse($res); - } - - protected function handleResponse($res) - { - $inv_res = json_decode($res, true); - - // make sure result is always an array - if ($inv_res == null) - return []; - - return $inv_res; + return [ + 'success' => true, + 'response' => json_decode($response->getBody(), true) + ]; } } diff --git a/src/Service/PayMongoConnector.php b/src/Service/PayMongoConnector.php new file mode 100644 index 00000000..d26ef7fd --- /dev/null +++ b/src/Service/PayMongoConnector.php @@ -0,0 +1,122 @@ +base_url = $base_url; + $this->public_key = $public_key; + $this->secret_key = $secret_key; + $this->hash = $this->generateHash(); + } + + public function createCheckout(Customer $cust, $items, $ref_no = null, $description = null, $success_url = null, $cancel_url = null, $metadata = []) + { + // build billing info + $billing = [ + 'name' => implode(" ", [$cust->getFirstName(), $cust->getLastName()]), + 'phone' => "0" . $cust->getPhoneMobile(), + ]; + + if ($cust->getEmail()) { + $billing['email'] = $cust->getEmail(); + } + + // build the request body + $body = [ + 'data' => [ + 'attributes' => [ + 'description' => $description, + 'billing' => $billing, + // NOTE: this may be variable later, hardcoding for now + 'payment_method_types' => [ + 'card', + 'paymaya', + 'gcash', + ], + /* NOTE: format for line items: + * ['name', 'description', 'quantity', 'amount', 'currency'] + */ + 'line_items' => $items, + 'reference_number' => $ref_no, + 'cancel_url' => $cancel_url, + 'success_url' => $success_url, + 'statement_descriptor' => $description, + 'send_email_receipt' => true, + 'show_description' => true, + 'show_line_items' => false, + 'metadata' => $metadata, + ], + ], + ]; + + return $this->doRequest('/v1/checkout_sessions', 'POST', $body); + } + + public function getCheckout($checkout_id) + { + return $this->doRequest('/v1/checkout_sessions/' . $checkout_id, 'GET'); + } + + protected function generateHash() + { + return base64_encode($this->secret_key); + } + + protected function doRequest($url, $method, $body = []) + { + $client = new Client(); + $headers = [ + 'Content-Type' => 'application/json', + 'accept' => 'application/json', + 'authorization' => 'Basic '. $this->hash, + ]; + + try { + $response = $client->request($method, $this->base_url . '/' . $url, [ + 'json' => $body, + 'headers' => $headers, + ]); + } catch (RequestException $e) { + $error = ['message' => $e->getMessage()]; + + ob_start(); + var_dump($body); + $varres = ob_get_clean(); + error_log($varres); + + error_log("--------------------------------------"); + error_log($e->getResponse()->getBody()->getContents()); + + error_log("PayMongo API Error: " . $error['message']); + error_log(Psr7\Message::toString($e->getRequest())); + + if ($e->hasResponse()) { + $error['response'] = Psr7\Message::toString($e->getResponse()); + } + + return [ + 'success' => false, + 'error' => $error, + ]; + } + + return [ + 'success' => true, + 'response' => json_decode($response->getBody(), true) + ]; + } +}