# Getting Started

> Accept your first crypto payment in five minutes. Create a payment link, redirect your customer, and receive settlement in your preferred stablecoin.

Source: https://mutopay.com/docs/getting-started/
Language: en

---

MutoPay is a crypto payment gateway. Your customer pays in any supported token on any supported chain; you receive your preferred stablecoin in your wallet. This guide takes you from zero to a working payment link in five minutes.

## What you need

1. A MutoPay account. Sign up at [mutopay.com/dashboard/register](https://mutopay.com/dashboard/register).
2. A settlement wallet address and preferred stablecoin/chain (set in [Settings](https://mutopay.com/dashboard/settings)).
3. A **channel API key** (prefix `ep_`). Every integration has its own channel. Create one at [Settings → Channels](https://mutopay.com/dashboard/settings).

## Test before you go live

When creating a channel, choose **Test** instead of Production to get a sandbox channel. Test channels mint keys with the `ep_test_` prefix and never touch a chain. Perfect for wiring up your integration end-to-end before accepting real funds.

What works the same as production:

- The same `POST /api/payments` request. No separate base URL.
- Real HMAC-SHA256 signed webhooks, with the same retry schedule (5 attempts, exponential backoff). Payloads carry an extra `"test": true` field so your handler can branch if it needs to.
- Your `redirect_url` fires as it would in production.

What's different:

- The hosted payment page shows a **TEST MODE** banner with four buttons (**Simulate complete**, **fail**, **expire**, **underpaid**) that fire the matching webhook on demand. No wallet connection, no on-chain interaction.
- Test payments are excluded from your dashboard stats and volume totals.
- The `mode` flag is **permanent on a channel**. To go live, create a separate Production channel and swap the key in your environment. Same model as Stripe's `sk_test_` / `sk_live_`.

Use a test channel for: webhook signature verification, status branching in your handler, idempotency under retry, and `redirect_url` flow. Then create a production channel and replace the key.

## Create a payment

```bash
curl -X POST https://mutopay.com/api/payments \
  -H "X-API-Key: ep_your_channel_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_usd": 25.00,
    "description": "Order #1042",
    "external_id": "order_1042",
    "callback_url": "https://yourstore.com/thanks"
  }'
```

Response:

```json
{
  "id": "pay_abc123",
  "status": "pending",
  "url": "https://mutopay.com/pay/pay_abc123",
  "expires_at": "2026-04-21T14:30:00Z"
}
```

Redirect your customer to the `url`. They pick a token, connect their wallet (or scan a QR code for manual transfers), and the hosted page handles the rest.

## Receive the result

Two options (use both in production):

1. **Webhook** (recommended). Configure your endpoint in the dashboard. MutoPay POSTs to it with an HMAC-SHA256 signature when the payment completes, fails, or expires. See [Verify a webhook signature](/docs/verify-webhook-signature/).
2. **Polling**. `GET https://mutopay.com/api/payments/{id}/status` returns the current `status`. Useful as a fallback or for the browser "thanks" page.

## What happens on-chain

- Customer pays in USDC on BSC → MutoPay executes a cross-chain swap → you receive USDC on Polygon (for example). Fees are deducted before settlement.
- Direct transfers (customer pays the same token/chain you want to receive) skip the swap.

## Next steps

- [Authentication](/docs/authentication/): channel keys vs. master key vs. JWT.
- [Create a Payment](/docs/create-payment/): full request/response reference with every parameter.
- [Webhooks](/docs/webhooks/): events, payload shape, retry schedule.
- [Interactive API reference](https://mutopay.com/api/docs): try every endpoint in your browser.
