> ## 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.

# Quick Start

> Build your first Paystack integration in minutes

## Overview

This guide walks you through creating a complete payment flow: initializing a transaction, redirecting the customer to pay, and verifying the payment.

<Note>
  This guide uses test mode. Remember to switch to live keys when you're ready to accept real payments.
</Note>

## Prerequisites

Before starting, make sure you have:

* Installed the SDK (see [Installation](/installation))
* Your Paystack test secret key from your [dashboard](https://dashboard.paystack.com/#/settings/developer)

## Step 1: Initialize the SDK

First, import and initialize the Paystack SDK with your secret key:

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

// Initialize with your secret key
const paystack = new Paystack(process.env.PAYSTACK_SECRET_KEY!);
```

<Tip>
  The SDK automatically validates your secret key format. It must start with `sk_test_` or `sk_live_`.
</Tip>

## Step 2: Initialize a Transaction

To accept a payment, first initialize a transaction. This creates a payment session and returns an authorization URL:

```typescript initialize.ts theme={null}
const result = await paystack.transaction.initialize({
  email: 'customer@email.com',
  amount: '50000', // Amount in kobo (₦500.00)
  currency: 'NGN' // Optional, defaults to NGN
});

if (result.error) {
  console.error('Validation error:', result.error.flatten());
} else if (result.data) {
  console.log('Authorization URL:', result.data.data.authorization_url);
  console.log('Reference:', result.data.data.reference);
  console.log('Access Code:', result.data.data.access_code);
  
  // Redirect customer to result.data.data.authorization_url
}
```

<Warning>
  Amounts in Paystack are specified in the smallest currency unit (kobo for NGN, cents for USD). To charge ₦500.00, pass `50000`.
</Warning>

### Understanding the Response

The initialize method returns:

* `authorization_url` - Redirect your customer here to complete payment
* `access_code` - Alternative payment access code
* `reference` - Unique transaction reference (auto-generated if not provided)

### Custom Transaction Options

You can customize the transaction with additional parameters:

```typescript advanced-initialize.ts theme={null}
const result = await paystack.transaction.initialize({
  email: 'customer@email.com',
  amount: '50000',
  currency: 'NGN',
  reference: 'ORDER_12345', // Your own unique reference
  callback_url: 'https://yoursite.com/verify', // Redirect after payment
  metadata: {
    custom_fields: [
      {
        display_name: 'Order ID',
        variable_name: 'order_id',
        value: 'ORDER_12345'
      }
    ]
  },
  channels: ['card', 'bank_transfer'], // Limit payment methods
  split_code: 'SPL_xxx' // For split payments
});
```

## Step 3: Verify the Transaction

After the customer completes payment, verify the transaction using the reference:

```typescript verify.ts theme={null}
const reference = 'your_transaction_reference';

const result = await paystack.transaction.verify(reference);

if (result.error) {
  console.error('Verification failed:', result.error.flatten());
} else if (result.data) {
  const transaction = result.data.data;
  
  console.log('Status:', transaction.status); // 'success', 'failed', or 'abandoned'
  console.log('Amount:', transaction.amount);
  console.log('Customer:', transaction.customer.email);
  console.log('Paid at:', transaction.paidAt);
  
  if (transaction.status === 'success') {
    // Payment successful - fulfill order
    console.log('✅ Payment verified successfully!');
  }
}
```

<Note>
  Always verify transactions on your server, not in client-side code. Never trust payment status from the client.
</Note>

## Complete Example

Here's a complete example combining initialization and verification:

<CodeGroup>
  ```typescript Node.js/Express theme={null}
  import express from 'express';
  import { Paystack } from '@efobi/paystack';

  const app = express();
  const paystack = new Paystack(process.env.PAYSTACK_SECRET_KEY!);

  app.use(express.json());

  // Initialize payment
  app.post('/api/payment/initialize', async (req, res) => {
    try {
      const { email, amount } = req.body;
      
      const result = await paystack.transaction.initialize({
        email,
        amount,
        callback_url: `${req.protocol}://${req.get('host')}/api/payment/verify`
      });
      
      if (result.error) {
        return res.status(400).json({ error: result.error.flatten() });
      }
      
      res.json({
        authorization_url: result.data?.data.authorization_url,
        reference: result.data?.data.reference
      });
    } catch (error) {
      res.status(500).json({ error: 'Payment initialization failed' });
    }
  });

  // Verify payment
  app.get('/api/payment/verify', async (req, res) => {
    try {
      const { reference } = req.query;
      
      if (!reference || typeof reference !== 'string') {
        return res.status(400).json({ error: 'Reference is required' });
      }
      
      const result = await paystack.transaction.verify(reference);
      
      if (result.error) {
        return res.status(400).json({ error: result.error.flatten() });
      }
      
      const transaction = result.data?.data;
      
      if (transaction?.status === 'success') {
        // Fulfill order here
        res.json({ message: 'Payment verified', transaction });
      } else {
        res.status(400).json({ message: 'Payment not successful' });
      }
    } catch (error) {
      res.status(500).json({ error: 'Verification failed' });
    }
  });

  app.listen(3000, () => {
    console.log('Server running on port 3000');
  });
  ```

  ```typescript Next.js (App Router) theme={null}
  // app/api/payment/initialize/route.ts
  import { NextResponse } from 'next/server';
  import { Paystack } from '@efobi/paystack';

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

  export async function POST(request: Request) {
    try {
      const { email, amount } = await request.json();
      
      const result = await paystack.transaction.initialize({
        email,
        amount,
        callback_url: `${process.env.NEXT_PUBLIC_URL}/verify`
      });
      
      if (result.error) {
        return NextResponse.json(
          { error: result.error.flatten() },
          { status: 400 }
        );
      }
      
      return NextResponse.json({
        authorization_url: result.data?.data.authorization_url,
        reference: result.data?.data.reference
      });
    } catch (error) {
      return NextResponse.json(
        { error: 'Payment initialization failed' },
        { status: 500 }
      );
    }
  }

  // app/api/payment/verify/route.ts
  import { NextResponse } from 'next/server';
  import { Paystack } from '@efobi/paystack';

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

  export async function GET(request: Request) {
    try {
      const { searchParams } = new URL(request.url);
      const reference = searchParams.get('reference');
      
      if (!reference) {
        return NextResponse.json(
          { error: 'Reference is required' },
          { status: 400 }
        );
      }
      
      const result = await paystack.transaction.verify(reference);
      
      if (result.error) {
        return NextResponse.json(
          { error: result.error.flatten() },
          { status: 400 }
        );
      }
      
      const transaction = result.data?.data;
      
      if (transaction?.status === 'success') {
        // Fulfill order here
        return NextResponse.json({ message: 'Payment verified', transaction });
      }
      
      return NextResponse.json(
        { message: 'Payment not successful' },
        { status: 400 }
      );
    } catch (error) {
      return NextResponse.json(
        { error: 'Verification failed' },
        { status: 500 }
      );
    }
  }
  ```

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

  const app = new Hono();
  const paystack = new Paystack(process.env.PAYSTACK_SECRET_KEY!);

  // Initialize payment
  app.post('/payment/initialize', async (c) => {
    try {
      const { email, amount } = await c.req.json();
      
      const result = await paystack.transaction.initialize({
        email,
        amount,
        callback_url: `${c.req.url}/verify`
      });
      
      if (result.error) {
        return c.json({ error: result.error.flatten() }, 400);
      }
      
      return c.json({
        authorization_url: result.data?.data.authorization_url,
        reference: result.data?.data.reference
      });
    } catch (error) {
      return c.json({ error: 'Payment initialization failed' }, 500);
    }
  });

  // Verify payment
  app.get('/payment/verify', async (c) => {
    try {
      const reference = c.req.query('reference');
      
      if (!reference) {
        return c.json({ error: 'Reference is required' }, 400);
      }
      
      const result = await paystack.transaction.verify(reference);
      
      if (result.error) {
        return c.json({ error: result.error.flatten() }, 400);
      }
      
      const transaction = result.data?.data;
      
      if (transaction?.status === 'success') {
        // Fulfill order here
        return c.json({ message: 'Payment verified', transaction });
      }
      
      return c.json({ message: 'Payment not successful' }, 400);
    } catch (error) {
      return c.json({ error: 'Verification failed' }, 500);
    }
  });

  export default app;
  ```
</CodeGroup>

## Expected Output

When you initialize a transaction, you'll get a response like:

```json theme={null}
{
  "status": true,
  "message": "Authorization URL created",
  "data": {
    "authorization_url": "https://checkout.paystack.com/xxxxx",
    "access_code": "xxxxx",
    "reference": "xxxxx"
  }
}
```

After verification, a successful payment returns:

```json theme={null}
{
  "status": true,
  "message": "Verification successful",
  "data": {
    "status": "success",
    "reference": "xxxxx",
    "amount": 50000,
    "currency": "NGN",
    "customer": {
      "email": "customer@email.com",
      "customer_code": "CUS_xxxxx"
    },
    "paidAt": "2024-01-15T10:30:00.000Z"
  }
}
```

## Error Handling

The SDK provides structured error handling:

```typescript error-handling.ts theme={null}
try {
  const result = await paystack.transaction.verify('invalid_reference');
  
  if (result.error) {
    // Validation or API error
    console.error('Validation errors:', result.error.flatten());
    
    // Access specific errors
    result.error.issues.forEach(issue => {
      console.error(`${issue.path}: ${issue.message}`);
    });
  } else if (result.data) {
    // Success
    console.log('Transaction:', result.data);
  }
} catch (error) {
  // Network or unexpected errors
  console.error('Unexpected error:', error.message);
}
```

## Testing Your Integration

<Steps>
  <Step title="Use test credentials">
    Always use test keys (`sk_test_...`) during development.
  </Step>

  <Step title="Test with Paystack test cards">
    Paystack provides test card numbers:

    * Success: `4084 0840 8408 4081` (CVV: any 3 digits)
    * Insufficient funds: `5060 6666 6666 6666`
  </Step>

  <Step title="Verify on your server">
    Never rely on client-side verification alone.
  </Step>

  <Step title="Test error scenarios">
    Test failed payments, abandoned transactions, and network errors.
  </Step>
</Steps>

## Next Steps

Now that you've completed your first integration, explore more features:

<CardGroup cols={2}>
  <Card title="Transactions API" icon="credit-card" href="/api-reference/transaction">
    Learn about all transaction operations
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Handle real-time payment notifications
  </Card>

  <Card title="Transfers" icon="paper-plane" href="/api-reference/transfer">
    Send money to customers and vendors
  </Card>

  <Card title="Virtual Accounts" icon="bank" href="/api-reference/virtual-account">
    Create dedicated virtual accounts
  </Card>
</CardGroup>

## Common Patterns

### Generating Custom References

```typescript theme={null}
function generateReference(prefix: string): string {
  const timestamp = Date.now();
  const random = Math.random().toString(36).substring(2, 9);
  return `${prefix}_${timestamp}_${random}`;
}

const result = await paystack.transaction.initialize({
  email: 'customer@email.com',
  amount: '50000',
  reference: generateReference('ORDER')
});
```

### Handling Webhook Verification

```typescript theme={null}
app.post('/webhooks/paystack', express.raw({ type: 'application/json' }), async (req, res) => {
  const signature = req.headers['x-paystack-signature'];
  const rawBody = req.body.toString('utf-8');
  
  try {
    await paystack.webhook.process(rawBody, signature);
    res.sendStatus(200);
  } catch (error) {
    res.sendStatus(400);
  }
});

paystack.webhook.on('charge.success', (data) => {
  console.log('Payment received:', data.reference);
  // Fulfill order
});
```

### Retry Logic for Verification

```typescript theme={null}
async function verifyWithRetry(reference: string, maxRetries = 3): Promise<any> {
  for (let i = 0; i < maxRetries; i++) {
    const result = await paystack.transaction.verify(reference);
    
    if (result.data) {
      return result.data;
    }
    
    // Wait before retry
    await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
  }
  
  throw new Error('Verification failed after retries');
}
```

## Getting Help

<CardGroup cols={2}>
  <Card title="API Reference" icon="book" href="/api-reference/paystack">
    Detailed documentation for all methods
  </Card>

  <Card title="GitHub Issues" icon="github" href="https://github.com/efobi-dev/paystack/issues">
    Report bugs or request features
  </Card>

  <Card title="Examples" icon="code" href="https://github.com/efobi-dev/paystack/tree/main/examples">
    Browse example projects
  </Card>

  <Card title="Paystack Docs" icon="book-open" href="https://paystack.com/docs/api/">
    Official Paystack API documentation
  </Card>
</CardGroup>
