Who This Guide Is For
New engineering teams integrating PayCA for the first time. You should already have:
- A workstation with Go 1.23+ and
curlor an API client such as Postman/Insomnia. - Network access to the sandbox base URL shared by your PayCA account manager.
- Client credentials (
x-client-id,x-client-secret) provisioned for the sandbox.
If you are renewing an existing integration, skip directly to Verify the Sandbox.
Step 1 - Configure Environment Variables
Store your sandbox credentials in environment variables or your preferred secrets manager so they never appear in plain-text scripts.
export PAYCA_BASE_URL="https://api.sandbox.payca.io"
export PAYCA_CLIENT_ID="6f1dbe35-43f7-466a-9941-1c01c5f8a6e7"
export PAYCA_CLIENT_SECRET="9a025859-1d2d-4c0f-90f5-28707c0b9d56"
Replace the sample values with the credentials you received from PayCA.
Step 2 - Verify the Sandbox
Check that your credentials work and the API is reachable.
curl -s \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
"$PAYCA_BASE_URL/health"
A healthy response reports the API build SHA and the database connection status. Capture the X-Request-ID header for support conversations.
Step 3 - Register Webhook Endpoints
Webhooks mirror every change to cards, accounts, and users. Each subscription handles exactly one event type, so call the endpoint once per type you want to receive (type = card, account, or user corresponds to the card_transaction, account_transaction, and user_account_transaction feeds).
curl -s -X POST "$PAYCA_BASE_URL/v1/webhooks" \
-H "Content-Type: application/json" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
-d '{
"url": "https://hooks.dev.example.com/payca/card",
"type": "card"
}'
Repeat the request with "type": "account" and "type": "user" (optionally pointing to separate URLs) to capture ledger and user wallet events. Each response returns a webhook id; persist every identifier so you can delete or resend deliveries later.
Step 4 - Pick a Master Funding Account
Issued cards and user wallets are funded from your master (primary client) accounts. List them with GET /v2/accounts, then pick an account in the currency you want to issue or fund.
curl -s "$PAYCA_BASE_URL/v2/accounts" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET"
Response snippet:
{
"accounts": [
{
"id": "c1bb6c19-3f9c-4cf0-9a08-5f2d00d021f1",
"currency": "USD",
"balance": { "available": "125000.00", "pending": "0.00" },
"status": "active",
"bins": [/* enabled BINs for this currency */]
}
]
}
Use accounts[].id as:
accountIdwhen issuing or topping up cards.fromAccountIdwhen transferring into a user wallet viaPOST /v1/users/transfer.
Step 5 - Issue a Card
Create a card by providing the funding account, target BIN, and initial balance. Include an idempotencyKey so failed retries remain safe.
curl -s -X POST "$PAYCA_BASE_URL/v1/cards" \
-H "Content-Type: application/json" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
-d '{
"accountId": "c1bb6c19-3f9c-4cf0-9a08-5f2d00d021f1",
"bin": "411111",
"balance": "50.00",
"externalUserId": "crm-98231",
"idempotencyKey": "issue-demo-001"
}'
The response returns the cardId, current balance snapshot, product code, and masked PAN. Store the cardId together with the accountId you debited.
Request field cheatsheet:
| Field | Required | Purpose |
|---|---|---|
accountId |
Yes | Account to debit (client or user). |
bin |
Yes | Six-digit BIN allocated to your tenant. |
balance |
Yes | Opening balance in card currency. |
externalUserId |
No | Echoed in downstream webhooks. |
idempotencyKey |
Strongly recommended | Ensures retries remain safe. |
Step 6 - Retrieve Sensitive Card Data (Optional)
If your PCI process requires access to the PAN and CVV, fetch them once and immediately vault them.
curl -s "$PAYCA_BASE_URL/v1/cards/<card-id>/sensitive" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET"
Step 7 - Fund the Card
You can add additional balance to the card at any time from any account you control (client or user):
curl -s -X POST "$PAYCA_BASE_URL/v1/cards/<card-id>/topup" \
-H 'Content-Type: application/json' \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
-d '{
"accountID": "c1bb6c19-3f9c-4cf0-9a08-5f2d00d021f1",
"amount": "75.00",
"idempotencyKey": "card-topup-75"
}'
Ensure the source account has enough available balance before calling the endpoint.
accountID and amount align with the CardTopUpRequest schema; reuse the same fields when calling /v1/cards/{id}/withdraw.
Step 8 - Run a Transaction End-to-End
Use the sandbox helper endpoint to simulate card flow. Substitute the cardId and currency from earlier steps.
curl -s -X POST "$PAYCA_BASE_URL/sandbox/transactions" \
-H "Content-Type: application/json" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
-d '{
"cardId": "<card-id>",
"currency": "USD",
"type": "authorization",
"amount": "42.55"
}'
Follow it with a settle request using the returned linkedId. Confirm that webhooks fire and ledger balances adjust as expected.
Step 9 - Instrument Observability
- Log every
X-Request-IDandx-signaturevalue from webhook deliveries. - Use the
trace_idfield provided by PayCA support to correlate ledger changes with upstream provider events. - Surface metrics: authorization success rate, decline reasons, average settlement time, and webhook processing latency.
Step 10 - Harden for Production
| Checklist | Description |
|---|---|
| Rotate credentials | Generate separate secrets per environment and service. |
| Enforce MTLS for webhooks | Restrict inbound IPs and verify certificates. |
| Set idempotency keys | Supply keys on every transfer, users API call, and payout. |
| Run load tests | Replay sandbox scenarios at production volume to validate webhook retries. |
| Map ledger accounts | Document every PayCA account ID alongside your ERP counterpart. |
Step 11 - (Optional) Create a User
If you plan to expose user wallets or need user-specific fee schedules, create users after you validate the core card pipeline. Each user gets a ledger wallet (userAccountId) you can fund from your master accounts via POST /v1/users/transfer. You can set status during creation (defaults to pending); switch to active via PATCH /v1/users/{id}/status before allowing transfers.
curl -s -X POST "$PAYCA_BASE_URL/v1/users" \
-H "Content-Type: application/json" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
-d '{
"userId": "c0ffee00-feed-face-cafe-babecafecafe",
"status": "pending",
"bins": [
{
"bin": "411111",
"currencyCode": "USD",
"provider": "visa",
"settings": { "minCardBalance": "25.00" },
"isTokenizable": true
}
],
"meta": {"segment": "testers"}
}'
Persist the returned userId and userAccountId (also exposed as id and account.id in GET /v1/users/{id}) if you intend to lock funds or top up via /v1/users/transfer. Transfers are permitted only for active users.
Where To Go Next
- Use the Sandbox Playbook to script and test multi-step scenarios (authorization -> split -> refund) before touching production balances.
- Review the Go-Live Runbook early so the deployment checklist and monitoring expectations are baked into your plan.
- Dive into the Card Issuing Integration Playbook for the authoritative card flow reference, including webhook linking and reconciliation tips.
- Read API Authentication & Headers for signing rules, pagination, and error handling specifics.
- Deep dive into Programme Entities to understand accounts, user wallets, cards, and revenue wallets.
- Walk through User Lifecycle & Control Flows once you decide to layer on user management.
When you are confident in sandbox results, request production credentials. The deployment checklist in the Go-Live Runbook ensures every dependency is ready before switching environments.
Quick Reference
| Step | Endpoint(s) | Notes |
|---|---|---|
| Sandbox health | GET /health |
Confirms credentials and platform reachability. |
| Register hooks | POST /v1/webhooks |
Capture card_transaction + account_transaction early. |
| Prepare funding | GET /v2/accounts |
List master accounts and confirm balances/BINs before you debit. |
| Issue card | POST /v1/cards |
Provide accountId, bin, balance, and idempotency key. |
| Operate card | POST /v1/cards/{id}/topup, /withdraw, /freeze, /unfreeze, DELETE /v1/cards/{id} |
Manage lifecycle and liquidity. |
| Observe activity | /sandbox/transactions, GET /v1/cards/{id}/transactions, webhooks |
Use referenceId to reconcile across feeds. |