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

# Your first complete payment in sandbox

> The whole cycle end to end: create a sub-client, open an account, fund it, and pay someone.

Six calls, in order. Each needs an id from the one before it, so keep them as you go.

Every step links to its endpoint page, where the full request, every field and a live **Try it** are. This page is the order and the common mistakes.

<Steps>
  <Step title="Create a sub-client">
    **[Create a user](/api-reference/users/create-a-user)**

    The body carries the registration documents as base64 data URIs, so this is the one call you cannot make from a copied snippet. The endpoint page lists every field it takes.

    **Keep:** `id`. It is the `user_id` every later call takes.
  </Step>

  <Step title="Wait for verification">
    **[Get a user](/api-reference/users/get-a-user)**

    The sub-client cannot hold money until it is verified. Read `status` and `verification_status`, or wait for the webhook rather than polling for it.

    **Watch for:** `missing_fields` names anything still outstanding, grouped by product. It is what you show your own customer, not your engineers.
  </Step>

  <Step title="Open a virtual account">
    **[Create a virtual account](/api-reference/virtual-accounts/create-a-virtual-account)**

    **Keep:** `id`, as the `virtual_account_id`.

    **Watch for:** the account comes back nearly empty. The bank details arrive when the bank assigns them and are `null` until then, so do not gate your flow on the account being usable immediately. [The virtual account object](/reference/virtual-accounts/the-virtual-account-object) lists everything it carries.
  </Step>

  <Step title="Put money in it">
    **[Simulate a deposit](/api-reference/virtual-accounts/simulate-a-deposit)** — sandbox only.

    This is not a notification: it credits the account for real, so a payout can then draw on it. It also fires the deposit webhook, which is how a real deposit announces itself.

    **Then check [the balance](/api-reference/virtual-accounts/get-virtual-account-balance)** before paying out. The balance includes any opening sandbox float, so a payout can succeed without a deposit — confirm the figure rather than assuming your deposit is all of it.
  </Step>

  <Step title="Create and save the counterparty you will send money to">
    **[Create a recipient](/api-reference/recipients/create-a-recipient)**

    **Keep:** `recipient_id`.

    **Watch for:** the `account_type` you choose here decides the rail every payment to them travels on, and every payment after that — see [Rail](/overview/model/rail).
  </Step>

  <Step title="Pay them">
    **[Execute a payout](/api-reference/payouts/execute-a-payout)**

    **Watch for:** the payout comes back with a `status` and an `events` list that grows as it moves. Which tracing identifiers arrive depends on the rail — a bank payout has no transaction hash, a crypto one has no wire reference. [The payout object](/reference/payouts/the-payout-object) has all of them.
  </Step>
</Steps>

## You are done

You have moved money end to end. What is worth doing next, in this order:

1. **Handle the webhooks.** Everything above was read by asking; in production the states announce themselves. See the [Webhooks guide](/webhooks/overview).
2. **Price before you pay**, when the amount matters to your customer — see [Quotation](/overview/model/quotation).

<Card title="Go-live checklist" icon="arrow-right" href="/get-started/go-live-checklist">
  What has to be true before you point this at production.
</Card>
