<?php
namespace Social\FrontendBundle\Controller;
use DateTime;
use Exception;
use Psr\Log\LoggerInterface;
use Social\FrontendBundle\Entity\PaymentCancel;
use Social\FrontendBundle\Entity\VerotelConfirmationPayment;
use Social\InternalBundle\Entity\PackagesList;
use Social\InternalBundle\Entity\UserDeletionQueue;
use Social\UserBundle\Entity\User;
use Social\FrontendBundle\Service\Mailer;
use Social\FrontendBundle\Entity\PaymentOffer;
use Social\InternalBundle\Entity\PackageSelectorTrackerEntity;
use Social\InternalBundle\Service\Core\CustomTelegramIntegration;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Social\InternalBundle\Service\PaymentMethods\Core\PaymentInterface;
/**
* Class PaymentController
*
* @package Social\FrontendBundle\Controller
*/
class PaymentController extends Controller
{
/**
* @param Request $request
*
* @return Response
*/
public function showPostPaymentModalsAction(Request $request)
{
$payment = $request->get('payment', null);
$etat = $request->get('etat', null);
$event = $request->get('event', null);
return $this->render('SocialFrontendBundle:Payment:show_post_payment_modals.html.twig',
['payment' => $payment, 'etat' => $etat, 'event' => $event]);
}
/**
* @param Request $request
*
* @return JsonResponse
*/
public function getPaymentUrlAction(Request $request)
{
$package = $request->get('package');
$source = $request->get('source');
// Getting payment methods definitions and get the active one. If not then go on default
$socialPaymentsDefinitions = $this->getParameter('social_payments');
if (isset($socialPaymentsDefinitions['payment_used_in_front']) && $socialPaymentsDefinitions['payment_used_in_front'] !== '') {
$loadedPaymentMethod = $socialPaymentsDefinitions['payment_used_in_front'];
if (isset($socialPaymentsDefinitions[$loadedPaymentMethod]) && $socialPaymentsDefinitions[$loadedPaymentMethod]['active'] == true) {
if ($this->container->has($socialPaymentsDefinitions[$loadedPaymentMethod]['service'])) {
$subscriptionManager = $this->get($socialPaymentsDefinitions[$loadedPaymentMethod]['service']);
} else {
$subscriptionManager = $this->get('social.subscription_manager');
}
} else {
$subscriptionManager = $this->get('social.subscription_manager');
}
} else {
$subscriptionManager = $this->get('social.subscription_manager');
}
// Initialize the payment
if (in_array('_init', get_class_methods($subscriptionManager))) {
$subscriptionManager->_init();
}
/** @var PackagesList $packageList */
$packageList = $this->getDoctrine()->getRepository(PackagesList::class)->findOneBy(['name' => $package]);
$amount = $packageList->getValue();
$this->get('social.mailer')->sendAdminPaymentInitiated($this->getUser(), $amount, 'modal');
$redirectUrl = $subscriptionManager->getPaymentLink($this->getUser(), $package, $source);
return new JsonResponse(
[
'redirect_url' => $redirectUrl,
]
);
}
/**
* @param Request $request
* @param Mailer $mailer
*
* @return JsonResponse
*/
public function cancelSubscriptionAction(Request $request)
{
try {
if ($this->getUser()) {
$centralPayService = $this->get('social_internal.payments.centralpay_provider_v2');
if ($request->isMethod('POST')) {
$centralPayService->cancelCentralPaySubscription($this->getUser());
}
}
} catch (Exception $exception) {
// $this->get('sentry.client')->captureException($exception);
}
return new JsonResponse(['redirect_url' => $this->generateUrl('social_frontend_account_details')]);
}
/**
* @param Request $request
*
* @return JsonResponse
*/
public function refundAction(Request $request)
{
$reason = $request->get('reason', '');
$mailer = $this->get('social.mailer');
/** @var User|null $user */
$user = $this->getUser();
$mailer->sendRefundEmail($user, $reason);
return new JsonResponse([]);
}
public function verotelPayIndexAction(Request $request)
{
$session = new Session();
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('SocialUserBundle:User')->find($this->getUser());
if ($user->getPackageName() == 'default') {
setcookie('tusData', json_encode($request->query->get('tus')), time()+3600);
$package = $request->query->get('package');
} else {
$package = $session->get('package');
}
//for cancel event
if (!$this->getUser() || $package == null) {
$verotelConfirmationPayment = $em->getRepository('SocialFrontendBundle:VerotelConfirmationPayment')
->findOneBy(['from_user' => $user], ['id' => 'DESC']);
$user->setPackageNextPaymentDueOn(null);
$cancelledDate = new \DateTime();
$verotelConfirmationPayment->setCancelledDate($cancelledDate);
$em->persist($user);
$em->persist($verotelConfirmationPayment);
$em->flush();
return new RedirectResponse($this->generateUrl('social_user_homepage'));
}
try {
$verotelPayService = $this->get('social_internal.payments.verotel_card');
if ($request->isMethod('POST')) {
if ($request->request->get('rmCard') && $request->request->get('rmCard') !== '') {
return new JsonResponse($verotelPayService->removeCard($this->getUser(),
$request->request->get('rmCard')));
}
}
$verotelProviderService = $this->get('social_internal.payments.verotel_card');
if ($request->isMethod('GET')) {
/** @var UserDeletionQueue $userDeletionQue */
$userDeletionQue = $em->getRepository(UserDeletionQueue::class)->findOneBy(['for_user' => $this->getUser(), 'isDeleted' => false]);
if ($userDeletionQue) {
$userDeletionQue->setIsDeleted(true);
}
$purchaseUrl = $verotelProviderService->getPaymentLink($this->getUser(), $package, null);
if ($user->getPackageName() == 'default' || $request->isXmlHttpRequest()) {
return new JsonResponse(['redirect_url' => $purchaseUrl]);
} else {
return new RedirectResponse($purchaseUrl);
}
}
return new RedirectResponse($this->generateUrl('social_user_homepage'));
}
catch (\Symfony\Component\Security\Acl\Exception\Exception $exception) {
$this->get('sentry.client')->captureException($exception);
return new JsonResponse([
'view' => null,
'errors' => ['Something wrong happended'],
]);
}
}
public function verotelPaymentPostBackCallAction(Request $request, LoggerInterface $cardBillingLogger)
{
$cardBillingLogger->info('req-post', $request->request->all());
$cardBillingLogger->info('req-get', $request->query->all());
if (!$request->get('event')) {
$this->redirectToRoute('social_frontend_homepage_account');
}
$verotelCardService = $this->get('social_internal.payments.verotel_card');
$verotelCardService->_init();
$postbackResult = '';
switch (strtolower($request->get('event'))) {
case 'rebill':
$postbackResult = $verotelCardService->rebillTransaction($request);
break;
case 'extend':
$postbackResult = $verotelCardService->extendRebillTransaction($request);
break;
case 'initial':
$postbackResult = $verotelCardService->checkInitialTransaction($request);
break;
case 'cancel':
$postbackResult = $verotelCardService->cancelTransaction($request);
break;
case 'expiry':
$postbackResult = $verotelCardService->expiryTransaction($request);
break;
case 'upgrade':
$postbackResult = $verotelCardService->upgradeTransaction($request);
break;
case 'downgrade':
$postbackResult = $verotelCardService->downgradeTransaction($request);
break;
case 'credit':
$postbackResult = $verotelCardService->creditTransaction($request);
break;
case 'chargeback':
$postbackResult = $verotelCardService->chargeBackTransaction($request);
break;
}
return new Response($postbackResult,200);
}
public function centralPayCheckAction(Request $request)
{
try {
if ($this->getUser() && $request->isXmlHttpRequest()) {
$data = $request->request->all();
$this->get('social_internal.bots.telegram')
->sendMessage("Iframe message", $data['data'], 'GOD', CustomTelegramIntegration::CHANNEL_SALES);
}
return new JsonResponse("OK");
} catch (\Exception $exception) {
return new JsonResponse("NOK");
}
}
public function centralPayIndexAction(Request $request, LoggerInterface $debuglogLogger)
{
$em = $this->get('doctrine.orm.entity_manager');
$user = $em->getRepository('SocialUserBundle:User')->find($this->getUser());
try {
if ($this->getUser()) {
/** @var UserDeletionQueue $userDeletionQue */
$userDeletionQue = $em->getRepository(UserDeletionQueue::class)->findOneBy(['for_user' => $this->getUser(), 'isDeleted' => false]);
if ($userDeletionQue) {
$userDeletionQue->setIsDeleted(true);
}
/* ////////////////////// V2 */
$centralPayService = $this->get('social_internal.payments.centralpay_provider_v2');
$centralPayProcess = $centralPayService->startProcess($request);
$debuglogLogger->info('started process in centralPayIndexAction for user ' . $user->getId());
$debuglogLogger->info('request method is ' . $request->getMethod());
if ($request->isMethod('POST')) {
if ($request->request->get('rmCard') && $request->request->get('rmCard') !== '') {
return new JsonResponse($centralPayService->removeCard($this->getUser(),
$request->request->get('rmCard')));
}
$content = json_decode($centralPayProcess->getContent());
$debuglogLogger->info('$centralPayProcess response is - ' . $centralPayProcess->getContent());
if ($content->error_flag === false && $content->sStep === 'upgraded') {
$debuglogLogger->info('in centralPayIndexAction error_flag is false');
/** @var VerotelConfirmationPayment $userVerotelPayment */
$userVerotelPayment = $em->getRepository('SocialFrontendBundle:VerotelConfirmationPayment')
->findOneBy(['from_user' => $user], ['id' => 'DESC']);
$debuglogLogger->info('in centralPayIndexAction $userVerotelPayment for user ' . $user->getId());
if ($userVerotelPayment) {
$debuglogLogger->info('$userVerotelPayment found from `payment_verotel_installments` table with ID ' . $userVerotelPayment->getId());
$isPaymentCancelled = $em->getRepository(PaymentCancel::class)->findOneBy(['uniqueTransactionId' => $userVerotelPayment->getTransactionID()]);
if (!$isPaymentCancelled) {
$verotelPayService = $this->get('social_internal.payments.verotel_card');
$verotelPayService->cancelSubscription($userVerotelPayment->getSaleID());
} else {
$debuglogLogger->info('Previous Sale is already cancelled in cardbilling ' . $userVerotelPayment->getId());
}
}
}
$debuglogLogger->info('in centralPayIndexAction in POST method');
}
$debuglogLogger->info('$centralPayProcess response = ' . json_encode($centralPayProcess));
return $centralPayProcess;
/* ////////////////////// V2 */
// Init the main service for central Pay
$paymentProviderService = $this->get('social_internal.payments.centralpay_provider_v2');
// If request is a get then it means that we need to display form or get in the 3DS check
if ($request->isMethod('GET')) {
$package = $request->query->get('package');
if ($package) {
$packageDetails = $paymentProviderService->getFormDisplayData($package);
if (false === $packageDetails['error_flag']) {
$packageDetails = $packageDetails['data'];
} else {
return $packageDetails;
}
//$savedCards = $this->getDoctrine()->getRepository('SocialInternalBundle:CentralPayEntity')
// ->getAllUserCards($this->getUser());
$registeredCustomerEntity = $this->getDoctrine()->getRepository('SocialInternalBundle:CentralPayCustomersEntity')
->findOneBy(['userReference' => $this->getUser()]);
$registeredCards = null;
if ($registeredCustomerEntity) {
$registeredCards = $registeredCustomerEntity->getSavedCards();
}
$centralPayParams = $this->getParameter('social_payments');
return new JsonResponse([
'error_flag' => false,
'errors' => null,
'view' => $this->renderView('@SocialFrontend/Payment/Partials/cp_payment_form.html.twig',
[
'savedCards' => $registeredCards,
'packageDetails' => $packageDetails,
'errors' => null,
'merchantKey' => $centralPayParams['centralPay']['merchantPublicKey'],
]),
]);
}
} elseif ($request->isMethod('POST')) {
if ($request->request->get('rmCard') && $request->request->get('rmCard') !== '') {
return new JsonResponse($paymentProviderService->removeCard($this->getUser(),
$request->request->get('rmCard')));
}
$response = $paymentProviderService->startProcess($request);
$tus = $request->request->get('tus');
if (true === $response['error_flag']) {
if (isset($response['sStep']) && 'pFail' === $response['sStep']) {
$response['view'] = $this->renderView('@SocialFrontend/Payment/Partials/cp_payment_finished.html.twig',
['data' => $response, 'errors' => null]);
$newTrack = new PackageSelectorTrackerEntity();
$newTrack->setUser($this->getUser()->getId());
$newTrack->setLogDate(new DateTime('now'));
$newTrack->setTrackedData($tus . ',failed');
$this->getDoctrine()->getManager()->persist($newTrack);
$this->getDoctrine()->getManager()->flush();
unset($response['data']);
return new JsonResponse($response);
}
// To be sure no sensitive data is going out
unset($response['data']);
return new JsonResponse($response);
}
if (isset($response['sStep']) && 'checkDS' === $response['sStep']) {
$response['view'] = $this->renderView('@SocialFrontend/Payment/Partials/enrollement_form.html.twig',
[
'enrollmentData' => $response['data'],
'errors' => null,
'internalData' => [
'userID' => $this->getUser()->getId(),
'package' => $package,
'mTI' => '',
'installmentID' => '',
'paReq' => '',
'paRes' => '',
],
]);
return new JsonResponse($response);
}
if (isset($response['sStep']) && 'upgraded' === $response['sStep']) {
$response['view'] = $this->renderView('@SocialFrontend/Payment/Partials/cp_payment_finished.html.twig',
['data' => $response, 'errors' => null]);
$newTrack = new PackageSelectorTrackerEntity();
$newTrack->setUser($this->getUser()->getId());
$newTrack->setLogDate(new DateTime('now'));
$newTrack->setTrackedData($tus . ',upgraded');
$this->getDoctrine()->getManager()->persist($newTrack);
$this->getDoctrine()->getManager()->flush();
return new JsonResponse($response);
}
}
}
// No user is logged in - redirect it to register/login
return new RedirectResponse($this->generateUrl('social_user_homepage'));
} catch (Exception $exception) {
$this->get('sentry.client')->captureException($exception);
$debuglogLogger->critical('Error occurred in centralPayIndex - ' . $exception->getMessage());
return new JsonResponse([
'view' => null,
'errors' => ['Something wrong happened'],
]);
}
}
public function centralPayChallengeAction(Request $request, LoggerInterface $debuglogLogger)
{
try {
$centralPayService = $this->get('social_internal.payments.centralpay_provider_v2');
$retour = json_decode(base64_decode($_POST['cres']), true);
$debuglogLogger->info('In centralPayChallengeAction');
$threeDSTransaction = $centralPayService->threeDS2Transaction($retour);
if ($request->isMethod('POST')) {
if ($request->request->get('rmCard') && $request->request->get('rmCard') !== '') {
return new JsonResponse($centralPayService->removeCard($this->getUser(),
$request->request->get('rmCard')));
}
$response = json_decode($threeDSTransaction->getContent());
return new Response($response->view);
}
return new RedirectResponse($this->generateUrl('social_user_homepage'));
} catch (Exception $exception) {
$this->get('sentry.client')->captureException($exception);
}
}
public function centralPaySmartFormAction(Request $request, LoggerInterface $debuglogLogger)
{
try {
setcookie('tusData', json_encode($request->request->get('tus')), time()+3600);
$debuglogLogger->info('Step 1 - Smart form has initiated - centralPaySmartFormAction() and Requested data for smart form ' . json_encode($request->request->all()));
if ($this->getUser()) {
$centralPayService = $this->get('social_internal.payments.centralpay_provider_v2');
/** @var UserDeletionQueue $userDeletionQue */
$userDeletionQue = $this->getDoctrine()->getRepository(UserDeletionQueue::class)->findOneBy(['for_user' => $this->getUser(), 'isDeleted' => false]);
if ($userDeletionQue) {
$userDeletionQue->setIsDeleted(true);
}
$debuglogLogger->info("Calling smartFormProcess()");
$centralPayProcess = $centralPayService->smartFormProcess($request);
if (isset($centralPayProcess) && $centralPayProcess['error_flag'] == false) {
$debuglogLogger->info('Step 3 - No error - Smart form rendered');
} else {
$debuglogLogger->info('Step 3 - Error - Something went wrong while getting the form rendering');
}
if (isset($centralPayProcess) && isset($centralPayProcess['url_sf']) && $centralPayProcess['url_sf']) {
$debuglogLogger->info('Step 4 - (Before payment)Smart form redirection url is returned from sf response - '. $centralPayProcess['url_sf']);
} else {
$debuglogLogger->info('Step 4 - Something went wrong while getting url');
}
return new JsonResponse([
'error_flag' => false,
'data' => $centralPayProcess['url_sf'] ?? []
]);
}
return new JsonResponse([
'error_flag' => true,
'message' => 'Something went wrong'
]);
} catch (Exception $exception) {
$debuglogLogger->info('Step LAST - Exception thrown while smart form: '. $exception->getMessage());
return new JsonResponse([
'error_flag' => true,
'message' => $exception->getMessage()
]);
}
}
public function centralPayRedirectAction(Request $request)
{
try {
return $this->render('@SocialFrontend/Payment/Partials/cp_after_redirect.html.twig',
[
'md' => $request->get('MD',$this->getParameter('project_name')),
'paRes' => $request->get('PaRes'),
]);
} catch (Exception $exception) {
/** @var LoggerInterface $centralPayLogger */
$centralPayLogger->error($exception->getMessage());
$centralPayLogger->error(json_encode($request->request->all()));
// This is really bad - but will not get pass payment transaction in the next step since the paRes is failing
return $this->render('@SocialFrontend/Payment/Partials/cp_after_redirect.html.twig',
[
'md' => '',
'paRes' => '',
]);
}
}
/**
* @param Request $request
* @param LoggerInterface $centralPayLogger
*
* @return JsonResponse
*/
public function centralPayHooksAction(
Request $request,
LoggerInterface $centralPayLogger,
LoggerInterface $centralPaySFLogger,
LoggerInterface $cardBillingLogger
): JsonResponse {
try {
$deflatedParams = json_decode($request->getContent(), true);
if (isset($deflatedParams['type'])) {
$centralPayService = $this->get('social_internal.payments.centralpay_provider_v2');
$centralPayLogger->info(">>>>>>>>>>>>>> Incoming hook:: \n>>>>>>> TYPE:::: {$deflatedParams['type']}\n" . json_encode($deflatedParams,
true) . "\n<<<<<<<<<<<<<<");
$response = $centralPayService->processHookRequest($deflatedParams);
$centralPayLogger->critical('>>>>>>>>>>>>>> END HOOK UTILITY ACTION WITH :: ');
$centralPayLogger->critical('>>>>>>> TYPE:::: ' . $deflatedParams['type']);
$centralPayLogger->critical(json_encode($response, true));
$centralPayLogger->critical('<<<<<<<<<<<<<<');
$centralPaySFLogger->info(">>>>>>>>>>>>>> Incoming hook:: \n>>>>>>> TYPE:::: {$deflatedParams['type']}\n" . json_encode($deflatedParams,
true) . "\n<<<<<<<<<<<<<<");
$centralPaySFLogger->critical('>>>>>>>>>>>>>> END HOOK UTILITY ACTION WITH :: ');
$centralPaySFLogger->critical('>>>>>>> TYPE:::: ' . $deflatedParams['type']);
$centralPaySFLogger->critical(json_encode($response, true));
$centralPaySFLogger->critical('<<<<<<<<<<<<<<');
return new JsonResponse($response, 200);
}
$this->get('sentry.client')->captureMessage('Payment hook type index in array not found!');
return new JsonResponse(['error_flag' => true, 'message' => 'Type is not found in cp request hook']);
} catch (Exception $e) {
$this->get('sentry.client')->captureMessage($e->getMessage(), ['exception' => $e]);
return new JsonResponse(['error_flag' => true, 'message' => $e->getMessage()]);
}
}
}