> ## Documentation Index
> Fetch the complete documentation index at: https://docs.payfonte.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authorization

> Authenticate Payfonte API requests using client-id and client-secret headers.

Every Payfonte API request is authenticated using two headers:

* `client-id`
* `client-secret`

<Danger>
  Never expose `client-secret` in frontend apps, mobile apps, browser storage,
  or public repositories.
</Danger>

## Authentication Model

<CardGroup cols={2}>
  <Card title="client-id" icon="fingerprint">
    Public identifier for your account and environment.
  </Card>

  <Card title="client-secret" icon="lock">
    Secret key used to authorize requests. Store only on trusted backend
    systems.
  </Card>

  <Card title="Header-Based Auth" icon="server">
    Pass both credentials in request headers on every API call.
  </Card>

  <Card title="Environment-Specific Keys" icon="flask">
    Sandbox and Production use different credentials. Do not mix them.
  </Card>
</CardGroup>

## Where To Get Your Keys

<Steps>
  <Step title="Sign in to Dashboard">
    Use [sandbox-app.payfonte.com](https://sandbox-app.payfonte.com) for testing or [app.payfonte.com](https://app.payfonte.com) for live operations.
  </Step>

  <Step title="Open API key settings">
    Navigate to `Settings -> Security ->  API Keys and Webhooks`.
  </Step>

  <Step title="Copy credentials securely">
    Save your `client-id` and `client-secret` into server environment variables.
  </Step>
</Steps>

## Request Example

<CodeGroup>
  ```bash cURL theme={null}
  curl --location 'https://sandbox-api.payfonte.com/payments/v1/checkouts' \
    --header 'client-id: <your-client-id>' \
    --header 'client-secret: <your-client-secret>' \
    --header 'Content-Type: application/json' \
    --data '{
      "reference": "test-001",
      "amount": 1000,
      "currency": "NGN",
      "country": "NG",
      "user": {
        "phoneNumber": "08012345678"
      }
    }'
  ```

  ```javascript Node.js (fetch) theme={null}
  await fetch("https://sandbox-api.payfonte.com/payments/v1/checkouts", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "client-id": process.env.PAYFONTE_SANDBOX_CLIENT_ID,
      "client-secret": process.env.PAYFONTE_SANDBOX_CLIENT_SECRET,
    },
    body: JSON.stringify({
      reference: "test-001",
      amount: 1000,
      currency: "NGN",
      country: "NG",
      user: { phoneNumber: "08012345678" },
    }),
  });
  ```
</CodeGroup>

## Common Mistakes

<AccordionGroup>
  <Accordion title="Using production keys in sandbox" icon="triangle-exclamation">
    Sandbox and production are separate environments. Use the matching base URL
    and matching credentials together.
  </Accordion>

  <Accordion title="Placing client-secret in frontend code" icon="shield-halved">
    Frontend code is public to end users. Keep all authenticated Payfonte API
    calls on your backend.
  </Accordion>

  <Accordion title="Forgetting required headers" icon="circle-info">
    Requests without either `client-id` or `client-secret` will fail
    authentication.
  </Accordion>

  <Accordion title="Hardcoding secrets in source control" icon="code">
    Always load credentials from environment variables or a secure secret
    manager.
  </Accordion>
</AccordionGroup>

## Security Checklist

* Keep `client-secret` on backend only.
* Use HTTPS for API and webhook endpoints.
* Rotate credentials if exposure is suspected.
* Restrict internal access to production secrets.

## Related Docs

<CardGroup cols={3}>
  <Card title="Environments" icon="server" href="/en/guides/introductions/environments">
    Sandbox and production URL/key setup.
  </Card>

  <Card title="Getting Started" icon="flag-checkered" href="/en/guides/introductions/getting-started">
    Make your first successful API call.
  </Card>

  <Card title="API Reference" icon="file-code" href="/en/api-reference/introduction">
    Full endpoint and schema details.
  </Card>
</CardGroup>
