From 5a2f57492db62d2385968c1d6d677cef65575932 Mon Sep 17 00:00:00 2001 From: Ramon Gutierrez Date: Mon, 12 Aug 2024 06:50:01 +0800 Subject: [PATCH] Tie battery sizes to subscription plans #799 --- src/Controller/BatterySizeController.php | 19 +++ src/Service/PayMongoConnector.php | 156 ++++++++++++++++++++++- 2 files changed, 171 insertions(+), 4 deletions(-) diff --git a/src/Controller/BatterySizeController.php b/src/Controller/BatterySizeController.php index 5af7730e..0ffb3444 100644 --- a/src/Controller/BatterySizeController.php +++ b/src/Controller/BatterySizeController.php @@ -9,11 +9,24 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use App\Service\PayMongoConnector; use Catalyst\MenuBundle\Annotation\Menu; class BatterySizeController extends Controller { + protected $pm; + + public function __construct(PayMongoConnector $pm, ParameterBagInterface $params) + { + $this->pm = $pm; + $this->pm->initialize( + $params->get('subscription_paymongo_public_key'), + $params->get('subscription_paymongo_secret_key'), + ); + } + /** * @Menu(selected="bsize_list") */ @@ -168,6 +181,9 @@ class BatterySizeController extends Controller $em->persist($row); $em->flush(); + // create new paymongo subscription plan + $this->pm->createOrUpdateSubPlan($row); + // return successful response return $this->json([ 'success' => 'Changes have been saved!' @@ -235,6 +251,9 @@ class BatterySizeController extends Controller // validated! save the entity $em->flush(); + // find if paymongo subscription plan exists, then update accordingly + $this->pm->createOrUpdateSubPlan($row); + // return successful response return $this->json([ 'success' => 'Changes have been saved!' diff --git a/src/Service/PayMongoConnector.php b/src/Service/PayMongoConnector.php index 61413501..5b4c4b9f 100644 --- a/src/Service/PayMongoConnector.php +++ b/src/Service/PayMongoConnector.php @@ -7,6 +7,7 @@ use GuzzleHttp\Psr7; use GuzzleHttp\Exception\RequestException; use App\Entity\Customer; +use App\Entity\BatterySize; class PayMongoConnector { @@ -88,6 +89,150 @@ class PayMongoConnector return $this->doRequest('/v1/webhooks/' . $id . '/enable', 'POST'); } + public function getPlans() + { + return $this->doRequest('/v1/subscriptions/plans', 'GET'); + } + + public function createPlan($plan_data) + { + $body = [ + 'data' => [ + 'attributes' => [ + 'amount' => (int)$plan_data['amount'], + 'currency' => 'PHP', + 'description' => $plan_data['description'], + 'interval' => $plan_data['interval'], + 'interval_count' => $plan_data['interval_count'], + 'name' => $plan_data['name'], + 'metadata' => $plan_data['metadata'], + ], + ], + ]; + + return $this->doRequest('/v1/subscriptions/plans', 'POST', $body); + } + + public function updatePlan($plan_id, $plan_data) + { + $body = [ + 'data' => [ + 'attributes' => [ + 'amount' => (int)$plan_data['amount'], + ], + ], + ]; + + return $this->doRequest('/v1/subscriptions/plans/' . $plan_id, 'PUT', $body); + } + + public function createOrUpdateSubPlan(BatterySize $bsize) + { + // get all plans + $plans = $this->getPlans(); + + // find the plan with the matching substring (battery size name) + $found_plan = null; + + if ($plans['success'] && !empty($plans['response']['data'])) { + foreach ($plans['response']['data'] as $plan) { + $plan_bsize_id = $plan['attributes']['metadata']['battery_size_id'] ?? null; + + if (!empty($plan_bsize_id)) { + $found_plan = $plan; + break; + } + } + } + + if (!empty($found_plan)) { + // update existing plan + $result = $this->updatePlan($found_plan['id'], [ + 'amount' => bcmul($bsize->getSubRecurringFee(), 100), + ]); + } else { + // create new plan + $result = $this->createPlan([ + 'name' => "RESQ Subscription", + 'amount' => bcmul($bsize->getSubRecurringFee(), 100), + 'description' => "Motolite Battery Subscription Plan", + 'interval' => 'monthly', + 'interval_count' => 1, + 'metadata' => [ + 'battery_size_id' => (string)$bsize->getID(), + ], + ]); + } + + return $result; + } + + public function findCustomer($email) + { + return $this->doRequest('/v1/customers?email=' . $email, 'GET'); + } + + public function createCustomer(Customer $cust) + { + $body = [ + 'data' => [ + 'attributes' => [ + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + 'phone' => $cust->getPhoneMobile(), + 'email' => $cust->getEmail(), + 'default_device' => 'email', + ], + ], + ]; + + return $this->doRequest('/v1/customers', 'POST', $body); + } + + public function updateCustomer(Customer $cust, $ext_cust_id) + { + $body = [ + 'data' => [ + 'attributes' => [ + 'first_name' => $cust->getFirstName(), + 'last_name' => $cust->getLastName(), + 'phone' => $cust->getPhoneMobile(), + 'email' => $cust->getEmail(), + ], + ], + ]; + + return $this->doRequest('/v1/customers/' . $ext_cust_id, 'PUT', $body); + } + + + public function createSubscription($ext_cust_id, $plan_id) + { + $body = [ + 'data' => [ + 'attributes' => [ + 'customer_id' => $ext_cust_id, + 'plan_id' => $plan_id, + ], + ], + ]; + + return $this->doRequest('/v1/subscriptions', 'POST', $body); + } + + public function attachPaymentIntent($pm_id, $pi_id) + { + $body = [ + 'data' => [ + 'attributes' => [ + 'payment_method' => $pm_id, + ], + ], + ]; + + return $this->doRequest('/v1/payment_intents/' . $pi_id . '/attach', 'POST', $body); + } + protected function generateHash() { return base64_encode($this->secret_key); @@ -102,11 +247,14 @@ class PayMongoConnector 'authorization' => 'Basic '. $this->hash, ]; + $request_params = ['headers' => $headers]; + + if (!empty($request_body)) { + $request_params['json'] = $request_body; + } + try { - $response = $client->request($method, $this->base_url . '/' . $url, [ - 'json' => $request_body, - 'headers' => $headers, - ]); + $response = $client->request($method, $this->base_url . $url, $request_params); } catch (RequestException $e) { $error = ['message' => $e->getMessage()];