Integrating Stripe Without the Plugin Bloat

Learn how to integrate Stripe payments directly into your website without heavy plugins. Cleaner code, better performance, and full control over checkout.

Integrating Stripe Without the Plugin Bloat

Stripe is the best payment processor for most online businesses. The API is excellent, the documentation is clear, and the fees are reasonable. But if you’re using WordPress, Shopify, or another platform, the standard advice is to install a payment plugin — and that’s where things get heavy.

Payment plugins are some of the most bloated pieces of software you’ll find on any website. They load large JavaScript bundles, add multiple database queries per page load, and often include functionality you’ll never use. All to do something that Stripe’s own libraries handle in a few dozen lines of code.

Here’s how to integrate Stripe directly, without the plugin bloat, and why it matters for your site’s performance and your business.

The Problem with Payment Plugins

They Load on Every Page

Most payment plugins load their CSS and JavaScript on every single page of your site, not just the pages where payment actually happens. A typical WordPress payment plugin might add 200-400KB of JavaScript to every page load. That’s script that needs to be downloaded, parsed, and executed — even on your About page where nobody is making a payment.

This isn’t a minor issue. On mobile connections, an extra 300KB of JavaScript can add one to two seconds to page load time. Across your entire site, this adds up to a measurably worse user experience and lower search rankings.

They Add Database Overhead

Payment plugins create their own database tables and run queries on page loads to check settings, verify licence keys, and load configuration. This database overhead slows down server response time, adding milliseconds to every request.

They Create Security Surface Area

Payment plugins handle sensitive operations — processing cards, managing customer data, handling refunds. Every line of plugin code is a potential security vulnerability. The more code involved in your payment flow, the more code that needs to be audited and kept updated.

Stripe itself is PCI compliant and handles the sensitive card data. A plugin sitting between your site and Stripe is an unnecessary link in the chain that introduces risk without adding value.

They Lock You Into Their Ecosystem

Many payment plugins add their own abstractions on top of Stripe. They create custom order management systems, their own receipt emails, their own refund workflows. This might seem helpful, but it means you’re dependent on the plugin’s interpretation of Stripe’s functionality rather than using Stripe directly.

When Stripe releases a new feature — payment links, subscription improvements, new payment methods — you wait for the plugin developer to implement it rather than using it immediately.

What Direct Stripe Integration Looks Like

Stripe provides everything you need to accept payments through their own libraries. Here’s what a clean integration involves.

The Server Side

Your server creates a Stripe Checkout Session or Payment Intent using Stripe’s official library. In Node.js, this looks roughly like:

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const session = await stripe.checkout.sessions.create({
  payment_method_types: ['card'],
  line_items: [{
    price_data: {
      currency: 'gbp',
      product_data: { name: 'Website Design Package' },
      unit_amount: 150000, // £1,500.00 in pence
    },
    quantity: 1,
  }],
  mode: 'payment',
  success_url: 'https://yoursite.com/thank-you',
  cancel_url: 'https://yoursite.com/checkout',
});

That’s it. A few lines of code that create a payment session. No plugin, no admin panel, no database tables.

The Client Side

On the frontend, you redirect the customer to Stripe’s hosted checkout page:

const response = await fetch('/api/create-checkout', { method: 'POST' });
const { sessionId } = await response.json();
const stripe = Stripe('pk_live_your_public_key');
stripe.redirectToCheckout({ sessionId });

Stripe’s Checkout page handles all the sensitive card input, validation, 3D Secure authentication, and payment processing. It’s PCI compliant by default, looks professional, and supports Apple Pay, Google Pay, and other payment methods automatically.

Webhooks for Order Fulfilment

After payment, Stripe sends a webhook to your server confirming the transaction. Your server processes this webhook to trigger order fulfilment — sending a confirmation email, updating a database, starting a service, whatever your business requires.

app.post('/webhook', async (req, res) => {
  const event = stripe.webhooks.constructEvent(
    req.body,
    req.headers['stripe-signature'],
    process.env.STRIPE_WEBHOOK_SECRET
  );

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    // Fulfil the order
    await sendConfirmationEmail(session.customer_email);
    await updateOrderStatus(session.id, 'paid');
  }

  res.json({ received: true });
});

The entire payment integration — server route, client redirect, and webhook handler — is typically under a hundred lines of code. Compare this to a payment plugin that installs thousands of files.

When to Use Stripe Checkout vs Stripe Elements

Stripe offers two approaches for the customer-facing payment experience.

Stripe Checkout (Hosted Page)

The customer is redirected to a Stripe-hosted page where they enter their payment details. This is the simplest approach and the one I recommend for most projects.

Advantages:

  • Zero frontend code for the payment form
  • Automatically PCI compliant
  • Supports all payment methods Stripe offers
  • Stripe optimises the conversion rate for you
  • Mobile-responsive by default
  • Handles 3D Secure and Strong Customer Authentication automatically

Disadvantages:

  • The customer leaves your site briefly (they return after payment)
  • Limited customisation of the checkout page appearance

Stripe Elements (Embedded Form)

Stripe Elements lets you embed payment form fields directly into your website. The card input looks like part of your site, and the customer never leaves.

Advantages:

  • Seamless brand experience
  • Customer stays on your site throughout
  • Full control over layout and design

Disadvantages:

  • More frontend code to write and maintain
  • You’re responsible for building the payment form layout
  • Need to handle more edge cases (validation, error states, loading states)
  • Still PCI compliant because Stripe’s JavaScript handles the sensitive data, but requires more careful implementation

For most small business websites and service-based businesses, Stripe Checkout is the right choice. The slight redirect is worth the simplicity and security benefits. Use Elements when the seamless on-site experience is genuinely important to your brand.

Framework-Specific Implementation

Astro + Stripe

Astro is a great match for Stripe integration because you can add payment functionality only where you need it. Create an API route for the checkout session, use a small client-side script on the payment page, and the rest of your site remains completely static — no payment code loaded anywhere else.

SvelteKit + Stripe

SvelteKit’s server-side endpoints are perfect for Stripe integration. Create a +server.js file for your checkout endpoint, handle webhooks in another server endpoint, and use SvelteKit’s form actions if you need server-side form processing.

Next.js + Stripe

Next.js API routes handle the server-side Stripe logic. The pattern is essentially the same as SvelteKit but using Next.js conventions for routing.

WordPress (Without a Plugin)

Yes, you can use Stripe with WordPress without a plugin. Add a custom REST API endpoint through your theme’s functions.php, use Stripe’s PHP library (installed via Composer or manually), and add a small JavaScript snippet to the page that needs payment functionality.

This approach loads Stripe’s JavaScript only on the page that needs it, adds zero database overhead, and gives you full control. It’s more work to set up than installing a plugin, but the performance and maintenance benefits are significant.

Handling Common Scenarios

Subscriptions

Stripe handles recurring payments natively. Creating a subscription is similar to a one-time payment — you create a Checkout Session with mode: 'subscription' instead of mode: 'payment'. Stripe manages the recurring billing, failed payment retries, and customer portal for managing subscriptions.

Invoicing

For service-based businesses (like web development), Stripe’s invoicing API lets you create and send invoices programmatically. Customers receive an email with a link to pay. This can be integrated into your project management workflow without any plugin.

Multi-Currency

Stripe supports over 135 currencies. If your business serves international customers, you can create checkout sessions in the customer’s local currency with minimal additional code.

Refunds

Processing refunds through Stripe’s API is a single function call. You can build a simple admin interface that lets you issue refunds directly, or handle them through the Stripe dashboard.

The Performance Difference

To illustrate the impact, here’s what a typical WordPress site looks like with and without a payment plugin.

With a Payment Plugin

  • Plugin loads its CSS (50-80KB) on every page
  • Plugin loads its JavaScript (200-400KB) on every page
  • Plugin makes 2-5 additional database queries per page load
  • Plugin may load external scripts for payment processing on every page
  • Total impact: 300-500KB extra weight and 50-200ms additional server processing on every single page

With Direct Stripe Integration

  • Stripe.js (approximately 25KB) loads only on the payment page
  • No additional CSS (your existing styles handle the button/form)
  • No additional database queries on non-payment pages
  • Zero performance impact on 95%+ of your site’s pages
  • Total impact on non-payment pages: nothing

For a site with ten pages, the plugin approach loads unnecessary payment code on nine of them. Direct integration loads it on only the one page that needs it.

Security Considerations

Direct Stripe integration is actually more secure than most plugins because there’s less code to audit, fewer dependencies, and a simpler architecture.

Key security practices for direct integration:

  • Never expose your secret key — it belongs in server-side environment variables only
  • Always verify webhook signatures — Stripe’s library makes this easy, and it prevents fake webhook attacks
  • Use Stripe Checkout or Elements — never handle raw card data on your server
  • Keep Stripe’s library updated — this is one dependency instead of an entire plugin with its own dependencies
  • Use HTTPS everywhere — this should be standard for any website in 2026, but it’s essential for payment pages

Getting Started

If you’re currently using a payment plugin and want to explore direct Stripe integration, the transition is straightforward. The Stripe documentation is some of the best API documentation available — clear examples, interactive code samples, and thorough guides for every scenario.

For existing sites, you can implement direct Stripe integration alongside your current plugin, test it thoroughly, then remove the plugin. This approach avoids any payment downtime.

If you’d like help implementing a clean Stripe integration for your website — whether it’s WordPress, Astro, SvelteKit, or anything else — get in touch. A direct integration typically takes a day or two of development time and immediately improves your site’s performance.

Stripe Payments Web Development

Need help with your website?

I help businesses in Cambridgeshire and beyond build better websites. Let's talk about your project.

Get in touch