Direct API (S2S)

Multi-Method Payments

Offer several payment methods in one session and let the customer choose.

Multi-method payments let you offer customers alternative options when their preferred method fails. For example, if a customer's card is declined, you can automatically offer a SPEI bank transfer or an OXXO voucher as a backup.

How the fallback flow works

The fallback logic builds a prioritized list of payment methods and attempts each one until a transaction succeeds. This way, if the preferred method fails (insufficient funds, card declined, or a technical issue), your system automatically tries alternatives without the customer manually selecting another option.

The flow follows these steps:

Start with the customer's preferred method and call the Tonder API.

If it's authorized or pending, complete the transaction.

If the payment fails or is declined, check whether alternative methods are available.

If more methods exist, automatically try the next one in your priority list.

If all methods are exhausted, show an error message; otherwise, process the successful payment.

User experience first. Always inform users about fallback attempts. Ask for permission before switching to alternative methods rather than automatically redirecting to methods they didn't choose.

Step 1: define your fallback strategy

Plan your payment method priority order. A typical sequence:

  1. Card: the most common and immediate method.
  2. SPEI: a reliable alternative, especially for larger amounts.
  3. OXXO: a final fallback for users without a bank account or card.

Your server-side logic controls this flow. The Tonder API processes each request as a standalone transaction.

Step 2: implement the fallback loop

Create a function that tries each method sequentially until one succeeds:

import uuid

def process_payment_with_fallback(customer_data, amount, preferred_method="CARD"):
    """Attempts to process a payment with a preferred method, with fallbacks."""

    payment_methods_priority = [
        preferred_method,
        "CARD",      # Fallback to card if it wasn't the preferred method
        "SPEI",      # Next, a bank transfer
        "oxxopay"    # Final fallback is cash
    ]

    # Avoid duplicate attempts (e.g. if preferred_method is already 'CARD')
    unique_methods = list(dict.fromkeys(payment_methods_priority))

    for method in unique_methods:
        print(f"Attempting payment with method: {method}")
        try:
            payment_data = {
                "operation_type": "payment",
                "amount": amount,
                "currency": "MXN",
                "customer": customer_data,
                "payment_method": {"type": method},
                "client_reference": f"order-{uuid.uuid4()}"
            }

            result = tonder_api.process_payment(payment_data)

            # A successful initiation has status 'authorized' or 'pending'.
            if result.get("status") in ["authorized", "pending"]:
                print(f"Payment initiated with {method}. Transaction ID: {result['id']}")
                return result
            else:
                print(f"Payment with {method} failed with status: {result.get('status')}")

        except Exception as e:
            print(f"API call for method {method} failed: {e}")
            continue

    raise Exception("All payment methods failed for this transaction.")

Next steps

Was this page helpful?

On this page