<?php
namespace App\Controller\Frontend;
use App\Utils\ApiSb;
use App\Utils\MailerUtils;
use App\Utils\NotifyUtils;
use App\Utils\Payments\Opayo\OpayoRecurringSaver;
use App\Utils\PayPalIPN;
use App\Utils\SB;
use Stripe\Event;
use Stripe\Stripe;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/notify")
*/
class NotifyController extends AbstractController
{
private string $projectDir;
private NotifyUtils $notifyUtils;
private MailerUtils $mailerUtils;
private PayPalIPN $payPalIPN;
private SB $sbUtil;
public function __construct(
KernelInterface $kernel,
NotifyUtils $notifyUtils,
MailerUtils $mailerUtils,
PayPalIPN $payPalIPN,
SB $sbUtil
) {
$this->projectDir = $kernel->getProjectDir();
$this->notifyUtils = $notifyUtils;
$this->mailerUtils = $mailerUtils;
$this->payPalIPN = $payPalIPN;
$this->sbUtil = $sbUtil;
}
/**
* @Route("/payu", name="fmApiPayuNotify")
* @Route("/payu/{lang}", name="fmApiPayuNotifyWithLang")
*/
public function payuNotifyApiAction(Request $request, $lang = null): Response
{
if ($lang === null || $lang === 'pl')
{
\OpenPayU_Configuration::setOauthTokenCache(new \OauthCacheFile($this->projectDir . '/var/payu/'));
\OpenPayU_Configuration::setEnvironment($_ENV['PAYU_ENVIRONMENT']);
\OpenPayU_Configuration::setMerchantPosId($_ENV['PAYU_MERCHANT_POS_ID']);
\OpenPayU_Configuration::setSignatureKey($_ENV['PAYU_SIGNATURE_KEY']);
\OpenPayU_Configuration::setOauthClientId($_ENV['PAYU_OAUTH_CLIENT_ID']);
\OpenPayU_Configuration::setOauthClientSecret($_ENV['PAYU_OAUTH_CLIENT_SECRET']);
}
elseif ($lang === 'es')
{
\OpenPayU_Configuration::setOauthTokenCache(new \OauthCacheFile($this->projectDir . '/var/payu/'));
\OpenPayU_Configuration::setEnvironment($_ENV['PAYU_ENVIRONMENT']);
\OpenPayU_Configuration::setMerchantPosId($_ENV['ES_PAYU_MERCHANT_POS_ID']);
\OpenPayU_Configuration::setSignatureKey($_ENV['ES_PAYU_SIGNATURE_KEY']);
\OpenPayU_Configuration::setOauthClientId($_ENV['ES_PAYU_OAUTH_CLIENT_ID']);
\OpenPayU_Configuration::setOauthClientSecret($_ENV['ES_PAYU_OAUTH_CLIENT_SECRET']);
}
elseif ($lang === 'pt')
{
\OpenPayU_Configuration::setOauthTokenCache(new \OauthCacheFile($this->projectDir . '/var/payu/'));
\OpenPayU_Configuration::setEnvironment($_ENV['PAYU_ENVIRONMENT']);
\OpenPayU_Configuration::setMerchantPosId($_ENV['PT_PAYU_MERCHANT_POS_ID']);
\OpenPayU_Configuration::setSignatureKey($_ENV['PT_PAYU_SIGNATURE_KEY']);
\OpenPayU_Configuration::setOauthClientId($_ENV['PT_PAYU_OAUTH_CLIENT_ID']);
\OpenPayU_Configuration::setOauthClientSecret($_ENV['PT_PAYU_OAUTH_CLIENT_SECRET']);
}
elseif ($lang === 'de')
{
\OpenPayU_Configuration::setOauthTokenCache(new \OauthCacheFile($this->projectDir . '/var/payu/'));
\OpenPayU_Configuration::setEnvironment($_ENV['PAYU_ENVIRONMENT']);
\OpenPayU_Configuration::setMerchantPosId($_ENV['DE_PAYU_MERCHANT_POS_ID']);
\OpenPayU_Configuration::setSignatureKey($_ENV['DE_PAYU_SIGNATURE_KEY']);
\OpenPayU_Configuration::setOauthClientId($_ENV['DE_PAYU_OAUTH_CLIENT_ID']);
\OpenPayU_Configuration::setOauthClientSecret($_ENV['DE_PAYU_OAUTH_CLIENT_SECRET']);
}
elseif ($lang === 'test')
{
\OpenPayU_Configuration::setOauthTokenCache(new \OauthCacheFile($this->projectDir . '/var/payu/'));
\OpenPayU_Configuration::setEnvironment('sandbox');
\OpenPayU_Configuration::setMerchantPosId($_ENV['TEST_PAYU_MERCHANT_POS_ID']);
\OpenPayU_Configuration::setSignatureKey($_ENV['TEST_PAYU_SIGNATURE_KEY']);
\OpenPayU_Configuration::setOauthClientId($_ENV['TEST_PAYU_OAUTH_CLIENT_ID']);
\OpenPayU_Configuration::setOauthClientSecret($_ENV['TEST_PAYU_OAUTH_CLIENT_SECRET']);
}
$content = $request->getContent();
try
{
$payuContent = \OpenPayU_Order::consumeNotification($content);
}
catch (\OpenPayU_Exception $e)
{
$messageBody = $this->notifyUtils->convertContentToMessage(json_decode($content, true));
$this->mailerUtils->sendNotifyEmail(
'PayU ERROR - GOS',
'Error message: '.$e->getMessage().'<br>'.$messageBody.'</ul>'
);
}
if (!$payuContent instanceof \OpenPayU_Result)
{
$messageBody = $this->notifyUtils->convertContentToMessage(json_decode($content, true));
$this->mailerUtils->sendNotifyEmail(
'PayU ERROR2 - GOS',
'Error message: '.$e->getMessage().'<br>'.$messageBody.'</ul><br>Route: ' . $request->get('_route')
);
return new Response('');
}
$wfList = $this->notifyUtils->checkOrdTran(
$payuContent->getResponse()->order->extOrderId,
$payuContent->getResponse()->order->orderId,
json_decode($content, true)
);
switch ($payuContent->getResponse()->order->status)
{
case 'COMPLETED':
$status = 2;
break;
case 'REJECTED':
$status = 3;
break;
case 'PENDING':
$status = 1;
break;
case 'CANCELED':
$status = 3;
break;
default:
$status = 999;
}
foreach ($wfList as $wf)
{
$this->notifyUtils->saveNotify(
json_decode($content, true),
$status,
$wf,
'payu',
$payuContent->getResponse()->order->orderId,
$payuContent->getResponse()->order->orderCreateDate
);
$this->notifyUtils->notifyUser($wf, $status);
$this->sbUtil->updateOrderTransactionResultStatus($wf, $status); // that's for recurring payments
}
return new Response('');
}
/**
* @Route("/payu-dev/test", name="fmApiPayuDevNotify")
*/
public function payuNotifyTestAction(Request $request): Response
{
// change to your own sandbox account if you want to test notifies
\OpenPayU_Configuration::setOauthTokenCache(new \OauthCacheFile($this->projectDir . '/var/payu/'));
\OpenPayU_Configuration::setEnvironment('sandbox');
\OpenPayU_Configuration::setMerchantPosId(575740);
\OpenPayU_Configuration::setSignatureKey('df2bd8f29ad5621685c440aaaf0e2d3a');
\OpenPayU_Configuration::setOauthClientId(575740);
\OpenPayU_Configuration::setOauthClientSecret('780bebc4d280d5c7f69abe7c33586494');
$messageBody = $this->notifyUtils->convertContentToMessage(json_decode($request->getContent(), true));
$this->mailerUtils->sendNotifyEmail(
'PayU Test Notify',
$messageBody,
'lukasz.mikowski@forum-media.pl'
);
return new Response('');
}
/**
* @Route("/payulatam", name="fmApiPayulatamNotify", methods={"POST"})
*/
public function payulatamNotifyApiAction(Request $request)
{
$content = $request->request->all();
$wfList = $this->notifyUtils->checkOrdTran(
$content['reference_sale'],
$content['transaction_id'],
$content
);
switch ($content['state_pol'])
{
case 4:
$status = 2;
break;
case 6:
$status = 3;
break;
case 104:
$status = 3;
break;
case 7:
$status = 1;
break;
default:
$status = 999;
}
foreach ($wfList as $wf)
{
$this->notifyUtils->saveNotify(
$content,
$status,
$wf,
'payu-latam',
$content['transaction_id'],
$content['transaction_date']
);
}
return new Response('<html><body></body></html>');
}
/**
* @Route("/paymentwall", name="fmApiPaymentwallNotify");
*/
public function paymentwallNotifyApiAction(Request $request)
{
\Paymentwall_Config::getInstance()->set(array(
'api_type' => \Paymentwall_Config::API_GOODS,
'public_key' => $this->getParameter('paymentwall_public_key'),
'private_key' => $this->getParameter('paymentwall_private_key')
));
$pingback = new \Paymentwall_Pingback($request->query->all(), $request->server->get('REMOTE_ADDR'));
if ($pingback->validate())
{
if ($pingback->getParameter('CHARGEBACK_TYPE') == 'refund')
{
$status = 16;
}
else if ($pingback->getParameter('CHARGEBACK_TYPE') == 'chargeback')
{
$status = 32;
}
else if ($pingback->isDeliverable())
{
$status = 2;
}
else if ($pingback->isCancelable())
{
$status = 3;
}
else if ($pingback->isUnderReview())
{
$status = 1;
}
else
{
$status = 999;
}
$paymentDate = (new \DateTime(
$pingback->getParameter('payment_date_utc'),
new \DateTimeZone('UTC')
))
->setTimeZone(new \DateTimeZone('Europe/Warsaw'));
$wfList = $this->notifyUtils->checkOrdTran(
$pingback->getParameter('wf'),
$pingback->getParameter('ref'),
$request->query->all()
);
foreach ($wfList as $wf)
{
$this->notifyUtils->saveNotify(
$request->query->all(),
$status,
$wf,
'paymentwall',
$pingback->getParameter('ref'),
$paymentDate->format('Y-m-d H:i:s')
);
}
return new Response('OK');
}
return new Response($pingback->getErrorSummary());
}
/**
* @Route("/paypal", name="fmApiPayPalNotify", methods={"POST"})
*/
public function payPalNotifyApiAction(Request $request)
{
// $this->payPalIPN->useSandbox();
$verified = $this->payPalIPN->verifyIPN();
if ($verified)
{
$content = $request->request->all();
$wfList = $this->notifyUtils->checkOrdTran($content['invoice'], $content['txn_id'], $content);
switch ($content['payment_status'])
{
case 'Completed':
$status = 2;
break;
case 'Pending':
$status = 1;
break;
case 'Failed':
$status = 3;
break;
case 'Processed':
$status = 3;
break;
case 'Voided':
$status = 3;
break;
case 'Reversed':
$status = 3;
break;
case 'Refunded':
$status = 3;
break;
case 'Expired':
$status = 3;
break;
case 'Denied':
$status = 3;
break;
case 'Created':
$status = 3;
break;
case 'Canceled_Reversal':
$status = 3;
break;
default:
$status = 999;
}
foreach ($wfList as $wf)
{
//WF27566-c077c/636247583e612 like
$wf = explode('/', $wf);
$wf = reset($wf);
$this->notifyUtils->saveNotify(
$content,
$status,
$wf,
'paypal',
$content['txn_id'],
$content['payment_date']
);
}
}
return new Response("<html><body></body></html>");
}
/**
* @Route("/dotpay", name="fmApiDotPayNotify", methods={"POST"})
*/
public function dotPayNotifyApiAction(Request $request)
{
$content = $request->request->all();
$wfList = $this->notifyUtils->checkOrdTran(
$content['control'],
$content['operation_number'],
$content
);
if ($content['operation_type'] == 'payment')
{
switch ($content['operation_status'])
{
case 'new':
$status = 1;
break;
case 'processing':
$status = 1;
break;
case 'completed':
$status = 2;
break;
case 'rejected':
$status = 3;
break;
case 'processing_realization_waiting':
$status = 1;
break;
case 'processing_realization':
$status = 1;
break;
default:
$status = 999;
}
}
else
{
$status = 3;
}
foreach ($wfList as $wf)
{
$this->notifyUtils->saveNotify(
$content,
$status,
$wf,
'dotpay',
$content['operation_number'],
$content['operation_datetime']
);
}
return new Response('OK');
}
/**
* @Route("/worldpay", name="fmApiWorldPayNotify", methods={"POST"})
*/
public function worldpayNotifyApiAction(Request $request)
{
$content = $request->request->all();
$wfList = $this->notifyUtils->checkOrdTran(
$content['cartId'],
$content['transId'],
$content
);
switch ($content['transStatus'])
{
case 'Y':
$status = 2;
break;
case 'C':
$status = 3;
break;
default:
$status = 999;
}
foreach ($wfList as $wf)
{
$this->notifyUtils->saveNotify(
$content,
$status,
$wf,
'worldpay',
$content['transId'],
date("Y-m-d H:i:s", $content['transTime']/1000)
);
}
if ($status !== 2)
$params['error'] = true;
$params['ordTran'] = $wfList[0];
return new Response($this->forward('App\Controller\Uniqskills\AfterPaymentController::afterPayUAction', $params)->getContent());
}
/**
* @Route("/opayo", name="fmApiOpayoNotify", methods={"POST"})
*/
public function opayoNotifyApiAction(Request $request, OpayoRecurringSaver $opayoRecurringSaver)
{
$content = $request->request->all();
$wfList = $this->notifyUtils->checkOrdTran(
$content['ordTran'],
$content['transactionId'],
$content
);
if (empty($content['statusCode']))
{
$status = 999;
}
elseif ($content['statusCode'] === '0000')
{
$status = 2;
}
else
{
$status = 3;
}
$isNetflix = $content['isNetflix'];
$isRecurring = $content['isRecurring'];
$domain = $content['domain'];
$vendorTxCode = $content['vendorTxCode'];
//Removing unnecessary, helper data
unset($content['ordTran']);
unset($content['isNetflix']);
unset($content['isRecurring']);
unset($content['domain']);
unset($content['vendorTxCode']);
foreach ($wfList as $wf)
{
$this->notifyUtils->saveNotify(
$content,
$status,
$wf,
'opayo',
$content['transactionId'],
date("Y-m-d H:i:s")
);
}
if ($status !== 2)
{
$params['error'] = true;
}
$params['ordTran'] = $wfList[0];
/*
* If recurring, save data in user_card table, which next will be sent to FO (check PaymentServiceProviderData).
* Then further recurring payments will be processed by FO.
*/
if ($status === 2 && $isRecurring == true)
{
$opayoRecurringSaver->saveTransaction($params['ordTran'], $content, $vendorTxCode);
}
//redirect to either netflix portal or uniqskills
if ($isNetflix)
{
$scheme = $_ENV['USING_HTTPS'] ? 'https://' : 'http://';
$continueUrl = parse_url($domain, PHP_URL_SCHEME) === null ? $scheme . $domain : $domain;
if ($status == 2)
{
$continueUrl .= '/payment-thank-you/' . $params['ordTran'];
}
else
{
$continueUrl .= '/koszyk/potwierdzenie/' . $params['ordTran'] . '?error=1';
}
return $this->redirect($continueUrl);
}
return $this->redirectToRoute('fmUniqskillsAfterOpayo', $params);
}
/**
* @Route("/stripe", name="fmApiStripeNotify", methods={"POST"})
*/
public function stripeNotifyApiAction(Request $request)
{
Stripe::setApiKey($_ENV['STRIPE_KEY']);
$payload = $request->request->all();
try {
$event = Event::constructFrom($payload);
} catch(\UnexpectedValueException $e) {
// Invalid payload
return new Response('', 400);
}
switch ($event->type) {
case 'checkout.session.completed':
$checkoutSession = $event->data->object;
$wfList = $this->notifyUtils->checkOrdTran(
$payload['data']['object']['client_reference_id'],
$payload['data']['object']['payment_intent'],
$payload['data']['object']
);
if ($checkoutSession->payment_status === 'paid' && $checkoutSession->status === 'complete') {
$status = 2;
} else {
$status = 999;
}
foreach ($wfList as $wf)
{
//WF27566-c077c/636247583e612 like
$wf = explode('/', $wf);
$wf = reset($wf);
$this->notifyUtils->saveNotify(
$payload['data']['object'],
$status,
$wf,
'stripe',
$payload['data']['object']['payment_intent'],
date("Y-m-d H:i:s", $payload['data']['object']['created'])
);
}
break;
default:
throw new \RuntimeException('Received unknown event type ' . $event->type);
}
return new Response();
}
}