Docs menu

Getting Started

Quickstart

From zero to a first successful, signed API call.

1. Get 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 means requesting a new one be issued and the old one revoked.

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

2. Sign your request

Every merchant-API request is signed with HMAC-SHA256 over a canonical string of method, path, timestamp, nonce, and body hash. The signature, timestamp, and nonce go in dedicated headers alongside an Idempotency-Key. Full scheme: Authentication & signing.

3. Make the call

This example creates a payment against a locally running backend. An amount ending in .00 or .50 is authorized and captured immediately by the mock bank connector; .99 declines, .13 times out.

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}"

Python, Node.js, and PHP versions of the same request are on the sandbox portal, which also lets you sign and send a request directly from your browser.