Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"authors": [
{
"name": "Igor Fedorov",
"role": "Original Developer"
},
{
"name": "Maksim Ego",
"role": "Developer"
}
],
Expand Down
3 changes: 3 additions & 0 deletions src/Options/InvoiceOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,14 @@ class InvoiceOptions
* Если параметр не передан, то используются региональные настройки браузера покупателя.
* Для значений отличных от ru или en используется английский язык.
* @param string|null $signatureValue
* @param int|null $previousInvoiceId - айди прошлого платежа, для проведения рекуррентных оплат
* доступна только при подверждение такого типа оплат в робокассе
*/
public function __construct(
float|string $outSum,
public readonly int|null $invId,
public readonly string $description,
public readonly int|null $previousInvoiceId = null,
public readonly Receipt|string|null $receipt = null,
DateTimeInterface|string|null $expirationDate = null,
public readonly ?string $email = null,
Expand Down
20 changes: 20 additions & 0 deletions src/Params/Receipt/Tax.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ enum Tax: string
* – НДС чека по расчетной ставке 20/120
*/
case vat120 = 'vat120';
/**
* – НДС по ставке 5%
*/
case vat5 = 'vat5';
/**
* – НДС по ставке 7%
*/
case vat7 = 'vat7';
/**
* – НДС чека по расчетной ставке 5/105
*/
case vat105 = 'vat105';
/**
* – НДС чека по расчетной ставке 7/107
*/
case vat107 = 'vat107';

public function getTaxSumFromItemSum(string $sum): string
{
Expand All @@ -48,6 +64,10 @@ private function getTaxMultiplier(): float|int
self::vat110 => 10 / 110,
self::vat20 => 0.2,
self::vat120 => 20 / 120,
self::vat5 => 0.05,
self::vat7 => 0.07,
self::vat105 => 5 / 105,
self::vat107 => 7 / 107,
};
}
}
35 changes: 35 additions & 0 deletions src/RobokassaApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,47 @@ public function getPaymentUrl(InvoiceOptions $invoiceOptions): string
return $this->paymentUrl . '?' . http_build_query($this->getPaymentParameters($invoiceOptions));
}

/**
* Sends a recurring payment request to the Robokassa API.
*
* This method constructs and sends a POST request to the Robokassa recurring payment URL.
* The request includes the necessary parameters in the request body, encoded as `application/x-www-form-urlencoded`.
*
* @param array $params The parameters to include in the recurring payment request. These should include all necessary fields
* such as `MerchantLogin`, `InvoiceID`, `PreviousInvoiceID`, `OutSum`, `Description`, and others required by Robokassa.
*
* @return \Psr\Http\Message\ResponseInterface The HTTP response returned by the Robokassa API. The response contains the status
* and any other relevant information returned by the API.
*
* @throws \RuntimeException If the returned response does not implement the expected `Psr\Http\Message\ResponseInterface`.
*/
public function sendRecurringPayment(array $params): ResponseInterface
{
$psr18Client = $this->getPsr18Client();

$bodyStream = $psr18Client->createStream(http_build_query($params));

$request = $psr18Client
->createRequest('POST', $this->recurringUrl)
->withHeader('Content-Type', 'application/x-www-form-urlencoded')
->withBody($bodyStream);

$response = $psr18Client->sendRequest($request);

if (!$response instanceof ResponseInterface) {
throw new \RuntimeException('Returned response does not implement Psr\Http\Message\ResponseInterface');
}

return $response;
}

public function getPaymentParameters(InvoiceOptions $invoiceOptions): array
{
return [
'MerchantLogin' => $this->merchantLogin,
'OutSum' => $invoiceOptions->outSum,
'Description' => $invoiceOptions->description,
'PreviousInvoiceID' => $invoiceOptions->previousInvoiceId ?? null,
'SignatureValue' => $invoiceOptions->signatureValue ?? $this->generateSignatureForPayment($invoiceOptions),
'IncCurrLabel' => $invoiceOptions->incCurrLabel,
'InvId' => isset($invoiceOptions->invId) ? (string)$invoiceOptions->invId : null,
Expand Down