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

# Offramp Flow (Sell Crypto)

> This document shows the complete offramp flow for converting crypto to fiat and disbursing to users via different payment methods.

**Key Features**:

* Rate locking (60 seconds validity)
* Two flow modes: External wallet or Integrated wallet
* Automatic refunds on fiat transfer failure
* Multi-network crypto support (EVM, TRON, Lightning, Stellar)

***

## 1. Transaction Initiation & Rate Locking

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Kotani Pay

    User->>Kotani Pay: POST /offramp
    Kotani Pay->>Kotani Pay: Validate API Key
    Kotani Pay->>Kotani Pay: Validate Request
    Kotani Pay->>Kotani Pay: Check Duplicate

    alt Has Rate ID
        Kotani Pay->>Kotani Pay: Validate Rate (60s expiry)
        alt Rate Expired
            Kotani Pay-->>User: 400 Rate Expired
        end
    end

    Kotani Pay->>Kotani Pay: Lock Exchange Rate (Crypto→Fiat)
    Kotani Pay->>Kotani Pay: Calculate Fiat Amount & Fees
```

***

## 2. Crypto Receipt

### External Wallet Flow

User sends crypto from their own wallet.

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Kotani Pay
    participant Blockchain

    Kotani Pay->>Kotani Pay: Generate Deposit Address
    Kotani Pay->>Kotani Pay: Status: PENDING
    Kotani Pay-->>User: Send Crypto to Address

    User->>Blockchain: Transfer Crypto
    Blockchain->>Kotani Pay: Transaction Detected

    loop Monitor Confirmations (3+ blocks)
        Kotani Pay->>Blockchain: Check Confirmation Count
        alt Confirmed
            Blockchain-->>Kotani Pay: Confirmed
            Kotani Pay->>Kotani Pay: Status: CRYPTO_RECEIVED
        else Failed/Timeout
            Blockchain-->>Kotani Pay: Failed
            Kotani Pay->>Kotani Pay: Status: FAILED
        end
    end
```

### Integrated Wallet Flow

Platform wallet holds crypto, instant processing.

```mermaid theme={null}
sequenceDiagram
    participant Kotani Pay
    participant Blockchain

    Kotani Pay->>Kotani Pay: Verify Wallet Ownership
    Kotani Pay->>Blockchain: Deduct Crypto from Wallet
    Kotani Pay->>Kotani Pay: Status: CRYPTO_RECEIVED
    Note over Kotani Pay: Crypto already in platform custody
```

***

## 3. Fiat Disbursement

### Mobile Money Disbursement

```mermaid theme={null}
sequenceDiagram
    participant Kotani Pay
    participant MNO as Mobile Money Network
    participant User

    Kotani Pay->>Kotani Pay: Validate Phone & Network
    Kotani Pay->>MNO: Initiate Disbursement

    alt Disbursement Success
        MNO-->>Kotani Pay: Payment Sent
        MNO->>User: Funds Received
        Kotani Pay->>Kotani Pay: Status: SUCCESS
    else Disbursement Failed
        MNO-->>Kotani Pay: Payment Failed
        Kotani Pay->>Kotani Pay: Status: REFUND_PENDING
    end
```

**Available Countries**: All supported countries
**Networks**: M-PESA, Airtel Money, MTN Mobile Money, Orange Money

### Bank Transfer Disbursement

```mermaid theme={null}
sequenceDiagram
    participant Kotani Pay
    participant Bank as Bank Provider
    participant User

    Kotani Pay->>Kotani Pay: Validate Bank Details
    Kotani Pay->>Kotani Pay: Verify Account Number
    Kotani Pay->>Bank: Initiate Bank Transfer

    alt Transfer Success
        Bank-->>Kotani Pay: Transfer Complete
        Bank->>User: Funds Received
        Kotani Pay->>Kotani Pay: Status: SUCCESS
    else Transfer Failed
        Bank-->>Kotani Pay: Transfer Failed
        Kotani Pay->>Kotani Pay: Status: REFUND_PENDING
    end
```

**Available Countries**: All supported countries
**Processing Time**: Instant to 24 hours

***

## 4. Automatic Refund (On Fiat Failure)

```mermaid theme={null}
sequenceDiagram
    participant Kotani Pay
    participant Blockchain
    participant User

    Note over Kotani Pay: Fiat transfer failed
    Kotani Pay->>Kotani Pay: Queue Refund Job (5 min delay)
    Kotani Pay->>Kotani Pay: Status: REFUND_PENDING

    loop Refund Process (Max 3 retries)
        Kotani Pay->>Blockchain: Return Crypto to Sender
        alt Refund Success
            Blockchain->>User: Crypto Returned
            Blockchain-->>Kotani Pay: Crypto Refunded
            Kotani Pay->>Kotani Pay: Status: REFUNDED
        else Refund Failed
            Kotani Pay->>Kotani Pay: Retry Count++
            alt Max Retries Reached
                Kotani Pay->>Kotani Pay: Status: REFUND_FAILED
                Note over Kotani Pay: Manual intervention required
            end
        end
    end
```

***

## 5. Webhook Notification

```mermaid theme={null}
sequenceDiagram
    participant Kotani Pay
    participant CronJob
    participant Integrator

    Kotani Pay->>CronJob: Queue Callback Job
    CronJob->>Integrator: POST Webhook (Signed)

    alt Webhook Success
        Integrator-->>CronJob: 200 OK
        CronJob->>Kotani Pay: CALLBACK_SENT
    else Webhook Failed
        CronJob->>CronJob: Retry 3x with Backoff
        alt Retries Exhausted
            CronJob->>CronJob: Cron Retry (Every 2h, Max 24h)
        end
    end
```

***

## Transaction Statuses

| Status            | Description                                           |
| ----------------- | ----------------------------------------------------- |
| `PENDING`         | Awaiting crypto payment                               |
| `CRYPTO_RECEIVED` | Crypto confirmed, preparing fiat transfer             |
| `PROCESSING`      | Fiat disbursement in progress                         |
| `SUCCESS`         | Fiat delivered successfully                           |
| `FAILED`          | Transaction failed                                    |
| `REFUND_PENDING`  | Refund queued (fiat failed, returning crypto)         |
| `REFUNDED`        | Crypto returned to sender                             |
| `REFUND_FAILED`   | Refund attempts exhausted, manual intervention needed |
| `TIMEOUT`         | Crypto not received within timeout period             |

***

## Crypto Networks Supported

### EVM Chains

* **Networks**: Ethereum, Polygon, Arbitrum, Base, Optimism, Celo
* **Tokens**: USDT, USDC, DAI
* **Confirmations**: 3 blocks required

### TRON

* **Tokens**: USDT (TRC20)
* **Confirmations**: Verified via TronGrid

### Lightning Network

* **Use Case**: Fast Bitcoin offramps
* **Payment**: Lightning invoice

### Stellar

* **Tokens**: USDC, other Stellar assets
* **Confirmations**: Near-instant

***

## Key Features

### Rate Locking

* Exchange rate locked at transaction creation
* Valid for 60 seconds
* Must request new rate if expired

### Automatic Refunds

* Triggered 5 minutes after fiat transfer failure
* Up to 3 retry attempts
* Returns crypto to original sender address
* Track via `/offramp/refund-status/:referenceId`

### Flexible Wallet Options

* **External Wallet**: User controls private keys
* **Integrated Wallet**: Platform-managed for instant processing

***

## Error Handling

### Rate Expired

```json theme={null}
{
  "statusCode": 400,
  "message": "Rate expired. Rates are valid for 60 seconds."
}
```

### Insufficient Crypto Amount

```json theme={null}
{
  "statusCode": 400,
  "message": "Insufficient crypto amount"
}
```

### Fiat Transfer Failed (Auto-Refund)

```json theme={null}
{
  "status": "REFUND_PENDING",
  "message": "Fiat transfer failed. Crypto refund will be processed in 5 minutes.",
  "refund": {
    "cryptoAmount": 10.5,
    "currency": "USDT",
    "network": "Polygon"
  }
}
```

***

## Best Practices

* **Pre-Check Rates**: Use `/rates/offramp-rate` before creating transaction
* **Validate Addresses**: Ensure sender address format matches network
* **Handle Callbacks**: Implement webhook endpoint with HMAC verification
* **Monitor Refunds**: Check refund status via `/offramp/refund-status/:referenceId`
* **Bank Transfers**: Verify bank account details before submission

***

## Testing

Use sandbox mode with test credentials provided in sandbox documentation.

**Test Scenarios**:

* Crypto amounts ending in `.00` trigger success
* Crypto amounts ending in `.99` trigger fiat failure + refund
* Crypto amounts ending in `.88` trigger timeout
