Advanced error handling

This guide describes how to build resilient integrations with the Paypercut API.

It covers retry strategies, idempotency, and how to handle transient failures safely.


Overview

Not all errors should be treated the same.

Your integration should distinguish between:

  • permanent failures that require correction
  • temporary failures that can be retried
  • network-level failures where the outcome is unknown

Blindly retrying all failed requests can lead to duplicate operations, inconsistent state, and degraded user experience.


Retry strategy

Retries should only be performed when a request fails due to a temporary condition.

Safe to retry

Retry when the failure is likely temporary:

  • HTTP 500 (internal error)
  • HTTP 502, 503, 504 (upstream issues)
  • network timeouts
  • connection failures
  • payment declines with advice_code = try_again_later

Do not retry

Do not retry when the failure is permanent:

  • HTTP 400 (invalid request)
  • HTTP 401 (authentication failed)
  • HTTP 403 (forbidden)
  • card declines with advice_code = do_not_try_again
  • validation errors

Exponential backoff

When retrying, use exponential backoff.

Example strategy:

  • Retry after 1 second
  • Retry after 2 seconds
  • Retry after 4 seconds
  • Retry after 8 seconds

Avoid tight retry loops. Always introduce delays between retry attempts.


Idempotency

Idempotency ensures that retrying a request does not create duplicate operations.

This is critical for:

  • creating payments
  • creating accounts
  • any operation with side effects

Idempotent requests

Your integration should send an idempotency key with all POST requests that create or mutate state.

Example:

POST /v2/payments
Idempotency-Key: 01HZY6...

Behavior

When the same idempotency key is reused:

  • the first request is processed normally
  • subsequent identical requests return the same result

This guarantees that retries do not create duplicate resources.


When to use idempotency

Use idempotency for:

  • payment creation
  • account creation
  • payout operations
  • any request that may be retried automatically

Always reuse the same idempotency key when retrying the same logical operation.


Network failures

Network failures are different from API errors.

Examples:

  • request timeout
  • connection reset
  • DNS failure

In these cases, the request outcome is unknown.


Handling unknown outcomes

When a request fails at the network level:

  • the request may have succeeded
  • the request may have failed
  • the client did not receive the response

To handle this safely:

  • retry using the same idempotency key
  • avoid issuing a new request without idempotency protection

Payment-specific retries

For payments, retry behavior should be guided by decline data.

Retry only when:

  • advice_code = try_again_later
  • the decline category is temporary or soft

Do not retry when:

  • advice_code = do_not_try_again
  • the decline is permanent (for example, insufficient funds or expired card)

Request customer action when:

  • decline_code = authentication_required
  • card details must be corrected
  • a different payment method is required

Handling timeouts

If a request times out:

  • do not assume failure
  • retry with the same idempotency key
  • check resource state if possible

Logging and observability

Your integration should log:

  • request payloads (excluding sensitive data)
  • response status codes
  • error objects
  • trace_id

The trace_id is the primary identifier used to debug issues with Paypercut support.


Send request with idempotency key

Ensure all state-changing requests include an idempotency key.

Handle response

Process successful responses and error responses accordingly.

Retry if appropriate

Retry only for transient failures using exponential backoff.

Log trace ID

Store the trace ID for debugging and support.


Best practices

  • Use idempotency for all write operations
  • Implement exponential backoff for retries
  • Avoid retrying permanent failures
  • Use decline and advice codes for payment decisions
  • Treat network failures as unknown outcomes
  • Log all errors with trace IDs