Use a computer

For full performance and fluidity, please open Pay Engineers on a desktop or laptop. On mobile, the experience is limited — especially authenticated sections and advanced tools after login.

python

Python requests sample

A Python example using the requests library to call a sandbox endpoint securely, with guidance on environment variables, session reuse, timeouts, retries and structured error handling.

Why requests

requests remains the most widely used HTTP client in the Python ecosystem and integrates cleanly with the os.environ-based configuration pattern most fintech and data teams already use for credentials. If you are building an async service, httpx is a drop-in-flavored alternative with the same design philosophy.

Environment variables

Load secrets from the environment rather than hard-coding them, and keep a .env.example (with placeholder values only) alongside a real .env that is git-ignored:

PROCESSOR_BASE_URL=https://sandbox.example.com
PROCESSOR_API_KEY=sk_sandbox_xxxxxxxxxxxxxxxx

Python example

import os
import requests
from requests.adapters import HTTPAdapter, Retry

session = requests.Session()
retries = Retry(total=3, backoff_factor=0.5, status_forcelist=[502, 503, 504])
session.mount("https://", HTTPAdapter(max_retries=retries))

base_url = os.environ["PROCESSOR_BASE_URL"]
api_key = os.environ["PROCESSOR_API_KEY"]

try:
    response = session.get(
        f"{base_url}/v1/ping",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Accept": "application/json",
        },
        timeout=10,
    )
    response.raise_for_status()
except requests.exceptions.Timeout:
    raise RuntimeError("Processor request timed out after 10s") from None
except requests.exceptions.HTTPError as exc:
    raise RuntimeError(f"Processor returned {response.status_code}: {response.text}") from exc
except requests.exceptions.ConnectionError as exc:
    raise RuntimeError("Could not reach processor — check DNS/TLS/network") from exc

data = response.json()

Session reuse

Creating a requests.Session() once and reusing it (as above) keeps TCP/TLS connections alive across calls via connection pooling, which noticeably reduces latency for services making frequent calls to the same processor host — avoid constructing a new session per request in hot paths.

Error handling

raise_for_status() turns any 4xx/5xx into a requests.exceptions.HTTPError, which you can catch alongside Timeout and ConnectionError to cover the three practical failure classes: request/auth errors, processor-side errors, and network-level failures. Always inspect response.status_code and the JSON error body (most processors include a stable error_code field) rather than pattern-matching on human-readable error text.

Security notes

  • Never log the raw Authorization header or full request/response bodies containing card or account data — mask or omit sensitive fields before any logging.info(...) call.
  • Pin a reasonable timeout on every call; a synchronous script with no timeout can hang a worker process indefinitely on a stalled connection.
  • Rotate PROCESSOR_API_KEY through your secrets manager (not by editing .env on a running server) so rotations are auditable.