diff --git a/composer.json b/composer.json index f9ef685..82ddaa6 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "leonardjke/omnipay-yoomoney", "type": "library", - "description": "YooMoney driver for Omnipay PHP payment library", + "description": "Yoomoney driver for Omnipay PHP payment library", "keywords": [ "php", "omnipay", diff --git a/src/Gateway.php b/src/Gateway.php index a19bc01..5f2302f 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -1,19 +1,12 @@ '', 'receiver' => '', 'quickpay_form' => 'shop', + // shop — для универсальной формы, small — для кнопки, donate — для «благотворительной» формы 'payment_type' => 'PC', + // PC - оплата из кошелька ЮMoney, AC - с банковской карты, MC - с баланса мобильного 'success_url' => null, 'targets' => null, + // Необязательный параметр (название магазина) 'need_fio' => false, 'need_email' => false, 'need_phone' => false, @@ -50,121 +48,6 @@ public function getDefaultParameters() ]; } - public function setSecret($value) - { - return $this->setParameter('secret', $value); - } - - public function getSecret() - { - return $this->getParameter('secret'); - } - - public function setReceiver($value) - { - return $this->setParameter('receiver', $value); - } - - public function getReceiver() - { - return $this->getParameter('receiver'); - } - - /** - * @param string $value shop — для универсальной формы, small — для кнопки, donate — для «благотворительной» формы - * - * @return Gateway - */ - public function setQuickpayForm($value) - { - return $this->setParameter('quickpay_form', $value); - } - - public function getQuickpayForm() - { - return $this->getParameter('quickpay_form'); - } - - /** - * @param string $value PC - оплата из кошелька ЮMoney, AC - с банковской карты, MC - с баланса мобильного - * - * @return Gateway - */ - public function setPaymentType($value) - { - return $this->setParameter('payment_type', $value); - } - - public function getPaymentType() - { - return $this->getParameter('payment_type'); - } - - public function setSuccessUrl($value) - { - return $this->setParameter('success_url', $value); - } - - public function getSuccessUrl() - { - return $this->getParameter('success_url'); - } - - public function setNeedFio($value) - { - return $this->setParameter('need_fio', $value); - } - - public function getNeedFio() - { - return $this->getParameter('need_fio'); - } - - public function setNeedEmail($value) - { - return $this->setParameter('need_email', $value); - } - - public function getNeedEmail() - { - return $this->getParameter('need_email'); - } - - public function setNeedPhone($value) - { - return $this->setParameter('need_phone', $value); - } - - public function getNeedPhone() - { - return $this->getParameter('need_phone'); - } - - public function setNeedAddress($value) - { - return $this->setParameter('need_address', $value); - } - - public function getNeedAddress() - { - return $this->getParameter('need_address'); - } - - /** - * @param string $value Необязательный параметр (название магазина) - * - * @return Gateway - */ - public function setTargets($value) - { - return $this->setParameter('targets', $value); - } - - public function getTargets() - { - return $this->getParameter('targets'); - } - /** * @param array $parameters * @@ -191,24 +74,11 @@ public function completePurchase(array $parameters = []) * Handle notification callback. * Replaces completeAuthorize() and completePurchase() * - * @return \Omnipay\Common\Message\AbstractRequest|ServerNotifyRequest + * @return \Omnipay\Common\Message\NotificationInterface */ - public function acceptNotification(array $parameters = array()) + public function acceptNotification(array $parameters = []) { - return $this->createRequest(ServerNotifyRequest::class, $parameters); + return $this->createRequest(NotificationRequest::class, $parameters); } - - public function __call1($name, $arguments) - { - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface authorize(array $options = array()) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface completeAuthorize(array $options = array()) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface capture(array $options = array()) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface refund(array $options = array()) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface fetchTransaction(array $options = []) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface void(array $options = array()) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface createCard(array $options = array()) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface updateCard(array $options = array()) - // TODO: Implement @method \Omnipay\Common\Message\RequestInterface deleteCard(array $options = array()) - } } diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php index a6cf8d4..3728429 100644 --- a/src/Message/AbstractRequest.php +++ b/src/Message/AbstractRequest.php @@ -3,129 +3,16 @@ namespace Omnipay\Yoomoney\Message; use Omnipay\Common\Message\AbstractRequest as OmnipayRequest; +use Omnipay\Yoomoney\Traits\Parametrable; abstract class AbstractRequest extends OmnipayRequest { + use Parametrable; + public $endpoint = 'https://yoomoney.ru/quickpay/confirm.xml'; public function getEndpoint() { return $this->endpoint; } - - public function setSecret($value) - { - return $this->setParameter('secret', $value); - } - - public function getSecret() - { - return $this->getParameter('secret'); - } - - public function setReceiver($value) - { - return $this->setParameter('receiver', $value); - } - - public function getReceiver() - { - return $this->getParameter('receiver'); - } - - /** - * @param string $value shop — для универсальной формы, small — для кнопки, donate — для «благотворительной» формы - * - * @return AbstractRequest - */ - public function setQuickpayForm($value) - { - return $this->setParameter('quickpay_form', $value); - } - - public function getQuickpayForm() - { - return $this->getParameter('quickpay_form'); - } - - /** - * @param string $value PC - оплата из кошелька ЮMoney, AC - с банковской карты, MC - с баланса мобильного - * - * @return AbstractRequest - */ - public function setPaymentType($value) - { - return $this->setParameter('payment_type', $value); - } - - public function getPaymentType() - { - return $this->getParameter('payment_type'); - } - - public function setSuccessUrl($value) - { - return $this->setParameter('success_url', $value); - } - - public function setReturnUrl($value) - { - return $this->setParameter('success_url', $value); - } - - public function getSuccessUrl() - { - return $this->getParameter('success_url'); - } - - public function setNeedFio($value) - { - return $this->setParameter('need_fio', $value); - } - - public function getNeedFio() - { - return $this->getParameter('need_fio'); - } - - public function setNeedEmail($value) - { - return $this->setParameter('need_email', $value); - } - - public function getNeedEmail() - { - return $this->getParameter('need_email'); - } - - public function setNeedPhone($value) - { - return $this->setParameter('need_phone', $value); - } - - public function getNeedPhone() - { - return $this->getParameter('need_phone'); - } - - public function setNeedAddress($value) - { - return $this->setParameter('need_address', $value); - } - - public function getNeedAddress() - { - return $this->getParameter('need_address'); - } - - public function setTargets($value) - { - return $this->setParameter('targets', $value); - } - - public function getTargets() - { - return $this->getParameter('targets'); - } - } diff --git a/src/Message/NotificationRequest.php b/src/Message/NotificationRequest.php new file mode 100644 index 0000000..5aa97e4 --- /dev/null +++ b/src/Message/NotificationRequest.php @@ -0,0 +1,260 @@ +data)) + { + return $this->data; + } + + return $this->data = $this->httpRequest->query->all(); + } + + /** + * @inheritdoc + */ + public function getTransactionStatus() + { + if (!$this->isValid()) + { + return self::STATUS_FAILED; + } + + if ($this->getUnaccepted()) + { + return self::STATUS_PENDING; + } + + if ($this->getCodePro()) + { + return self::STATUS_PENDING; + } + + return self::STATUS_COMPLETED; + } + + /** + * @inheritdoc + */ + public function getMessage() + { + if (!$this->isValid()) + { + return self::HASH_ERROR; // Хэш не совпадает + } + + if ($this->getUnaccepted()) + { + return self::UNACCEPTED; // Перевод еще не зачислен. Получателю нужно освободить место в кошельке + } + + if ($this->getCodePro()) + { + return self::PROTECTED; // Перевод защищен кодом протекции + } + + return null; + } + + public function isValid() + { + return $this->getSignature() === $this->buildSignature(); + } + + private function getSignature() + { + return $this->getSha1Hash(); + } + + private function buildSignature() + { + $params = [ + $this->getDataItem('notification_type'), + $this->getDataItem('operation_id'), + $this->getDataItem('amount'), + $this->getDataItem('currency'), + $this->getDataItem('datetime'), + $this->getDataItem('sender'), + $this->getDataItem('codepro'), + $this->getSecret(), + $this->getDataItem('label', ''), + ]; + + return hash('sha1', implode("&", $params)); + } + + protected function getDataItem($name, $default = null) + { + $data = $this->getData(); + + return $data[$name] ?? $default; + } + + public function getLabel() + { + return $this->getTransactionId(); + } + + public function getAccount() + { + return $this->getTransactionId(); + } + + public function getTransactionId() + { + return $this->getDataItem('label'); + } + + public function getTransactionReference() + { + return $this->getDataItem('operation_id'); + } + + public function getOperationId() + { + return $this->getTransactionReference(); + } + + public function getAmount() + { + return $this->formatCurrency($this->getDataItem('amount', 0)); + } + + public function getWithdrawAmount() + { + return $this->formatCurrency($this->getDataItem('withdraw_amount', 0)); + } + + public function getCurrency() + { + return 'RUB'; + } + + public function getNotificationType() + { + return $this->getDataItem('notification_type'); + } + + public function getBillId() + { + return $this->getDataItem('bill_id'); + } + + public function getCodePro() + { + return filter_var($this->getDataItem('codepro'), FILTER_VALIDATE_BOOLEAN); + } + + public function getUnaccepted() + { + return filter_var($this->getDataItem('unaccepted'), FILTER_VALIDATE_BOOLEAN); + } + + public function getDatetime() + { + return $this->getDataItem('datetime'); + } + + public function getSender() + { + return $this->getDataItem('sender'); + } + + public function getSha1Hash() + { + return $this->getDataItem('sha1_hash'); + } + + public function getOperationLabel() + { + return $this->getDataItem('operation_label'); + } + + public function getTestMode() + { + return filter_var($this->getDataItem('test_notification', false), FILTER_VALIDATE_BOOLEAN); + } + + public function getLastName() + { + return $this->getDataItem('lastname'); + } + + public function getFirstname() + { + return $this->getDataItem('firstname'); + } + + public function getFathersname() + { + return $this->getDataItem('fathersname'); + } + + public function getEmail() + { + return $this->getDataItem('email'); + } + + public function getPhone() + { + return $this->getDataItem('phone'); + } + + public function getCity() + { + return $this->getDataItem('city'); + } + + public function getStreet() + { + return $this->getDataItem('street'); + } + + public function getBuilding() + { + return $this->getDataItem('building'); + } + + public function getSuite() + { + return $this->getDataItem('suite'); + } + + public function getFlat() + { + return $this->getDataItem('flat'); + } + + public function getZip() + { + return $this->getDataItem('zip'); + } + + public function getSecret() + { + return $this->getParameter('secret'); + } + + public function setReceiver($value) + { + return $this->setParameter('receiver', $value); + } + + public function sendData($data) + { + return $this; + } +} diff --git a/src/Message/ServerNotifyRequest.php b/src/Message/ServerNotifyRequest.php deleted file mode 100644 index 487e74c..0000000 --- a/src/Message/ServerNotifyRequest.php +++ /dev/null @@ -1,99 +0,0 @@ -data = $httpRequest->request->all(); - } - - public function getData() - { - if (!$this->isValid()) { - throw new InvalidResponseException("Callback hash does not match expected value"); - } - - return $this->data; - } - - public function sendData($data) - { - return $this->data; - } - - public function isValid() - { - return $this->getSignature() === $this->buildSignature(); - } - - /** - * Alias for isValid - */ - public function isSuccessful() - { - return $this->isValid(); - } - - private function getSignature() - { - return $this->getSha1Hash(); - } - - private function buildSignature() - { - $params = [ - $this->getDataItem('notification_type'), - $this->getDataItem('operation_id'), - $this->getDataItem('amount'), - $this->getDataItem('currency'), - $this->getDataItem('datetime'), - $this->getDataItem('sender'), - $this->getDataItem('codepro'), - $this->getSecret(), - $this->getDataItem('label', ''), - ]; - - return hash('sha1', implode("&", $params)); - } - - /** - * Was the transaction successful? - * - * @return string Transaction status, one of {@see STATUS_COMPLETED}, {@see #STATUS_PENDING}, - * or {@see #STATUS_FAILED}. - */ - public function getTransactionStatus() - { - if (!$this->isValid()) { - return self::STATUS_FAILED; - } - - $isUnaccepted = $this->getUnaccepted(); - - return filter_var($isUnaccepted, FILTER_VALIDATE_BOOL) ? - self::STATUS_PENDING : self::STATUS_COMPLETED; - } - - public function getMessage() - { - if (!$this->isValid()) { - return sprintf('Callback hash does not match expected value'); - } - - return ''; - } -} diff --git a/src/Traits/Parametrable.php b/src/Traits/Parametrable.php new file mode 100644 index 0000000..a7c857f --- /dev/null +++ b/src/Traits/Parametrable.php @@ -0,0 +1,125 @@ +setParameter('secret', $value); + } + + public function getSecret() + { + return $this->getParameter('secret'); + } + + public function setReceiver($value) + { + return $this->setParameter('receiver', $value); + } + + public function getReceiver() + { + return $this->getParameter('receiver'); + } + + /** + * @param string $value shop — для универсальной формы, small — для кнопки, donate — для «благотворительной» формы + * + * @return Gateway + */ + public function setQuickpayForm($value) + { + return $this->setParameter('quickpay_form', $value); + } + + public function getQuickpayForm() + { + return $this->getParameter('quickpay_form'); + } + + /** + * @param string $value PC - оплата из кошелька ЮMoney, AC - с банковской карты, MC - с баланса мобильного + * + * @return Gateway + */ + public function setPaymentType($value) + { + return $this->setParameter('payment_type', $value); + } + + public function getPaymentType() + { + return $this->getParameter('payment_type'); + } + + public function setSuccessUrl($value) + { + return $this->setParameter('success_url', $value); + } + + public function getSuccessUrl() + { + return $this->getParameter('success_url'); + } + + public function setNeedFio($value) + { + return $this->setParameter('need_fio', $value); + } + + public function getNeedFio() + { + return $this->getParameter('need_fio'); + } + + public function setNeedEmail($value) + { + return $this->setParameter('need_email', $value); + } + + public function getNeedEmail() + { + return $this->getParameter('need_email'); + } + + public function setNeedPhone($value) + { + return $this->setParameter('need_phone', $value); + } + + public function getNeedPhone() + { + return $this->getParameter('need_phone'); + } + + public function setNeedAddress($value) + { + return $this->setParameter('need_address', $value); + } + + public function getNeedAddress() + { + return $this->getParameter('need_address'); + } + + /** + * @param string $value Необязательный параметр (название магазина) + * + * @return Gateway + */ + public function setTargets($value) + { + return $this->setParameter('targets', $value); + } + + public function getTargets() + { + return $this->getParameter('targets'); + } + +} diff --git a/src/Traits/ResponseFieldsTrait.php b/src/Traits/ResponseFieldsTrait.php deleted file mode 100644 index 217f9a0..0000000 --- a/src/Traits/ResponseFieldsTrait.php +++ /dev/null @@ -1,161 +0,0 @@ -data[$name]) ? $this->data[$name] : $default; - } - - public function getLabel() - { - return $this->getTransactionId(); - } - - public function getAccount() - { - return $this->getTransactionId(); - } - - public function getTransactionId() - { - return $this->getDataItem('label'); - } - - public function getTransactionReference() - { - return $this->getDataItem('operation_id'); - } - - public function getOperationId() - { - return $this->getTransactionReference(); - } - - public function getAmount() - { - return $this->formatCurrency($this->getDataItem('amount', 0)); - } - - public function getWithdrawAmount() - { - return $this->formatCurrency($this->getDataItem('withdraw_amount', 0)); - } - - public function getCurrency() - { - return 'RUB'; - } - - public function getNotificationType() - { - return $this->getDataItem('notification_type'); - } - - public function getBillId() - { - return $this->getDataItem('bill_id'); - } - - public function getCodePro() - { - return $this->getDataItem('codepro'); - } - - public function getUnaccepted() - { - return $this->getDataItem('unaccepted'); - } - - public function getDatetime() - { - return $this->getDataItem('datetime'); - } - - public function getSender() - { - return $this->getDataItem('sender'); - } - - public function getSha1Hash() - { - return $this->getDataItem('sha1_hash'); - } - - public function getOperationLabel() - { - return $this->getDataItem('operation_label'); - } - - public function getTestMode() - { - return $this->getDataItem('test_notification', false); - } - - public function getLastName() - { - return $this->getDataItem('lastname'); - } - - public function getFirstname() - { - return $this->getDataItem('firstname'); - } - - public function getFathersname() - { - return $this->getDataItem('fathersname'); - } - - public function getEmail() - { - return $this->getDataItem('email'); - } - - public function getPhone() - { - return $this->getDataItem('phone'); - } - - public function getCity() - { - return $this->getDataItem('city'); - } - - public function getStreet() - { - return $this->getDataItem('street'); - } - - public function getBuilding() - { - return $this->getDataItem('building'); - } - - public function getSuite() - { - return $this->getDataItem('suite'); - } - - public function getFlat() - { - return $this->getDataItem('flat'); - } - - public function getZip() - { - return $this->getDataItem('zip'); - } - -}