Prosoft Pay

Sandbox — test the API

Sign and send a real, signed POST /v1/payments request in curl, Python, Node.js, or PHP. No login required — this page is for developers integrating against the Prosoft Pay API, not the admin dashboard.

1. Authentication

Every merchant-API request is signed with HMAC-SHA256 over a canonical string of METHOD\nPATH\nTIMESTAMP\nNONCE\nSHA256_HEX(body), using your API secret as the HMAC key. The signature and KeyId go in the Authorization header; timestamp and nonce go in X-ProsoftPay-Timestamp / X-ProsoftPay-Nonce. A request outside a 5-minute timestamp window, or a reused nonce, is rejected. Full scheme, error codes, and webhook verification: docs/INTEGRATION_GUIDE.md and docs/API_SPEC.md in the repository.

2. Get sandbox credentials

Contact your account representative to have a KeyId + secret issued for your tenant — the secret is shown once, at issuance, and cannot be retrieved again. Self-service rotation isn't available yet; a lost or compromised secret also means requesting reissuance.

Running Prosoft Pay locally for development? From backend/, run python -m app.scripts.seed to print a fresh KeyId + secret for the BCB and DemoInsurer demo tenants.

3. Sign and send your first request

Replace YOUR_KEY_ID / YOUR_SECRET with your real credentials and point BASE_URL at the sandbox once it's deployed (https://api-sandbox.prosoftpay.com) — the default below targets a locally running backend on localhost:8000. An amount ending in .00 or .50 is authorized and captured immediately by the mock bank connector; .99 declines, .13 times out. The curl example is a self-contained inline version of the repository's own scripts/sign-request.sh.

KEY_ID="YOUR_KEY_ID"
SECRET="YOUR_SECRET"
BASE_URL="http://localhost:8000"  # sandbox: https://api-sandbox.prosoftpay.com

METHOD="POST"
PATH_URL="/v1/payments"
BODY='{"amount":"150000.00","currency":"BIF","external_ref":"policy-2026-00432","capture_mode":"automatic"}'

TIMESTAMP="$(date +%s)"
NONCE="$(uuidgen | tr '[:upper:]' '[:lower:]')"
IDEMPOTENCY_KEY="$(uuidgen | tr '[:upper:]' '[:lower:]')"

BODY_HASH="$(printf '%s' "$BODY" | openssl dgst -sha256 -hex | awk '{print $NF}')"

CANONICAL="${METHOD}
${PATH_URL}
${TIMESTAMP}
${NONCE}
${BODY_HASH}"

SIGNATURE="$(printf '%s' "$CANONICAL" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}')"

curl -sS -X "$METHOD" \
  -H "Authorization: ProsoftPay-HMAC-SHA256 KeyId=${KEY_ID}, Signature=${SIGNATURE}" \
  -H "X-ProsoftPay-Timestamp: ${TIMESTAMP}" \
  -H "X-ProsoftPay-Nonce: ${NONCE}" \
  -H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
  -H "Content-Type: application/json" \
  -d "$BODY" \
  "${BASE_URL}${PATH_URL}"