REST API
WalletPro exposes a versioned REST API under the walletpro/v1 namespace, giving you full programmatic control over wallet balances, transactions, top-ups, redemption codes, and transfers. All endpoints follow WordPress REST API conventions and ship with an OpenAPI 3.1 spec and TypeScript types.
Overview
The WalletPro REST API is built on top of the WordPress REST API infrastructure (WP_REST_Server). Every route lives under:
https://yourstore.com/wp-json/walletpro/v1/
The API covers four primary resource groups:
| Resource group | Base path | Description |
|---|---|---|
| Wallets | /wallets |
Read and modify customer wallet balances |
| Transactions | /transactions |
Ledger entries, credits, debits, top-ups, transfers |
| Codes | /codes |
Generate, list, and redeem redemption codes |
| Transfers | /transfers |
Customer-to-customer wallet transfers |
All responses are JSON. All monetary amounts are returned as strings in the wallet's currency minor unit to avoid floating-point rounding (e.g., "amount": "1000" = $10.00 USD when the currency has 2 decimal places). The currency field on every response indicates which currency applies.
The OpenAPI 3.1 specification is available at /wp-json/walletpro/v1/openapi.json on any site with WalletPro active. TypeScript types are published to @walletpro/types on npm and are regenerated from the spec on every release.
Authentication
WalletPro endpoints respect the standard WordPress REST API authentication stack. Choose the method appropriate for your integration context.
Application Passwords (recommended for server-to-server)
Generate an Application Password at wp-admin > Users > Profile > Application Passwords. Include it as HTTP Basic Auth on every request:
# Base64-encode "username:application-password" (spaces stripped from the password)
curl -X GET \
"https://yourstore.com/wp-json/walletpro/v1/wallets/42" \
-H "Authorization: Basic dXNlcm5hbWU6eHh4eCB4eHh4IHh4eHggeHh4eA=="
WooCommerce API Keys (read/write scoping)
Generate keys at WooCommerce > Settings > Advanced > REST API > Add Key. Pass them as query parameters or Basic Auth (consumer_key as username, consumer_secret as password):
curl -X GET \
"https://yourstore.com/wp-json/walletpro/v1/wallets?consumer_key=ck_xxx&consumer_secret=cs_xxx"
Always use HTTPS. Passing API keys over plain HTTP exposes credentials in server logs. WalletPro will reject requests when WordPress detects an insecure connection and the FORCE_SSL_ADMIN constant is true.
Cookie + Nonce (browser / same-origin)
For JavaScript running in the same browser session (e.g., a custom Blocks extension), pass the logged-in cookie and a nonce in the X-WP-Nonce header:
const res = await fetch('/wp-json/walletpro/v1/wallets/me', {
headers: {
'X-WP-Nonce': wpApiSettings.nonce,
},
credentials: 'include',
});
const wallet = await res.json();
Permissions
Endpoint access is governed by WordPress capabilities:
| Capability | Default role | Access granted |
|---|---|---|
manage_woocommerce |
Shop Manager, Administrator | All endpoints, read and write any wallet |
read (own user) |
Customer | GET /wallets/me, GET /transactions (own), POST /transfers (own) |
walletpro_read_wallets |
Custom, grant via role editor | Read any wallet without full manage_woocommerce |
The custom walletpro_read_wallets and walletpro_write_wallets capabilities can be granted to any role using a role editor plugin, enabling read-only API integrations without elevating the account to shop manager.
Enabling the API
The REST API is active by default when WalletPro is installed. To confirm or adjust settings:
- Go to WooCommerce > WalletPro > Settings > Developer.
- Confirm Enable REST API is checked (default: on).
- Optionally enable REST API request logging to write every request and response to the WalletPro audit log, useful during integration testing, not recommended for production.
- Under Rate limiting, set Max requests per minute (API). Default is
120per authenticated identity. Set to0to disable rate limiting for trusted server integrations.
Wallets Endpoints
GET /walletpro/v1/wallets
List all wallets. Requires manage_woocommerce.
| Parameter | Type | Required | Description |
|---|---|---|---|
page |
integer | optional | Page number. Default 1. |
per_page |
integer | optional | Results per page. Default 10, max 100. |
currency |
string | optional | ISO 4217 currency code to filter by (e.g., USD). |
balance_min |
string | optional | Minimum balance in minor units (inclusive). |
balance_max |
string | optional | Maximum balance in minor units (inclusive). |
orderby |
string | optional | balance, created, or updated. Default created. |
order |
string | optional | asc or desc. Default desc. |
# List wallets with balance over $50.00 (USD, minor unit = cents → 5000)
curl -X GET \
"https://yourstore.com/wp-json/walletpro/v1/wallets?balance_min=5000¤cy=USD" \
-u "ck_xxx:cs_xxx"
Response:
{
"data": [
{
"id": 42,
"user_id": 7,
"currency": "USD",
"balance": "8500",
"balance_formatted": "$85.00",
"spending_limit": "20000",
"auto_reload_enabled": true,
"auto_reload_threshold": "1000",
"auto_reload_amount": "5000",
"created_at": "2025-03-01T09:00:00Z",
"updated_at": "2026-06-15T14:22:11Z"
}
],
"meta": {
"total": 1,
"total_pages": 1,
"page": 1,
"per_page": 10
}
}
GET /walletpro/v1/wallets/me
Returns the wallet for the currently authenticated user. Customers can call this endpoint with cookie + nonce authentication to read their own balance.
curl -X GET \
"https://yourstore.com/wp-json/walletpro/v1/wallets/me" \
-H "X-WP-Nonce: abc123" \
--cookie "wordpress_logged_in_xxx=..."
GET /walletpro/v1/wallets/{id}
Retrieve a single wallet by wallet ID. Requires manage_woocommerce or ownership.
POST /walletpro/v1/wallets/{id}/credit
Credit an amount to a wallet. Requires manage_woocommerce.
| Parameter | Type | Required | Description |
|---|---|---|---|
amount |
string | required | Amount to credit in minor units (e.g., "500" = $5.00). |
reason |
string | required | Human-readable reason stored in the audit ledger (max 255 chars). |
note |
string | optional | Internal note visible only to admins. |
expiry_date |
string (ISO 8601) | optional | Date after which this credit expires. Leave blank for no expiry. |
idempotency_key |
string | optional | UUID v4. If supplied, duplicate requests with the same key within 24 hours return the original transaction instead of creating a new one. |
curl -X POST \
"https://yourstore.com/wp-json/walletpro/v1/wallets/42/credit" \
-u "ck_xxx:cs_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": "1000",
"reason": "Loyalty reward Q2",
"expiry_date": "2026-12-31T23:59:59Z",
"idempotency_key": "550e8400-e29b-41d4-a716-446655440000"
}'
Response (201 Created):
{
"transaction_id": 1891,
"wallet_id": 42,
"type": "credit",
"amount": "1000",
"balance_after": "9500",
"reason": "Loyalty reward Q2",
"expiry_date": "2026-12-31T23:59:59Z",
"hmac_chain": "sha256:a3f8...",
"created_at": "2026-06-20T10:05:33Z"
}
POST /walletpro/v1/wallets/{id}/debit
Debit an amount from a wallet. The debit is atomic, if the wallet has insufficient balance and the request does not include "allow_partial": true, the endpoint returns 422 Unprocessable Entity and no funds are moved.
| Parameter | Type | Required | Description |
|---|---|---|---|
amount |
string | required | Amount to debit in minor units. |
reason |
string | required | Human-readable reason stored in the audit ledger. |
allow_partial |
boolean | optional | If true and balance is insufficient, debits the full available balance and returns 206 Partial Content. Default false. |
idempotency_key |
string | optional | UUID v4. Same semantics as the credit endpoint. |
Transactions Endpoints
GET /walletpro/v1/transactions
List ledger entries. Authenticated customers see only their own transactions. Admins can filter by any wallet.
| Parameter | Type | Required | Description |
|---|---|---|---|
wallet_id |
integer | optional | Filter to a specific wallet (admin only). |
type |
string | optional | Comma-separated list of types: credit, debit, topup, transfer_in, transfer_out, cashback, milestone, referral, withdrawal, expiry. |
after |
string (ISO 8601) | optional | Return transactions created after this date. |
before |
string (ISO 8601) | optional | Return transactions created before this date. |
page |
integer | optional | Page number. Default 1. |
per_page |
integer | optional | Default 25, max 100. |
# Fetch all cashback and milestone credits for wallet 42 in June 2026
curl -X GET \
"https://yourstore.com/wp-json/walletpro/v1/transactions?wallet_id=42&type=cashback,milestone&after=2026-06-01T00:00:00Z&before=2026-06-30T23:59:59Z" \
-u "ck_xxx:cs_xxx"
GET /walletpro/v1/transactions/{id}
Retrieve a single transaction. Each transaction object includes hmac_chain, the HMAC-SHA256 hash of this entry chained to the previous entry's hash, enabling tamper detection across the ledger.
{
"id": 1891,
"wallet_id": 42,
"type": "cashback",
"amount": "250",
"balance_before": "7250",
"balance_after": "7500",
"reason": "3% cashback on order #8812",
"order_id": 8812,
"currency": "USD",
"hmac_chain": "sha256:9c2a1f...",
"created_at": "2026-06-18T16:44:02Z"
}
Codes Endpoints
POST /walletpro/v1/codes
Generate one or more redemption codes. Requires manage_woocommerce.
| Parameter | Type | Required | Description |
|---|---|---|---|
amount |
string | required | Credit value of each code in minor units. |
quantity |
integer | optional | Number of codes to generate. Default 1, max 500 per request. |
expiry_date |
string (ISO 8601) | optional | Date after which codes cannot be redeemed. |
max_redemptions |
integer | optional | Maximum number of times each code can be redeemed. Default 1. |
prefix |
string | optional | String prepended to generated code strings (max 8 chars). Useful for campaign tracking (e.g., "SUMMER-"). |
restrict_to_user_id |
integer | optional | Lock code redemption to a specific user ID. |
curl -X POST \
"https://yourstore.com/wp-json/walletpro/v1/codes" \
-u "ck_xxx:cs_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": "2000",
"quantity": 50,
"prefix": "SUMMER-",
"expiry_date": "2026-08-31T23:59:59Z",
"max_redemptions": 1
}'
Response (201 Created):
{
"codes": [
{ "code": "SUMMER-A3KF92", "amount": "2000", "expiry_date": "2026-08-31T23:59:59Z" },
{ "code": "SUMMER-B7XQ14", "amount": "2000", "expiry_date": "2026-08-31T23:59:59Z" }
// ... 48 more
],
"count": 50
}
POST /walletpro/v1/codes/{code}/redeem
Redeem a code to the authenticated customer's wallet. Customers call this endpoint. No request body is required, the code is in the URL path.
curl -X POST \
"https://yourstore.com/wp-json/walletpro/v1/codes/SUMMER-A3KF92/redeem" \
-H "X-WP-Nonce: abc123" \
--cookie "wordpress_logged_in_xxx=..."
GET /walletpro/v1/codes
List all codes. Supports filtering by status (active, redeemed, expired), prefix, and date range. Requires manage_woocommerce.
Transfers Endpoints
POST /walletpro/v1/transfers
Transfer funds from the authenticated user's wallet to another customer's wallet. Requires the Wallet Transfers feature to be enabled at WooCommerce > WalletPro > Settings > Features > Allow customer-to-customer transfers.
| Parameter | Type | Required | Description |
|---|---|---|---|
to_user_email |
string | required | Email address of the recipient. Must be a registered customer. |
amount |
string | required | Amount to transfer in minor units. |
note |
string | optional | Optional message to include with the transfer (shown to recipient). |
Response includes two transaction objects: the transfer_out debit from the sender and the transfer_in credit to the recipient, both with matching transfer_group_id for cross-referencing.
Error Responses
All errors follow the WordPress REST API error envelope:
{
"code": "walletpro_insufficient_balance",
"message": "The wallet balance (4200) is less than the requested debit amount (5000).",
"data": {
"status": 422,
"balance": "4200",
"requested": "5000"
}
}
| Error code | HTTP status | Meaning |
|---|---|---|
walletpro_insufficient_balance |
422 | Debit or transfer amount exceeds available balance |
walletpro_spending_limit_exceeded |
422 | Transaction would breach the configured spending limit |
walletpro_velocity_cap_exceeded |
429 | Too many debits within the velocity window |
walletpro_code_already_redeemed |
409 | Redemption code has already been used |
walletpro_code_expired |
410 | Redemption code is past its expiry date |
walletpro_kyc_required |
403 | Customer must complete KYC verification before this action |
walletpro_step_up_required |
403 | Transaction requires step-up authentication; check data.step_up_url |
walletpro_idempotent_replay |
200 | Duplicate idempotency key, original transaction returned, not a new one |
walletpro_transfers_disabled |
403 | Customer-to-customer transfers are not enabled on this store |
Idempotency
All state-mutating endpoints (credit, debit, transfer, code generation) accept an optional idempotency_key field in the request body. The key must be a UUID v4 string. Duplicate requests with the same key from the same authenticated identity within 24 hours return the original response with HTTP 200 and the error code walletpro_idempotent_replay rather than performing the operation again.
This makes it safe to retry requests on network failure without risk of double-crediting or double-debiting.
Generate idempotency keys client-side with crypto.randomUUID() in modern browsers and Node.js 14.17+, or uuid.v4() from the uuid npm package. Store the key alongside the pending operation in your system before making the request so you can replay it on failure.
OpenAPI Spec and TypeScript Types
The full OpenAPI 3.1 specification is served live from your WordPress installation:
GET /wp-json/walletpro/v1/openapi.json
No authentication is required to read the spec. It reflects the exact endpoints, parameters, and response schemas available on your installed version of WalletPro.
TypeScript types are generated directly from the spec and published to npm:
npm install --save-dev @walletpro/types
import type { Wallet, Transaction, RedemptionCode } from '@walletpro/types';
async function getMyWallet(): Promise<Wallet> {
const res = await fetch('/wp-json/walletpro/v1/wallets/me', {
headers: { 'X-WP-Nonce': wpApiSettings.nonce },
credentials: 'include',
});
if (!res.ok) throw new Error(await res.text());
return res.json() as Promise<Wallet>;
}
The @walletpro/types package version matches WalletPro plugin versioning. Pin the package version in your package.json to match the plugin version running on your store to ensure schema compatibility.
Rate Limiting
Requests are rate-limited per authenticated identity (Application Password user, WooCommerce API key, or logged-in user session). When a limit is exceeded, the API returns 429 Too Many Requests with the following headers:
| Header | Description |
|---|---|
X-WalletPro-RateLimit-Limit |
Maximum requests allowed per window |
X-WalletPro-RateLimit-Remaining |
Requests remaining in the current window |
X-WalletPro-RateLimit-Reset |
Unix timestamp when the window resets |
Retry-After |
Seconds to wait before retrying |
Adjust the per-identity limit at WooCommerce > WalletPro > Settings > Developer > Max requests per minute (API). The redemption code endpoint has a separate, stricter rate limit configurable at WooCommerce > WalletPro > Settings > Codes > API rate limit (code redemptions) to guard against brute-force code enumeration.
Webhook Integration
Rather than polling the transactions endpoint, use WalletPro signed outbound webhooks to receive real-time notifications when wallet events occur. See the Webhooks reference for event types, payload structure, and signature verification.
Store API Extension (Blocks / Headless)
The REST API documented here is the administrative and customer-facing REST API. For integration with the WooCommerce Blocks checkout flow or headless storefronts using the Store API, see the Store API Extension reference, which covers the wallet balance display, apply-to-order endpoint, and cart totals extension.