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.

Developer REST API OpenAPI 3.1 TypeScript Headless Authentication

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:

  1. Go to WooCommerce > WalletPro > Settings > Developer.
  2. Confirm Enable REST API is checked (default: on).
  3. 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.
  4. Under Rate limiting, set Max requests per minute (API). Default is 120 per authenticated identity. Set to 0 to 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&currency=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.