diff --git a/composer.json b/composer.json index c20c992..35ef981 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,10 @@ "authors": [ { "name": "Igor Fedorov", + "role": "Original Developer" + }, + { + "name": "Maksim Ego", "role": "Developer" } ], diff --git a/src/Options/InvoiceOptions.php b/src/Options/InvoiceOptions.php index dd3ff04..db34da5 100644 --- a/src/Options/InvoiceOptions.php +++ b/src/Options/InvoiceOptions.php @@ -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, diff --git a/src/Params/Receipt/Tax.php b/src/Params/Receipt/Tax.php index 669a6f5..d5edf31 100644 --- a/src/Params/Receipt/Tax.php +++ b/src/Params/Receipt/Tax.php @@ -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 { @@ -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, }; } } diff --git a/src/RobokassaApi.php b/src/RobokassaApi.php index 6ff6a9f..b043148 100644 --- a/src/RobokassaApi.php +++ b/src/RobokassaApi.php @@ -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,