Add insurance endpoints, insurance and paymongo connectors #761

This commit is contained in:
Ramon Gutierrez 2023-09-06 04:05:15 +08:00
parent 8c11ec9e8f
commit db75e7becd
14 changed files with 904 additions and 47 deletions

View file

@ -261,3 +261,34 @@ 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]

View file

@ -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]

View file

@ -0,0 +1,6 @@
# paymongo
paymongo_listener:
path: /paymongo/listen
controller: App\Controller\PayMongoController::listen
methods: [POST]

View file

@ -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:

View file

@ -0,0 +1,291 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Service\InsuranceConnector;
use App\Service\PayMongoConnector;
use App\Entity\InsuranceApplication;
use App\Entity\CustomerVehicle;
use App\Ramcar\InsuranceApplicationStatus;
use App\Ramcar\InsuranceMVType;
use App\Ramcar\InsuranceClientType;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use DateTime;
class InsuranceController extends ApiController
{
protected $client;
public function __construct(EntityManagerInterface $em, KernelInterface $kernel, InsuranceConnector $client)
{
parent::__construct($em, $kernel);
$this->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;
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class PayMongoController extends Controller
{
public function listen(Request $req, EntityManagerInterface $em)
{
$payload = $req->request->all();
error_log(print_r($payload, true));
return $this->json([
'success' => true,
'payload' => $payload,
]);
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1,238 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="insurance_application")
*/
class InsuranceApplication
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// link to customer
/**
* @ORM\ManyToOne(targetEntity="Customer")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
*/
protected $customer;
// link to customer vehicle
/**
* @ORM\ManyToOne(targetEntity="CustomerVehicle", inversedBy="insurance")
* @ORM\JoinColumn(name="customer_vehicle_id", referencedColumnName="id")
*/
protected $customer_vehicle;
// paramount transaction id
/**
* @ORM\Column(type="string", length=32)
* @Assert\NotBlank()
*/
protected $transaction_id;
// premium amount
/**
* @ORM\Column(type="decimal", precision=7, scale=2)
* @Assert\NotBlank()
*/
protected $premium_amount;
// status
/**
* @ORM\Column(type="string", length=32)
*/
protected $status;
// URL of COC
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $coc_url;
// date the application was submitted
/**
* @ORM\Column(type="datetime")
*/
protected $date_submitted;
// date the application was paid
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $date_paid;
// date the application was marked as completed by the insurance api
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $date_completed;
// form data when submitting the application
/**
* @ORM\Column(type="json")
*/
protected $metadata;
// paymongo checkout url
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $checkout_url;
// paymongo checkout id
/**
* @ORM\Column(type="string", length=32, nullable=true)
*/
protected $checkout_id;
public function __construct()
{
$this->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;
}
}

View file

@ -0,0 +1,16 @@
<?php
namespace App\Ramcar;
class InsuranceApplicationStatus extends NameValue
{
const CREATED = 'created';
const PAID = 'paid';
const COMPLETED = 'completed';
const COLLECTION = [
'created' => 'Created',
'paid' => 'Paid',
'completed' => 'Completed',
];
}

View file

@ -0,0 +1,14 @@
<?php
namespace App\Ramcar;
class InsuranceClientType extends NameValue
{
const INDIVIDUAL = 'i';
const CORPORATE = 'c';
const COLLECTION = [
'i' => 'Individual',
'c' => 'Corporate',
];
}

View file

@ -0,0 +1,32 @@
<?php
namespace App\Ramcar;
class InsuranceMVType extends NameValue
{
const CAR = '1';
const SHUTTLE_BUS = '2';
const MOTORCYCLE = '3';
const MC_WITH_SIDECAR = '4';
const NON_CONVENTIONAL = '5';
const SUV = '8';
const TRUCK = '9';
const TRAILER = '10';
const UV_PRIVATE = '11';
const UV_COMMERCIAL = '12';
const TRICYCLE = '13';
const COLLECTION = [
'1' => "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",
];
}

View file

@ -0,0 +1,18 @@
<?php
namespace App\Ramcar;
class InsuranceVehicleLine extends NameValue
{
const PCOC = 'pcoc';
const MCOC = 'mcoc';
const CCOC = 'ccoc';
const LCOC = 'lcoc';
const COLLECTION = [
'pcoc' => 'Private Car',
'mcoc' => 'Motorcycle / Motorcycle with Sidecar / Tricycle (Private)',
'ccoc' => 'Commercial Vehicle',
'lcoc' => 'Motorcycle / Motorcycle with Sidecar / Tricycle (Public)',
];
}

View file

@ -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());
}
curl_setopt_array($curl, $options);
$res = curl_exec($curl);
curl_close($curl);
error_log('Insurance API connector');
error_log(print_r($options, true));
error_log($res);
// response
return $this->handleResponse($res);
return [
'success' => false,
'error' => $error,
];
}
protected function handleResponse($res)
{
$inv_res = json_decode($res, true);
//error_log(print_r(json_decode($response->getBody(), true), 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)
];
}
}

View file

@ -0,0 +1,122 @@
<?php
namespace App\Service;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7;
use GuzzleHttp\Exception\RequestException;
use App\Entity\Customer;
class PayMongoConnector
{
protected $base_url;
protected $public_key;
protected $secret_key;
protected $hash;
public function __construct($base_url, $public_key, $secret_key)
{
$this->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)
];
}
}