# Cross-Chain Payments

Customers can pay for any Makapay payment link using **any supported token on any supported chain**, even if it's different from what the merchant requested. The customer's tokens are automatically bridged and swapped via [deBridge](https://debridge.com/) so that the merchant always receives exactly what they asked for, on the chain they asked for.

## Who this is for

* **Customers** who hold crypto on a different chain than the merchant's payment link is set up for. Example: a merchant accepts USDT on Ethereum, but the customer has USDC on Solana.
* **Merchants** who want to expand their addressable customer base without forcing buyers to bridge funds first.

## How it works (customer view)

1. Customer opens a payment link (`/pay/[id]`) and sees the merchant's expected amount + token + chain. Default flow (same-token, same-chain) is unchanged.
2. Below the on-chain payment area there's a small link: **"Pay with another token / chain"**. Click it.
3. A modal appears asking the customer to connect a wallet:
   * **EVM wallet** — MetaMask, Rabby, Coinbase Wallet, WalletConnect — for Ethereum, Polygon, BNB Chain, Base, Arbitrum, Optimism, Avalanche.
   * **Solana wallet** — Phantom or Solflare — for paying with SOL or any SPL token (USDC, USDT, EURC).
   * The customer can connect both at once if they have funds on different ecosystems.
4. As soon as a wallet connects, Makapay queries the customer's balances across every deBridge-supported chain (single Alchemy Data API call) and pre-quotes every viable route via deBridge's `create-tx` endpoint.
5. The customer sees a list of payment options:
   * **Clickable options** at the top, sorted by lowest source-side cost. The cheapest option is tagged **"Lowest cost"**.
   * **Insufficient-balance options** below, grayed out, with copy like "Need 0.05 more SOL".
   * Each option shows the source amount required (incl. a 1% slippage buffer), the chain, and an estimated USD value for stablecoin pairs.
6. Click an option → wallet popup → sign the deBridge order → tx broadcasts on the source chain.
7. The modal switches to a status timeline: **Broadcasted → Order locked → Solver delivered → Finalising → Complete**.
8. While the order is in flight, the merchant's payment expiry is automatically extended by 15 minutes so the system keeps watching the destination address.

## How it works (merchant view)

**You don't need to do anything.** From the merchant's side, the cross-chain flow is invisible:

* The merchant's payment link looks identical.
* The CREATE2 destination address receives exactly the requested amount + fee, just like a normal customer payment.
* The fee model is identical: 1% + $0.10, deducted on settlement, gas paid by the Gas Tank.
* Webhooks fire at the normal "received" point (full settlement after block confirmations).

You will see one new on-page indicator: a blue banner — **"Cross-chain payment in flight"** — showing on the `/pay/[id]` page when an active deBridge order is being filled. This explains why the payment hasn't expired even after the original countdown ran out.

## Settlement timing

| Source → Destination                          | Approximate time                              |
| --------------------------------------------- | --------------------------------------------- |
| Same-chain (existing flow)                    | 30s – 3min                                    |
| EVM → EVM (e.g. USDC-Polygon → USDT-Ethereum) | \~60s – 2min                                  |
| Solana → EVM (e.g. SOL → USDT-Ethereum)       | \~30s – 90s + destination block confirmations |

Cross-chain payments take roughly the same time as existing same-chain payments on Ethereum because the bottleneck is destination-side block confirmations, which apply to both. Layer-2 destinations (Base, Polygon) are noticeably faster.

## Failure modes

### "No solver fills the order"

If price moves more than 1% during the signing window, or if the customer picked a token with low solver liquidity, the order may sit in `Created` state. Two recovery paths:

* **Auto-cancel** after 5 minutes. Makapay's operator EOA initiates a cancel transaction on the destination chain. The locked source-side input is refunded to the customer's source wallet via deBridge's DMP message.
* **Manual cancel** by the customer in the modal: a "Cancel & refund" button appears once 90 seconds have passed. Same outcome — refund to source wallet.

### "Customer broadcasts but Solana tx fails"

No deBridge order is created. The customer sees an error and can retry within the original payment window.

### "Customer sees the success screen but merchant hasn't been credited yet"

Expected behaviour. deBridge's `Fulfilled` event fires when the solver delivers funds to the CREATE2 address. Makapay's pipeline still needs to wait for destination-chain block confirmations before sweeping to the merchant. The customer-facing modal shows "Solver delivered" → "Finalising" while this completes. Total wait: \~60–90s on EVM destinations after `Fulfilled`.

## Supported tokens (Phase 1)

Per chain, the customer can pay with:

| Source chain | Tokens                |
| ------------ | --------------------- |
| Ethereum     | USDT, USDC, ETH, EURC |
| Optimism     | USDT, USDC, ETH       |
| BNB Chain    | USDT, USDC, BNB       |
| Polygon      | USDT, USDC, MATIC     |
| Base         | USDC, ETH, EURC       |
| Arbitrum     | USDT, USDC, ETH       |
| Avalanche    | USDT, USDC, AVAX      |
| Solana       | USDT, USDC, SOL, EURC |

Tokens outside this list are filtered out of the customer-facing picker even if deBridge technically supports them. This keeps fill rates high (curated tokens have proven solver liquidity) and the UI scannable.

## Supported destinations

The merchant's destination (where they receive funds) must be an EVM chain in the deBridge supported list. Phase 1 supports: Ethereum, Optimism, BNB Chain, Polygon, Base, Arbitrum, Avalanche.

**MakaChain is not supported as a deBridge destination.** Same-chain MakaChain payments stay on the existing flow — there's no cross-chain entry point on MakaChain payment pages.

## Fees

| Fee                               | Who pays              | Notes                                        |
| --------------------------------- | --------------------- | -------------------------------------------- |
| Makapay platform fee (1% + $0.10) | Merchant              | Identical to same-chain payments.            |
| deBridge protocol fee (\~4 bps)   | Customer              | Deducted source-side by the protocol.        |
| Source-chain gas                  | Customer              | Paid by the customer's wallet on broadcast.  |
| Destination-chain gas             | Merchant via Gas Tank | Identical to same-chain.                     |
| 1% slippage buffer                | Customer              | Absorbed by the solver. Industry-standard.   |
| Affiliate fee                     | —                     | Phase 1: 0% — no Makapay markup on the swap. |

## Limits & out of scope

* **POS terminals do not surface the cross-chain option in Phase 1** — the timing (\~60–90s minimum) is too slow for in-store cashier UX. POS payments stay same-chain.
* **Tron support** is deferred to Phase 2. Phase 1 ships EVM + Solana only.
* **Solana / Tron / non-EVM as merchant destinations** — out of scope. The merchant always receives EVM tokens on EVM chains.

## Troubleshooting

### "Cannot cancel — a cross-chain swap is in flight"

The merchant tried to cancel a payment while a deBridge order was being filled. Wait until the swap either fulfils (payment completes normally) or is auto-cancelled (after 5 minutes). The lock prevents orphaning of in-flight funds.

### "deBridge create-tx failed: ERROR\_LOW\_GIVE\_AMOUNT"

The customer's source amount is too small to cover deBridge protocol fees + solver margin. Show a "increase amount" hint. This typically means a payment for less than \~$5 USD on certain expensive routes.

### "deBridge create-tx failed: COMPLIANCE\_ADDRESS\_BLOCKED"

The customer's wallet is on a sanctions list. The order cannot be built. Customer should pay from a different wallet.

### Customer's `srcTxHash` posted, but no `deBridgeOrderId` linked

The poller (every 30s) calls `/v1.0/dln/tx/{srcTxHash}/order-ids` to recover the orderId from a broadcast transaction hash. If this fails for >2 minutes, an ops alert fires. Most often resolves automatically once the source-chain tx achieves finality.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.makapay.io/features/cross-chain-payments.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
