README.md
<img src="https://banners.beyondco.de/Yandex%20Checkout.png?theme=light&packageName=orkhanahmadov%2Fyandex-checkout&pattern=architect&style=style_1&description=YooMoney+%28Yandex+Checkout%29+integration+package+for+Laravel&md=1&showWatermark=0&fontSize=100px&images=credit-card&widths=200&heights=200" />
[![Latest Stable Version](https://poser.pugx.org/orkhanahmadov/yandex-checkout/v/stable)](https://packagist.org/packages/orkhanahmadov/yandex-checkout)
[![Latest Unstable Version](https://poser.pugx.org/orkhanahmadov/yandex-checkout/v/unstable)](https://packagist.org/packages/orkhanahmadov/yandex-checkout)
[![Total Downloads](https://img.shields.io/packagist/dt/orkhanahmadov/yandex-checkout)](https://packagist.org/packages/orkhanahmadov/yandex-checkout)
[![GitHub license](https://img.shields.io/github/license/orkhanahmadov/yandex-checkout.svg)](https://github.com/orkhanahmadov/yandex-checkout/blob/master/LICENSE.md)
[![Build Status](https://img.shields.io/travis/orkhanahmadov/yandex-checkout.svg)](https://travis-ci.org/orkhanahmadov/yandex-checkout)
[![Test Coverage](https://api.codeclimate.com/v1/badges/c2a7ab12371ec106ba13/test_coverage)](https://codeclimate.com/github/orkhanahmadov/yandex-checkout/test_coverage)
[![Maintainability](https://api.codeclimate.com/v1/badges/c2a7ab12371ec106ba13/maintainability)](https://codeclimate.com/github/orkhanahmadov/yandex-checkout/maintainability)
[![Quality Score](https://img.shields.io/scrutinizer/g/orkhanahmadov/yandex-checkout.svg)](https://scrutinizer-ci.com/g/orkhanahmadov/yandex-checkout)
[![StyleCI](https://github.styleci.io/repos/311930802/shield?branch=master)](https://github.styleci.io/repos/311930802?branch=master)
Easy and complete YooKassa (previously Yandex Checkout) integration for Laravel
# Todo
- Test coverage
# Table of Contents
1. [Requirements](#requirements)
2. [Installation](#installation)
3. [Usage](#usage)
4. [Models](#models)
5. [Commands](#commands)
6. [Events](#events)
7. [Configuration](#configuration)
## Requirements
* PHP **7.3** or above
* Laravel **6** or above
## Installation
You can install the package via composer:
```bash
composer require orkhanahmadov/yandex-checkout
```
Run this command to publish required migration file:
``` shell script
php artisan vendor:publish --provider="Orkhanahmadov\YandexCheckout\YandexCheckoutServiceProvider" --tag=migrations
```
## Usage
First, set Yandex Checkout shop ID and secret key in `.env` file. You can get these from [YooMoney merchant page](https://yookassa.ru/my).
```
YANDEX_CHECKOUT_SHOP_ID=
YANDEX_CHECKOUT_SECRET_KEY=
```
To use Yandex Checkout service you need instance of `Orkhanahmadov\YandexCheckout\YandexCheckoutService`.
You can instantiate this class using Laravel's service container, for example by injecting to your controller
``` php
use Orkhanahmadov\YandexCheckout\YandexCheckoutService;
class MyController
{
public function index(YandexCheckoutService $yandexCheckout)
{
//
}
}
```
Or you can use Laravel's service resolver to create instance of the class:
``` php
use Orkhanahmadov\YandexCheckout\YandexCheckoutService;
class MyClass
{
public function doSomething()
{
$yandexCheckout = app(YandexCheckoutService::class);
//
}
}
```
### Available methods:
### `createPayment()`
Creates new payment based on passed credentials and accepts 2 arguments:
* `Model` - Eloquent model payment is associated
* `Payment request` - Payment request that contains amount, currency, etc information
``` php
$product = Product::first();
$yandexCheckout = app(YandexCheckoutService::class);
$paymentRequest = CreatePaymentRequest::builder()->build([
'amount' => [
'value' => 49.99,
'currency' => 'RUB',
],
'confirmation' => [
'type' => 'redirect',
'return_url' => 'https://example.com',
],
'capture' => true,
'description' => 'Payment for product: ' . $product->id,
]);
$yandexCheckout->createPayment($product, $paymentRequest);
```
Method returns created instance of `Orkhanahmadov\YandexCheckout\Models\YandexCheckout` model.
You should use `$confirmation_url` property to get unique payment URL and redirect user to this URL to start payment.
### `paymentInfo()`
Gets information on previously created payment. Accepts single argument:
* `Payment` - This is Yandex Checkout's payment id as a string, or instance of previously created `Orkhanahmadov\YandexCheckout\Models\YandexCheckout` model.
``` php
$product = Product::first();
$yandexCheckout = app(YandexCheckoutService::class);
$payment = $yandexCheckout->createPayment($product, ...);
$paymentInfo = $yandexCheckout->paymentInfo($payment);
// or
$paymentInfo = $yandexCheckout->paymentInfo('1234-ABCD-5678');
```
Method returns updated instance of `Orkhanahmadov\YandexCheckout\Models\YandexCheckout` model with Yandex Checkout's response.
## Models
Package ships with `Orkhanahmadov\YandexCheckout\Models\YandexCheckout` Eloquent model.
Model stores following information for each payment:
* `payment_id` - string, unique payment key provided by Yandex Checkout
* `status` - string, payment status code
* `response` - array, serialized checkout object
Besides usual Eloquent functionality this model also has specific accessors, scopes
and relationship abilities which you can utilize.
### Accessors
* `succeeded` - Returns `true` if payment marked as "succeeded", `false` otherwise
* `paid` - Returns `true` if checkout is paid, `false` otherwise
* `confirmation_url` - Returns "confirmation URL" which should be used to start payment
* `cancellation_reason` - Returns payment's cancellation/fail reason. Returns `null` when payment is successful or not started yet
### Scopes
* `succeeded()` - Filters "succeeded" payments only
* `pending()` - Filters "pending" payments only. Pending payments are the payments that has status other than "succeeded" or "canceled".
### Relationship
You can make any existing Eloquent model "payable" and attach Yandex Checkouts to it.
Use `Orkhanahmadov\YandexCheckout\Traits\HandlesYandexCheckout` trait in your existing model to establish direct model relationship.
``` php
use Illuminate\Database\Eloquent\Model;
use Orkhanahmadov\YandexCheckout\Traits\HandlesYandexCheckout;
class Product extends Model
{
use HandlesYandexCheckout;
}
```
Now `Product` model has direct relationship with Yandex Checkouts.
By using `HandlesYandexCheckout` your model also gets access to payment related relationships and payment methods.
#### `createPayment()`
``` php
$product = Product::first();
$paymentRequest = CreatePaymentRequest::builder()->build([
'amount' => [
'value' => 49.99,
'currency' => 'RUB',
],
'confirmation' => [
'type' => 'redirect',
'return_url' => 'https://example.com',
],
'capture' => true,
'description' => 'Payment for product: ' . $product->id,
]);
$product->createPayment($paymentRequest);
```
#### `yandexCheckouts()`
Eloquent relationship method. Return all related Yandex Checkouts.
``` php
$product = Product::first();
$product->yandexCheckouts; // returns collection of related Yandex Checkouts
$product->yandexCheckouts()->where('payment_id', '123-ABC-456'); // use it as regular Eloquent relationship
$product->yandexCheckouts()->pending(); // use scopes on YandexCheckout model
```
## Commands
Package ships with artisan command for checking payment results.
``` shell script
php artisan yandex-checkout:check
```
Executing above command will loop through all "pending" checkouts and update their models.
Command also accepts payment ID as an argument to check single checkout result.
``` shell script
php artisan yandex-checkout:check 1234-ABCD-5678
```
You can set up a Cron job schedule to frequently check all "pending" checkout.
``` php
protected function schedule(Schedule $schedule)
{
$schedule->command('yandex-checkout:check')->everyMinute();
}
```
## Events
Package ships with Laravel events which gets fired on specific conditions.
Available event classes:
* `Orkhanahmadov\YandexCheckout\Events\CheckoutCreated` - gets fired when new checkout is created
* `Orkhanahmadov\YandexCheckout\Events\CheckoutSucceeded` - gets fired when payment status changes to "succeeded"
* `Orkhanahmadov\YandexCheckout\Events\CheckoutCanceled` - gets fired when payment status changes to "canceled"
* `Orkhanahmadov\YandexCheckout\Events\CheckoutChecked` - gets fired when payment information is checked
Each event receives instance of `Orkhanahmadov\YandexCheckout\Models\YandexCheckout` Eloquent model as public `$yandexCheckout` property.
You can set up event listeners to trigger when specific payment event gets fired.
``` php
protected $listen = [
'Orkhanahmadov\YandexCheckout\Events\CheckoutSucceeded' => [
'App\Listeners\DispatchOrder',
'App\Listeners\SendInvoice',
],
];
```
## Configuration
Run this command to publish package config file:
``` shell script
php artisan vendor:publish --provider="Orkhanahmadov\YandexCheckout\YandexCheckoutServiceProvider" --tag=config
```
Config file contains following settings:
* `shop_id` - Defines Yandex Checkout's "shop ID", defaults to `.env` variable
* `secret_key` - Defines Yandex Checkout's "secret key", defaults to `.env` variable
* `table_name` - Defines name for Yandex Checkout payments database table. Default: "yandex_checkouts"
* `events` - Payment events related settings
* `created` - "Checkout created" event class. By default uses `Orkhanahmadov\YandexCheckout\Events\CheckoutCreated` class
* `succeeded` - "Checkout succeeded" event class. By default uses `Orkhanahmadov\YandexCheckout\Events\CheckoutSucceeded` class
* `canceled` - "Checkout canceled" event class. By default uses `Orkhanahmadov\YandexCheckout\Events\CheckoutCanceled` class
* `checked` - "Checkout checked" event class. By default uses `Orkhanahmadov\YandexCheckout\Events\CheckoutChecked` class
If you want to use your own event class for specific payment event you can replace class namespace with your class namespace.
Each checkout event receives instance of `Orkhanahmadov\YandexCheckout\Models\YandexCheckout` Eloquent model.
Because of this, make sure you add payment model as dependency to your event class constructor signature or
you can extend `Orkhanahmadov\YandexCheckout\Events\CheckoutEvent` class which already has payment model as dependency.
Setting specific payment event to `null` disables that event.
### Testing
``` bash
composer test
```
### Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
### Security
If you discover any security related issues, please email orkhan@fastmail.com instead of using the issue tracker.
## Credits
- [Orkhan Ahmadov](https://github.com/orkhanahmadov)
- [LinksDerIsar](https://www.linksderisar.com)
- [All Contributors](../../contributors)
## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.