> ## Documentation Index
> Fetch the complete documentation index at: https://paystack-sdk.efobi.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Learn how to authenticate and secure your Paystack SDK integration

The Paystack TypeScript SDK uses API keys to authenticate requests. All API requests must include a valid secret key to interact with the Paystack API.

## Getting Your API Keys

To use the SDK, you'll need to obtain your API keys from the Paystack Dashboard:

<Steps>
  <Step title="Log in to Paystack">
    Visit [https://dashboard.paystack.com](https://dashboard.paystack.com) and sign in to your account.
  </Step>

  <Step title="Navigate to Settings">
    Click on **Settings** in the sidebar, then select **API Keys & Webhooks**.
  </Step>

  <Step title="Copy Your Secret Key">
    You'll see both your **Test** and **Live** secret keys. Copy the appropriate key for your environment.
  </Step>
</Steps>

<Warning>
  Never expose your secret keys in client-side code, public repositories, or version control systems. Secret keys should only be used server-side.
</Warning>

## Test vs Live Keys

Paystack provides two types of secret keys to separate development and production environments:

<CardGroup cols={2}>
  <Card title="Test Keys" icon="flask">
    * Prefix: `sk_test_`
    * Use for development and testing
    * No real money is processed
    * Safe to experiment with
  </Card>

  <Card title="Live Keys" icon="rocket">
    * Prefix: `sk_live_`
    * Use for production
    * Processes real transactions
    * Requires extra security measures
  </Card>
</CardGroup>

### Key Format Validation

The SDK automatically validates your API key format when initializing the Paystack client. Here's the validation logic from `src/index.ts:34-42`:

```typescript src/index.ts theme={null}
const secretKeySchema = z
  .string()
  .startsWith("sk_live_")
  .or(z.string().startsWith("sk_test_"));
  
if (!secretKeySchema.safeParse(secretKey).success) {
  throw new Error(
    "Invalid secret key. It must start with 'sk_live_' or 'sk_test_'.",
  );
}
```

If you provide a key that doesn't start with either prefix, the SDK will throw an error immediately.

## Basic Setup

Initialize the SDK by passing your secret key to the `Paystack` constructor:

```typescript theme={null}
import { Paystack } from '@efobi/paystack';

const paystack = new Paystack('sk_test_your_secret_key_here');
```

The constructor validates the key format and throws an error if invalid:

```typescript theme={null}
// ✅ Valid - will work
const paystack = new Paystack('sk_test_abc123...');
const paystack = new Paystack('sk_live_xyz789...');

// ❌ Invalid - will throw error
const paystack = new Paystack('invalid_key'); // Error: Invalid secret key
const paystack = new Paystack('pk_test_...');  // Error: Invalid secret key (public key)
```

## Environment Variables

The recommended approach is to store your API keys in environment variables rather than hardcoding them:

<CodeGroup>
  ```bash .env theme={null}
  # Development environment
  PAYSTACK_SECRET_KEY=sk_test_your_test_key_here

  # Production environment
  # PAYSTACK_SECRET_KEY=sk_live_your_live_key_here
  ```

  ```typescript Node.js theme={null}
  import { Paystack } from '@efobi/paystack';

  // Using process.env
  const paystack = new Paystack(process.env.PAYSTACK_SECRET_KEY!);
  ```

  ```typescript Bun theme={null}
  import { Paystack } from '@efobi/paystack';

  // Bun has built-in .env support
  const paystack = new Paystack(Bun.env.PAYSTACK_SECRET_KEY!);
  ```

  ```typescript Next.js theme={null}
  import { Paystack } from '@efobi/paystack';

  // Next.js environment variables
  const paystack = new Paystack(process.env.PAYSTACK_SECRET_KEY!);
  ```

  ```typescript Deno theme={null}
  import { Paystack } from '@efobi/paystack';

  // Deno environment variables
  const paystack = new Paystack(Deno.env.get('PAYSTACK_SECRET_KEY')!);
  ```
</CodeGroup>

### Environment-Based Configuration

You can dynamically select keys based on your environment:

```typescript theme={null}
import { Paystack } from '@efobi/paystack';

const secretKey = process.env.NODE_ENV === 'production'
  ? process.env.PAYSTACK_LIVE_KEY!
  : process.env.PAYSTACK_TEST_KEY!;

const paystack = new Paystack(secretKey);
```

## How Authentication Works

Under the hood, the SDK uses Bearer token authentication. From `src/main/fetcher.ts:38-39`:

```typescript src/main/fetcher.ts theme={null}
const init: RequestInit = {
  method,
  headers: {
    Authorization: `Bearer ${this.secretKey}`,
  },
};
```

Every API request automatically includes your secret key in the `Authorization` header. You don't need to manually add authentication to individual requests.

## Security Best Practices

<AccordionGroup>
  <Accordion title="Never commit keys to version control">
    Add `.env` files to your `.gitignore`:

    ```bash .gitignore theme={null}
    .env
    .env.local
    .env.*.local
    ```

    Use environment variables or secret management services instead.
  </Accordion>

  <Accordion title="Use different keys for each environment">
    Maintain separate API keys for:

    * Local development (test key)
    * Staging/QA (test key)
    * Production (live key)

    This prevents accidental charges during testing.
  </Accordion>

  <Accordion title="Rotate keys regularly">
    Periodically regenerate your API keys, especially if:

    * A team member with access leaves
    * You suspect a key may have been compromised
    * As part of routine security maintenance

    You can regenerate keys from the Paystack Dashboard without downtime by updating both old and new keys simultaneously.
  </Accordion>

  <Accordion title="Restrict key access">
    * Limit which team members can view live keys
    * Use secret management tools (AWS Secrets Manager, HashiCorp Vault, etc.)
    * Never log or display secret keys in application logs
    * Avoid sending keys via email or chat
  </Accordion>

  <Accordion title="Server-side only">
    Secret keys should **never** be used in:

    * Frontend JavaScript (React, Vue, etc.)
    * Mobile apps (iOS, Android)
    * Browser extensions
    * Any client-side code

    Always make Paystack API calls from your backend server.
  </Accordion>
</AccordionGroup>

## Multi-Account Support

If you need to work with multiple Paystack accounts, create separate instances:

```typescript theme={null}
import { Paystack } from '@efobi/paystack';

const mainAccount = new Paystack(process.env.PAYSTACK_MAIN_KEY!);
const subAccount = new Paystack(process.env.PAYSTACK_SUB_KEY!);

// Use different instances for different accounts
const mainTxn = await mainAccount.transaction.initialize({
  email: 'customer@example.com',
  amount: '50000'
});

const subTxn = await subAccount.transaction.initialize({
  email: 'customer@example.com',
  amount: '25000'
});
```

## Troubleshooting

<Accordion title="Error: Invalid secret key">
  **Cause**: The provided key doesn't start with `sk_test_` or `sk_live_`.

  **Solution**:

  * Verify you're using the **secret key**, not the public key (which starts with `pk_`)
  * Check for typos or extra whitespace
  * Ensure the key is copied completely from the dashboard

  ```typescript theme={null}
  // ❌ Wrong - using public key
  const paystack = new Paystack('pk_test_...');

  // ✅ Correct - using secret key
  const paystack = new Paystack('sk_test_...');
  ```
</Accordion>

<Accordion title="401 Unauthorized errors">
  **Cause**: The API key is invalid, expired, or doesn't have permission.

  **Solution**:

  * Verify the key is still active in your Paystack Dashboard
  * Check if you're using the correct environment (test vs live)
  * Regenerate the key if necessary
</Accordion>

<Accordion title="Environment variable not found">
  **Cause**: The environment variable isn't loaded or is undefined.

  **Solution**:

  * Ensure your `.env` file is in the correct location
  * Check if you need to install `dotenv` (Node.js): `npm install dotenv`
  * Load environment variables: `import 'dotenv/config'` (Node.js)
  * Restart your development server after changing `.env`
</Accordion>

## Next Steps

<CardGroup cols={2}>
  <Card title="Error Handling" icon="triangle-exclamation" href="/core-concepts/error-handling">
    Learn how to handle API errors and validation issues
  </Card>

  <Card title="Type Safety" icon="shield-check" href="/core-concepts/type-safety">
    Understand TypeScript types and runtime validation
  </Card>
</CardGroup>
