Get your dream built 10x faster

Replit and Sage Pay Integration: 2026 Guide

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

Book a free consultation

How to Integrate Replit with Sage Pay

To integrate Replit with Sage Pay (now called Opayo by Elavon), you treat Replit as a normal server environment: run an API or web server inside your Repl, expose a port, use HTTPS via Replit’s public URL, store Opayo credentials in Replit Secrets, and implement Opayo’s REST or Form Integration flow. Nothing is automatic. You must explicitly create the payment session on your backend, redirect the user to Opayo’s hosted payment page, and handle the post‑payment callback (webhook) back into your Repl. Replit works fine for development and light production, as long as you keep sensitive keys out of code and use persistent external storage for anything critical.

 

What Integrating Replit with Sage Pay (Opayo) Actually Means

 

Opayo (formerly Sage Pay) is a UK payment gateway. Integrating it inside Replit means your Repl acts as the backend server responsible for:

  • Creating Opayo payment sessions
  • Redirecting users to the secure Opayo checkout page
  • Receiving Opayo's callback / POST-back after payment
  • Verifying the callback signature
  • Marking the order as paid

You do not run Sage Pay inside Replit; you only talk to its real API using HTTPS.

 

Core Steps in Plain Terms

 

  • Your Repl runs a web server (Node, Python, etc.) on port 3000 and binds to 0.0.0.0.
  • Replit exposes it publicly as a URL like https://your-repl-name.username.repl.co.
  • You create Opayo credentials in your Opayo dashboard.
  • You store those credentials in Replit under Secrets (environment variables).
  • Your Repl creates a payment session via Opayo’s REST API.
  • You redirect the user to Opayo’s Hosted Checkout.
  • Opayo sends the result back to a callback route in your Repl, which you must implement.

 

Setting Up Replit Environment

 

In Replit:

  • Open the Secrets panel and create:
    • OPAYO_VENDOR_NAME
    • OPAYO_API_KEY
    • OPAYO_API_PASSWORD
  • Ensure your server listens on 0.0.0.0:3000.
  • Open the "Ports" tab to confirm that port 3000 is mapped to the public URL.

 

Example Node.js Server Running in Replit

 

This is a minimal working example using Express, following Opayo’s REST API patterns.

// server.js
import express from "express";
import fetch from "node-fetch";

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Load credentials from Replit Secrets
const vendor = process.env.OPAYO_VENDOR_NAME;
const apiKey = process.env.OPAYO_API_KEY;
const apiPassword = process.env.OPAYO_API_PASSWORD;

// Create a payment session
app.post("/create-session", async (req, res) => {
  try {
    const payload = {
      amount: 1000, // amount in minor units (e.g., ÂŁ10.00)
      currency: "GBP",
      description: "Test Purchase",
      customerFirstName: "John",
      customerLastName: "Doe",
      billingAddress: {
        address1: "123 Example Street",
        city: "London",
        postalCode: "EC1A 1AA",
        country: "GB"
      },
      entryMethod: "Ecommerce"
    };

    const response = await fetch("https://pi-test.sagepay.com/api/v1/transactions", {
      method: "POST",
      headers: {
        Authorization: "Basic " + Buffer.from(apiKey + ":" + apiPassword).toString("base64"),
        "Content-Type": "application/json"
      },
      body: JSON.stringify(payload)
    });

    const data = await response.json();

    // The nextURL is where you redirect the user
    return res.json({ redirectUrl: data._links.nextUrl.href });
  } catch (err) {
    console.error(err);
    return res.status(500).send("Error creating session");
  }
});

// Callback route Opayo redirects to after payment
app.post("/opayo-callback", (req, res) => {
  // Validate signature using Opayo docs
  // req.body contains the transaction status
  console.log("Opayo callback received:", req.body);

  // Acknowledge receipt to Opayo
  return res.send("OK");
});

// Bind to 0.0.0.0 so Replit can expose the server
app.listen(3000, "0.0.0.0", () => {
  console.log("Server running on port 3000");
});

 

Important Notes About Real Opayo Integration

 

  • Opayo has sandbox vs live endpoints; the example uses the test endpoint pi-test.sagepay.com.
  • Opayo's callback must be publicly accessible, so use Replit’s deployment URL in your Opayo dashboard.
  • You must verify the callback signature following Opayo’s official documentation. They provide the hashing formula; it must match exactly.
  • Never hardcode API credentials. Always store them in Replit Secrets.

 

Workflow in the Browser

 

  • User presses “Pay”.
  • Your frontend calls /create-session on your Repl backend.
  • Your backend returns a redirectUrl from Opayo.
  • Your frontend redirects the user to that Opayo URL.
  • User enters card details at Opayo’s secure page.
  • Opayo calls your /opayo-callback route with the result.
  • You mark the order paid in your database (hosted externally for reliability).

 

Production Considerations on Replit

 

  • Use a Replit Deployment (Autoscale or Reserved VM) so your webhook route is always up.
  • Never rely on Replit’s filesystem for order storage; use an external DB like Supabase, Neon, or MongoDB Atlas.
  • Rotate Opayo keys periodically.
  • Use HTTPS URLs only. Replit already provides HTTPS.

 

This is the correct, real‑world method: explicit server, explicit routes, explicit Opayo REST calls, and no magic behind the scenes. You run a normal web backend inside Replit and talk to Opayo exactly as you would from any other server.

Use Cases for Integrating Sage Pay and Replit

1

Accept Payments in a Replit‑Hosted Web App

 

A Replit web server (Node/Express, Flask, or FastAPI) can securely collect payment details in the browser using Sage Pay’s client-side encryption or hosted payment page, then send the encrypted payload to your server. The server uses your Sage Pay credentials stored in Replit Secrets to call Sage Pay’s REST API. This avoids handling raw card data and keeps compliance manageable. Replit simply hosts the app, binds to 0.0.0.0, and exposes the port publicly so customers can pay through a production URL.

  • Store vendor name, API keys, and encryption keys as environment variables.
  • Use a Replit Workflow to start background tasks like order confirmations.
  • Persist order records in an external DB since Replit’s filesystem resets.
// Node/Express example: sending a Sage Pay transaction request
import fetch from "node-fetch";
import express from "express";
const app = express();
app.use(express.json());

app.post("/pay", async (req, res) => {
  const payload = req.body; // encrypted card data from frontend
  const result = await fetch("https://pi-live.sagepay.com/api/v1/transactions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Basic " + process.env.SAGEPAY_AUTH // vendor:password base64
    },
    body: JSON.stringify(payload)
  });
  res.json(await result.json());
});

app.listen(3000, "0.0.0.0");

2

Accept Payments in a Replit‑Hosted Web App

 

You can run a live Replit server that receives Sage Pay webhooks when a transaction changes status (successful, failed, refunded). Webhooks are simple HTTP POST requests. Sage Pay will call your public Repl URL or Deployment URL. Inside Replit, you expose your server on a fixed port and verify each webhook message using Sage Pay’s signature rules. This setup keeps UI pages responsive while payment state updates happen in the background.

  • Place webhook secret keys in Replit Secrets.
  • Verify message signatures before updating order status.
  • Send webhook events into a queue or external DB since Replit restarts.
// Basic webhook endpoint with signature verification
app.post("/sagepay/webhook", (req, res) => {
  const signature = req.headers["x-signature"];
  const expected = processWebhookSignature(req.body, process.env.SAGEPAY_WEBHOOK_KEY);
  if (signature !== expected) return res.status(401).end();

  // Update order status in your external DB
  res.status(200).end();
});

3

Create a Lightweight Test Environment for Sage Pay Integrations

 

Replit is ideal for building a fast, isolated test environment for Sage Pay before shipping real payments. You run a mock checkout UI, connect it to Sage Pay’s test API, and inspect requests and responses in real time. Because Replit restarts processes, it is best used as a temporary sandbox for integration development rather than a production payment processor. Still, it enables rapid prototyping of full flows—checkout, encryption, backend call, webhook callback—within one Repl.

  • Switch between Sage Pay test and live environments using environment variables.
  • Test webhooks by sending manual POST requests using curl or Replit shell.
  • Keep test card numbers in .env (Replit Secrets) or mock them directly.
// Triggering your local webhook endpoint from Replit shell
curl -X POST https://your-repl-url.replit.app/sagepay/webhook \
  -H "x-signature: test" \
  -H "Content-Type: application/json" \
  -d '{"Status":"OK"}'

Book Your Free 30‑Minute Migration Call

Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.

Book a Free Consultation

Troubleshooting Sage Pay and Replit Integration

1

Why does Sage Pay callback URL fail to reach the Replit web server?

Sage Pay callbacks fail because Replit URLs are not stable inbound endpoints. Your Repl sleeps, restarts, changes its public URL, and cannot expose a fixed HTTPS callback that Sage Pay can reach reliably. Sage Pay needs a permanent, always‑on, TLS‑valid URL, but a Repl’s runtime is not guaranteed to be online when Sage Pay sends the callback.

 

Why This Happens

 

A Replit webserver only works while the Repl is actively running and bound to 0.0.0.0. The preview URL is a proxy, not a public webhook endpoint, and it may rotate or sleep. Payment gateways like Sage Pay expect a static HTTPS URL that cannot disappear. When your Repl pauses, the callback is sent into a dead connection, so Sage Pay reports failure.

  • Repl sleeps or restarts → callback arrives while server is down.
  • Ephemeral preview domain → Sage Pay cannot whitelist or reliably hit it.
  • No fixed inbound port mapping → Replit proxy may reject external POSTs.

 

import express from "express"
const app = express()
app.post("/sagepay", (req, res)=>{
  res.send("OK")   // Works only while Repl is awake!
})
app.listen(3000,"0.0.0.0")

 

2

How to fix CORS or mixed‑content errors when sending payment requests from a Replit app to Sage Pay?

CORS or mixed‑content errors happen because the browser blocks calls from your Replit frontend to Sage Pay. You must send payment requests from your Replit backend only, using HTTPS on both sides. The frontend should never call Sage Pay directly.

 

Fix

 

Expose a backend route in your Replit server, call that from the browser, and let the server make the HTTPS request to Sage Pay. Ensure your Replit URL is HTTPS to avoid mixed‑content.

  • Frontend → your backend (same origin, no CORS)
  • Backend → Sage Pay over HTTPS using server‑side code

 

// server.js
import express from "express";
import fetch from "node-fetch";
const app = express();

app.post("/pay", async (req,res)=>{
  const r = await fetch("https://pi-live.sagepay.com/api/v1/transactions", {
    method:"POST",
    headers:{ "Content-Type":"application/json" },
    body: JSON.stringify(req.body)
  });
  res.json(await r.json());
});

app.listen(3000,"0.0.0.0");

3

Why do Sage Pay API keys or environment variables not load correctly in a Replit deployment?

Replit deployments often fail to load Sage Pay keys because deployment environments don’t automatically copy Secrets from the Repl runtime. Secrets must be explicitly added in the Deployment settings, and any mismatch in key names, missing variables, or use of reserved characters makes the Sage Pay client think no credentials exist.

 

Why it Happens

 

Replit runs your code in two different places: the Editor run and the Deployment. Each has its own environment. If your Sage Pay keys only exist in the Repl’s Secrets panel, the deployment won’t see them. Sage Pay also requires exact variable names and correct formatting; an extra space or wrong name means the variable resolves as empty.

  • Deployment env vars must be added under Deploy → Environment.
  • Check for hidden whitespace or wrong naming.
  • Restart the deployment after changing vars.

 

const vendor = process.env.SAGEPAY_VENDOR;  // Must exist in Deployment env
if (!vendor) throw new Error("Missing SagePay vendor ID");
Book a Free Consultation

Schedule a 30‑Minute No‑Code‑to‑Code Consultation

Grab a quick video call to discuss the fastest, most cost‑efficient path from no‑code to production‑ready code. Zero sales fluff—just practical advice tailored to your project.

Contact us

Common Integration Mistakes: Replit + Sage Pay

Incorrect Callback URLs

 

Developers often set Sage Pay (Opayo) callback URLs that don’t match the actual public URL of the running Repl. Replit only exposes routes through the generated HTTPS URL or the Deployment URL, never through localhost. If the callback doesn’t point to that public URL, Sage Pay can’t POST the payment result back, leaving payments in a “pending” state.

  • Always use the visible Replit web URL for Sage Pay notifications.
  • Ensure your server listens on 0.0.0.0 so callbacks actually reach the process.
app.post("/sagepay/callback", (req, res) => {
  // verify payload, update order, send 200 OK
  res.send("OK");
});

Hard‑coding Credentials

 

Placing Sage Pay vendor names, keys, or encryption passwords directly in code causes accidental exposure because Repls are forkable and readable. Replit’s correct approach is storing all sensitive data in Secrets, which appear inside the app as environment variables that won’t leak in forks, logs, or Git history.

  • Use the Secrets panel for vendor, integration key, and encryption password.
  • Never commit any Sage Pay credentials into the repo.
const vendor = process.env.SAGEPAY_VENDOR;      // from Replit Secrets
const key = process.env.SAGEPAY_KEY;            // sensitive

Ignoring HTTPS Requirements

 

Sage Pay requires HTTPS for redirects and notifications. Replit already provides HTTPS for the main public URL, but the mistake happens when devs test against raw ports like http://0.0.0.0:3000 inside the browser. Sage Pay will reject these non‑HTTPS endpoints, causing failed payments or rejected requests.

  • Use only the provided HTTPS URL when registering notification and success/fail pages.
  • Do not use internal port URLs from your local browser.
app.listen(3000, "0.0.0.0");  // Replit maps this to an HTTPS public URL

Missing Signature/Encryption Validation

 

Some developers trust the callback body directly without performing Sage Pay's required signature or encryption checks. On Replit, this is particularly risky because public URLs are easily discoverable. Without validating Sage Pay’s signature, any actor could POST fake “payment successful” data to your callback endpoint.

  • Always verify Sage Pay signatures or decrypt the payload as specified in Opayo docs.
  • Reject any callback that fails validation.
// Pseudocode placeholder: perform real Opayo signature/decryption per docs
if (!isValidSagePay(req.body)) return res.status(400).send("Invalid");

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â