This guide shows how to load funds into PayCA, distribute them to users, and double-check that balances reflect each operation.

What You Control

  • Tenant balance – Prefunded amount PayCA holds on behalf of your organisation per currency.
  • User wallets – Balances tied to individual users (userAccountId).
  • Card transactions – Authorisations, settlements, refunds, and declines generated by your customers.

Everything else (provider clearing accounts, scheme fees, reconciliations) is managed by PayCA and surfaced back to you via APIs and webhooks.

Workflow Overview

  1. Prefund your tenant balance through the finance channel agreed with PayCA.
  2. Transfer funds from the tenant balance into a user wallet using the API.
  3. Simulate card spend (sandbox) or let production traffic run.
  4. Reconcile balances and events using API endpoints and webhook payloads.

Step 1 – Check Available Balance

curl -s "$PAYCA_BASE_URL/v1/users/stats" \
  -H "x-client-id: $PAYCA_CLIENT_ID" \
  -H "x-client-secret: $PAYCA_CLIENT_SECRET"

Focus on:

  • liquidity.balance – Available funds.
  • liquidity.pending – Holds from outstanding authorisations.
  • liquidity.feesThisMonth – Fees accrued so far.

Set an alerting threshold so operations teams know when to top up the tenant balance.

Step 2 – Allocate Funds to a User

curl -s -X POST "$PAYCA_BASE_URL/v1/users/transfer" \
  -H "Content-Type: application/json" \
  -H "x-client-id: $PAYCA_CLIENT_ID" \
  -H "x-client-secret: $PAYCA_CLIENT_SECRET" \
  -H "Idempotency-Key: transfer-user-123-20250602" \
  -d '{
    "fromAccountId": "<tenant-account-id>",
    "toAccountId": "<user-account-id>",
    "amount": "250.00",
    "currency": "USD"
  }'

Success response returns a transaction identifier. Store it together with the idempotency key so you can safely retry if the network fails.

Expect a user_account_transaction webhook describing the movement. Use it to update downstream systems (CRM, ERP, customer notifications).

Step 3 – Observe Card Activity

In sandbox, trigger transactions via POST /sandbox/transactions. In production, ingest live webhooks.

Watch for:

  • card_transaction webhooks (authorization, cleared, refunded, declined).
  • user_account_transaction updates reflecting balance changes.
  • Optional account_transaction events that show tenant-level movements such as fees.

Step 4 – Reconcile

Daily or weekly, pull the data you need for reconciliation:

  1. BalancesGET /v1/users/stats plus per-user GET /v1/users/{id}.
  2. Activity – Export webhooks keyed by data.id for the relevant date range.
  3. Fees – Sum account_transaction events where type=fee or rely on feesThisMonth for quick snapshots.
  4. Variance – Compare API totals with your internal ledger. Investigate difference by tracing back through referenceId and idempotency keys.

Best Practices

  • Always include an Idempotency-Key on transfers to guard against double posting.
  • Store webhooks before processing to ensure you can replay or audit them later.
  • Automate alerts for low tenant balance and high decline rates.
  • Tag transfers with metadata (e.g., statement period, campaign) to simplify reporting.

Troubleshooting

Issue Likely Cause Next Step
Transfer rejected with ErrInvalidArg Currency mismatch or bad account ID. Verify both accounts use the same currency and exist.
Authorization denied with insufficient_liquidity Tenant balance too low. Top up via finance channel and retry.
Duplicate transfer detected Same idempotency key already used. Reuse the key only when replaying the same intent.
Missing webhook Receiver returned non-2xx or timed out. Fix the receiver and call /v1/webhooks/resend.

For more about webhook ingestion, head to Webhook Handling Patterns. To learn how fees are reported back to you, see Fees & Revenue Recognition.