McTaba Labs logo
Software EngineeringThe WhiteboardProjectsEventsMasterclassesWebinarsLearn
Book Call

500+ developers already in the community

Get answers, find accountability partners, and stay ahead

Join Discord →
McTaba Labs logo

Educating 1 million students in tech by 2030.

Programs

  • HighSchool Graduates Launchpad
  • AI & Business Automation
  • Corporate Training
  • McTaba Story & Mission
  • Full-Stack Curriculum
  • Course Pricing & Plans
  • Frequently Asked Questions

Resources

  • Join Discord Community
  • Tech Events in Nairobi
  • Masterclasses
  • Free Resources
  • Learn
  • Campus
  • Africa Tech Talent Report
  • Partner With Us
  • Start a Project
  • Our Work

Contact Us

  • 124 Manyani East Road, Lavington, Nairobi
  • +254727795603
  • Book a Discovery Call

Office Hours:

Mon-Fri: 9am - 2pm EAT

Sat: 10am - 12pm EAT

© 2027 McTaba Labs - A product of Edtech Industries. All rights reserved.

Privacy PolicyTerms of ServiceRefund Policy
  1. Learn
  2. Paystack for African Developers
  3. Paystack Access Codes: What They Are and How Long They Live
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 20, 2026

Paystack Access Codes: What They Are and How Long They Live

A Paystack access code is a short alphanumeric string returned alongside the authorization_url when you initialize a transaction. You pass it to PaystackPop.checkout() for inline (popup) checkout. Access codes expire after a period of inactivity, typically around 24 hours, though Paystack does not publish a guaranteed TTL. If an access code expires, initialize a new transaction.

In this article

  1. 1. What Is an Access Code?
  2. 2. Access Code vs Authorization URL
  3. 3. How Long Do Access Codes Live?
  4. 4. What Happens When an Access Code Expires
  5. 5. Common Mistakes with Access Codes
  6. 6. Access Codes in Mobile Apps
  7. 7. Reusing References vs Reusing Access Codes
  8. 8. Debugging Access Code Issues
  9. 9. Stay Up to Date

What Is an Access Code?

When you call POST /transaction/initialize, Paystack returns a response with three fields that matter for checkout:

// Response from POST /transaction/initialize
{
  "status": true,
  "message": "Authorization URL created",
  "data": {
    "authorization_url": "https://checkout.paystack.com/0peioxfhpn",
    "access_code": "0peioxfhpn",
    "reference": "order_142_1721472000000"
  }
}

Notice that the access code is the tail end of the authorization URL. They are two ways to reach the same checkout session. The authorization_url is a full URL you can redirect the browser to. The access_code is the short identifier you pass to Paystack's inline JavaScript library when you want a popup checkout instead of a full-page redirect.

Think of the access code as a session ticket. It tells Paystack which transaction the customer is paying for, what amount to charge, which payment channels to show, and what metadata to attach. All of that was locked in when you called initialize.

Access Code vs Authorization URL

Both values come from the same initialize call and represent the same checkout session. The difference is how you use them.

Authorization URL (redirect checkout)

You send the customer's browser to the full URL. The customer leaves your site, completes payment on Paystack's hosted page, and gets redirected back to your callback URL. This is the simplest integration path.

// Redirect the customer to Paystack's hosted checkout
window.location.href = data.authorization_url;

Access code (inline/popup checkout)

You pass the code to PaystackPop, which opens the checkout in an iframe overlay on your page. The customer stays on your site visually. When they finish, you get a JavaScript callback instead of a page redirect.

// Open Paystack checkout as a popup on your page
var popup = new PaystackPop();
popup.checkout({
  accessCode: data.access_code,
  onSuccess: function(transaction) {
    // Verify server-side before granting value
    verifyPayment(transaction.reference);
  },
  onCancel: function() {
    console.log('Customer closed checkout');
  },
});

The payment experience is identical from Paystack's side. Card collection, 3DS challenges, bank transfer instructions, and OTP prompts all work the same way. The only difference is whether the customer sees it in a new page or in a popup on your page.

For a detailed comparison of the two approaches and when to choose each one, see redirect vs inline checkout.

Get weekly developer tips

Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.

No spam. Unsubscribe anytime.

How Long Do Access Codes Live?

Paystack does not publish an official TTL (time to live) for access codes. In practice, they expire after a period of inactivity, generally within 24 hours of creation. This is a deliberate design choice: checkout sessions should not live forever because amounts, exchange rates, and inventory can change.

Here is what this means for your integration:

  • If a customer clicks "Pay" and you initialize a transaction, the access code is valid for long enough to complete a normal checkout flow (minutes to a few hours).
  • If you initialize a transaction, store the access code, and try to use it the next day, it will almost certainly be expired.
  • If a customer opens the checkout popup but walks away for several hours without completing payment, the session may expire and the popup will show an error.

The practical rule: initialize the transaction as close to the moment of payment as possible. Do not pre-initialize transactions during page load or when the user adds items to a cart. Initialize when the user clicks the "Pay Now" button.

What Happens When an Access Code Expires

When you try to use an expired access code with PaystackPop, the behavior varies depending on the library version and the browser. Common outcomes include:

  • The popup opens but shows an error message like "This transaction has expired"
  • The popup opens to a blank or loading screen that never resolves
  • The checkout form appears but fails when the customer tries to submit payment

If you are using redirect checkout with the authorization URL, an expired session typically shows an error page on Paystack's checkout domain.

None of these are good experiences for your customer. The fix is to detect the failure and re-initialize.

// Frontend: handle checkout with expiration recovery
async function openCheckout() {
  // Always get a fresh access code from your server
  var response = await fetch('/api/pay', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      email: customerEmail,
      amount: orderAmount,
      orderId: currentOrderId,
    }),
  });

  var result = await response.json();

  var popup = new PaystackPop();
  popup.checkout({
    accessCode: result.access_code,
    onSuccess: function(transaction) {
      verifyPayment(transaction.reference);
    },
    onCancel: function() {
      // Customer closed the popup
      // The access code may still be valid for a retry
      // But safest to re-initialize on next attempt
      console.log('Checkout cancelled');
    },
  });
}

The key pattern: call your server to initialize a fresh transaction every time the customer clicks "Pay." Do not cache access codes on the frontend.

Common Mistakes with Access Codes

Mistake 1: Pre-initializing transactions on page load

Some developers call the initialize endpoint when the checkout page loads, store the access code in a variable, and use it when the customer clicks "Pay" five or thirty minutes later. If the customer takes too long, the access code might expire. Worse, if the order details change (quantity updated, coupon applied), the pre-initialized transaction has the wrong amount.

Initialize when the customer commits to paying, not when they land on the page.

Mistake 2: Storing access codes in a database for later use

Access codes are ephemeral. They are tied to a specific checkout session that expires. Storing them in your database and trying to reuse them hours or days later will fail. If you need to let a customer resume a payment later, initialize a new transaction with the same reference. Paystack will return the existing transaction if the reference matches and it has not been completed.

Mistake 3: Using the access code as a transaction identifier

The access code identifies the checkout session, not the transaction. Use the reference for tracking, verification, and reconciliation. The reference is the stable identifier that appears in webhooks, verify responses, and your dashboard. The access code is just a checkout entry point.

Mistake 4: Exposing the initialize endpoint without rate limiting

Every call to /transaction/initialize creates a pending transaction on Paystack's side. If your frontend endpoint that triggers initialization has no rate limiting, a bot or a frustrated user clicking rapidly can create hundreds of pending transactions. Add rate limiting on your server and use deterministic references (tied to the order ID) so that duplicate initialize calls return the same transaction.

Access Codes in Mobile Apps

If you are building a mobile app (React Native, Flutter, or native Android/iOS), access codes work the same way. Your mobile app calls your backend to initialize, gets back the access code, and uses it to open a WebView-based checkout.

// React Native example (conceptual)
// 1. Call your backend
var response = await fetch('https://yourapi.com/api/pay', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: email, amount: amount }),
});
var data = await response.json();

// 2. Open the authorization URL in a WebView
// or use a Paystack mobile SDK that accepts the access code
var checkoutUrl = data.authorization_url;
// Navigate to checkoutUrl in your in-app browser

The access code expiration behavior is the same on mobile. Initialize just before the customer is ready to pay. If the app goes to the background and the user comes back much later, initialize again.

Some Paystack mobile SDKs accept the access code directly and handle the WebView internally. Check the SDK documentation for your platform. The core rule stays the same: fresh access code, server-side initialization, verify after payment.

Reusing References vs Reusing Access Codes

There is an important distinction between reusing a reference and reusing an access code.

Reusing a reference: If you call /transaction/initialize with the same reference as an existing pending transaction, Paystack returns the existing transaction (with a fresh access code and authorization URL). This is the correct way to handle retries. If a customer's first checkout attempt fails or is abandoned, you can initialize again with the same reference and Paystack will not create a duplicate.

// Server-side: re-initialize with the same reference
var reference = 'order_' + orderId;

var response = await fetch('https://api.paystack.co/transaction/initialize', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: customerEmail,
    amount: amountInKobo,
    reference: reference, // Same reference as before
  }),
});

var data = await response.json();
// data.data.access_code is a fresh access code
// data.data.authorization_url is a fresh URL
// Both point to the same underlying transaction

Reusing an access code: This does not work reliably. Once an access code expires or the checkout session ends, the code is dead. Always get a fresh one from the initialize response.

The pattern that works: tie your reference to the order, and always call initialize before opening checkout. Let Paystack handle the deduplication through the reference. For deeper patterns on reference design, see transaction reference design patterns.

Debugging Access Code Issues

When the checkout popup fails silently or shows a vague error, here is how to narrow it down.

Check the transaction status on your dashboard

Log into your Paystack dashboard and search for the transaction reference. If the transaction shows as "abandoned" or "failed," the access code has expired or the checkout session ended. Initialize a new transaction.

Check the browser console

PaystackPop logs errors to the browser console when something goes wrong. Open your browser's developer tools and look for messages from the Paystack inline script. Common messages include session expiry notices and network errors.

Verify the access code matches the environment

A test access code (from a transaction initialized with a test secret key) will not work in a live checkout, and vice versa. Make sure your frontend is loading the correct Paystack inline script and that the access code was generated with the matching secret key.

Check the timing

Log timestamps when you initialize the transaction and when you attempt to open checkout. If there is a gap of more than a few hours, the access code may have expired. Restructure your flow to initialize closer to the payment attempt.

For more on debugging payment issues, see the Transaction Timeline API and reading gateway responses.

Stay Up to Date

Paystack occasionally changes how checkout sessions behave, updates expiration windows, or modifies inline library behavior. We keep these guides updated when things change.

Sign up for the McTaba newsletter to get notified when we publish new Paystack integration guides or spot breaking changes.

Key Takeaways

  • ✓An access code is a short string (like "0peioxfhpn") returned when you initialize a transaction. It identifies the checkout session for use with the inline popup.
  • ✓The authorization_url and the access_code point to the same transaction. The URL is for redirect checkout; the access code is for PaystackPop inline checkout.
  • ✓Access codes expire after a period of inactivity. Do not store them for later use. Always initialize a fresh transaction when the customer is ready to pay.
  • ✓If you try to use an expired access code, PaystackPop will show an error or a blank checkout. Your frontend should catch this and re-initialize the transaction.
  • ✓Never expose your secret key to retrieve or refresh access codes on the frontend. The initialize call must always happen server-side.
  • ✓Access codes are single-use in practice. Once a customer completes or abandons the checkout, the access code cannot be reused for a new payment.

Frequently Asked Questions

Can I extend the lifetime of a Paystack access code?
No. There is no API call to extend or refresh an access code. If the code has expired, you need to call /transaction/initialize again to get a new one. If you use the same reference, Paystack returns the existing transaction with a fresh access code.
Is the access code the same as the authorization code?
No. The access code identifies a checkout session and is used to open the payment popup. The authorization code (auth_code) is returned after a successful card payment and can be used to charge the same card again in the future. They serve completely different purposes.
Can I use an access code on a different domain than where the transaction was initialized?
Yes. The access code is not domain-locked. You can initialize a transaction from your server and use the access code on any frontend that loads the Paystack inline script. However, the callback URL you specified during initialization determines where the customer is redirected after payment.
What happens if I call initialize with the same reference twice?
If the first transaction is still pending (not completed, not abandoned), Paystack returns the existing transaction with a new access code and authorization URL. This is the designed behavior for retry scenarios. If the transaction was already completed, Paystack returns an error.
Do I need the access code if I am using redirect checkout?
No. For redirect checkout, you only need the authorization_url. Redirect the customer to that URL and Paystack handles everything. The access code is specifically for inline/popup checkout using PaystackPop.

Learn Paystack Integration

KES 2,999

The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.

Start Paystack Course

Not ready? Create Free Account

Keep reading

Accepting Payments with Paystack: Complete Guide

Everything you need to accept your first payment with Paystack: choosing between Initialize Transaction and the Charge API, handling amounts in kobo, attaching metadata, setting callback URLs, and designing transaction references that keep your system clean.

Read more

Using Paystack Custom Fields to Collect Extra Checkout Information

Paystack custom fields let you attach structured, human-readable data to a transaction that shows up on the checkout page, in your dashboard, and in webhook payloads. This guide covers display_name vs variable_name, common field patterns, and how to extract custom field data when the webhook arrives.

Read more

Paystack Customer Objects: Create, Fetch, Update, Whitelist

Paystack creates a customer object every time a new email hits your checkout. You can also create customers explicitly, update their details, fetch their transaction history, and whitelist or blacklist them for risk control. This guide covers every operation with working Node.js code.

Read more

Building a Wallet Top-Up Flow on Paystack

A step-by-step guide to building wallet top-up flows with Paystack. Initialize payment, handle webhooks, credit wallets safely, enforce minimum amounts, and prevent double-crediting in production.

Read more

Paystack Webhooks on AWS Lambda and API Gateway

A complete guide to handling Paystack webhooks on AWS Lambda behind API Gateway. Covers the critical binary media type configuration for raw body passthrough, Lambda handler structure, HMAC-SHA512 signature verification, and production patterns for reliable payment event processing.

Read more

Explore related topics

M-Pesa & African Stack

M-Pesa Daraja API tutorials, USSD development, and WhatsApp Business API guides. The African Stack that global bootcamps do not teach.

Learn to Code in Kenya

Everything a Kenyan needs to know before writing their first line of code. Career paths, real costs, hardware requirements, and honest answers about what it takes.

Learning to Code

Roadmaps, language guides, and practical advice for learning to code and launching a programming career.

Breaking Into Tech

Practical, no-nonsense guides for anyone looking to start or change their career in tech. From choosing your first language to acing interviews.

The African Stack: Skills for This Market

The skills that make Kenyan developers hard to replace: M-Pesa, USSD, WhatsApp, fintech, and building for the African market.

Bonaventure Ogeto

Bonaventure Ogeto

Founder, McTaba Labs

Bonaventure is the founder of McTaba Labs, a coding bootcamp in Nairobi, Kenya. He has spent years building products for the African market and mentoring the next generation of developers across the continent.