Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions api-reference/authentication.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: "Authentication"
sidebarTitle: "Authentication"
description: "Authenticate requests to the WalletConnect Pay API with API keys."
---

Every request to the WalletConnect Pay API is authenticated with an API key, passed in the `Api-Key` header:

```bash
curl "https://api.pay.walletconnect.com/v1/merchants" \
-H "Api-Key: $WCP_API_KEY"
```

API keys are created and managed in the [dashboard](https://merchant.pay.walletconnect.com/en/api-keys). A key is shown only once at creation — store it in a secret manager. Anyone with the key can act on behalf of your account.

## Test and live keys

Your account has two kinds of keys, one for each mode:

| Key prefix | Mode | Behavior |
|---|---|---|
| `wcp_test_` | **Test** | Payments are simulated; no funds move. See [Test mode](/payments/test-mode). |
| `wcp_` | **Live** | Real payments with on-chain settlement. |

The key is the **only** thing that selects test or live. Both key types work against the same base URL and the same endpoints, and there is no test flag or mode parameter on any request.

<Warning>
Responses do not say whether a resource is test or live — that's determined by the key that created it.
</Warning>

## Errors

| Status | Meaning |
|---|---|
| `401 Unauthorized` | The key is missing, malformed, or revoked. |
| `403 Forbidden` | The key is valid but lacks permission for this account or resource. |

## Key safety

- **Never expose keys in client-side code.** All API calls should be made from your backend.
- **Use test keys everywhere except production.** Development, CI, and staging should use `wcp_test_` keys.
- **Rotate compromised keys immediately** from the [dashboard](https://merchant.pay.walletconnect.com/en/api-keys).
8 changes: 6 additions & 2 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"payments/token-and-chain-coverage",
"payments/fiat-coverage",
"payments/wallet-coverage",
"payments/cex-coverage"
"payments/cex-coverage",
"payments/test-mode"
]
},
{
Expand Down Expand Up @@ -135,6 +136,7 @@
"group": "Overview",
"pages": [
"api-reference/index",
"api-reference/authentication",
"api-reference/versioning"
]
},
Expand Down Expand Up @@ -202,7 +204,8 @@
"payments/token-and-chain-coverage",
"payments/fiat-coverage",
"payments/wallet-coverage",
"payments/cex-coverage"
"payments/cex-coverage",
"payments/test-mode"
]
},
{
Expand Down Expand Up @@ -292,6 +295,7 @@
"group": "Overview",
"pages": [
"api-reference/index",
"api-reference/authentication",
"api-reference/versioning"
]
},
Expand Down
Binary file added images/test-mode-create-payment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/test-mode-payment-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/test-mode-simulation-actions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/test-mode-test-console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 17 additions & 9 deletions payments/merchant/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ sidebarTitle: "Quickstart"
description: "Go from zero to your first payment with the WalletConnect Pay Merchant API in six steps."
---

This guide takes you from zero to a live payment in six steps:
This guide takes you from zero to your first payment in six steps.

1. **Create an API key** in the dashboard.
Every account has two modes: **test**, where payments are simulated and no funds move, and **live**, where payments execute on-chain for real. Both use the same API — the only difference is which API key you use (`wcp_test_…` vs `wcp_…`). This guide runs through the flow in **test mode first**, so you can build and verify everything safely. See [Test mode](/payments/test-mode) for the full picture.

1. **Create a test API key** in the dashboard.
2. **Authenticate** your requests with the key.
3. **Create your first merchant** via `POST /v1/merchants`.
4. **Configure crypto settlement** via `POST /v1/merchants/{merchantId}/settlements/crypto`.
Expand All @@ -19,20 +21,22 @@ Don't have access to the dashboard yet? [Contact sales](https://share.hsforms.co

<Steps>

<Step title="Create an API key" stepNumber="1">
<Step title="Create a test API key" stepNumber="1">

1. Open [**API Keys**](https://merchant.pay.walletconnect.com/en/api-keys) in the dashboard and sign in if prompted.
2. Click **Create key**. Copy the key — it is shown only once.
2. Create a **test key** — it starts with `wcp_test_`. Copy the key — it is shown only once.
3. Store it in a secret manager. Anyone with this key can act on behalf of your account.

With a test key, everything in this guide behaves like production except that no funds move. See [Test mode](/payments/test-mode) for exactly what test payments do and don't do.

</Step>

<Step title="Authenticate" stepNumber="2">

Every request to the Merchant API uses the `Api-Key` header.

```bash
export WCP_API_KEY="wcp_…" # the key you just created
export WCP_API_KEY="wcp_test_…" # the test key you just created
export WCP_BASE="https://api.pay.walletconnect.com"
```

Expand Down Expand Up @@ -163,7 +167,7 @@ curl "$WCP_BASE/v1/payments/$WCP_PAYMENT_ID/status" \
"isFinal": true,
"pollInMs": null,
"info": {
"txId": "0xabc123…",
"txId": "test:pay_…",
"optionAmount": {
"unit": "caip19/eip155:8453/erc20:0x...",
"value": "1000000"
Expand All @@ -174,12 +178,16 @@ curl "$WCP_BASE/v1/payments/$WCP_PAYMENT_ID/status" \

Use `isFinal` to decide when to stop polling. While the payment is still in flight, the response returns `isFinal: false` and a `pollInMs` hint for how long to wait before polling again. Once `isFinal` is `true`, `status` is one of `succeeded`, `failed`, `cancelled`, or `expired` and `pollInMs` is `null`.

<Tip>
Prefer webhooks for production — they remove the need to poll. The status endpoint is the right tool for one-off checks, scripts, and debugging.
</Tip>
<Note>
In test mode the `txId` is synthetic (`test:{paymentId}`) — no transaction is executed on-chain. Live payments return a real transaction hash.
</Note>

See the full response schema in [Get the payment status](/api-reference/latest/get-v1-payments-id-status).

</Step>

</Steps>

## From test to live

That's the whole flow. Repeating these same six steps with a **live key** (`wcp_` prefix) means every payment you create is a **real payment** — on-chain execution, real funds, real settlement. Nothing else changes: same API, same endpoints, same code. Test-mode data doesn't carry over, so you'll create your merchants and settlement configuration again with the live key.
8 changes: 8 additions & 0 deletions payments/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,19 @@ To learn more about what’s available and what’s coming next, contact us by f

## Get Started

Every integration can be built and verified end to end in [test mode](/payments/test-mode) — same API, no real funds — before going live.

<CardGroup cols={2}>
<Card title="Wallet Integration" icon="wallet" href="/payments/wallets/overview">
Integrate WalletConnect Pay into your wallet.
</Card>
<Card title="Ecommerce" icon="cart-shopping" href="/payments/ecommerce/overview">
Add crypto payments to your online checkout.
</Card>
<Card title="Merchant Quickstart" icon="rocket" href="/payments/merchant/quickstart">
Create your first test payment via the Merchant API in six steps.
</Card>
<Card title="Test Mode" icon="flask" href="/payments/test-mode">
Build and verify your integration without moving real funds.
</Card>
</CardGroup>
139 changes: 139 additions & 0 deletions payments/test-mode.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
title: "Test mode"
sidebarTitle: "Test mode"
description: "Integrate and verify your WalletConnect Pay setup end to end without moving real funds."
---

Every WalletConnect Pay account has two modes: **test** and **live**. Test mode lets you build and verify your full integration — merchants, settlement configuration, and payments — without executing anything on-chain.

Throughout these docs and on the hosted payment page, <span style={{color: "#7C3AED", fontWeight: 600}}>purple</span> indicates test mode. In the dashboard, the **Test / Live** selector at the top shows which mode you're working in.

## How test mode works

Test and live are separated at the **account level**, and you choose the mode by **which API key you use**. There is no `test` flag or mode parameter on any request — a payment created with a test key is a test payment, and a payment created with a live key is a live payment.

```mermaid actions={false}
flowchart LR
subgraph test ["Test mode"]
TK["wcp_test_… key"] --> TP["Test payment"]
TP --> TS["Synthetic settlement<br/>(no on-chain execution)"]
end
subgraph live ["Live mode"]
LK["wcp_… key"] --> LP["Live payment"]
LP --> LS["Real on-chain settlement"]
end
API["Same API<br/>api.pay.walletconnect.com"] --> TK
API --> LK
style test fill:#F5F3FF,stroke:#7C3AED,color:#5B21B6
style TK fill:#EDE9FE,stroke:#7C3AED,color:#5B21B6
style TP fill:#EDE9FE,stroke:#7C3AED,color:#5B21B6
style TS fill:#EDE9FE,stroke:#7C3AED,color:#5B21B6
```

Both modes use the **same API, the same base URL, and the same endpoints**. Nothing about your code changes between test and live except the key.

| | Test mode | Live mode |
|---|---|---|
| **API key prefix** | `wcp_test_` | `wcp_` |
| **Base URL** | `https://api.pay.walletconnect.com` | `https://api.pay.walletconnect.com` |
| **On-chain execution** | None — settlement is simulated | Real transactions |
| **Transaction hash** | Synthetic (`test:{paymentId}`) | Real on-chain hash |
| **Payment limit** | None | Pilot limit until your account goes live |
| **Data** | Fully separate from live data | Fully separate from test data |

## Test API keys

Test keys are created in the [dashboard](https://merchant.pay.walletconnect.com/en/api-keys), alongside live keys. You can tell them apart by the prefix: test keys always start with `wcp_test_`.

```bash
export WCP_API_KEY="wcp_test_…" # test key — safe to experiment with
export WCP_BASE="https://api.pay.walletconnect.com"
```

Merchants, settlement configurations, and payments created with a test key exist only in test mode. They are never visible to live requests, and vice versa.

<Warning>
API responses do **not** say whether a resource is test or live. The mode is determined entirely by the key that created the resource — if you need to tell test and live data apart in your systems, track which key produced it.
</Warning>

## What test payments do

A test payment moves through the same lifecycle as a live payment — created, processing, succeeded — so you can exercise your full integration, including status polling. The differences:

- **No funds move.** Nothing is executed on-chain and no settlement is delivered.
- **The transaction hash is synthetic.** Completed test payments report a `txId` of the form `test:{paymentId}` instead of a real on-chain hash.
- **Amounts are realistic.** Payment options are quoted from the amount you request, converted per token at current exchange rates — the same way live payments are priced.

## Test mode in the dashboard

You can run the whole test flow from the [dashboard](https://merchant.pay.walletconnect.com) without writing any code.

### Create a test payment

1. Switch the dashboard to **Test** with the selector in the top-right corner.
2. If you don't have any merchants in test mode yet, open **Merchants** and click **Create merchant** — give it a name and a contact email. Merchants are separate between test and live, so your live merchants don't appear in test.
3. Open **Payments** and click **Create payment**.
4. Select a merchant and enter any amount — test mode has no payment limit.
5. Click **Create payment**, then **Copy link** to share the payment link or open it yourself.

<Frame caption="Create payment in test mode (note the selector on Test, top right) — pick a merchant and enter any amount.">
<img src="/images/test-mode-create-payment.png" alt="Create payment dialog in test mode with a merchant selected and an amount of 10 USD entered" />
</Frame>

### Simulate status changes

Test payments don't move through their lifecycle on their own — you drive them, from either of two places:

- **The hosted payment page** — open the generated payment link. In test mode the page shows a <span style={{color: "#7C3AED", fontWeight: 600}}>purple</span> banner ("You're in test mode. No real funds move.") and lets you pay with a simulated **Test Wallet**. A floating **Test Console** lets you simulate the transition: **Confirm success**, **Simulate failure**, **Expire payment**, or **Cancel payment**.
- **The dashboard payments list** — in test mode, each payment row has a **Simulation actions** menu (three dots): pick **Mark as [status]** to transition it.

<Columns cols={2}>
<Frame caption="The hosted payment page in test mode — purple banner, Test Wallet, and the Test Console at the bottom.">
<img src="/images/test-mode-payment-page.png" alt="Hosted payment page in test mode showing the purple test-mode banner, a Test Wallet payment option, and the Test Console button" />
</Frame>
<Frame caption="The Test Console — available actions depend on the payment's current status.">
<img src="/images/test-mode-test-console.png" alt="Test Console panel titled Simulate transition, showing a test payment with Expire payment and Cancel payment actions" />
</Frame>
</Columns>

<div style={{marginTop: "2rem"}}>
<Frame caption="Simulation actions in the dashboard — a processing payment can be marked as succeeded, failed, or expired.">
<img src="/images/test-mode-simulation-actions.png" alt="Dashboard payments list in test mode with the Simulation actions menu open on a processing payment, showing Mark as Succeeded, Mark as Failed, and Mark as Expired options" />
</Frame>
</div>

### Allowed status transitions

Whichever surface you use, a test payment can only move along these paths:

```mermaid actions={false}
stateDiagram-v2
direction LR
requires_action --> processing
requires_action --> expired
requires_action --> cancelled
processing --> succeeded
processing --> failed
processing --> expired
```

Terminal states (`succeeded`, `failed`, `expired`, `cancelled`) have no further actions. This lets you exercise every status your integration needs to handle — including the failure paths that are hard to produce on demand with real payments.

## The pilot limit

Test mode has no payment limit — build and verify as much as you need.

**Live mode** starts in **pilot**: live payments are real, but they count toward a total payment limit until your account is taken off pilot. In live mode, the dashboard home shows a **Pilot to Live** card with the limit you have left. When you're ready to process real volume, click **Request to go live** — our team reviews the request and removes the limit.

Switching from test to live is just a key swap: create a **live key** (prefix `wcp_`) in the [dashboard](https://merchant.pay.walletconnect.com/en/api-keys) and use it instead — same API, same endpoints, no code changes. Test-mode data does not carry over, so re-create your merchants and settlement configuration with the live key.

## Next steps

<CardGroup cols={2}>
<Card title="Quickstart" icon="rocket" href="/payments/merchant/quickstart">
Create your first test payment in six steps.
</Card>
<Card title="Authentication" icon="key" href="/api-reference/authentication">
How API keys and the Api-Key header work.
</Card>
</CardGroup>
6 changes: 5 additions & 1 deletion payments/wallets/walletkit/ai-prompts/flutter.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,11 @@ if (actions.isEmpty) {

### Test Payment Links

Contact WalletConnect for test payment links or use the WalletConnect Pay sandbox environment.
Create test payment links from the WalletConnect Pay dashboard using a test-mode API key:

```
https://pay.walletconnect.com/?pid=<payment-id>
```

### Debug Logging

Expand Down
2 changes: 1 addition & 1 deletion payments/wallets/walletkit/ai-prompts/react-native.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ if (isPaymentLink(uri)) {

### Test Payment Links

Create test payment links from WalletConnect Pay dashboard:
Create test payment links from the WalletConnect Pay dashboard using a test-mode API key:

```
https://pay.walletconnect.com/?pid=<payment-id>
Expand Down