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 a Webhook Endpoint
Webhooks mirror every change to cards, accounts, and users. Even if you intend to poll, subscribe now so you can see real event payloads during onboarding.
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",
"events": ["card_transaction", "account_transaction", "user_account_transaction"],
"description": "Sandbox integration"
}'
The response contains a webhook id. Persist it because you will need the identifier to resend failed deliveries.
Step 4 - List Accounts and Pick an Issuing Source
Issued cards draw funds from your programme mirror account. List the accounts available to your tenant and note the UUID of the account you want to debit.
curl -s "$PAYCA_BASE_URL/v1/accounts" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET"
Identify the account whose currency matches the card you plan to issue. Use its id as the accountId in the next step.
Response snippet:
{
"data": [
{
"id": "c1bb6c19-3f9c-4cf0-9a08-5f2d00d021f1",
"currency": "USD",
"balance": {
"available": "125000.00",
"pending": "0"
}
}
],
"page": 0,
"total": 1
}
id feeds the card issuance request, while balance.available shows the funds you can draw down.
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",
"tokenize": true,
"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 mirror accountId you debited.
Request field cheatsheet:
| Field | Required | Purpose |
|---|---|---|
accountId |
Yes | Mirror account to debit. |
bin |
Yes | Six-digit BIN allocated to your tenant. |
balance |
Yes | Opening balance in card currency. |
tokenize |
No | Issue as tokenizable when true. |
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 and Mirror Account
Keep your mirror account topped up to avoid failed issuances. You can add additional balance to the card at any time:
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"
}'
In sandbox, work with your PayCA contact if you need to replenish the programme mirror account itself. For production you will fund it via your normal treasury process.
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. The call seeds BIN pricing and returns the userAccountId used for optional 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", "isTokenizable": true}],
"meta": {"segment": "testers"}
}'
Persist the returned id and userAccountId if you intend to lock funds or top up via /v1/users/transfer.
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 mirrors, user accounts, 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 /v1/accounts |
Identify mirror account IDs and balances. |
| Issue card | POST /v1/cards |
Provide accountId, bin, balance, and idempotency key. |
| Operate card | POST /v1/cards/{id}/topup, /withdraw, /freeze, /unfreeze, /tokenize, DELETE /v1/cards/{id} |
Manage lifecycle and liquidity. |
| Observe activity | /sandbox/transactions, GET /v1/cards/{id}/transactions, webhooks |
Use referenceId to reconcile across feeds. |