---
title: "Retry a failed payment"
description: "Learn how to recover from failed payments by retrying with the same payment method, a different saved method, or new payment details."
canonical: "https://studio.inttegro.com/guides/retry-a-payment"
format: inttegro-machine-docs/v1
language: "Java"
sdk_version: "v8.3.0"
reader_profile: optional
reader_manifest: "https://studio.inttegro.com/machine/java/readers/index.json"
reader_identification: "Optional: declare your client only if known and your current-session capabilities; use reader_manifest for supplemental recommendations."
preamble_estimated_tokens: 436
model_token_report: "https://studio.inttegro.com/machine/token-report.json"
preamble_questions: 5
preamble_source: "curated"
recommended_mcp_tools: ["get_integration_guide","check_integration_readiness","pay_order"]
estimated_tokens: 2987
token_estimate_method: "utf8_bytes_divided_by_4"
---

## Machine preamble

**Summary:** Recover a failed payment on the existing order, choose a valid payment-method path, and verify the new attempt without treating the retry request as paid.

### Five questions

#### Q1. Should a failed charge create a new order?

No. Look up the failed order and use [Pay for an order](https://studio.inttegro.com/machine/java/api/orders.md#pay-for-an-order) against that order ID. Its customer and line items remain the purchase being collected.

#### Q2. Which retry method should be used?

For a transient failure, retry the attached method; if the customer chooses otherwise, use another saved method or new payment details. Check the existing order and current method state before selecting a branch.

#### Q3. Can a retry reuse the prior OTP?

No. Each retry has a fresh payment attempt and customer confirmation path. Follow its returned next action and [confirm that attempt](https://studio.inttegro.com/machine/java/api/orders.md#confirm-a-payment) when required.

#### Q4. What proves the retry recovered the sale?

[Look up the same order](https://studio.inttegro.com/machine/java/api/orders.md#lookup-an-order) and inspect current payment state. The retry call's acceptance or an OTP prompt does not establish a paid outcome.

#### Q5. Can MCP execute the retry?

Yes, with an authenticated connection and exact confirmation. [pay_order](https://studio.inttegro.com/machine/java/inttegro-mcp/tools.md#pay_order) can deliberately retry after a masked saved-method choice; new payment details and OTP stay in secure Inttegro Checkout. Use [get_order](https://studio.inttegro.com/machine/java/inttegro-mcp/tools.md#get_order) afterward to verify the result; a rendered card alone is not authoritative.

## Document content

# Retry a failed payment

Payment failures happen—networks timeout, customers enter wrong PINs, or mobile money accounts have insufficient balance. Instead of losing the sale, give your customers an easy way to retry. This guide shows you three strategies for recovering from failed payments, each optimized for different scenarios.

> Mcp Guide Callout is interactive content. Use the canonical page to view it.

## How payment retries work

When a payment fails, the order remains in the system with all its details intact. You use the `/orders/pay` endpoint to retry payment without creating a new order. This preserves the order ID, line items, and customer information while giving you flexibility in how to process the payment. You can retry with the same payment method (network glitch scenarios), switch to a different saved payment method (customer preference), or collect entirely new payment details (expired card, wrong account). Each retry triggers a fresh OTP and payment confirmation flow.

> **Note:**
>
> Payment retries are safe and idempotent. The order total remains unchanged,
> and each retry creates a new payment attempt that's tracked separately. Your
> customer won't be double-charged.

## Scenario 1: retry with the current payment method

Use this approach when the failure was likely temporary—a network timeout, momentary connectivity issue, or the customer accidentally dismissed the OTP prompt. The payment method itself is still valid; it just needs another attempt.

When you call `/orders/pay` with only the `orderId(…)`, Inttegro automatically retries the payment using the payment method already attached to the order. This is the simplest retry flow and works great for transient failures.

**Retry with current method — POST /orders/pay**

```java
import com.inttegro.Client;
import com.inttegro.orders.OrderPayParams;

public class Example {
  public static void main(String[] args) throws Exception {
    var client = new Client(System.getenv("INTTEGRO_API_KEY"));
    var params = OrderPayParams.builder()
      .orderId("or_failed_123")
      .build();
    var result = client.orders().pay(params);
  }
}
```

- `orderId(…)` — `string` — required

  The ID of the order with the failed payment. Find this in your original
  order creation response.

Inspect the returned order for its next action. If confirmation is required, submit the order ID, payment ID, confirmation-request ID, and customer token using [Confirm a payment](https://studio.inttegro.com/machine/java/api/orders.md#confirm-a-payment). The new payment attempt has its own identifiers; do not reuse identifiers from the failed attempt.

## Scenario 2: retry with a different saved payment method

Use this when the customer wants to switch to a different payment method they've previously used. Maybe their primary mobile money account has insufficient funds, or they prefer to use a different network this time. You'll pass the `paymentMethodId(…)` of an alternative saved method.

This only works for returning customers who have multiple saved payment methods. You can get available payment method IDs from the customer's previous orders or by calling the customer endpoint (if you've implemented customer management).

**Retry with saved method — POST /orders/pay**

```java
import com.inttegro.Client;
import com.inttegro.orders.OrderPayParams;

public class Example {
  public static void main(String[] args) throws Exception {
    var client = new Client(System.getenv("INTTEGRO_API_KEY"));
    var params = OrderPayParams.builder()
      .orderId("or_failed_123")
      .paymentMethodId("pm_alternative_method")
      .build();
    var result = client.orders().pay(params);
  }
}
```

- `orderId(…)` — `string` — required

  The ID of the order with the failed payment.

- `paymentMethodId(…)` — `string`

  The ID of an alternative saved payment method to use for this retry. The
  payment method must belong to the same customer as the original order.

> **Note:**
>
> The payment method must belong to the customer who owns the order. Inttegro
> validates this automatically and returns an error if there's a mismatch. This
> prevents accidental or malicious payment method substitution.

## Scenario 3: retry with new payment details

Use this when the customer needs to provide completely new payment information—they changed numbers, they closed their mobile money account, or they want to pay with a method they've never used before. You'll pass full payment details via `paymentMethodData(…)`, just like creating a new order.

This is the most flexible retry option. It works whether the customer is new or returning, and it automatically saves the new payment method for future use.

**Retry with new details — POST /orders/pay**

```java
import com.inttegro.Client;
import com.inttegro.orders.OrderPayParams;
import com.inttegro.paymentmethods.PaymentMethodData;
import com.inttegro.paymentmethods.PaymentMethodType;
import com.inttegro.paymentmethods.MobileMoneyParams;
import com.inttegro.paymentmethods.MobileMoneyNetwork;

public class Example {
  public static void main(String[] args) throws Exception {
    var client = new Client(System.getenv("INTTEGRO_API_KEY"));
    var params = OrderPayParams.builder()
      .orderId("or_failed_123")
      .paymentMethodData(PaymentMethodData.builder()
          .type(PaymentMethodType.MOBILE_MONEY)
          .mobileMoney(MobileMoneyParams.builder()
              .network(MobileMoneyNetwork.TELECEL)
              .accountNumber("0209876543")
              .build())
          .build())
      .build();
    var result = client.orders().pay(params);
  }
}
```

- `orderId(…)` — `string` — required

  The ID of the order with the failed payment.

- `paymentMethodData(…)` — `object`

  Complete payment method details. Structured exactly like the`paymentMethodData(…)` you'd provide when creating a new order.

  - `paymentMethodData(…).type(…)` — `string` — required

    Payment method type. Currently only `"mobile_money"` is supported.

  - `paymentMethodData(…).mobileMoney(…)` — `object`

    Mobile money payment details (required when `paymentMethodData(…).type(…)` is `"mobile_money"`).

    - `paymentMethodData(…).mobileMoney(…).network(…)` — `string` — required

      Mobile money network: `"airtel"`, `"mtn"`, `"telecel"`, or `"vodafone"`.

    - `paymentMethodData(…).mobileMoney(…).accountNumber(…)` — `string` — required

      Mobile money account number (typically a phone number). Should match
      the number that will receive the OTP.

> **Note:**
>
> When you provide new payment details, Inttegro automatically saves the payment
> method and associates it with the customer. The customer can use this method
> for future purchases without re-entering it.

## Confirming the retry

Regardless of which retry method you use, inspect the returned order. When its next action requires confirmation, submit [`order(…).id(…)`](https://java.inttegro.dev/v8.3.0/com/inttegro/orders/Order.html), [`order(…).payment(…).id(…)`](https://java.inttegro.dev/v8.3.0/com/inttegro/orders/Order.html), [`order(…).payment(…).nextAction(…).confirmPayment(…).request(…).id(…)`](https://java.inttegro.dev/v8.3.0/com/inttegro/orders/Order.html), and the customer's token. See [Confirm a payment](https://studio.inttegro.com/machine/java/api/orders.md#confirm-a-payment) for complete SDK examples.

## Best practices

### Let customers choose their retry strategy

Don't automatically retry with the same method. Show a failure message that explains what happened and give customers options: "Try again with this account", "Use a different saved account", or "Pay with a new account". This respects customer preference and improves success rates.

### Handle common failure patterns

Track why payments fail and adjust your retry UI accordingly. If the failure was `insufficient_funds`, suggest an alternative payment method immediately. If it was `network_timeout`, auto-retry once with the same method before asking the customer. If it was `invalid_pin`, explain that they need to enter the correct PIN—retrying won't help until they fix their input.

### Preserve order context

When retrying, show the customer what they're paying for. Display the order summary, line items, and total prominently so they can verify everything before confirming the OTP. This prevents confusion about duplicate charges.

### Set retry limits

Don't allow unlimited retries. After 3-5 failed attempts, pause and suggest the customer contact their mobile money provider or try a different payment method entirely. This prevents fraud patterns and protects against brute-force attacks.

### Monitor retry success rates

Track which retry strategies work best for your customers. If retries with saved methods succeed more often than new payment details, optimize your UI to suggest saved methods first. Use this data to improve your payment flow over time.

> **Note:**
>
> Never expose payment method IDs in client-side code or URLs. Always fetch them
> server-side and validate ownership before allowing retries. Treat payment
> method IDs with the same security as you would credit card numbers.
