Cashier provides an expressive, fluent interface to manage billing services.

v2.1.0 2021-11-30 11:16 UTC

README

Cashier provides an expressive, fluent interface to manage billing services.

Cashier Provider Core

Stable Version Unstable Version Total Downloads License

Installation

Note

Drivers will usually automatically install the correct Cashier Provider Core version, but you can do this manually.

To get the latest version of Cashier Provider Core, simply require the project using Composer:

$ composer require cashier-provider/core

Or manually update require block of composer.json and run composer update.

{
    "require": {
        "cashier-provider/core": "^2.0"
    }
}

You should publish the config file and migrations with:

php artisan vendor:publish --provider="CashierProvider\Core\ServiceProvider"

Further, if necessary, edit the migration file copied to your application and run the command to apply migrations:

php artisan migrate

Upgrade from andrey-helldar/cashier

For application

  1. Replace andrey-helldar/cashier with cashier-provider/core in the composer.json file;
  2. In the config/cashier.php file replace the Helldar\Cashier namespace with CashierProvider\Core.
  3. Call the composer update command.

For driver developers

  1. Replace andrey-helldar/cashier with cashier-provider/core in the composer.json file;
  2. Replace the Helldar\CashierDriver namespace with CashierProvider in all files.
  3. Replace the Helldar\Cashier namespace with CashierProvider\Core in all files.
  4. Call the composer update command.

Using

Cashier allows you to connect any payment driver compatible with your application.

Depending on the type of payment, Cashier will automatically call the required driver to work with the bank's API.

Configuration

Before starting, edit the config/cashier.php file:

use App\Models\Payment as Model;
use CashierProvider\Core\Constants\Attributes;
use CashierProvider\Core\Constants\Status;

return [
    'payment' => [

        // Please provide a link to the payment model.
        'model' => App\Models\Payment::class,

        // Specify the field names for the payment types based on which
        // the required driver will be loaded, the status identifier and
        // the entry creation date fields.
        'attributes' => [
            Attributes::TYPE => 'type_id',

            Attributes::STATUS => 'status_id',

            Attributes::CREATED_AT => 'created_at',
        ],

        // Indicate the correspondence of statuses in your system.
        // Values can be either integer or string.
        'statuses' => [
            Status::NEW => Model::STATUS_NEW,

            Status::SUCCESS => Model::STATUS_SUCCESS,

            Status::FAILED => Model::STATUS_FAILED,

            Status::REFUND => Model::STATUS_REFUND,

            Status::WAIT_REFUND => Model::STATUS_WAIT_REFUND,
        ],

        // Here you need to specify the name of the drivers called
        // for the payment types.
        'map' => [
            Model::PAYMENT_TYPE_QR_SBER => 'driver_name',
        ],
    ],

    // This parameter determines in which queue workers will be sent for
    // requests to banks.
    'queue' => [

        // This value indicates which queue service the jobs will fall into.
        // Here you may define a default connection.
        'connection' => env('QUEUE_CONNECTION'),

        // This value specifies the names of the queue into which the task will
        // be placed.
        'names' => [
            'start' => env('CASHIER_QUEUE'),
            'check' => env('CASHIER_QUEUE'),
            'refund' => env('CASHIER_QUEUE'),
        ],
    ],

    // This parameter defines the parameters for automatic refunds.
    'auto_refund' => [

        // This setting determines whether you want to issue an automatic refund
        // of payments.
        'enabled' => env('CASHIER_AUTO_REFUND_ENABLED', false),
    ],

    // This setting defines the list of drivers for the implementation of
    // payments.
    'drivers' => [
        'driver_name' => [

            // Here you need to fill in the data of the connected payment driver
            // Connection information is usually found in the driver documentation.

        ]
    ]
];

Using Trait

Add the necessary trait to your Payment model:

namespace App\Models;

use CashierProvider\Core\Concerns\Casheable;
use Illuminate\Database\Eloquent\Model;

class Payment extends Model
{
    use Casheable;
}

Cron Commands

You need to register a call to the console command to periodically start checking payment statuses.

Add a call to app/Console/Kernel.php file:

use Illuminate\Console\Scheduling\Schedule;

protected function schedule(Schedule $schedule)
{
    $schedule->command('cashier:check')->withoutOverlapping()->everyThirtyMinutes();
    $schedule->command('cashier:refund')->withoutOverlapping()->daily();
}
  • cashier:check - Launching a re-verification of payments with a long processing cycle.
  • cashier:refund - Launching the command to check payments for refunds.

You can specify any start time for the cashier:check command, but we recommend using the call every thirty minutes.

Note: we do not recommend calling the command every 15 minutes or more often - this can fill up the task queue and delay the processing of new items.

Queue Handler

If your application uses a queue handler (we hope you are using it), then you will need to add configuration to it.

This must be done if you give it your connection and names.

For example:

[program:queue-payments-start]
process_name = %(process_num)02d
command = php /var/www/artisan queue:work database --queue=payments_start --tries=100
autostart = true
autorestart = true
numprocs = 4
user = www-data
redirect_stderr = true
stdout_logfile = /var/www/storage/logs/queue-payments-start.log

[program:queue-payments-check]
process_name = %(process_num)02d
command = php /var/www/artisan queue:work database --queue=payments_check --tries=100
autostart = true
autorestart = true
numprocs = 4
user = www-data
redirect_stderr = true
stdout_logfile = /var/www/storage/logs/queue-payments-check.log

[program:queue-payments-refund]
process_name = %(process_num)02d
command = php /var/www/artisan queue:work database --queue=payments_refund --tries=100
autostart = true
autorestart = true
numprocs = 1
user = www-data
redirect_stderr = true
stdout_logfile = /var/www/storage/logs/queue-payments-refund.log

Manual

use App\Models\Payment;
use CashierProvider\Core\Services\Jobs;

$model = Payment::findOrfail(1234);

$jobs = Jobs::make($model);

$jobs->start();
$jobs->check();
$jobs->refund();
$jobs->retry();

Drivers

Available

Driver Description
cashier-provider/cash Driver for managing cash payments in the Cashier Provider ecosystem
cashier-provider/sber-qr Driver for payment with QR codes via Sber
cashier-provider/tinkoff-qr Driver for payment with QR codes via Tinkoff

Authorization drivers

Driver Description
cashier-provider/sber-auth Sber Cashier Authorization Driver
cashier-provider/tinkoff-auth Tinkoff Cashier Authorization Driver

Development

Note

You can join our team, create a driver repository and maintain it.

Create main classes with the following inheritance:

Class Extends Description
Driver CashierProvider\Core\Services\Driver Main driver file. Contains information on exchanging information with the bank via the API.
Exceptions\Manager CashierProvider\Core\Exceptions\Manager Error handling manager. Contains information about error codes returned from the bank.
Helpers\Statuses CashierProvider\Core\Services\Statuses Types of statuses. Groups the statuses returned by the bank by type.
Resources\Details CashierProvider\Core\Resources\Details Details cast. Contains information for working with the bank. For example, in the cashier-provider/sber-qr driver, it contains a link to generate a QR code. In your driver, you are free to specify the methods you need.
Requests\Create CashierProvider\Core\Http\Request Request to the bank to initiate a payment session.
Requests\Status CashierProvider\Core\Http\Request Request to the bank to check the status of the payment.
Requests\Cancel CashierProvider\Core\Http\Request Request to the bank to cancel the payment and return the funds to the client if he has already paid for the services.
Responses\Created, Responses\Refund, Responses\Status CashierProvider\Core\Http\Response Classes for processing responses from the bank.
namespace CashierProvider\BankName\BankTechnology;

use CashierProvider\BankName\BankTechnology\Exceptions\Manager;
use CashierProvider\BankName\BankTechnology\Helpers\Statuses;
use CashierProvider\BankName\BankTechnology\Requests\Cancel;
use CashierProvider\BankName\BankTechnology\Requests\Create;
use CashierProvider\BankName\BankTechnology\Requests\Status;
use CashierProvider\BankName\BankTechnology\Resources\Details;
use CashierProvider\BankName\BankTechnology\Responses\Created;
use CashierProvider\BankName\BankTechnology\Responses\Refund;
use CashierProvider\BankName\BankTechnology\Responses\Status as StatusResponse;
use CashierProvider\Core\Services\Driver as BaseDriver;
use Helldar\Contracts\Cashier\Http\Response;

class Driver extends BaseDriver
{
    protected $exceptions = Manager::class;

    protected $statuses = Statuses::class;

    protected $details = Details::class;

    public function start(): Response
    {
        $request = Create::make($this->model);

        return $this->request($request, Created::class);
    }

    public function check(): Response
    {
        $request = Status::make($this->model);

        return $this->request($request, StatusResponse::class);
    }

    public function refund(): Response
    {
        $request = Cancel::make($this->model);

        return $this->request($request, Refund::class);
    }
}

These are the main files for driver development.

For convenience, we have created a Cashier Provider Driver Template, on the basis of which you can create your own driver. And also the Cashier Provider Authorization Driver Template.