Skip to content

Платежи через Яндекс.Кассу с поддержкой 54-ФЗ

License

Notifications You must be signed in to change notification settings

appwilio/yakassa

Repository files navigation

Пакет для работы с Юмани.Кассой (бывшая Яндекс.Касса)

Latest Version on Packagist Testing Quality Score Code Coverage StyleCI Total Downloads License MIT

Ранняя альфа, использовать осторожно!

Возможности:

  • создание платёжной формы;
  • передача данных согласно 54-ФЗ;
  • обработка уведомлений checkOrder и paymentAviso.

Требования:

  • php >= 7.1
  • Laravel >= 5.3

Установка

composer require appwilio/yakassa

Подключение сервис-провайдера:

// config/app.php
'providers' => [
    ...
    Appwilio\YaKassa\YaKassaServiceProvider::class,
],

Настройки:

Описание параметров.

// config/services.php
...
'yakassa' => [
    'test_mode'     => env('YAKASSA_TEST_MODE', true),
    'shop_id'       => env('YAKASSA_SHOP_ID', ''),
    'showcase_id'   => env('YAKASSA_SHOWCASE_ID', ''),
    'shop_password' => env('YAKASSA_SHOP_PASSWORD', ''),        
],
...

Подготовка основных данных для платёжной формы

Заказ должен имплементировать интерфейс \Appwilio\YaKassa\Contracts\YaKassaOrder:

use Appwilio\YaKassa\Contracts\YaKassaOrder;

class Order implements YaKassaOrder
{
    public function getOrderSum(): float
    {
        return $this->total;
    }
    
    public function getCustomerNumber(): string
    {
        return $this->customer->id;
    }
    
    public function getOrderNumber(): ?string
    {
        return $this->id;
    }
    
    public function getPaymentType(): ?string
    {
        return 'PC';
    }
    
    public function getCustomerEmail(): ?string
    {
        return $this->customer->email;
    }
    
    public function getCustomerPhone(): ?string
    {
        return $this->customer->phone;
    }
}

Дополнительные данные согласно требованиям 54-ФЗ

Внимание! Протокол дополняется, текущая версия 2.1. Общая информация, описание изменений.

Заказ должен имплементировать интерфейс \Appwilio\YaKassa\Contracts\YaKassaOrder54FZ:

use Appwilio\YaKassa\Contracts\YaKassaOrder54FZ;

class Order implements YaKassaOrder54FZ
{
    public function getOrderSum(): float
    {
        return $this->total;
    }
    
    public function getCustomerNumber(): string
    {
        return $this->customer->id;
    }
    
    public function getItems(): iterable
    {
        return $this->items; // товары/услуги в заказе
    }
    
    public function getTaxSystem(): ?int
    {
        return YaKassaOrder54FZ::TAX_OSN;
    }
    
    public function getCustomerContact(): string
    {
        return $this->customer->phone;
    }
        
    public function getOrderNumber(): ?string
    {
        return $this->id;
    }
    
    public function getPaymentType(): ?string
    {
        return 'PC';
    }
    
    public function getCustomerEmail(): ?string
    {
        return $this->customer->email;
    }
    
    public function getCustomerPhone(): ?string
    {
        return $this->customer->phone;
    }
}

Каждая позиция заказа должна имплементировать интерфейс \Appwilio\YaKassa\Contracts\YaKassaOrderItem54FZ:

use Appwilio\YaKassa\Contracts\YaKassaOrderItem54FZ;

class OrderItem implements YaKassaOrderItem54FZ
{
    public function getAmount(): float
    {
        return $this->amount;
    }

    public function getQuantity(): float
    {
        return $this->quantity;
    }

    public function getTaxRate(): int
    {
        return YaKassaOrderItem54FZ::VAT_18;
    }

    public function getCurrency(): ?string
    {
        return null; // равнозначно RUB
    }

    public function getTitle(): string
    {
        return $this->product->title;
    }
}

Создание платёжной формы

В контролллере:

use Appwilio\YaKassa\YaKassa;

class OrdersController
{
    public function showPaymentForm(YaKassa $kassa, $orderId)
    {
        $order = Order::find($orderId);
        
        $paymentForm = $kassa->buildPaymentForm($order);
        
        return view('payment', ['form' => $paymentForm]);
    }    
}

В шаблоне:

<form method="POST" action="{{ $form->getPaymentUrl() }}">
    @foreach ($form->toArray() as $k => $v) 
        <input type="hidden" name="{{ $k }}" value="{{ $v }}" />
    @endforeach
    
    ...
</form>

Обработка уведомлений

Общее описание механизма уведомлений

use Appwilio\YaKassa\YaKassa;

class YaHookController extends Controller
{
    public function checkOrder(YaKassa $kassa)
    {
        $order = Order::find($kassa->getRequest()->getOrderNumber());

        if (! $order) {
            return $kassa->responseDeclined();
        }

        // используем реальное значение суммы заказа, а не присланное Я.Кассой
        $kassa->setGenuineOrderSumAmount($order->total);

        if (! $kassa->verify()) {
            return $kassa->responseUnauthorized();
        }

        return $kassa->responseAccepted();
    }
}