src/Payment/Gateway/MyPay.php line 232

Open in your IDE?
  1. <?php
  2. namespace App\Payment\Gateway;
  3. use App\Entity\Pratica;
  4. use App\Form\Extension\TestiAccompagnatoriProcedura;
  5. use App\Payment\AbstractPaymentData;
  6. use App\Payment\PaymentDataInterface;
  7. use App\Services\MyPayService;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use Psr\Log\LoggerInterface;
  10. use Symfony\Component\Form\FormError;
  11. use Symfony\Component\Form\FormEvent;
  12. use Symfony\Component\Form\FormEvents;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\Routing\RouterInterface;
  15. use Symfony\Contracts\Translation\TranslatorInterface;
  16. class MyPay extends AbstractPaymentData implements EventSubscriberInterface
  17. {
  18.   /**
  19.    * The expected structure of paymentData is
  20.    * importo: 1234 (integer, actual value is this / 100 )
  21.    * payment_attempts: [
  22.    *   payment_id_sent_to_gw: [
  23.    *       start_request:    array (actual request sent)
  24.    *       start_response:   array (actual remote response)
  25.    *       outcome_request:  array (actual request sent)
  26.    *       outcome_response: array (actual remote response)
  27.    *     ]
  28.    *   payment_id_sent_to_gw
  29.    *   payment_id_sent_to_gw
  30.    *   ...
  31.    * ]
  32.    * overall_outcome: -1 for pending, 0 for good, values from documentation for other cases
  33.    */
  34.   const IDENTIFIER 'mypay';
  35.   const PAYMENT_ATTEMPTS 'payment_attempts';
  36.   const IMPORTO 'total_amounts';
  37.   const OVERALL_OUTCOME 'overall_outcome';
  38.   const OUTCOME_REQUEST 'outcome_request';
  39.   const OUTCOME_RESPONSE 'outcome_response';
  40.   const START_REQUEST 'start_request';
  41.   const START_RESPONSE 'start_response';
  42.   /** Pending */
  43.   const PAA_PAGAMENTO_NON_INIZIATO 'PAA_PAGAMENTO_NON_INIZIATO';
  44.   const PAA_PAGAMENTO_IN_CORSO 'PAA_PAGAMENTO_IN_CORSO';
  45.   /** Effettivamente conclusi negativamente */
  46.   const PAA_PAGAMENTO_ANNULLATO 'PAA_PAGAMENTO_ANNULLATO';
  47.   const PAA_PAGAMENTO_SCADUTO 'PAA_PAGAMENTO_SCADUTO';
  48.   const ESITO_UNSET = -999;
  49.   const ESITO_PENDING = -1;
  50.   const ESITO_ESEGUITO 0;
  51.   const ESITO_NON_ESEGUITO 1;
  52.   const ESITO_PARZIALMENTE_ESEGUITO 2;
  53.   const ESITO_DECORRENZA_TERMINI 3;
  54.   const ESITO_PARZIALE_DECORRENZA_TERMINI 4;
  55.   const LATEST_ATTEMPT_ID 'latest_attempt_id';
  56.   const PAYMENT_STEP_LABEL 'steps.common.payment_gateway.label';
  57.   /**
  58.    * @var LoggerInterface
  59.    */
  60.   private $logger;
  61.   /**
  62.    * @var MyPayService
  63.    */
  64.   private $myPayService;
  65.   /**
  66.    * @var EntityManagerInterface
  67.    */
  68.   private $em;
  69.   /**
  70.    * @var TranslatorInterface $translator
  71.    */
  72.   private $translator;
  73.   public function __construct(LoggerInterface $loggerMyPayService $myPayServiceEntityManagerInterface $emRouterInterface $routerTranslatorInterface $translator)
  74.   {
  75.     $this->logger $logger;
  76.     $this->myPayService $myPayService;
  77.     $this->em $em;
  78.     $this->router $router;
  79.     $this->translator $translator;
  80.   }
  81.   public function getIdentifier(): string
  82.   {
  83.     return self::IDENTIFIER;
  84.   }
  85.   public static function getPaymentParameters(): array
  86.   {
  87.     return [
  88.       'codIpaEnte'=> 'gateway.mypay.ipa_code',
  89.       'password'=> 'gateway.mypay.password',
  90.       'datiSpecificiRiscossione'=> 'gateway.mypay.data',
  91.       'identificativoTipoDovuto'=> 'gateway.mypay.id_type'
  92.     ];
  93.   }
  94.   public static function getFields()
  95.   {
  96.     return array(
  97.       self::PAYMENT_ATTEMPTS,
  98.       self::IMPORTO
  99.     );
  100.   }
  101.   /** Event Subscriber **/
  102.   public static function getSubscribedEvents()
  103.   {
  104.     return array(
  105.       FormEvents::PRE_SET_DATA => 'onPreSetData',
  106.       FormEvents::PRE_SUBMIT => 'onPreSubmit'
  107.     );
  108.   }
  109.   /**
  110.    * @param $data
  111.    * @return mixed|void
  112.    */
  113.   public static function getSimplifiedData($data)
  114.   {
  115.     $result = [];
  116.     $result['status'] = PaymentDataInterface::STATUS_PAYMENT_PENDING;
  117.     if (isset($data['payment_amount'])) {
  118.       $result['payment_amount'] = number_formatfloatval($data['payment_amount']), 2'.''' );
  119.     }
  120.     if (isset($data['payment_financial_report'])) {
  121.       $financialReport $data['payment_financial_report'];
  122.       foreach ($financialReport as $k => $v) {
  123.         $financialReport[$k]['importo'] = number_formatfloatval($v['importo']), 2'.''' );
  124.       }
  125.       $result['payment_financial_report'] = $financialReport;
  126.     }
  127.     // Request
  128.     if (isset($data['request'])) {
  129.       $result['status'] = PaymentDataInterface::STATUS_PAYMENT_PROCESSING;
  130.       $paymentExpireDate $data['request']['dataEsecuzionePagamento'];
  131.       try {
  132.         $date = new \DateTime($data['request']['dataEsecuzionePagamento']);
  133.         $paymentExpireDate $date->format(\DateTime::W3C);
  134.       } catch (\Exception $e) {
  135.         // Do nothing
  136.       }
  137.       $result['iud'] = $data['request']['identificativoUnivocoDovuto'];
  138.       $result['reason'] = $data['request']['causaleVersamento'];
  139.       $result['expire_at'] = $paymentExpireDate;
  140.     }
  141.     // Response
  142.     if (isset($data['response'])) {
  143.       $result['iuv'] = $data['response']['identificativoUnivocoVersamento'];
  144.     }
  145.     // Result
  146.     if (isset($data['outcome'])) {
  147.       $paymentDate null;
  148.       if ($data['outcome']['status'] == 'OK') {
  149.         $result['status'] = PaymentDataInterface::STATUS_PAYMENT_PAID;
  150.         if (isset($data['outcome']["data"]["datiPagamento"]["datiSingoloPagamento"]["dataEsitoSingoloPagamento"])) {
  151.           $paymentDate $data['outcome']["data"]["datiPagamento"]["datiSingoloPagamento"]["dataEsitoSingoloPagamento"];
  152.           try {
  153.             $date = new \DateTime($paymentDate);
  154.             $paymentDate $date->format(\DateTime::W3C);
  155.           } catch (\Exception $e) {
  156.             // Do nothing
  157.           }
  158.         }
  159.       } else {
  160.         $result['status'] = PaymentDataInterface::STATUS_PAYMENT_FAILED;
  161.       }
  162.       $result['paid_at'] = $paymentDate;
  163.       $result['mypay_status_code'] = $data['outcome']['status_code'];
  164.       $result['mypay_status_message'] = $data['outcome']['status_message'];
  165.     }
  166.     return $result;
  167.   }
  168.   public function onPreSetData(FormEvent $event)
  169.   {
  170.     $form $event->getForm();
  171.     /** @var Pratica $pratica */
  172.     $pratica $event->getData();
  173.     $options $event->getForm()->getConfig()->getOptions();
  174.     /** @var TestiAccompagnatoriProcedura $helper */
  175.     $helper $options["helper"];
  176.     $data $pratica->getPaymentData();
  177.     try {
  178.       if (isset($data['response']) && $data['response']['esito'] == 'OK') {
  179.         $url $this->myPayService->getMyPayUrlForCurrentPayment($pratica);
  180.         $helper->setDescriptionText($this->generatePaymentButtons($pratica$url));
  181.       } else {
  182.         $this->myPayService->createPaymentRequestForPratica($pratica);
  183.         $this->em->flush();
  184.         $url $this->myPayService->getMyPayUrlForCurrentPayment($pratica);
  185.         $helper->setDescriptionText($this->generatePaymentButtons($pratica$url));
  186.       }
  187.     } catch (\Exception $e) {
  188.       $this->logger->error("Warning user about not being able to create a payment request for pratica " $pratica->getId() . ' - ' $e->getMessage());
  189.       $helper->setDescriptionText($this->translator->trans('payment.mypay_error'));
  190.     }
  191.   }
  192.   /**
  193.    * @param FormEvent $event
  194.    */
  195.   public function onPreSubmit(FormEvent $event)
  196.   {
  197.     /** @var Pratica $application */
  198.     $application $event->getForm()->getData();
  199.     $data $application->getPaymentData();
  200.     if (!isset($data['response']) || empty($data['response'])) {
  201.       $event->getForm()->addError(
  202.         new FormError($this->translator->trans('payment.error_select_payment'))
  203.       );
  204.     }
  205.   }
  206.   /**
  207.    * @param Pratica $pratica
  208.    * @param $url
  209.    * @return string
  210.    */
  211.   private function generatePaymentButtonsPratica $pratica$url )
  212.   {
  213.     $urlAvviso htmlspecialchars_decode($url['urlFileAvviso']);
  214.     $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>';
  215.     $buttons .= "<p class='mt-5'>".$this->translator->trans('gateway.mypay.redirect_text', ['%gateway_name%' => 'MyPay'])."</p><div class='text-center mt-5'><a href='{$url['url']}' class='btn btn-lg btn-primary'>".$this->translator->trans('gateway.mypay.redirect_button')."</a></div>";
  216.     $buttons .= "<p class='mt-5'>".$this->translator->trans('gateway.mypay.download_text')."</p><div class='text-center mt-5'><a href='{$urlAvviso}' class='btn btn-lg btn-secondary'>".$this->translator->trans('gateway.mypay.download_button')."</a></div>";
  217.     return $buttons;
  218.   }
  219. }