| title | Axis Quickstart: From Signup to Live Payment in 5 Steps |
|---|---|
| sidebarTitle | Quickstart |
| description | Create a business account, provision a wallet, fund it, issue an API key, and fire your first payment — end-to-end in under 10 minutes. |
This guide walks you through the complete Axis onboarding flow from zero to a live payment. You will sign up for a developer account, register your business, create a scoped wallet for your agent, fund the wallet via a virtual bank account, and fire your first payment intent — all in under 10 minutes. Every step below maps to a real API call your frontend or setup script will make.
Create an Axis account by posting your credentials and account type to the auth endpoint. Use `accountType: "business"` if you are setting up payment infrastructure for a product, or `"developer"` for personal/sandbox use.When you sign up with `accountType: "business"`, Axis automatically provisions a business record and returns a `businessId` in the response — no separate business registration call is needed at this step.
**Request**
```bash
curl -X POST https://your-axis-instance.com/v1/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "ada@paystackdemo.io",
"password": "Sup3rS3cret!",
"accountType": "business"
}'
```
```json
{
"email": "ada@paystackdemo.io",
"password": "Sup3rS3cret!",
"accountType": "business"
}
```
**Response**
```json
{
"status": "success",
"data": {
"user": {
"id": "a3f7c291-8b4e-4d2a-9f1c-0e5b7d3a6c82",
"email": "ada@paystackdemo.io",
"accountType": "business",
"businessId": "b9e2d104-3c7f-4a1b-8e5d-2f0c9a4b6e31",
"createdAt": "2025-01-15T09:00:00.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJhM2Y3YzI5MS04YjRlLTRkMmEtOWYxYy0wZTViN2QzYTZjODIiLCJhY2NvdW50VHlwZSI6ImJ1c2luZXNzIiwiYnVzaW5lc3NJZCI6ImI5ZTJkMTA0LTNjN2YtNGExYi04ZTVkLTJmMGM5YTRiNmUzMSIsImlhdCI6MTcwNTMxMjAwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
}
```
Store the `token` — you will send it as `Authorization: Bearer <token>` on every subsequent developer-authenticated request. Tokens expire after **7 days**.
**Request**
```bash
curl -X POST https://your-axis-instance.com/v1/onboarding \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"businessName": "Paystack Demo Ltd",
"contactEmail": "ada@paystackdemo.io",
"contactPhone": "+2348012345678"
}'
```
```json
{
"businessName": "Paystack Demo Ltd",
"contactEmail": "ada@paystackdemo.io",
"contactPhone": "+2348012345678"
}
```
**Response**
```json
{
"status": "success",
"data": {
"businessId": "b9e2d104-3c7f-4a1b-8e5d-2f0c9a4b6e31",
"businessName": "Paystack Demo Ltd",
"contactEmail": "ada@paystackdemo.io",
"contactPhone": "+2348012345678",
"status": "active",
"createdAt": "2025-01-15T09:01:30.000Z"
}
}
```
| Field | Purpose |
|---|---|
| `spendLimitPerTx` | Maximum single transaction amount, in kobo |
| `spendLimitPeriod` | Maximum total spend within a rolling window, in kobo |
| `periodWindowDays` | Length of the rolling period window in days |
| `expiry` | ISO 8601 date-time after which the wallet rejects all payment intents |
| `useAllowlist` | When `true`, only merchants in `merchantAllowlist` are accepted |
| `merchantAllowlist` | Array of merchant name strings the agent is permitted to pay |
**Request**
```bash
curl -X POST https://your-axis-instance.com/api/wallets \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"name": "procurement-agent-wallet",
"userId": "a3f7c291-8b4e-4d2a-9f1c-0e5b7d3a6c82",
"spendLimitPerTx": 500000,
"spendLimitPeriod": 5000000,
"periodWindowDays": 30,
"expiry": "2026-01-15T00:00:00.000Z",
"useAllowlist": true,
"merchantAllowlist": ["Dangote Cement", "MTN Nigeria", "Julius Berger"]
}'
```
```json
{
"name": "procurement-agent-wallet",
"userId": "a3f7c291-8b4e-4d2a-9f1c-0e5b7d3a6c82",
"spendLimitPerTx": 500000,
"spendLimitPeriod": 5000000,
"periodWindowDays": 30,
"expiry": "2026-01-15T00:00:00.000Z",
"useAllowlist": true,
"merchantAllowlist": ["Dangote Cement", "MTN Nigeria", "Julius Berger"]
}
```
**Response**
```json
{
"status": "success",
"data": {
"wallet": {
"id": "wal_01hq9xkv9g7o0r4n0e6z",
"name": "procurement-agent-wallet",
"userId": "a3f7c291-8b4e-4d2a-9f1c-0e5b7d3a6c82",
"balance": 0,
"spendLimitPerTx": 500000,
"spendLimitPeriod": 5000000,
"periodWindowDays": 30,
"expiry": "2026-01-15T00:00:00.000Z",
"useAllowlist": true,
"merchantAllowlist": ["Dangote Cement", "MTN Nigeria", "Julius Berger"],
"status": "active",
"createdAt": "2025-01-15T09:03:00.000Z"
},
"apiKey": {
"id": "key_01hq9xkvah8p1s5o1f7a",
"prefix": "ax_live_3f9a1c",
"fullKey": "ax_live_3f9a1c0b2e7d4a8f5c1e3b9d2a7f0c4e8b1d5a3f7c2e9b4d0a6f8c1e3b5d2a7f4",
"walletId": "wal_01hq9xkv9g7o0r4n0e6z",
"createdAt": "2025-01-15T09:03:00.000Z"
},
"virtualAccount": {
"id": "vac_01hq9xkvbh9q2t6p2g8b",
"accountNumber": "0123456789",
"accountName": "Axis / Paystack Demo Ltd",
"bankName": "Guaranty Trust Bank",
"bankCode": "058",
"currency": "NGN"
}
}
}
```
<Warning>
The `apiKey.fullKey` value is returned **exactly once** — at wallet creation. Axis stores only a hashed version and cannot recover the plain-text key later. Copy `fullKey` into a secure secrets manager (e.g. AWS Secrets Manager, HashiCorp Vault, or your CI/CD environment variables) immediately. If it is lost, you must create a new wallet to obtain a fresh key.
</Warning>
From the response above:
```
Account Number : 0123456789
Account Name : Axis / Paystack Demo Ltd
Bank : Guaranty Trust Bank (058)
Currency : NGN
```
You can fund the wallet using:
- **Internet banking or mobile app** — a standard NGN transfer to the account number above from any Nigerian bank.
- **Programmatic transfer** — use your existing payment processor (e.g. Paystack, Flutterwave) to initiate a transfer to the virtual account.
Once the inbound payment settles, Axis receives a webhook from the issuing bank and automatically credits the wallet balance. The credit is reflected in the wallet's `balance` field (in kobo) and recorded as a `LedgerEntry`.
```json
{
"event": "wallet.funded",
"data": {
"walletId": "wal_01hq9xkv9g7o0r4n0e6z",
"amountCredited": 2000000,
"newBalance": 2000000,
"currency": "NGN",
"fundedAt": "2025-01-15T09:15:42.000Z"
}
}
```
There is no polling required — subscribe to the `wallet.funded` webhook event in your Axis dashboard to be notified when funds arrive.
**Request**
```bash
curl -X POST https://your-axis-instance.com/api/payment-intent \
-H "Content-Type: application/json" \
-H "x-api-key: ax_live_3f9a1c0b2e7d4a8f5c1e3b9d2a7f0c4e8b1d5a3f7c2e9b4d0a6f8c1e3b5d2a7f4" \
-d '{
"amount": 250000,
"merchantName": "Dangote Cement",
"recipientAccountNo": "0098765432",
"recipientBankCode": "058",
"reason": "Q1 2025 cement procurement — invoice #DC-00412"
}'
```
```json
{
"amount": 250000,
"merchantName": "Dangote Cement",
"recipientAccountNo": "0098765432",
"recipientBankCode": "058",
"reason": "Q1 2025 cement procurement — invoice #DC-00412"
}
```
| Field | Type | Required | Description |
|---|---|---|---|
| `amount` | integer | ✅ | Amount in kobo (e.g. `250000` = ₦2,500.00) |
| `merchantName` | string | ✅ | Must match an entry in `merchantAllowlist` when `useAllowlist` is `true` |
| `recipientAccountNo` | string | ✅ | 10-digit NUBAN account number of the recipient |
| `recipientBankCode` | string | ✅ | 3-digit NIP bank code (e.g. `058` for GTBank, `011` for First Bank, `057` for Zenith) |
| `reason` | string | ❌ | Optional payment description attached to the transaction record |
**Success response**
```json
{
"status": "success",
"data": {
"transactionId": "txn_01hq9xkvci0r3u7q3h9c",
"status": "successful",
"amount": 250000,
"currency": "NGN",
"merchantName": "Dangote Cement",
"recipientAccountNo": "0098765432",
"recipientBankCode": "058",
"recipientAccountName": "Dangote Cement PLC",
"reason": "Q1 2025 cement procurement — invoice #DC-00412",
"walletBalanceAfter": 1750000,
"executedAt": "2025-01-15T10:02:17.000Z"
}
}
```
Axis checks all of the following before executing the transfer. A failed check returns a `400` or `403` with a descriptive error:
- Wallet is **active** and not expired
- `amount` ≤ `spendLimitPerTx`
- Total spend in the current period window + `amount` ≤ `spendLimitPeriod`
- Wallet `balance` ≥ `amount`
- `merchantName` is in `merchantAllowlist` (when `useAllowlist: true`)