src/Controller/MainController.php line 47
<?phpnamespace App\Controller;use App\Entity\Order;use App\Entity\Package;use App\Entity\UserFeature;use App\Services\AmeriaPaymentService;use Doctrine\ORM\EntityManagerInterface;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpKernel\KernelInterface;use Symfony\Component\Routing\Annotation\Route;use Symfony\Component\Routing\Generator\UrlGeneratorInterface;use Symfony\Bundle\FrameworkBundle\Console\Application;use Symfony\Component\Console\Input\ArrayInput;use Symfony\Component\Console\Output\BufferedOutput;class MainController extends BaseController{private AmeriaPaymentService $paymentService;public function __construct(EntityManagerInterface $entityManager, AmeriaPaymentService $paymentService){parent::__construct($entityManager);$this->paymentService = $paymentService;}#[Route('api/result/save', name: 'page_api_save', methods: ['POST'])]public function resultSave(Request $request){$payloadString = $request->request->get('payload');// Decode JSON string → array$payload = json_decode($payloadString, true);dump($payload);die;}#[Route('/checkout/{id}', name: 'page_checkout')]public function checkout(Package $package, KernelInterface $kernel): \Symfony\Component\HttpFoundation\RedirectResponse{// $application = new Application($kernel);// $application->setAutoExit(false);//// $input = new ArrayInput([// 'command' => 'doctrine:schema:update',// '--force' => true,// ]);//// $output = new BufferedOutput();//// $application->run($input, $output);//// dump($output->fetch());// die;$order = new Order();$order->setPackage($package);$order->setUser($this->getUser());$order->setPrice($package->getPrice());$this->entityManager->persist($order);$this->entityManager->flush();$backUrl = $this->generateUrl('payment_callback', [], UrlGeneratorInterface::ABSOLUTE_URL);$opaque = bin2hex(random_bytes(16));$paymentId = $this->paymentService->initializePayment(['order_id' => $order->getId(),'amount' => (float)$order->getPrice(),'currency' => 'AMD','back_url' => $backUrl,'opaque' => $opaque,'description' => 'Payment for Order #' . $order->getId()]);$order->setPaymentId($paymentId);$order->setOpaque($opaque);$this->entityManager->flush();return $this->redirect($this->paymentService->getRedirectUrl($paymentId, 'am'));}#[Route('/order/callback', name: 'payment_callback')]public function paymentCallback(Request $request){$paymentId = $request->query->get('paymentID');$opaqueToken = $request->query->get('opaque');if (!$paymentId) {return $this->redirectToRoute('payment_error_view', ['msg' => 'missing_parameters']);}// 1. Audit local record state$localPayment = $this->entityManager->getRepository(Order::class)->findOneBy(['paymentId' => $paymentId]);if (!$localPayment) {return $this->redirectToRoute('payment_error_view', ['msg' => 'payment_not_found']);}if ($localPayment->getStatus() === \App\Enum\Order::CALCULATED) {return $this->redirectToRoute('page_success', ['orderId' => $localPayment->getPaymentId()]);}// Verify state security tokenif ($localPayment->getOpaque() !== $opaqueToken) {return $this->redirectToRoute('payment_error_view', ['msg' => 'token_mismatch']);}// 2. Query actual data payload live from server to guarantee status legitimacy$details = $this->paymentService->getPaymentDetails($paymentId);$responseCode = $details['ResponseCode'] ?? null;/*** Simple Buy Logic Processing:* Ameria Status Definition rules:* Status = 3 means Authorized (Hold applied, configuration might require Confirm call)* Status = 10 means Settled / Cleared Successfully*/if ($responseCode == 00) {// If setup enforces authorization check, execute final confirm statement// if ($status == 3) {// $confirmResult = $this->paymentService->confirmPayment($paymentId, (float)$localPayment->getPrice());// if (($confirmResult['ResponseCode'] ?? null) !== 00) {// $localPayment->setStatus(\App\Enum\Order::FAILED);// $this->entityManager->flush();// return $this->redirectToRoute('payment_error_view', ['msg' => 'capture_failed']);// }// }$localPayment->setStatus(\App\Enum\Order::SUCCESS);$this->entityManager->flush();foreach ($localPayment->getPackage()->getPackageFeatures() as $packageFeature) {$userFeature = new UserFeature();$userFeature->setUser($this->getUser());$userFeature->setType($packageFeature->getType());$userFeature->setOrder($localPayment);$userFeature->setPackage($localPayment->getPackage());$userFeature->setAttempt($packageFeature->getAttempt());if ($packageFeature->getDuration() && $packageFeature->getDuration()?->format('%r%y%m%d%h%i%s%f') !== '0000000') {$now = new \DateTime();$expire = $now->add($packageFeature->getDuration());$userFeature->setDatetime($expire);}$this->entityManager->persist($userFeature);}$localPayment->setStatus(\App\Enum\Order::CALCULATED);$this->entityManager->flush();return $this->redirectToRoute('page_success', ['orderId' => $localPayment->getPaymentId()]);}return $this->redirectToRoute('payment_error_view', ['msg' => 'bank_declined', 'code' => $responseCode]);}#[Route('/order/success', name: 'page_success')]public function success(): \Symfony\Component\HttpFoundation\Response{return $this->render('@web/page/order/success.html.twig',[]);}#[Route('/order/error', name: 'payment_error_view', methods: ['GET'])]public function error(Request $request){return $this->render('@web/page/order/error.html.twig', ['message' => $request->query->get('msg'),'code' => $request->query->get('code')]);}}