Skip to content
Last updated

Use this guide to set the minimum security contract for every ConnectPSP request before you move on to Cash-In or Cash-Out flows.

Request identity model

All API requests require two forms of identification:

HeaderDescriptionWhen Required
AuthorizationBearer <jwt_token>All endpoints (except POST /auth/token)
ApplicationTokenFixed GUID identifying your integrationAll endpoints (except POST /auth/token)
DigitalSignatureHMAC-SHA256 hash — see belowSensitive operations: Cash-Out, Rebalance
  1. Generate a JWT with POST /auth/token
  2. Send Authorization + ApplicationToken on authenticated endpoints
  3. Add DigitalSignature only on sensitive operations such as Cash-Out and Rebalance
  4. Optionally add X-Idempotency-Key on POST /cash-in and POST /cash-out to make retries safe (recommended)

Step 1 — Obtain a JWT Token

Call POST /auth/token with the clientId and clientSecret provided by ConnectPSP during onboarding.

curl -X POST https://api.homologacao.connectpsp.com/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "YOUR_CLIENT_ID",
    "clientSecret": "YOUR_CLIENT_SECRET"
  }'

Response:

{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "tokenType": "Bearer",
  "expiresIn": 3600,
  "issuedAt": "2026-03-10T14:00:00Z"
}
FieldMeaning
accessTokenJWT used in the Authorization header
tokenTypeHeader scheme, expected to be Bearer
expiresInToken lifetime in seconds
issuedAtToken issuance timestamp

⏱️ Tokens expire in 1 hour (expiresIn: 3600). Implement refresh logic in your application to re-authenticate before the token expires.


Step 2 — Send the minimum authenticated request

Send the accessToken in all subsequent requests:

curl https://api.homologacao.connectpsp.com/cash-in/US7B1JQ \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "ApplicationToken: f47ac10b-58cc-4372-a567-0e02b2c3d479"

This is the baseline header pair you should expect on almost every request outside the token endpoint.


Step 3 — Digital Signature (Sensitive Operations)

Cash-Out (POST /cash-out) and Rebalance (POST /account/rebalance) require an additional DigitalSignature header to guarantee integrity and authorization.

How to Compute

The Digital Signature is an HMAC-SHA256 hash of your JWT token concatenated with your CryptoToken (a separate fixed secret provided during onboarding, different from clientSecret).

DigitalSignature = HMAC_SHA256(key: cryptoToken, message: jwtToken)
                   → returned as a lowercase hexadecimal string

Examples

Node.js:

const crypto = require('crypto');

function computeSignature(jwtToken, cryptoToken) {
  return crypto
    .createHmac('sha256', cryptoToken)
    .update(jwtToken)
    .digest('hex');
}

const signature = computeSignature(accessToken, 'your-crypto-token-here');
// Use in: -H "DigitalSignature: <signature>"

Python:

import hmac, hashlib

def compute_signature(jwt_token: str, crypto_token: str) -> str:
    return hmac.new(
        crypto_token.encode(),
        jwt_token.encode(),
        hashlib.sha256
    ).hexdigest()

cURL (full example for Cash-Out):

SIGNATURE=$(echo -n "$JWT_TOKEN" | openssl dgst -sha256 -hmac "$CRYPTO_TOKEN" | awk '{print $2}')

curl -X POST https://api.homologacao.connectpsp.com/cash-out \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "ApplicationToken: $APP_TOKEN" \
  -H "DigitalSignature: $SIGNATURE" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

🔑 Never expose your cryptoToken or clientSecret in client-side code or public repositories.


Idempotency

X-Idempotency-Key is optional on POST /cash-in and POST /cash-out, and recommended. Generate a new key per operation — a UUID v4 is ideal; any string up to 100 characters is accepted.

If a network failure causes you to retry the same request, sending the same X-Idempotency-Key with the same body guarantees you receive the original response without creating a duplicate transaction.

# Generate a new UUID for each new operation; reuse it only to retry that same operation
X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
SituationResult
No X-Idempotency-KeyProcessed normally, with no idempotency. externalReference still blocks duplicates with 409 DUPLICATED_EXTERNAL_REFERENCE
Same key, same body, within 24 hoursThe original response, unchanged, with the header Idempotent-Replayed: true. Nothing new is created
Same key, different body422 IDEMPOTENCY_KEY_REUSED — generate a new key for a new operation
Same key while the first request is still running409 IDEMPOTENCY_KEY_IN_PROGRESS — check the result in a moment
Key longer than 100 characters400 IDEMPOTENCY_KEY_INVALID

Only successful responses are stored. If the first attempt ends in an error, the key is released and a retry with the same key is processed again.

externalReference is your second line of defence and works with or without the header: it is unique per client, so a second Cash-In or Cash-Out with the same externalReference is always rejected with 409 DUPLICATED_EXTERNAL_REFERENCE.

  • Initial Setup — onboarding baseline and environment setup
  • Webhooks — async confirmation flow after authenticated requests
  • Error Handling — what to do when auth or signature validation fails