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

# invoice.settled

> Funds have been transferred to your wallet. This is the event to act on — it is the only event that guarantees funds are in your wallet.

## When it fires

After Settlx successfully transfers the settled funds to your configured wallet address. At this point the payment lifecycle is complete and the money is yours.

***

## What to do

**Fulfill the order.** This is the only event that confirms funds have arrived in your wallet.

* Release the digital product
* Activate the subscription
* Ship the physical order
* Grant account access

Do not fulfill on any earlier event such as `invoice.confirmed`. Payment confirmation does not mean settlement is complete.

***

## What lands in your wallet

The amount that arrives in your wallet is `data.settlement.netAmount` — the gross amount minus all fees.

| Field                         | Description                          |
| ----------------------------- | ------------------------------------ |
| `data.settlement.grossAmount` | Amount before fees are deducted      |
| `data.settlement.netAmount`   | **Amount that lands in your wallet** |
| `data.fees.platformFee`       | Settlx platform fee                  |
| `data.fees.networkFee`        | On-chain gas fee                     |
| `data.fees.totalFees`         | Sum of all fees deducted             |

***

## Payload

**Includes:** `invoice`, `payment`, `settlement`, `fees`. Also includes `conversion` if a token swap occurred.

```json theme={null}
{
  "event": "invoice.settled",
  "eventId": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890_invoice.settled_1744455900000",
  "timestamp": "2026-04-12T11:05:00.000Z",
  "data": {
    "invoice": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "amount": "49.99",
      "currency": "USD",
      "settlementCurrency": "USDT",
      "settlementChain": "polygon",
      "status": "settled",
      "createdAt": "2026-04-12T10:00:00.000Z",
      "metadata": { "orderId": "order_123", "customerId": "cust_456" }
    },
    "payment": {
      "id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
      "transactionHash": "0xabc123...",
      "amount": "49.99",
      "currency": "USDT",
      "chain": "polygon",
      "confirmations": 12,
      "status": "confirmed"
    },
    "settlement": {
      "id": "d4e5f6a7-b8c9-0123-def0-456789012345",
      "transactionHash": "0xdef456...",
      "grossAmount": "49.99",
      "netAmount": "48.74",
      "currency": "USDT",
      "chain": "polygon",
      "status": "completed"
    },
    "fees": {
      "platformFee": "0.75",
      "platformFeePercent": "1.5%",
      "networkFee": "0.50",
      "providerFee": "0.00",
      "totalFees": "1.25",
      "currency": "USDT"
    }
  }
}
```

***

## Handler example

```javascript Node.js theme={null}
app.post('/webhooks/settlx', express.raw({ type: 'application/json' }), async (req, res) => {
  // Verify signature first — see Webhook Overview for full verification code
  verifySignature(req);

  const event = JSON.parse(req.body);

  if (event.event === 'invoice.settled') {
    const { invoice, settlement, fees } = event.data;

    // Always identify the order by your own metadata, not by invoice.id
    const orderId = invoice.metadata?.orderId;
    if (!orderId) {
      console.error('Missing orderId in invoice metadata', invoice.id);
      return res.status(200).json({ received: true }); // Acknowledge but log the issue
    }

    // Use eventId for idempotency — store it and skip if already processed
    const alreadyProcessed = await db.events.exists(event.eventId);
    if (alreadyProcessed) {
      return res.status(200).json({ received: true });
    }
    await db.events.insert(event.eventId);

    // netAmount is what landed in your wallet after all fees
    const amountReceived = settlement.netAmount;
    const currency = settlement.currency;

    // Fulfill the order
    await db.orders.update(orderId, { status: 'fulfilled' });
    await fulfillOrder(orderId, { amountReceived, currency });

    console.log(`Order ${orderId} fulfilled. Received ${amountReceived} ${currency}.`);
  }

  res.status(200).json({ received: true });
});
```

<Warning>
  Always use `data.invoice.metadata.orderId` to identify the order. Never rely on `data.invoice.id` alone as your order identifier — invoice IDs are internal to Settlx and not meaningful to your system without the metadata link.
</Warning>

***

## Related events

* [`invoice.confirmed`](/webhook-events/invoice-confirmed) — Payment detected on-chain. Settlement has not completed yet.
* [`invoice.underpaid`](/webhook-events/invoice-underpaid) — Payment received but below the required amount.
