src/Payment/Gateway/GenericExternalPay.php line 100

Open in your IDE?
  1. <?php
  2. namespace App\Payment\Gateway;
  3. use App\Entity\CPSUser;
  4. use App\Entity\Pratica;
  5. use App\Form\Admin\Servizio\PaymentDataType;
  6. use App\Form\Extension\TestiAccompagnatoriProcedura;
  7. use App\Payment\AbstractPaymentData;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use GuzzleHttp\Exception\GuzzleException;
  10. use Psr\Log\LoggerInterface;
  11. use Symfony\Component\Form\FormError;
  12. use Symfony\Component\Form\FormEvent;
  13. use Symfony\Component\Form\FormEvents;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Component\Routing\RouterInterface;
  17. use Symfony\Contracts\Translation\TranslatorInterface;
  18. use GuzzleHttp\Client;
  19. use GuzzleHttp\Psr7\Request;
  20. class GenericExternalPay extends AbstractPaymentData implements EventSubscriberInterface
  21. {
  22.   const IDENTIFIER 'generic-external';
  23.   const IMPORTO 'total_amounts';
  24.   /**
  25.    * @var LoggerInterface
  26.    */
  27.   private $logger;
  28.   /**
  29.    * @var EntityManagerInterface
  30.    */
  31.   private $entityManager;
  32.   /**
  33.    * @var TranslatorInterface $translator
  34.    */
  35.   private $translator;
  36.   /**
  37.    * @var RouterInterface
  38.    */
  39.   private $router;
  40.   /**
  41.    * @param LoggerInterface $logger
  42.    * @param EntityManagerInterface $entityManager
  43.    * @param RouterInterface $router
  44.    * @param TranslatorInterface $translator
  45.    */
  46.   public function __construct(LoggerInterface $loggerEntityManagerInterface $entityManagerRouterInterface $routerTranslatorInterface $translator)
  47.   {
  48.     $this->logger $logger;
  49.     $this->entityManager $entityManager;
  50.     $this->router $router;
  51.     $this->translator $translator;
  52.   }
  53.   public function getIdentifier(): string
  54.   {
  55.     return self::IDENTIFIER;
  56.   }
  57.   public static function getPaymentParameters()
  58.   {
  59.     return [];
  60.   }
  61.   public static function getFields()
  62.   {
  63.     return array(
  64.       self::IMPORTO
  65.     );
  66.   }
  67.   /** Event Subscriber **/
  68.   public static function getSubscribedEvents()
  69.   {
  70.     return array(
  71.       FormEvents::PRE_SET_DATA => 'onPreSetData',
  72.       FormEvents::PRE_SUBMIT => 'onPreSubmit'
  73.     );
  74.   }
  75.   /**
  76.    * @param $data
  77.    * @return mixed|void
  78.    */
  79.   public static function getSimplifiedData($data)
  80.   {
  81.     return $data;
  82.   }
  83.   public function onPreSetData(FormEvent $event)
  84.   {
  85.     $pratica $event->getData();
  86.     $options $event->getForm()->getConfig()->getOptions();
  87.     $helper $options["helper"];
  88.     $text '<div class="row mt-5"><div class="col-sm-4"><strong>'.$this->translator->trans('pratica.numero').'</strong></div><div class="col-sm-8 d-inline-flex"><code>'.$pratica->getId().'</code></div></div>';
  89.     $helper->setDescriptionText($text);
  90.   }
  91.   /**
  92.    * @param FormEvent $event
  93.    */
  94.   public function onPreSubmit(FormEvent $event)
  95.   {
  96.   }
  97.   /**
  98.    * @param Pratica $pratica
  99.    * @param $url
  100.    * @return string
  101.    */
  102.   private function generatePaymentButtonsPratica $pratica$url )
  103.   {
  104.     $buttons '<div class="row mt-5"><div class="col-sm-4"><strong>'.$this->translator->trans('pratica.numero').'</strong></div><div class="col-sm-8 d-inline-flex"><code>'.$pratica->getId().'</code></div></div>';
  105.     $buttons .= "<p class='mt-5'>".$this->translator->trans('gateway.mypay.redirect_text', ['%gateway_name%' => $pratica->getPaymentType()])."</p><div class='text-center mt-5'><a href='{$url['online_url']}' class='btn btn-lg btn-primary'>".$this->translator->trans('gateway.mypay.redirect_button')."</a></div>";
  106.     return $buttons;
  107.   }
  108.   /**
  109.    * @param Pratica $pratica
  110.    * @return mixed
  111.    */
  112.   private function getPaymentUrl(Pratica $pratica)
  113.   {
  114.     $data $pratica->getPaymentData();
  115.     return $data['response'];
  116.   }
  117.   /**
  118.    * @param Pratica $pratica
  119.    * @return array
  120.    * @throws \Exception|GuzzleException
  121.    */
  122.   private function createPaymentRequest(Pratica $pratica): array
  123.   {
  124.     $data $pratica->getPaymentData();
  125.     $gateway $pratica->getPaymentType();
  126.     $requestBody $this->createPaymentRequestBody($pratica);
  127.     $client = new Client();
  128.     $request = new Request(
  129.       'POST',
  130.       $gateway->getUrl(),
  131.       ['Content-Type' => 'application/json'],
  132.       \json_encode($requestBody)
  133.     );
  134.     /** @var Response $response */
  135.     $response $client->send($request);
  136.     if (!in_array($response->getStatusCode(), [Response::HTTP_OKResponse::HTTP_CREATEDResponse::HTTP_ACCEPTEDResponse::HTTP_NO_CONTENT])) {
  137.       throw new \Exception("Error sending payment request: " $response->getBody()->getContents());
  138.     }
  139.     $decoded json_decode($response->getBody()->getContents(), true);
  140.     /*
  141.      {
  142.          "status":"OK",
  143.          "status_code":"000",
  144.          "status_message":"Operazione completata con successo",
  145.          "remote_id":"ef3bf5a5‐d9a9‐4b27‐b0d2‐aa87d6d9ae95",
  146.          "iuv":"200910522634614",
  147.          "codice_avviso":"001200910522634614",
  148.          "online_url":"https://acardste.vaservices.eu/wallet/welcome?idSession=fc1723d2‐d40e‐4c2e‐89aec03f599d5894",
  149.          "file_url":"https://acardste.vaservices.eu/wallet/welcome?idSession=fc1723d2‐d40e‐4c2e‐89aec03f599d5894"
  150.       }
  151.      */
  152.     if ($decoded['status'] === 'KO') {
  153.       $this->logger->error('Error response when creating a payment request', ['request' => $requestBody'response' => $decoded]);
  154.       throw new \Exception("Unable to create a payment request.");
  155.     }
  156.     $data['request'] = $requestBody;
  157.     $data['response'] = $decoded;
  158.     $pratica->setPaymentData($data);
  159.     return $decoded;
  160.   }
  161.   /**
  162.    * @param Pratica $pratica
  163.    * @return array
  164.    * @throws \Exception
  165.    */
  166.   private function createPaymentRequestBody(Pratica $pratica)
  167.   {
  168.     $data $pratica->getPaymentData();
  169.     $paymentParameters $pratica->getServizio()->getPaymentParameters();
  170.     $paymentDayLifeTime 90;
  171.     $gateway $pratica->getPaymentType();
  172.     $paymentIdentifier $gateway->getIdentifier();
  173.     $amount $data[PaymentDataType::PAYMENT_AMOUNT];if (!$amount) {
  174.       throw new \Exception('Missing amount');
  175.     }
  176.     $description $data[PaymentDataType::PAYMENT_DESCRIPTION];
  177.     /** @var CPSUser $user */
  178.     $user $pratica->getUser();
  179.     $provincia $user->getProvinciaResidenza() ? $user->getProvinciaResidenza() : 'TN';
  180.     if (strlen($provincia) > 2) {
  181.       $provincia substr($provincia02);
  182.     }
  183.     /*
  184.       {
  185.        “amount”:10,
  186.        “reason”:“string”,
  187.        “type”:“string”,
  188.        “tenant_id”:“string”,
  189.        “order_id”:“”,
  190.        “payment_split”:[
  191.        ],
  192.        “expiration_time”:null,
  193.        “return_url”:“string”,
  194.        “notify_url”:“string”,
  195.        “remote_id”:“string”,
  196.        “payer”:{
  197.           “name”:“string”,
  198.           “surname”:“string”,
  199.           “fiscal_code”:“string”
  200.        },
  201.        “pagopa_payment_code”:null
  202.       }
  203.      */
  204.     $request = array(
  205.       'amount' => $amount,
  206.       'reason' => $description,
  207.       'type' => $paymentParameters['gateways'][$paymentIdentifier]['parameters']['identificativoTipoDovuto'],
  208.       'tenant_id' => $pratica->getServizio()->getEnte()->getId(),
  209.       'order_id' => $this->calculateIUDFromPratica($pratica),
  210.       'remote_id' => $pratica->getId(),
  211.       'notifyUrl' => $this->generateNotifyUrl($pratica),
  212.       'return_url' => $this->generateCallbackUrl($pratica),
  213.       'payer' => [
  214.         'name' => $user->getNome(),
  215.         'surname' => $user->getCognome(),
  216.         'fiscal_code' => $this->getCodiceFiscale($pratica),
  217.         'email' => $user->getEmail(),
  218.         'address' => $user->getIndirizzoResidenza(),
  219.         'postal_code' => $user->getCapResidenza(),
  220.         'city' => $user->getCittaResidenza(),
  221.         'county' => $provincia
  222.       ],
  223.       'pagopa_payment_code'=> $paymentParameters['gateways'][$paymentIdentifier]['parameters']['datiSpecificiRiscossione'] ?? '9/3300.1',
  224.       'expiration_time' => (new \DateTime())->modify('+'.$paymentDayLifeTime.'days')->format('Y-m-d'),
  225.       'payment_split' => []
  226.     );
  227.     if (isset($data[PaymentDataType::PAYMENT_FINANCIAL_REPORT])) {
  228.       foreach ( $data[PaymentDataType::PAYMENT_FINANCIAL_REPORT] as $v ) {
  229.         $temp =[];
  230.         $temp['codCapitolo'] = $v['codCapitolo'];
  231.         $temp['codUfficio'] = $v['codUfficio'];
  232.         $temp['accertamento']['importo'] = $v['importo'];
  233.         if (isset($v['codAccertamento']) && !empty($v['codAccertamento'])) {
  234.           $temp['accertamento']['codAccertamento'] = $v['codAccertamento'];
  235.         }
  236.         $request['payment_split'][]= $temp;
  237.       }
  238.     }
  239.     return $request;
  240.   }
  241.   /**
  242.    * @param Pratica $pratica
  243.    * @return string
  244.    */
  245.   private function generateNotifyUrl(Pratica $pratica): string
  246.   {
  247.     return $this->router->generate('applications_payment_api_post', [
  248.       'id' => $pratica->getId()
  249.     ], RouterInterface::ABSOLUTE_URL);
  250.   }
  251.   /**
  252.    * @param Pratica $pratica
  253.    * @return string
  254.    */
  255.   public function generateCallbackUrl(Pratica $pratica): string
  256.   {
  257.     return $this->router->generate('pratiche_payment_callback', [
  258.       'pratica' => $pratica->getId()
  259.     ], RouterInterface::ABSOLUTE_URL);
  260.   }
  261.   /**
  262.    * @param $cf
  263.    * @return bool
  264.    */
  265.   private function getCodiceFiscale(Pratica $pratica): string
  266.   {
  267.     $cf $pratica->getUser()->getCodiceFiscale();
  268.     $cfParts explode('-'$cf);
  269.     if ( count($cfParts) > 1) {
  270.       $cf $cfParts[0];
  271.     }
  272.     return $cf;
  273.   }
  274.   /**
  275.    * @param Pratica $pratica
  276.    * @return string
  277.    */
  278.   private function calculateIUDFromPratica(Pratica $pratica)
  279.   {
  280.     return str_replace('-'''$pratica->getId());
  281.   }
  282. }