Consolidate subscription setup payment intent checking and initial activation when applicable #799
This commit is contained in:
parent
40c629eee3
commit
1fd883b07b
6 changed files with 111 additions and 11 deletions
|
|
@ -336,7 +336,17 @@ apiv2_subscription_create:
|
||||||
controller: App\Controller\CustomerAppAPI\SubscriptionController::createSubscription
|
controller: App\Controller\CustomerAppAPI\SubscriptionController::createSubscription
|
||||||
methods: [POST]
|
methods: [POST]
|
||||||
|
|
||||||
apiv2_subscription_payment_intent:
|
apiv2_subscription_finalize:
|
||||||
path: /apiv2/subscription/payment_intent/{pid}
|
path: /apiv2/subscription/{id}/finalize
|
||||||
controller: App\Controller\CustomerAppAPI\SubscriptionController::getPaymentIntent
|
controller: App\Controller\CustomerAppAPI\SubscriptionController::finalizeSubscription
|
||||||
methods: [GET]
|
methods: [GET]
|
||||||
|
|
||||||
|
#apiv2_subscription_payment_intent:
|
||||||
|
# path: /apiv2/subscription/payment_intent/{pi_id}
|
||||||
|
# controller: App\Controller\CustomerAppAPI\SubscriptionController::getPaymentIntent
|
||||||
|
# methods: [GET]
|
||||||
|
|
||||||
|
#apiv2_subscription_activate:
|
||||||
|
# path: /apiv2/subscription/{id}/activate
|
||||||
|
# controller: App\Controller\CustomerAppAPI\SubscriptionController::activateSubscription
|
||||||
|
# methods: [POST]
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ parameters:
|
||||||
subscription_paymongo_public_key: "%env(SUBSCRIPTION_PAYMONGO_PUBLIC_KEY)%"
|
subscription_paymongo_public_key: "%env(SUBSCRIPTION_PAYMONGO_PUBLIC_KEY)%"
|
||||||
subscription_paymongo_secret_key: "%env(SUBSCRIPTION_PAYMONGO_SECRET_KEY)%"
|
subscription_paymongo_secret_key: "%env(SUBSCRIPTION_PAYMONGO_SECRET_KEY)%"
|
||||||
subscription_paymongo_webhook_id: "%env(SUBSCRIPTION_PAYMONGO_WEBHOOK_ID)%"
|
subscription_paymongo_webhook_id: "%env(SUBSCRIPTION_PAYMONGO_WEBHOOK_ID)%"
|
||||||
|
subscription_months: "%env(SUBSCRIPTION_MONTHS)%"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,74 @@ class SubscriptionController extends ApiController
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function finalizeSubscription(Request $req, $id, PayMongoConnector $pm)
|
||||||
|
{
|
||||||
|
// check requirements
|
||||||
|
$validity = $this->validateRequest($req);
|
||||||
|
|
||||||
|
if (!$validity['is_valid']) {
|
||||||
|
return new ApiResponse(false, $validity['error']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize paymongo connector
|
||||||
|
$this->initializeSubscriptionPayMongoConnector($pm);
|
||||||
|
|
||||||
|
// get subscription
|
||||||
|
$sub_obj = $this->em->getRepository(Subscription::class)->findOneBy([
|
||||||
|
'id' => $id,
|
||||||
|
'status' => SubscriptionStatus::PENDING,
|
||||||
|
'customer' => $this->session->getCustomer(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (empty($sub_obj)) {
|
||||||
|
return new ApiResponse(false, 'Invalid subscription provided.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// get paymongo subscription so we can verify if the latest invoice is paid or not
|
||||||
|
$pm_sub = $pm->getSubscription($sub_obj->getExtApiId());
|
||||||
|
if (empty($pm_sub['response']['data']['id'])) {
|
||||||
|
return new ApiResponse(false, 'Error retrieving subscription. Please try again later.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the latest invoice has been paid
|
||||||
|
// NOTE: ignore this, this is unreliable due to race condition
|
||||||
|
/*
|
||||||
|
if ($pm_sub['response']['data']['attributes']['latest_invoice']['status'] !== 'paid') {
|
||||||
|
return new ApiResponse(false, 'Latest invoice for subscription is not yet paid.');
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// get payment intent
|
||||||
|
$pi = $pm->getPaymentIntent($pm_sub['response']['data']['attributes']['latest_invoice']['payment_intent']['id']);
|
||||||
|
if (empty($pi['response']['data']['id'])) {
|
||||||
|
return new ApiResponse(false, 'Error retrieving payment intent. Please try again later.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the paymongo sub is active, and the payment was successful, update the internal subscription status
|
||||||
|
if (
|
||||||
|
$sub_obj->getStatus() === SubscriptionStatus::PENDING &&
|
||||||
|
$pi['response']['data']['attributes']['status'] === 'succeeded'
|
||||||
|
) {
|
||||||
|
$sub_start_date = new DateTime();
|
||||||
|
$sub_end_date = clone $sub_start_date;
|
||||||
|
$sub_end_date->modify('+' . $this->getParameter('subscription_months') . ' month');
|
||||||
|
|
||||||
|
$sub_obj->setStatus(SubscriptionStatus::ACTIVE)
|
||||||
|
->setDateStart($sub_start_date)
|
||||||
|
->setDateEnd($sub_end_date);
|
||||||
|
|
||||||
|
$this->em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
error_log("PI STATUS: " . $pi['response']['data']['attributes']['status']);
|
||||||
|
|
||||||
|
// response
|
||||||
|
return new ApiResponse(true, '', [
|
||||||
|
'payment_intent' => $pi['response']['data'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public function getPaymentIntent(Request $req, $pid, PayMongoConnector $pm)
|
public function getPaymentIntent(Request $req, $pid, PayMongoConnector $pm)
|
||||||
{
|
{
|
||||||
// check requirements
|
// check requirements
|
||||||
|
|
@ -172,7 +240,7 @@ class SubscriptionController extends ApiController
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setSubscriptionAsPaid(Request $req, $sub_id, PayMongoConnector $pm)
|
public function activateSubscription(Request $req, $id, PayMongoConnector $pm)
|
||||||
{
|
{
|
||||||
// check requirements
|
// check requirements
|
||||||
$validity = $this->validateRequest($req);
|
$validity = $this->validateRequest($req);
|
||||||
|
|
@ -186,7 +254,7 @@ class SubscriptionController extends ApiController
|
||||||
|
|
||||||
// get subscription
|
// get subscription
|
||||||
$obj = $this->em->getRepository(Subscription::class)->findOneBy([
|
$obj = $this->em->getRepository(Subscription::class)->findOneBy([
|
||||||
'id' => $sub_id,
|
'id' => $id,
|
||||||
'status' => SubscriptionStatus::PENDING,
|
'status' => SubscriptionStatus::PENDING,
|
||||||
'customer' => $this->session->getCustomer(),
|
'customer' => $this->session->getCustomer(),
|
||||||
]);
|
]);
|
||||||
|
|
@ -195,6 +263,17 @@ class SubscriptionController extends ApiController
|
||||||
return new ApiResponse(false, 'Invalid subscription provided.');
|
return new ApiResponse(false, 'Invalid subscription provided.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get paymongo subscription so we can verify if the latest invoice is paid or not
|
||||||
|
$pm_sub = $pm->getSubscription($obj->getExtApiId());
|
||||||
|
if (empty($pm_sub['response']['data']['id'])) {
|
||||||
|
return new ApiResponse(false, 'Error retrieving subscription. Please try again later.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the latest invoice has been paid
|
||||||
|
if ($pm_sub['response']['data']['attributes']['latest_invoice']['status'] !== 'succeeded') {
|
||||||
|
return new ApiResponse(false, 'Latest invoice for subscription is not yet paid.');
|
||||||
|
}
|
||||||
|
|
||||||
// mark subscription as paid
|
// mark subscription as paid
|
||||||
$obj->setStatus(SubscriptionStatus::ACTIVE)
|
$obj->setStatus(SubscriptionStatus::ACTIVE)
|
||||||
->setDateStart(new DateTime());
|
->setDateStart(new DateTime());
|
||||||
|
|
@ -206,4 +285,5 @@ class SubscriptionController extends ApiController
|
||||||
'success' => true,
|
'success' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ use App\Ramcar\JOStatus;
|
||||||
use App\Ramcar\ServiceType;
|
use App\Ramcar\ServiceType;
|
||||||
use App\Ramcar\TradeInType;
|
use App\Ramcar\TradeInType;
|
||||||
use App\Ramcar\InsuranceApplicationStatus;
|
use App\Ramcar\InsuranceApplicationStatus;
|
||||||
|
use App\Ramcar\SubscriptionStatus;
|
||||||
use App\Service\PayMongoConnector;
|
use App\Service\PayMongoConnector;
|
||||||
use App\Service\PriceTierManager;
|
use App\Service\PriceTierManager;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
@ -518,9 +519,9 @@ class VehicleController extends ApiController
|
||||||
// get active subscription row
|
// get active subscription row
|
||||||
if ($include_active_sub) {
|
if ($include_active_sub) {
|
||||||
$active_sub = null;
|
$active_sub = null;
|
||||||
$sobj = $cv->getLatestActiveSubscription();
|
$sobj = $cv->getLatestSubscription();
|
||||||
if (!empty($sobj)) {
|
if (!empty($sobj) && $sobj->getStatus() == SubscriptionStatus::ACTIVE) {
|
||||||
|
$active_sub = $sobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row['active_subscription'] = $active_sub;
|
$row['active_subscription'] = $active_sub;
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,8 @@ class Subscription
|
||||||
|
|
||||||
public function setStatus($status)
|
public function setStatus($status)
|
||||||
{
|
{
|
||||||
return $this->status = $status;
|
$this->status = $status;
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStatus()
|
public function getStatus()
|
||||||
|
|
@ -169,7 +170,8 @@ class Subscription
|
||||||
|
|
||||||
public function setExtApiId($ext_api_id)
|
public function setExtApiId($ext_api_id)
|
||||||
{
|
{
|
||||||
return $this->ext_api_id = $ext_api_id;
|
$this->ext_api_id = $ext_api_id;
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExtApiId()
|
public function getExtApiId()
|
||||||
|
|
@ -179,7 +181,8 @@ class Subscription
|
||||||
|
|
||||||
public function setMetadata($metadata)
|
public function setMetadata($metadata)
|
||||||
{
|
{
|
||||||
return $this->metadata = $metadata;
|
$this->metadata = $metadata;
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMetadata()
|
public function getMetadata()
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,11 @@ class PayMongoConnector
|
||||||
return $this->doRequest('/v1/subscriptions', 'POST', $body);
|
return $this->doRequest('/v1/subscriptions', 'POST', $body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSubscription($sub_id)
|
||||||
|
{
|
||||||
|
return $this->doRequest('/v1/subscriptions/'. $sub_id, 'GET');
|
||||||
|
}
|
||||||
|
|
||||||
public function getPaymentIntent($pi_id)
|
public function getPaymentIntent($pi_id)
|
||||||
{
|
{
|
||||||
return $this->doRequest('/v1/payment_intents/' . $pi_id, 'GET');
|
return $this->doRequest('/v1/payment_intents/' . $pi_id, 'GET');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue