netfantom/robokassa-api

Robokassa Api for PHP 8.1

dev-main 2023-11-28 07:19 UTC

This package is auto-updated.

Last update: 2024-09-28 09:07:56 UTC


README

Latest Stable Version Total Downloads License PHP Version Require codecov type-coverage psalm-level

此模块包含与Robokassa交互的基本方法集。

需要 PHP 8.1+ 和任何 PSR-18 HTTP Client

使用对象 InvoiceOptionsSecondReceiptOptionsInvoicePayResult 来配置模块、生成请求和处理响应

使用Composer安装

composer require igor-netfantom/robokassa-api:@dev

模块使用了 php-http/discovery,它会自动从已安装的包中找到合适的 PSR-18 HTTP Client,如果没有找到合适的,则会建议安装列表中的包

如果需要,可以在模块设置中指定要使用的 PSR-18 HTTP Client

模块配置

https://docs.robokassa.ru/pay-interface/

$robokassa = new \netFantom\RobokassaApi\RobokassaApi(
    merchantLogin: 'robo-demo',
    password1: 'password_1',
    password2: 'password_2',
    isTest: false,
    psr18Client: new \Http\Discovery\Psr18Client(),  // необязательно
);

RobokassaApi::psr18Client 不必指定。

PSR-18 HTTP Client 用于发送一些请求
(生成第二个收据,获取收据状态,发送短信)

可以在创建和配置 RobokassaApi 对象后更改或获取它。

如果未指定,将通过 php-http/discovery 自动尝试搜索合适的已安装的 PSR-18 HTTP Client

$robokassa = new \netFantom\RobokassaApi\RobokassaApi(
    // ...
    psr18Client: new \Http\Discovery\Psr18Client(),  // вручную указываем свой psr18Client 
    // или
    psr18Client: null,  // разрешить автоматический поиск подходящего psr18Client
);

$psr18Client = $robokassa->getPsr18Client(); // получение указанного psr18Client или поиск подходящего

$robokassa->setPsr18Client(new \Http\Discovery\Psr18Client()); // изменение psr18Client

方法

获取支付参数以传递给Robokassa

(用于生成带有 POST 请求方法的 ФОРМЫ 支付)

https://docs.robokassa.ru/script-parameters/
https://docs.robokassa.ru/fiscalization/

use netFantom\RobokassaApi\Options\InvoiceOptions;
use netFantom\RobokassaApi\Params\Option\{Culture, OutSumCurrency, Receipt};
use netFantom\RobokassaApi\Params\Item\{PaymentMethod, PaymentObject};
use netFantom\RobokassaApi\Params\Receipt\{Item, Sno, Tax};
use netFantom\RobokassaApi\RobokassaApi;

$robokassa = new RobokassaApi(
    // ...
);
$paymentParametersArray = $robokassa->getPaymentParameters(new InvoiceOptions(
    outSum: 999.99,
    invId: 1,
    description: 'Description',
    receipt: new Receipt(
        items: [
            new Item(
                name: "Название товара 1",
                quantity: 1,
                sum: 100,
                tax: Tax::vat10,
                payment_method: PaymentMethod::full_payment,
                payment_object: PaymentObject::commodity,
            ),
            new Item(
                name: "Название товара 2",
                quantity: 3,
                sum: 450,
                tax: Tax::vat10,
                payment_method: PaymentMethod::full_payment,
                payment_object: PaymentObject::service,
                cost: 150,
                nomenclature_code: '04620034587217',
            ),
        ],
        sno: Sno::osn
    ),
    expirationDate: (new DateTimeImmutable())->add(new DateInterval('PT48H')),
    email: 'user@email.com',
    outSumCurrency: OutSumCurrency::USD,
    userIP: '127.0.0.1',
    incCurrLabel: null,
    userParameters: [
        'user_id' => '123',
        'parameter2' => 'parameter2_value',
        // ...
    ],
    encoding: 'utf-8',
    culture: Culture::ru,
));
//[
//    'MerchantLogin' => ...,
//    'OutSum' => ...,
//    'Description' => ...,
//    'SignatureValue' => ...,
//    'IncCurrLabel' => ...,
//    'InvId' => ...,
//    'Culture' => ...,
//    'Encoding' => ...,
//    'Email' => ...,
//    'ExpirationDate' => ...,
//    'OutSumCurrency' => ...,
//    'UserIp' => ...,
//    'Receipt' => ...,
//    'IsTest' => ...,
//    'shp_...' => ...,
//    'shp_...' => ...,
//    'shp_...' => ...,
//    // ...
//]

获取支付参数的 JSON 字符串 格式

(用于使用 Robokassa PopUp iFrame 小部件的 robokassa_iframe.js)

https://docs.robokassa.ru/iframe/

<?php
use netFantom\RobokassaApi\Options\InvoiceOptions;
use netFantom\RobokassaApi\Params\Option\{Culture, OutSumCurrency, Receipt};
use netFantom\RobokassaApi\Params\Item\{PaymentMethod, PaymentObject};
use netFantom\RobokassaApi\Params\Receipt\{Item, Sno, Tax};
use netFantom\RobokassaApi\RobokassaApi;

$robokassa = new RobokassaApi(
    // ...
);
$paymentParametersJsonString = $robokassa->getPaymentParametersAsJson(new InvoiceOptions(
    // ...
));
?>
<script type="text/javascript" src="https://auth.robokassa.ru/Merchant/bundle/robokassa_iframe.js"></script>
<input type="submit" onclick="Robokassa.StartPayment(<?= $paymentParametersJsonString ?>)" value="Оплатить">

获取带有指定参数的支付URL

(由于 GET 请求长度超过 2083 个字符可能无法工作,因此建议发送带有收据 Receipt 的账单,通过生成带有 RobokassaApi::getPaymentParameters() 参数和 POST 发送方法的表单来形成)

use netFantom\RobokassaApi\Options\InvoiceOptions;
use netFantom\RobokassaApi\RobokassaApi;

$robokassa = new RobokassaApi(
    // ...
);
$invoiceOptions = new InvoiceOptions(
    // ...
);
$url = $robokassa->getPaymentUrl($invoiceOptions);

发送第二个收据

使用任何 PSR-18 Http Client 进行发送。

可以通过以下方式了解发送结果

  • 直接从获取的 Psr\Http\Message\ResponseInterface
  • 或通过 getReceiptAttachResult() 方法将响应转换为 ReceiptAttachResult

https://docs.robokassa.ru/second-check/

use Http\Discovery\Psr18Client;
use netFantom\RobokassaApi\Options\SecondReceiptOptions;
use netFantom\RobokassaApi\Params\Item\{PaymentMethod, PaymentObject};
use netFantom\RobokassaApi\Params\Receipt\{Client, Item, Payment, Sno, Tax};
use netFantom\RobokassaApi\Results\ReceiptAttachResult;
use netFantom\RobokassaApi\RobokassaApi;
use Psr\Http\Message\{RequestInterface, ResponseInterface};

$robokassa = new RobokassaApi(
    // ...
);
$items = [
    new Item(
        name: 'Товар',
        quantity: 1,
        sum: 100,
        tax: Tax::none,
        payment_method: PaymentMethod::full_payment,
        payment_object: PaymentObject::commodity
    )
];
/** @var ResponseInterface $response */
$response = $robokassa->sendSecondReceiptAttach(new SecondReceiptOptions(
    id: 14,
    originId: 13,
    url: 'https://www.robokassa.ru/',
    total: 100,
    items: $items,
    vats: RobokassaApi::getVatsFromItems($items),
    sno: Sno::osn,
    client: new Client(
        email: 'test@test.ru',
        phone: '71234567890',
    ),
    payments: [
        new Payment(100),
    ],
));

/** @var ReceiptAttachResult $receiptAttachResult */
$receiptAttachResult = $robokassa->getReceiptAttachResult($response);

$receiptAttachResult->ResultCode; // Статус получения данных от Клиента.
$receiptAttachResult->ResultDescription; // Описание результата обработки чека.
$receiptAttachResult->OpKey; // Идентификатор операции.

// ИЛИ можно сформировать запрос для самостоятельной отправки PSR-18 HTTP клиентом:
/** @var RequestInterface $request */
$request = $robokassa->secondReceiptAttachRequest(new SecondReceiptOptions(
    // ...
));
$response = (new Psr18Client())->sendRequest($request);
$receiptAttachResult = $robokassa->getReceiptAttachResult($response);

获取收据状态

使用任何 PSR-18 Http Client 发送请求。

可以通过以下方式了解请求发送结果

  • 直接从获取的 Psr\Http\Message\ResponseInterface
  • 或通过 getReceiptStatusResult() 方法将响应转换为 ReceiptStatusResult

https://docs.robokassa.ru/second-check/

use Http\Discovery\Psr18Client;
use netFantom\RobokassaApi\Options\ReceiptStatusOptions;
use netFantom\RobokassaApi\Results\ReceiptStatusResult;
use netFantom\RobokassaApi\RobokassaApi;
use Psr\Http\Message\{RequestInterface, ResponseInterface};

$robokassa = new RobokassaApi(
// ...
);
/** @var ResponseInterface $response */
$response = $robokassa->getReceiptStatus(new ReceiptStatusOptions(
    id: 34,
));

/** @var ReceiptStatusResult $receiptStatusResult */
$receiptStatusResult = $robokassa->getReceiptStatusResult($response);

$receiptStatusResult->Code; // Статус регистрации чека.
$receiptStatusResult->Description; // Описание результата формирования чека
$receiptStatusResult->Statuses;
$receiptStatusResult->FnNumber; // Номер ФН
$receiptStatusResult->FiscalDocumentNumber; // Фискальный номер документа
$receiptStatusResult->FiscalDocumentAttribute; // Фискальный признак документа
$receiptStatusResult->FiscalDate; // Дата и время формирования фискального чека
$receiptStatusResult->FiscalType;


// ИЛИ можно сформировать запрос для самостоятельной отправки PSR-18 HTTP клиентом:
/** @var RequestInterface $request */
$request = $robokassa->receiptStatusRequest(new ReceiptStatusOptions(
    id: 34,
));
$response = (new Psr18Client())->sendRequest($request);
$receiptStatusResult = $robokassa->getReceiptStatusResult($response);

发送短信

使用任何 PSR-18 Http Client 进行发送。

可以通过以下方式了解发送结果

  • 直接从获取的 Psr\Http\Message\ResponseInterface
  • 或通过 getSmsSendResult() 方法将响应转换为 SmsSendResult

https://docs.robokassa.ru/sms/

use Http\Discovery\Psr18Client;
use netFantom\RobokassaApi\Results\SmsSendResult;
use netFantom\RobokassaApi\RobokassaApi;
use Psr\Http\Message\{RequestInterface, ResponseInterface};

$robokassa = new RobokassaApi(
    // ...
);

/** @var int $phone Номер телефона в международном формате без символа «+». Например, 8999*******. */
$phone = 89991234567;

/** @var string $message Строка в кодировке UTF-8 длиной до 128 символов, содержащая текст отправляемого SMS. */
$message = 'All work fine!';

/** @var ResponseInterface $response */
$response = $robokassa->sendSms($phone, $message);

/** @var SmsSendResult $smsSendResult */
$smsSendResult = $robokassa->getSmsSendResult($response);

$smsSendResult->result; // Значение логического типа, указывающее на общий успех или неуспех обработки запроса.
$smsSendResult->errorCode; // Целочисленное значение кода ошибки обработки
$smsSendResult->errorMessage; // Текстовое описание возникшей в процессе обработки запроса ошибки.
$smsSendResult->count; // Целочисленное значение, указывающее на количество SMS, доступное после этого запроса
                       // (данное значение заполняется только в случае успешного исполнения запроса)


// ИЛИ можно сформировать запрос для самостоятельной отправки PSR-18 HTTP клиентом:
/** @var RequestInterface $request */
$request = $robokassa->smsRequest(
    // ...
);
$response = (new Psr18Client())->sendRequest($request);
$smsSendResult = $robokassa->getSmsSendResult($response);

从Robokassa获取支付账单的结果

结果由从Robokassa获得的 GETPOST 参数数组构成

https://docs.robokassa.ru/pay-interface/

use netFantom\RobokassaApi\Results\InvoicePayResult;
use netFantom\RobokassaApi\RobokassaApi;

$robokassa = new RobokassaApi(
    // ...
);

/** @var InvoicePayResult $invoicePayResult */
$invoicePayResult = RobokassaApi::getInvoicePayResultFromRequestArray($_POST);

/** Проверка подписи результата оплаты счета */
if (!$robokassa->checkSignature($invoicePayResult)) {
    throw new RuntimeException('Bad signature');
}

$invoicePayResult->invId; // номер счета
$invoicePayResult->outSum; // сумма оплаты
$invoicePayResult->signatureValue; // подпись
$invoicePayResult->userParameters; // дополнительные пользовательские параметры

辅助方法

获取发送短信的数据

(此方法可用于自行生成请求)

https://docs.robokassa.ru/sms/

use netFantom\RobokassaApi\RobokassaApi;

$robokassa = new RobokassaApi(
    // ...
);

/** @var int $phone Номер телефона в международном формате без символа «+». Например, 8999*******. */
$phone = 89991234567;

/** @var string $message строка в кодировке UTF-8 длиной до 128 символов, содержащая текст отправляемого SMS. */
$message = 'All work fine!';

/** @var array $parameters */
$parameters = $robokassa->getSendSmsData($phone, $message);
// [
//    'login' => ...,
//    'phone' => $phone,
//    'message' => $message,
//    'signature' => ...
// ]

获取发送第二个收据或检查收据状态的数据

(此方法可用于自行生成请求)

数据由Robokassa提供的键签名的键编码为Base64。

https://docs.robokassa.ru/second-check/

use netFantom\RobokassaApi\Options\SecondReceiptOptions;
use netFantom\RobokassaApi\RobokassaApi;

$robokassa = new RobokassaApi(
    // ...
);

$secondReceiptData = $robokassa->getBase64SignedPostData(new SecondReceiptOptions(
    // ...
));

// eyJtZXJjaGFudElkIjogInJvYm9rYXNzYV9zZWxsIiwiaWQiOiAiMTQiLCJvcmlnaW5JZCI6ICIxMyIsIm9wZXJh
// dGlvbiI6ICJzZWxsIiwKInNubyI6ICJvc24iLCJ1cmwiOiAiaHR0cHM6Ly93d3cucm9ib2thc3NhLnJ1LyIsInRv
// dGFsIjogMTAwLCJpdGVtcyI6IFt7Im5hbWUiOiAi0KLQvtCy0LDRgCIsInF1YW50aXR5IjogMSwic3VtIjogMTAw
// LCJ0YXgiOiAibm9uZSIsInBheW1lbnRfbWV0aG9kIjogImZ1bGxfcGF5bWVudCIsInBheW1lbnRfb2JqZWN0Ijog
// ImNvbW1vZGl0eSJ9XSwiY2xpZW50IjogeyJlbWFpbCI6ICJ0ZXN0QHRlc3QucnUiLCJwaG9uZSI6ICI3MTIzNDU2
// Nzg5MCJ9LCJwYXltZW50cyI6IFt7InR5cGUiOiAyLCJzdW0iOiAxMDB9XSwidmF0cyI6IFt7InR5cGUiOiAibm9u
// ZSIsInN1bSI6IDB9XX0.MzAwMTU4NjIwMTE0M2RhNDIzMjg5NmM0NDI0NGJkYmI