> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tribridge.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Tribridge is a crypto payment gateway for Solana and Sui (TON is coming soon). API base URL is https://tribridge.onrender.com. Server-side calls authenticate with the x-api-key header using a tri_test_... key (fully simulated test mode, no real funds) or tri_live_... key (real mainnet payments) — never expose keys client-side. Merchant test mode is simulated, not testnet. Refunds are automatic only (underpaid/overpaid), there is no manual refund endpoint. Always verify webhook HMAC-SHA256 signatures from the X-Tribridge-Signature header before trusting payloads.

# Refunds

> Automatic on-chain refunds for underpaid and overpaid payments — same asset, gas paid by Tribridge.

There is **no manual refund endpoint** — refunds on Tribridge are fully automatic. When a customer pays the wrong amount, Tribridge detects the mismatch, notifies you via webhook, and sends the refundable amount straight back to the payer's wallet on-chain. You do nothing.

## When refunds happen

| Situation | Webhook you receive | What Tribridge refunds |
| - | - | - |
| **Underpaid** — customer sent less than invoiced | `payment.underpaid` | The entire received amount, back to the payer |
| **Overpaid** — customer sent more than invoiced | `payment.overpaid` | Only the surplus above the invoiced amount |

Refunds always move the **same asset that was received**: SPL tokens for stablecoin payments on Solana (e.g. USDC), the same coin type on Sui, or the native SOL/SUI for native payments.

## How it works, step by step

<Steps>
  <Step title="Mismatch detected">
    The detection engine matches the deposit against the expected amount. If it doesn't match exactly, the payment is flagged and a `payment.underpaid` or `payment.overpaid` webhook fires with both the received and expected amounts.
  </Step>

  <Step title="Refund queued">
    Tribridge records the refund on the payment (`refund_status: pending`, plus the reason and amount) and fires it from the one-time deposit wallet back to the payer's address.
  </Step>

  <Step title="Gas covered by the relayer">
    You and your customer never think about gas. For token refunds the deposit wallet's native balance covers fees; for native SOL/SUI refunds a tiny gas buffer is kept back (5,000 lamports on Solana, \~0.003 SUI on Sui) and the rest is refunded. If the amount is too small to cover its own gas, the refund is marked `failed` rather than burning the funds.
  </Step>

  <Step title="Completion recorded">
    On success the payment stores `refund_status: completed` with the refund transaction hash. Failures are retried automatically (up to 5 attempts) — a stuck refund recovers on its own once the wallet can pay gas.
  </Step>
</Steps>

## Tracking refund status

Each payment carries refund fields you can inspect from the dashboard, activity log (`refund.requested`, `refund.completed`, `refund.failed` events), and your webhooks:

| `refund_status` | Meaning |
| - | - |
| `none` | No refund applies (exact payment). |
| `pending` | Refund queued or being retried. |
| `completed` | Refund landed on-chain (`refund_tx_hash` set). |
| `failed` | Refund could not complete after retries (e.g. amount too small for gas). |

## What you should build

* Handle `payment.underpaid` and `payment.overpaid` in your order logic — never assume the received amount equals the invoiced amount.
* Treat a mismatch as "not paid": don't fulfill the order on an underpaid event; on an overpaid event, fulfill for the invoiced amount and let the surplus refund run.
* Show customers their refund transaction hash from the dashboard if they ask where their money went.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.