Skip to content

Commit

Permalink
Implemented success story
Browse files Browse the repository at this point in the history
  • Loading branch information
SilverFire committed May 21, 2019
1 parent 32b9724 commit da2a11b
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 27 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
}
],
"require": {
"php": ">=7.1",
"ext-json": "*",
"omnipay/common": "~2.3",
"yandex-money/yandex-checkout-sdk-php": "^1.2.1"
},
Expand Down
58 changes: 35 additions & 23 deletions src/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@

namespace Omnipay\YandexKassa;

use Guzzle\Http\ClientInterface;
use Omnipay\Common\AbstractGateway;
use Omnipay\Common\Message\AbstractRequest;
use Omnipay\YandexKassa\Message\AuthenticateRequest;
use Omnipay\YandexKassa\Message\CompletePurchaseRequest;
use Omnipay\YandexKassa\Message\CaptureRequest;
use Omnipay\YandexKassa\Message\CaptureResponse;
use Omnipay\YandexKassa\Message\DetailsRequest;
use Omnipay\YandexKassa\Message\DetailsResponse;
use Omnipay\YandexKassa\Message\IncomingNotificationRequest;
use Omnipay\YandexKassa\Message\PurchaseRequest;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
use YandexCheckout\Client;

/**
Expand All @@ -26,6 +28,24 @@
*/
class Gateway extends AbstractGateway
{
/** @var Client|null */
private $yandexClient;

public function __construct(ClientInterface $httpClient = null, HttpRequest $httpRequest = null)
{
parent::__construct($httpClient, $httpRequest);
}

protected function getYandexClient(): Client
{
if ($this->yandexClient === null) {
$this->yandexClient = new Client();
$this->yandexClient->setAuth($this->getShopId(), $this->getSecret());
}

return $this->yandexClient;
}

public function getName()
{
return 'Yandex.Kassa';
Expand Down Expand Up @@ -57,48 +77,40 @@ public function setSecret($value)
*/
public function purchase(array $parameters = [])
{
return $this->createRequest(PurchaseRequest::class, array_merge($parameters, [
'yandexClient' => $this->buildYandexClient($parameters),
]));
return $this->createRequest(PurchaseRequest::class, $this->injectYandexClient($parameters));
}

/**
* @param array $parameters
* @return CompletePurchaseRequest|\Omnipay\Common\Message\AbstractRequest
* @return CaptureResponse|\Omnipay\Common\Message\AbstractRequest
*/
public function completePurchase(array $parameters = [])
public function capture(array $parameters = [])
{
return $this->createRequest(CompletePurchaseRequest::class, $parameters);
return $this->createRequest(CaptureRequest::class, $this->injectYandexClient($parameters));
}

/**
* @param array $parameters
* @return \Omnipay\Common\Message\AbstractRequest|DetailsResponse
* @return \Omnipay\Common\Message\AbstractRequest|DetailsRequest
*/
public function details(array $parameters = [])
{
if (!isset($parameters['access_token'])) {
$authentication = $this->authenticate($parameters)->send();
$parameters['access_token'] = $authentication->getAccessToken();
}

return $this->createRequest(DetailsRequest::class, $parameters);
return $this->createRequest(DetailsRequest::class, $this->injectYandexClient($parameters));
}

/**
* @param array $parameters
* @return AuthenticateRequest|AbstractRequest
* @return \Omnipay\Common\Message\AbstractRequest|DetailsResponse
*/
public function authenticate(array $parameters = [])
public function notification(array $parameters = [])
{
return $this->createRequest(AuthenticateRequest::class, $parameters);
return $this->createRequest(IncomingNotificationRequest::class, $this->injectYandexClient($parameters));
}

private function buildYandexClient(array $parameters): Client
private function injectYandexClient(array $parameters): array
{
$client = new Client();
$client->setAuth($this->getShopId(), $this->getSecret());
$parameters['yandexClient'] = $this->getYandexClient();

return $client;
return $parameters;
}
}
50 changes: 50 additions & 0 deletions src/Message/CaptureRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
* Yandex.Kassa driver for Omnipay payment processing library
*
* @link https://github.com/hiqdev/omnipay-yandex-kassa
* @package omnipay-yandex-kassa
* @license MIT
* @copyright Copyright (c) 2019, HiQDev (http://hiqdev.com/)
*/

namespace Omnipay\YandexKassa\Message;

use Omnipay\Common\Exception\InvalidRequestException;
use Throwable;

/**
* Class CompletePurchaseRequest.
*
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
*/
class CaptureRequest extends AbstractRequest
{
public function getData()
{
$this->validate('shopId', 'secret', 'transactionId', 'transactionReference', 'amount', 'currency');

return $this->httpRequest->request->all();
}

/**
* @param mixed $data
* @return \Omnipay\Common\Message\ResponseInterface|CaptureResponse
* @throws InvalidRequestException
*/
public function sendData($data)
{
try {
$result = $this->client->capturePayment([
'amount' => [
'value' => $this->getAmount(),
'currency' => $this->getCurrency(),
],
], $this->getTransactionReference(), 'capture-' . $this->getTransactionId());

return $this->response = new CaptureResponse($this, $result);
} catch (Throwable $e) {
throw new InvalidRequestException('Failed to capture payment: ' . $e->getMessage(), 0, $e);
}
}
}
33 changes: 33 additions & 0 deletions src/Message/CaptureResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* Yandex.Kassa driver for Omnipay payment processing library
*
* @link https://github.com/hiqdev/omnipay-yandex-kassa
* @package omnipay-yandex-kassa
* @license MIT
* @copyright Copyright (c) 2019, HiQDev (http://hiqdev.com/)
*/

namespace Omnipay\YandexKassa\Message;

use Omnipay\Common\Exception\InvalidResponseException;
use YandexCheckout\Model\PaymentStatus;
use YandexCheckout\Request\Payments\Payment\CreateCaptureResponse;

/**
* Class CaptureResponse
*
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
* @property CreateCaptureResponse $data
*/
class CaptureResponse extends DetailsResponse
{
protected function ensureResponseIsValid(): void
{
parent::ensureResponseIsValid();

if ($this->getState() !== PaymentStatus::SUCCEEDED) {
throw new InvalidResponseException(sprintf('Failed to capture payment "%s"', $this->getTransactionReference()));
}
}
}
42 changes: 42 additions & 0 deletions src/Message/DetailsRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Omnipay\YandexKassa\Message;

use Omnipay\Common\Exception\InvalidResponseException;
use Omnipay\Common\Message\ResponseInterface;

/**
* Class DetailsRequest
*
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
*/
class DetailsRequest extends AbstractRequest
{
public function getData()
{
$this->validate('transactionReference');

return [];
}

/**
* Send the request with specified data
*
* @param mixed $data The data to send
* @return DetailsResponse|ResponseInterface
* @throws InvalidResponseException
*/
public function sendData($data): ResponseInterface
{
try {
$response = $this->client->getPaymentInfo($this->getTransactionReference());

return new DetailsResponse($this, $response);
} catch (\Throwable $e) {
throw new InvalidResponseException(
'Error communicating with payment gateway: ' . $e->getMessage(),
$e->getCode()
);
}
}
}
90 changes: 90 additions & 0 deletions src/Message/DetailsResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace Omnipay\YandexKassa\Message;

use Omnipay\Common\Exception\InvalidResponseException;
use Omnipay\Common\Message\AbstractResponse;
use Omnipay\Common\Message\RequestInterface;
use YandexCheckout\Model\PaymentInterface;

/**
* Class DetailsResponse
*
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
* @property PaymentInterface $data
*/
class DetailsResponse extends AbstractResponse
{
/**
* @return RequestInterface|DetailsRequest
*/
public function getRequest()
{
return parent::getRequest();
}

public function __construct(RequestInterface $request, PaymentInterface $payment)
{
parent::__construct($request, $payment);

$this->ensureResponseIsValid();
}

protected function ensureResponseIsValid(): void
{
if ($this->getTransactionId() === null) {
throw new InvalidResponseException(sprintf(
'Transaction ID is missing in payment "%s"',
$this->getTransactionReference()
));
}
}

/**
* Is the response successful?
*
* @return boolean
*/
public function isSuccessful(): bool
{
return $this->data->paid;
}

public function getAmount(): string
{
return $this->data->getAmount()->getValue();
}

public function getCurrency(): string
{
return $this->data->getAmount()->getCurrency();
}

public function getPaymentDate(): \DateTime
{
return $this->data->getCreatedAt();
}

public function getTransactionReference(): string
{
return $this->data->getId();
}

public function getTransactionId(): ?string
{
return $this->data->getMetadata()['transactionId'] ?? null;
}

public function getState(): string
{
return $this->data->getStatus();
}

public function getPayer(): string
{
$method = $this->data->getPaymentMethod();

return $method->getTitle();
}

}
40 changes: 40 additions & 0 deletions src/Message/IncomingNotificationRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Omnipay\YandexKassa\Message;

use Omnipay\Common\Exception\InvalidResponseException;
use Omnipay\Common\Message\ResponseInterface;

/**
* Class IncomingNotificationRequest
*
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
*/
class IncomingNotificationRequest extends AbstractRequest
{
public function getData()
{
$body = $this->httpRequest->getContent();

return json_decode($body, true);
}

/**
* Send the request with specified data
*
* @param mixed $data The data to send
* @return ResponseInterface
* @throws InvalidResponseException
*/
public function sendData($data): ResponseInterface
{
try {
return new IncomingNotificationResponse($this, $data);
} catch (\Throwable $e) {
throw new InvalidResponseException(
'Error communicating with payment gateway: ' . $e->getMessage(),
$e->getCode()
);
}
}
}
Loading

0 comments on commit da2a11b

Please sign in to comment.