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

# Payments guide

Everything you need to move money with Pesaswap, from your first test payment to recurring charges and payouts. Every page assumes you already have an API key and a `profile_id` — creating a merchant account, generating keys, and setting up connectors are covered elsewhere.

<Note>
  Base URL for these examples: `https://api.sandbox.pesaswap.io`. Authenticate every request with the `api-key: {{api_key}}` header. Swap the base URL for `https://api.pesaswap.io` in production.
</Note>

## Start here

<Card title="Accept your first payment" icon="rocket" href="/essentials/payments-guide/quickstart">
  The shortest path to a real M-Pesa payment: create, let the customer approve on their phone, poll until it settles. Start here if you are new.
</Card>

## Collecting money

<CardGroup cols={2}>
  <Card title="Wallet payments" icon="wallet" href="/essentials/payments-guide/wallet-payments">
    M-Pesa Express, Airtel Money, and MTN MoMo. One request shape, three wallets.
  </Card>

  <Card title="Card payments and 3DS" icon="credit-card" href="/essentials/payments-guide/card-payments">
    Cards with 3D Secure — the redirect flow and how to confirm the real outcome.
  </Card>

  <Card title="Mandates and recurring" icon="repeat" href="/essentials/payments-guide/mandates-and-recurring">
    Save a payment method once, then charge the customer again when they are away.
  </Card>

  <Card title="Refunds" icon="rotate-ccw" href="/essentials/payments-guide/refunds">
    Return money to a payer against a payment that has already succeeded.
  </Card>
</CardGroup>

## Paying money out

<Card title="Payouts" icon="banknote" href="/essentials/payments-guide/payouts">
  Send money to a recipient over M-Pesa, Airtel, MTN MoMo, PesaLink, Paybill, or Paytill.
</Card>

## How a payment completes

Most flows in this guide share one shape. You create a payment, the customer approves it out of band (an STK prompt on their phone, or a bank 3DS challenge), and then you **poll** for the result:

<Steps>
  <Step title="Create and confirm">
    `POST /payments` with `confirm: true`. The response comes back with a non-final status — the money has not moved yet.
  </Step>

  <Step title="The customer approves">
    They enter their M-Pesa PIN, or complete the bank challenge. This happens on their device, outside your API calls.
  </Step>

  <Step title="Poll for the outcome">
    `GET /payments/{payment_id}?force_sync=true` until the status settles to `succeeded` or `failed`.
  </Step>
</Steps>

<Warning>
  `force_sync` defaults to `false`, which returns the last **stored** status without contacting the connector. Omit `force_sync=true` and your polling loop will never see the payment settle.
</Warning>
