Card deposits add external fiat funds to a PayCA account. The API is provider-independent: your integration uses PayCA credentials and PayCA deposit statuses, while PayCA selects the acquiring route.
Deposit access is enabled per client. Ask your PayCA account manager to enable the required currencies and allow-list your checkout return URLs before starting the integration.
Integration Flow #
- Request the funding options available for the account currency and payer country.
- Quote the amount the payer will be charged and the amount the account will receive.
- Create one deposit order with an
Idempotency-Keyand the quoted values. - Redirect the payer to the returned
checkoutUrl. - After the payer returns, retrieve the deposit until it reaches a terminal status.
- Subscribe to
depositwebhooks for status events and later reversals.
A checkout redirect is not proof that funds are available. Treat only status: completed as a successful account credit.
Prerequisites #
You need:
- PayCA
x-client-idandx-client-secretcredentials. - An active PayCA account in the currency you want to receive.
- Card deposits enabled for your client, account currency, and payer country.
- HTTPS complete and cancel redirect URL prefixes allow-listed by PayCA.
- A webhook endpoint registered with
type: deposit.
The deposit currency always equals the target account currency. Card deposit and currency conversion are separate operations; no FX conversion happens during a deposit.
Step 1 - Discover Funding Options #
Call GET /v2/accounts/{accountId}/funding-options with the payer's ISO 3166-1 alpha-2 billing country.
curl -s "$PAYCA_BASE_URL/v2/accounts/$ACCOUNT_ID/funding-options?country=US" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET"
Example response:
{
"options": [
{
"method": "card",
"currency": "USD",
"minAmount": "20.00",
"maxAmount": "500.00",
"fee": {
"mode": "add_on",
"rate": "5.00",
"fixed": "1.00",
"declineRate": "2.00",
"declineFixed": "0.50",
"refundRate": "3.00",
"refundFixed": "0.25"
}
}
]
}
The values above are illustrative. Always use the response returned for the current client, account currency, and country. An empty options array means no external funding method is currently available for that combination.
Step 2 - Quote the Deposit #
Use POST /v2/accounts/{accountId}/deposit-quote before showing a price or opening a checkout.
amountMode determines which amount the caller controls:
| Mode | Meaning |
|---|---|
credited |
amount is what the PayCA account should receive. |
charged |
amount is the maximum total the payer should be charged. |
curl -s -X POST "$PAYCA_BASE_URL/v2/accounts/$ACCOUNT_ID/deposit-quote" \
-H "Content-Type: application/json" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
-d '{
"method": "card",
"amount": "20.00",
"amountMode": "credited",
"country": "US"
}'
Example response:
{
"requestedAmount": "20.00",
"amountMode": "credited",
"currency": "USD",
"processingFee": "2.00",
"declineFee": "0.90",
"refundFee": "0.85",
"creditedAmount": "20.00",
"chargedAmount": "22.00"
}
Show at least chargedAmount, creditedAmount, and processingFee before the payer continues. declineFee and refundFee describe fees that may be charged later if those outcomes occur.
Step 3 - Create the Deposit #
Create the order using the quote's requestedAmount and expected values. Send a new, unique Idempotency-Key for each deposit intent.
curl -s -X POST "$PAYCA_BASE_URL/v2/accounts/$ACCOUNT_ID/deposits" \
-H "Content-Type: application/json" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET" \
-H "Idempotency-Key: order-20260813-0001" \
-d '{
"method": "card",
"amount": "20.00",
"expectedChargedAmount": "22.00",
"expectedCreditedAmount": "20.00",
"expectedPaycaFee": "2.00",
"expectedDeclineFee": "0.90",
"expectedRefundFee": "0.85",
"country": "US",
"userId": "73f77d0f-8b30-46e8-9081-b506180f764e",
"payer": {
"email": "payer@example.com",
"firstName": "Alex",
"lastName": "Morgan",
"taxId": "123456789",
"dateOfBirth": "1990-04-12",
"city": "New York",
"postalCode": "10001",
"address": "123 Example Street"
},
"completeRedirectUrl": "https://app.example.com/deposits/complete",
"cancelRedirectUrl": "https://app.example.com/deposits/cancel"
}'
userId is required when the target account is not bound to a user. The user must belong to the target account.
For a payer's first deposit, send at least email and firstName. Supplying the complete identity set allows screening to start through the API. If more information or verification is required, the hosted checkout collects it from the payer. A previously established payer identity may be reused, so payer can be omitted on later deposits for the same user.
Example 201 Created response:
{
"id": "f99bc4a6-604f-47a8-941b-6b02d4963504",
"status": "awaiting_payment",
"method": "card",
"accountId": "4a40c2a9-b145-4335-bf19-f302b9b72062",
"amount": "20.00",
"currency": "USD",
"paycaFee": "2.00",
"declineFee": "0.90",
"refundFee": "0.85",
"chargedAmount": "22.00",
"checkoutUrl": "https://checkout.example/deposit/f99bc4a6-604f-47a8-941b-6b02d4963504",
"createdAt": "2026-08-13T10:30:00Z"
}
Redirect the payer's full browser window to checkoutUrl. Do not embed or modify the hosted checkout URL.
Safe Retries #
If the create request times out, retry it with the same Idempotency-Key and unchanged body. PayCA returns the original deposit instead of creating a second payable checkout.
Use a new key when the account, amount, payer, country, or redirect URLs change. A reused key with a different request returns 409. A stale expected quote also returns 409; request a new quote and ask the payer to confirm the updated amounts.
Step 4 - Track the Result #
The browser may return before settlement finishes. Retrieve the order with:
curl -s "$PAYCA_BASE_URL/v2/accounts/$ACCOUNT_ID/deposits/$DEPOSIT_ID" \
-H "x-client-id: $PAYCA_CLIENT_ID" \
-H "x-client-secret: $PAYCA_CLIENT_SECRET"
Use GET /v2/accounts/{accountId}/deposits for history and reconciliation. It includes unsuccessful and in-progress attempts as well as completed deposits.
| Status | Meaning | Funds available? |
|---|---|---|
created |
PayCA recorded the order; checkout creation is not complete yet. | No |
awaiting_payment |
Checkout is ready and waiting for the payer. | No |
processing |
Payment was confirmed but settlement or account credit is pending. | No |
completed |
Settlement was confirmed and the account credit was recorded. | Yes |
failed |
Payment failed. | No |
cancelled |
The checkout was cancelled. | No |
expired |
The checkout expired before payment completed. | No |
manual_review |
The order requires review before it can continue. | No |
refunded |
A previously paid deposit was refunded and its credit reversed. | No |
chargeback |
A previously paid deposit was charged back and its credit reversed. | No |
The current card route normally remains processing during its settlement window. Build against status transitions rather than a fixed timer.
Step 5 - Subscribe to Deposit Webhooks #
Register a webhook with type: deposit:
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.example.com/payca/deposits",
"type": "deposit"
}'
Example delivery:
{
"event": "account.deposit.completed",
"data": {
"id": "f99bc4a6-604f-47a8-941b-6b02d4963504",
"status": "completed",
"method": "card",
"accountId": "4a40c2a9-b145-4335-bf19-f302b9b72062",
"amount": "20.00",
"currency": "USD",
"chargedAmount": "22.00",
"creditedAmount": "20.00",
"paycaFee": "2.00",
"declineFee": "0.90",
"refundFee": "0.85",
"createdAt": "2026-08-13T10:30:00Z",
"completedAt": "2026-08-13T13:30:00Z"
}
}
Deposit events are:
account.deposit.completedaccount.deposit.failedaccount.deposit.cancelledaccount.deposit.expiredaccount.deposit.refundedaccount.deposit.chargebackaccount.deposit.manual_review
No webhook is sent for created, awaiting_payment, or processing; poll the deposit endpoint while an order is in flight. A deposit can move from completed to refunded or chargeback later, so keep processing deposit webhooks after the initial credit.
Verify x-signature before parsing the body and deduplicate deliveries by x-idempotency-key. See Webhook Handling Patterns for signature and replay details.
Fees and Reconciliation #
processingFee/paycaFeeis fixed when the order is created.providerFeemay be absent until it is reported; absence does not mean zero.declineFeeis charged separately after a decline when configured.refundFeeis charged separately after a refund when configured.- On
completed, reconcilecreditedAmountagainst the account balance. - On
refundedorchargeback, reverse the previously recognised deposit in your own ledger and reconcile the current PayCA account balance.
Common Errors #
| HTTP status | Meaning | Action |
|---|---|---|
400 |
Invalid amount, unsupported route, missing identity, or redirect URL not allow-listed. | Correct the request or contact PayCA to update the client configuration. |
403 |
Deposits are not enabled for this client. | Ask your PayCA account manager to enable card deposits. |
404 |
The account or deposit does not exist for this client. | Verify IDs and tenant ownership. |
409 |
Idempotency key conflicts with another request, or the expected quote changed. | Reuse the original body, or requote and create a new intent. |
Integration Checklist #
- Use
funding-optionsas the source of truth for availability and limits. - Display the quote before redirecting the payer.
- Send the expected quote fields on create.
- Generate and persist one idempotency key per deposit intent.
- Use only allow-listed complete and cancel redirect URLs.
- Never credit funds based on the browser redirect.
- Treat only
completedas an available balance credit. - Handle later
refundedandchargebackevents. - Reconcile deposit history and the PayCA account balance.