curl --request POST \
--url https://api.paygentic.io/v2/invoices/{id}/retryPayment \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reason": "<string>"
}
'import requests
url = "https://api.paygentic.io/v2/invoices/{id}/retryPayment"
payload = { "reason": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reason: '<string>'})
};
fetch('https://api.paygentic.io/v2/invoices/{id}/retryPayment', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.paygentic.io/v2/invoices/{id}/retryPayment",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reason' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.paygentic.io/v2/invoices/{id}/retryPayment"
payload := strings.NewReader("{\n \"reason\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.paygentic.io/v2/invoices/{id}/retryPayment")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paygentic.io/v2/invoices/{id}/retryPayment")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"object": "retry_payment_result",
"success": true,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"paymentIntentId": "pi_1234567890abcdef"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"paymentIntentId": "pi_1234567890abcdef",
"error": {
"message": "Payment is settling asynchronously: processing",
"code": "processing"
}
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"paymentIntentId": "pi_1234567890abcdef",
"error": {
"message": "Payment failed: card_declined",
"type": "card_error",
"code": "card_declined",
"declineCode": "insufficient_funds"
}
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"error": {
"message": "Payment session has expired",
"code": "PAYMENT_SESSION_EXPIRED"
}
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"error": {
"message": "Cannot retry payment: no usable stored payment method",
"code": "no_payment_method"
}
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"error": {
"message": "Cannot retry payment: the payment provider did not answer. Try again later.",
"code": "provider_unavailable"
}
}Retry Payment
Charge the customer’s saved payment method again for an unpaid invoice.
The invoice must be in status ISSUED or PAYMENT_FAILED, auto-charge must be on for its subscription, and the invoice must have a payment session. If not, the response is 400.
The response status tells you the result. Only 200 means that the charge succeeded. Every other response from this operation that has a retry_payment_result body has success: false, and error.code gives the reason:
| Status | error.code | Meaning |
|---|---|---|
| 200 | — | The charge succeeded, the provider had already collected it, or no amount is unpaid. |
| 202 | processing | The provider accepted the charge. It settles later (for example, a bank debit). |
| 402 | a decline code, for example card_declined, insufficient_funds, do_not_honor, authentication_required | The provider declined the payment method. |
| 409 | concurrent_attempt | Another payment attempt for this invoice is in progress. |
| 409 | PAYMENT_SESSION_EXPIRED | The payment link expired (after 30 days). Create a new link with POST /v2/invoices/{id}/payment and method: hosted_link, then retry. If the customer also has no usable saved payment method, the response is 422 instead. |
| 409 | another value, or no code | The payment session cannot be charged in its current state (for example session_unusable, non_confirmable, PAYMENT_PROCESSING, PAYMENT_ALREADY_COMPLETED). Read error.message for the cause. |
| 422 | no_payment_method | The customer has no usable saved payment method. Send a payment link instead. |
| 502 | provider_unavailable or none | The payment provider did not answer, or the provider failed the charge for a reason that is not known. Retry later. |
A 500 response has the standard error body, not retry_payment_result. It is an internal error, and a retry does not fix it.
An invoice that does not exist returns 403, the same as an invoice of another merchant.
This operation is rate limited to one call each minute for each invoice.
curl --request POST \
--url https://api.paygentic.io/v2/invoices/{id}/retryPayment \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reason": "<string>"
}
'import requests
url = "https://api.paygentic.io/v2/invoices/{id}/retryPayment"
payload = { "reason": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reason: '<string>'})
};
fetch('https://api.paygentic.io/v2/invoices/{id}/retryPayment', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.paygentic.io/v2/invoices/{id}/retryPayment",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reason' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.paygentic.io/v2/invoices/{id}/retryPayment"
payload := strings.NewReader("{\n \"reason\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.paygentic.io/v2/invoices/{id}/retryPayment")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paygentic.io/v2/invoices/{id}/retryPayment")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"object": "retry_payment_result",
"success": true,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"paymentIntentId": "pi_1234567890abcdef"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"paymentIntentId": "pi_1234567890abcdef",
"error": {
"message": "Payment is settling asynchronously: processing",
"code": "processing"
}
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"paymentIntentId": "pi_1234567890abcdef",
"error": {
"message": "Payment failed: card_declined",
"type": "card_error",
"code": "card_declined",
"declineCode": "insufficient_funds"
}
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"error": {
"message": "Payment session has expired",
"code": "PAYMENT_SESSION_EXPIRED"
}
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"error": {
"message": "Cannot retry payment: no usable stored payment method",
"code": "no_payment_method"
}
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"object": "retry_payment_result",
"success": false,
"invoiceId": "inv_a1b2c3d4e5f6g7h8",
"error": {
"message": "Cannot retry payment: the payment provider did not answer. Try again later.",
"code": "provider_unavailable"
}
}Authorizations
API key authentication
Path Parameters
The invoice ID
Body
Optional reason for the manual retry (for audit logging)
Response
The charge succeeded, the provider had already collected it, or the invoice has no unpaid amount. success is true.
The result of a payment retry. Every response status of the retry operation that is not an error envelope uses this shape.
The object type
retry_payment_result True only when the charge succeeded or no amount is unpaid. The response status is 200 only when this is true.
The invoice ID
The provider's payment reference for the charge, when the provider has one.
Present when success is false.
Show child attributes
Show child attributes
Was this page helpful?