diff --git a/config/routes/apiv2.yaml b/config/routes/apiv2.yaml index 6702a5a2..a7332516 100644 --- a/config/routes/apiv2.yaml +++ b/config/routes/apiv2.yaml @@ -329,4 +329,9 @@ apiv2_subscription_plan_details: apiv2_subscription_paymongo_public_key: path: /apiv2/subscription/ppk controller: App\Controller\CustomerAppAPI\SubscriptionController::getPaymongoPublicKey - methods: [GET] \ No newline at end of file + methods: [GET] + +apiv2_subscription_create: + path: /apiv2/subscription + controller: App\Controller\CustomerAppAPI\SubscriptionController::createSubscription + methods: [POST] diff --git a/src/Controller/CustomerAppAPI/ApiController.php b/src/Controller/CustomerAppAPI/ApiController.php index fdc0ec59..577a05a6 100644 --- a/src/Controller/CustomerAppAPI/ApiController.php +++ b/src/Controller/CustomerAppAPI/ApiController.php @@ -13,6 +13,7 @@ use App\Ramcar\JOStatus; use App\Entity\Warranty; use App\Entity\JobOrder; use App\Entity\CustomerSession; +use App\Service\PayMongoConnector; class ApiController extends BaseApiController { @@ -164,4 +165,12 @@ class ApiController extends BaseApiController { return 'Our services are currently limited to some areas in Metro Manila, Baguio, Batangas, Laguna, Cavite, Pampanga, and Palawan. We will update you as soon as we are available in your area. Thank you for understanding. Keep safe!'; } + + protected function initializeSubscriptionPayMongoConnector(PayMongoConnector &$pm) + { + $pm->initialize( + $this->getParameter('subscription_paymongo_public_key'), + $this->getParameter('subscription_paymongo_secret_key'), + ); + } } diff --git a/src/Controller/CustomerAppAPI/CustomerController.php b/src/Controller/CustomerAppAPI/CustomerController.php index 6ce9259f..c8cc9e53 100644 --- a/src/Controller/CustomerAppAPI/CustomerController.php +++ b/src/Controller/CustomerAppAPI/CustomerController.php @@ -9,6 +9,7 @@ use App\Ramcar\CustomerSource; use App\Entity\Customer; use App\Entity\PrivacyPolicy; use App\Service\HashGenerator; +use App\Service\PayMongoConnector; class CustomerController extends ApiController { @@ -43,7 +44,7 @@ class CustomerController extends ApiController ]); } - public function updateInfo(Request $req) + public function updateInfo(Request $req, PayMongoConnector $pm) { // validate params $validity = $this->validateRequest($req); @@ -64,6 +65,12 @@ class CustomerController extends ApiController $this->em->flush(); + // initialize paymongo connector + $this->initializeSubscriptionPayMongoConnector($pm); + + // update customer paymongo record if exists + $pm->updateCustomerIfExists($cust); + // response return new ApiResponse(); } diff --git a/src/Controller/CustomerAppAPI/SubscriptionController.php b/src/Controller/CustomerAppAPI/SubscriptionController.php index cda8f0e0..3c3b24d1 100644 --- a/src/Controller/CustomerAppAPI/SubscriptionController.php +++ b/src/Controller/CustomerAppAPI/SubscriptionController.php @@ -31,11 +31,8 @@ class SubscriptionController extends ApiController $batts = $vehicle->getActiveBatteries(); if (!empty($batts)) { - // initialize paymongo - $pm->initialize( - $this->getParameter('subscription_paymongo_public_key'), - $this->getParameter('subscription_paymongo_secret_key'), - ); + // initialize paymongo connector + $this->initializeSubscriptionPayMongoConnector($pm); $plan = $pm->getPlanByBatterySize($batts[0]->getSize()); } @@ -60,4 +57,43 @@ class SubscriptionController extends ApiController 'content' => $this->getParameter('subscription_paymongo_public_key'), ]); } + + public function createSubscription(Request $req, PayMongoConnector $pm) + { + // check requirements + $validity = $this->validateRequest($req, [ + 'plan_id', + ]); + + if (!$validity['is_valid']) { + return new ApiResponse(false, $validity['error']); + } + + // get customer + $cust = $this->session->getCustomer(); + if ($cust == null) { + return new ApiResponse(false, 'No customer information found.'); + } + + // initialize paymongo connector + $this->initializeSubscriptionPayMongoConnector($pm); + + // get paymongo customer + $pm_cust = $pm->findOrCreateCustomer($cust); + if (empty($pm_cust)) { + return new ApiResponse(false, 'Error retrieving customer record. Please try again later.'); + } + + // create subscription + // NOTE: for now we save ourselves the extra API call and assume the plan_id is valid since this won't change often anyway + $pm_sub = $pm->createSubscription($pm_cust['id'], $req->request->get('plan_id')); + if (!isset($pm_sub['data']['id'])) { + return new ApiResponse(false, 'Error creating subscription. Please try again later.'); + } + + // response + return new ApiResponse(true, '', [ + 'subscription_id' => $pm_sub['data']['id'], + ]); + } } diff --git a/src/Service/CustomerHandler/ResqCustomerHandler.php b/src/Service/CustomerHandler/ResqCustomerHandler.php index f8685801..2f947cee 100644 --- a/src/Service/CustomerHandler/ResqCustomerHandler.php +++ b/src/Service/CustomerHandler/ResqCustomerHandler.php @@ -4,6 +4,7 @@ namespace App\Service\CustomerHandler; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -24,7 +25,7 @@ use App\Entity\Battery; use App\Entity\VehicleManufacturer; use App\Entity\BatteryManufacturer; use App\Entity\CustomerTag; - +use App\Service\PayMongoConnector; use DateTime; class ResqCustomerHandler implements CustomerHandlerInterface @@ -34,14 +35,22 @@ class ResqCustomerHandler implements CustomerHandlerInterface protected $country_code; protected $security; protected $template_hash; + protected $pm; public function __construct(EntityManagerInterface $em, ValidatorInterface $validator, - string $country_code, Security $security) + string $country_code, Security $security, PayMongoConnector $pm, ParameterBagInterface $params) { $this->em = $em; $this->validator = $validator; $this->country_code = $country_code; $this->security = $security; + $this->pm = $pm; + + // initialize paymongo connector + $this->pm->initialize( + $params->get('subscription_paymongo_public_key'), + $params->get('subscription_paymongo_secret_key'), + ); $this->loadTemplates(); } @@ -391,6 +400,9 @@ class ResqCustomerHandler implements CustomerHandlerInterface $em->persist($cust); $em->flush(); + // update customer paymongo record if exists + $this->pm->updateCustomerIfExists($cust); + $result = [ 'id' => $cust->getID(), ]; diff --git a/src/Service/PayMongoConnector.php b/src/Service/PayMongoConnector.php index 68ff17ba..b39d0fb2 100644 --- a/src/Service/PayMongoConnector.php +++ b/src/Service/PayMongoConnector.php @@ -174,7 +174,7 @@ class PayMongoConnector return $result; } - public function findCustomer($email) + public function findCustomerByEmail($email) { return $this->doRequest('/v1/customers?email=' . $email, 'GET'); } @@ -211,7 +211,57 @@ class PayMongoConnector return $this->doRequest('/v1/customers/' . $ext_cust_id, 'PUT', $body); } - + + public function updateCustomerIfExists(Customer $cust) + { + $email = $cust->getEmail(); + + // if no email, then we don't need to update + if (empty($email)) { + return false; + } + + // check if we have an existing paymongo customer with this email + $found_cust = $this->findCustomerByEmail($email); + + if (isset($found_cust['data']['id'])) { + // update existing customer record + return $this->updateCustomer($cust, $found_cust['data']); + } + + return false; + } + + public function findOrCreateCustomer(Customer $cust) + { + $email = $cust->getEmail(); + + // if no email, then we don't need to update + if (empty($email)) { + return false; + } + + // check if we have an existing paymongo customer with this email + $found_cust = $this->findCustomerByEmail($email); + + $pm_cust = null; + + if (isset($found_cust['data']['id'])) { + // we found a customer record + $pm_cust = $found_cust['data']; + } else { + // we create a new customer record + $new_cust = $this->createCustomer($cust); + + if (isset($new_cust['data']['id'])) { + // customer record was created successfully + $pm_cust = $new_cust['data']; + } + } + + // NOTE: if $pm_cust is null at this point, an error occurred during customer creation and we check the request logs for more details + return $pm_cust; + } public function createSubscription($ext_cust_id, $plan_id) {