PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/module/Payment/src/Controller/IndexController.php

https://bitbucket.org/omelnic/s0m
PHP | 124 lines | 83 code | 20 blank | 21 comment | 3 complexity | 37dd6d3e86a36c2f62a90048beda6b10 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. <?php
  2. namespace Payment\Controller;
  3. use Payment\Entity\PaymentStatus;
  4. use Application\Entity\User\UserAbstract;
  5. use Payment\Service\Payment;
  6. use Payment\Form\PaymentForm;
  7. use Payment\Service\PaymentFormFields;
  8. use S0mWeb\WTL\StdLib\ServiceLocatorAwareInterface;
  9. use S0mWeb\WTL\StdLib\ServiceLocatorAwareTrait;
  10. use Zend\Mvc\Controller\AbstractActionController;
  11. use Zend\View\Model\ViewModel;
  12. /**
  13. * Class PaymentController
  14. *
  15. * @author nonick <web@nonick.name>
  16. */
  17. class IndexController extends AbstractActionController implements ServiceLocatorAwareInterface
  18. {
  19. use ServiceLocatorAwareTrait;
  20. public function indexAction()
  21. {
  22. return $this->notFoundAction();
  23. }
  24. public function confirmationAction()
  25. {
  26. /** @var PaymentForm $paymentForm */
  27. $paymentForm = $this->getServiceLocator()->get(PaymentForm::class);
  28. /** @var PaymentFormFields $paymentFormFields */
  29. $paymentFormFields = $this->getServiceLocator()->get(PaymentFormFields::class);
  30. $paymentData = [
  31. 'access_key' => $paymentFormFields->getAccessKey(), // R - ключ доступа к платежному терминалу
  32. 'profile_id' => $paymentFormFields->getProfileId(), // R - id активного профиля
  33. 'transaction_uuid' => uniqid(), // R - уникальный ключ для каждой транзакци создаваемый на нашей стороне, для проверки повторных попыток оплаты (на стороне cybersource)
  34. 'signed_field_names' => $paymentFormFields->getSignedFields(), // R - список полей учавствующих в подписи
  35. 'unsigned_field_names' => '', // поля исключаемые из подписи
  36. 'signed_date_time' => gmdate("Y-m-d\TH:i:s\Z"), // R - дата и время генерации подписи, учавствует в проверке кол-ва попытак повторных оплат транзакци
  37. 'transaction_type' => 'sale', // R - тип транзакции, authorization - как бы отложенная покупка, sale - мгновеная продажа товара, мануал стр. 14 пункт 4 (для уточнения)
  38. 'locale' => 'en', // R - локаль
  39. 'reference_number' => time(), // R - номер заказа, уникальный, по большому счету id счета в нашей системе
  40. 'amount' => 19.00, // R - float - сумма транзакции
  41. 'currency' => 'USD', // R - валюта транзакции
  42. 'signature' => '', // R - подпись, хеш по подписываемым полям
  43. ];
  44. $paymentData['signature'] = $paymentFormFields->getSignature($paymentData);
  45. $paymentForm->setData($paymentData);
  46. $paymentForm->setAttribute('action', $paymentFormFields->getEndpoint());
  47. if (!$paymentForm->isValid()) {
  48. return $this->redirect()->toRoute('payment/invalidForm');
  49. }
  50. $viewModel = new ViewModel();
  51. $viewModel->setVariable('form', $paymentForm);
  52. return $viewModel;
  53. }
  54. public function receiptAction()
  55. {
  56. $writer = new \Zend\Log\Writer\Stream(getcwd().'/data/logs/payments.log');
  57. $logger = new \Zend\Log\Logger();
  58. $logger->addWriter($writer);
  59. /**
  60. * 1. Проверяем ответ от сервера
  61. * 1.1 Оплата прошла успешно - изменяем счет и пользователя (создаем пользователя)
  62. * 1.2 От оплаты отказались - переводим счет в отмененный
  63. * 2. Перенаправляем пользователя в ЛК
  64. */
  65. $paymentsParams = $this->params()->fromPost();
  66. /** @var PaymentFormFields $paymentFormFields */
  67. $paymentFormFields = $this->getServiceLocator()->get(PaymentFormFields::class);
  68. $params = [];
  69. foreach ($paymentsParams as $key => $value) {
  70. $params[$key] = $value;
  71. }
  72. $signature = $paymentFormFields->getSignature($params);
  73. if ($params['signature'] != $signature) {
  74. return $this->redirect()->toRoute('payment/paymentError');
  75. }
  76. /** @var Payment $paymentService */
  77. $paymentService = $this->getServiceLocator()->get(Payment::class);
  78. /** @var PaymentStatus $status */
  79. $status = PaymentStatus::createFromScalar($params['decision']);
  80. $payment = $paymentService->insertPaymentLog($params);
  81. switch($status->getValue()) {
  82. case PaymentStatus::STATUS_ACCEPT:
  83. /** @var UserAbstract $user */
  84. // $user = $this->auth()->getIdentity();
  85. // $user->setPremium();
  86. break;
  87. case PaymentStatus::STATUS_CANCEL: // пользователь отменил транзакцию
  88. case PaymentStatus::STATUS_DECLINE: // транзакция отклонена (не заполнены все обязательные поля или проблемы при оплате)
  89. case PaymentStatus::STATUS_ERROR: // доступ запрещен или страница не найдена
  90. case PaymentStatus::STATUS_REVIEW: // транзакция отменена, но "оплата" все ещё может прийти (скорее всего, что-то типа задержки ответа, вероятно ответ от сервера может прийти на этот коллбэк постом в любое время, нужно разобраться и обработаь ситуевину)
  91. // Authorization was declined; however, the capture may still be possible. Review payment details.
  92. // по идее у нас все залогировано, сообщаем пользователю что произошла ошибка, выводим id транзакции и счета, пусть свяжеться с сапортом
  93. break;
  94. }
  95. $viewModel = new ViewModel();
  96. $viewModel->setVariables(
  97. [
  98. 'result' => $status->getValue(),
  99. 'payment' => $payment,
  100. ]
  101. );
  102. return $viewModel;
  103. }
  104. }