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. End to End Payment Tests with Cypress
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 22, 2026

End to End Payment Tests with Cypress

Cypress cannot directly interact with cross-origin iframes by default. To test the Paystack popup, either: (1) use the cypress-iframe plugin (cy.frameLoaded() + cy.iframe()) to interact with iframe content, or (2) stub the Paystack API responses in your backend and mock the checkout callback. The second approach is more reliable for CI pipelines.

Cypress Test with cypress-iframe Plugin

// cypress/e2e/checkout.cy.js
// Requires: npm install -D cypress-iframe
// In cypress/support/commands.js: import 'cypress-iframe'
// In cypress.config.js: chromeWebSecurity: false

describe('Paystack checkout flow', () => {
  it('completes payment with test card', () => {
    cy.visit('/checkout?product=1');

    // Click pay button
    cy.get('[data-testid="pay-button"]').click();

    // Wait for Paystack iframe to load
    cy.frameLoaded('iframe[name="checkout"]');

    // Interact with inputs inside the iframe
    cy.iframe('iframe[name="checkout"]')
      .find('input[placeholder="Card Number"]')
      .type('4084084084084081');

    cy.iframe('iframe[name="checkout"]')
      .find('input[placeholder="MM/YY"]')
      .type('05/30');

    cy.iframe('iframe[name="checkout"]')
      .find('input[placeholder="CVV"]')
      .type('408');

    cy.iframe('iframe[name="checkout"]')
      .contains('button', 'Pay')
      .click();

    // Assert redirect to success page
    cy.url({ timeout: 30000 }).should('include', '/payment/success');
    cy.contains('Payment Successful').should('be.visible');
  });
});

// Alternative: stub approach (more reliable in CI)
describe('Paystack checkout — stubbed approach', () => {
  it('handles successful payment callback', () => {
    cy.intercept('POST', '/api/checkout', {
      statusCode: 200,
      body: { authorization_url: 'https://checkout.paystack.com/test', reference: 'ref_001' },
    }).as('initCheckout');

    cy.visit('/checkout?product=1');
    cy.get('[data-testid="pay-button"]').click();

    cy.wait('@initCheckout');

    // Simulate the Paystack callback being called (as if payment succeeded)
    cy.window().then((win) => {
      win.PaystackPop.setup({ callback: (response) => win.handlePaystackCallback(response) });
      win.handlePaystackCallback({ reference: 'ref_001', status: 'success' });
    });

    cy.url({ timeout: 10000 }).should('include', '/payment/success');
  });
});

Learn More

This guide is part of the Paystack testing guide.

Sign up for the McTaba newsletter

Key Takeaways

  • ✓Cypress blocks cross-origin iframes by default — set chromeWebSecurity: false in cypress.config.js for local testing with Paystack popup.
  • ✓Use the cypress-iframe plugin for clean iframe interactions: cy.frameLoaded("[name='checkout']") then cy.iframe().find("input").type(...).
  • ✓An alternative to iframe interaction: stub your backend API responses and simulate the post-payment callback directly.
  • ✓Always use Paystack test mode credentials — never run Cypress tests against live Paystack keys.
  • ✓Use cy.intercept() to verify your frontend makes the correct request to your checkout endpoint.
  • ✓E2E tests should verify the database state after payment — add a cy.task() to query the DB and assert the order is marked paid.

Frequently Asked Questions

Why does Cypress say "This iframe is cross-origin and cannot be accessed"?
Cypress enforces same-origin policy by default. Setting chromeWebSecurity: false in cypress.config.js disables this check, allowing iframe interaction. This is fine for local testing but should not be needed in production — the cross-origin restriction is a browser security feature, not a bug.
Is the stubbed approach or the real iframe approach better for Paystack tests?
The stubbed approach (intercepting your backend checkout endpoint) is faster and more reliable in CI — it does not depend on Paystack's popup UI rendering correctly. The real iframe approach tests more of the actual user flow but is slower and can fail if Paystack changes their popup structure. Use the real approach for a small set of smoke tests and the stubbed approach for broader coverage.
How do I add a cy.task() to verify database state after payment?
In cypress.config.js, add a task: on("task", { checkOrderStatus: async (orderId) => { const order = await db.orders.findByPk(orderId); return order.status; } }). In your test: cy.task("checkOrderStatus", orderId).should("eq", "paid"). This runs database queries in the Node.js environment outside the browser.
Can Cypress tests run in GitHub Actions?
Yes. Use the official cypress-io/github-action GitHub Action or install Cypress manually (npm ci && npx cypress install). Run with --headless --browser chrome. Ensure your test environment variables (PAYSTACK_SECRET_KEY=sk_test_...) are set as GitHub Actions secrets.

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

Testing Paystack Integrations: The Complete Guide

A complete guide to testing Paystack integrations at every level: test mode, test cards, unit tests with mocks, integration tests, end-to-end flows with Playwright, webhook simulation, contract testing, CI pipelines, staging environments, load testing, and coverage targets for payment code.

Read more

Simulating Declined Cards on Paystack

A card decline is one of the most common failure states in a payment flow, and your application must handle it gracefully. This guide shows how to simulate specific card declines in Paystack test mode and how to verify your decline handling code works correctly.

Read more

Mocking the Paystack API in PHPUnit

PHPUnit tests for Paystack integrations in Laravel or PHP can run without any network calls using Laravel's Http::fake() or Mockery. This guide shows how to mock Paystack responses, test webhook handlers, and verify your payment logic in isolation.

Read more

Seeding Test Data for a Payments Feature

Good test data is essential for testing payment features. This guide covers creating Paystack test mode resources (plans, subaccounts, split codes) and seeding your application database with matching payment records for realistic test scenarios.

Read more

Paystack "Declined by Financial Institution" Error

The "Declined by financial institution" response means the customer's bank rejected the transaction. This is not a Paystack error or a bug in your code. The bank made the decision, and neither you nor Paystack can override it.

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.