Add endpoint for creating subscriptions, sync updating of customers with paymongo API if record exists #799

This commit is contained in:
Ramon Gutierrez 2024-08-13 05:45:46 +08:00
parent 7af20f3d69
commit 919b56688d
6 changed files with 130 additions and 11 deletions

View file

@ -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]
methods: [GET]
apiv2_subscription_create:
path: /apiv2/subscription
controller: App\Controller\CustomerAppAPI\SubscriptionController::createSubscription
methods: [POST]

View file

@ -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'),
);
}
}

View file

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

View file

@ -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'],
]);
}
}

View file

@ -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(),
];

View file

@ -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)
{