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 curl or 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-ID and x-signature value from webhook deliveries.
  • Use the trace_id field 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

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.