Revolut for WooCommerce: Why I Built My Own Integration
The payment step is the most fragile moment in a whole store. A customer who breezed through your catalog and added to cart will still hesitate, for a second, when it is time to enter a card. Everything they feel in that second, confidence or doubt, is decided by how the checkout looks and behaves. That is the lens I want to use here, because it explains a decision that might otherwise sound like over-engineering: why I stopped using the off-the-shelf Revolut gateway on a WooCommerce store and built my own integration instead. To be fair up front, the standard plugin is a reasonable choice for plenty of stores. It just fell down in exactly the places that matter most when a brand cares about its checkout, and the technical mechanics below are grounded in Revolut's official documentation so you can verify them.
Where the off-the-shelf gateway fell short for us
The plugin took card payments, and for a simple store that is enough. For a brand-sensitive checkout, three things kept undermining the experience:
- The wallets were unreliable. Apple Pay and Google Pay are the fastest, highest-trust way to pay for the customers who have them, and they were not showing up or behaving consistently across devices and browsers. A wallet button that is sometimes there and sometimes not is worse than none, because it makes the checkout feel broken.
- The checkout jumped. The payment step shifted and re-rendered as it loaded and as the customer moved through it. That little jump, a layout shift, a redirect, a flash, reads to a shopper as instability, and instability is the last thing you want them feeling while holding their card.
- The card fields were too bare to trust. This was the big one. The default card inputs looked so plain and generic that they did not feel like part of our store. At the exact moment a customer is deciding whether to hand over their details, a field that looks unfinished quietly tells them not to. We could watch it cost us.
None of these are catastrophic on their own. Together, on the one screen where hesitation turns into an abandoned cart, they were expensive, and they were not things the plugin let us fix.
The insight: own the experience without owning the risk
The instinct when card fields look untrustworthy is to build your own card form, and that instinct is dangerous, because the moment raw card data touches your own inputs and your own server, your PCI scope explodes. The breakthrough was realizing I did not have to choose between a trustworthy UI and a safe one.
Revolut's web SDK exposes the card input as a secure hosted field, an iframe element you mount into your own page using createCardField, documented in the card field guide. The sensitive card entry stays inside Revolut's iframe, so card data never touches my code and PCI scope is unchanged, but I control everything around it: the container, the typography, the spacing, the labels, the card brand icons, the inline validation messages, and the trust cues. So I wrapped Revolut's secure element in a checkout that finally looked and felt like the rest of the store.
import RevolutCheckout from '@revolut/checkout';
// order.token comes from creating the order on the server (see below)
const { createCardField } = await RevolutCheckout(order.token, 'prod');
createCardField({
target: document.getElementById('my-branded-card-container'),
onSuccess() { /* authorized: show a pending state, let the webhook confirm */ },
onError(error) { /* render a friendly, on-brand inline error */ }
});
That single change, a polished container around a secure field, did more for conversion than any amount of copy on the page, because it removed the doubt at the precise instant it appears. It is the same judgment we lay out in when you need custom code rather than another plugin: reach for custom exactly when an off-the-shelf tool blocks the thing that matters most.
Fixing the wallets properly
With the UI under my control, the wallets became a deliberate feature instead of an unpredictable one. Apple Pay and Google Pay come through the SDK's wallet flow, built on the browser Payment Request API and described in the wallets guide. Two rules made them dependable:
- Render the button only when a wallet is actually available. You call
canMakePayment()first and render the button only on success, otherwise you destroy it. That alone removes the "sometimes there, sometimes not" feeling, because the button now appears precisely when it will work. - Register the domain for Apple Pay. Apple Pay requires hosting Revolut's validation file at
/.well-known/apple-developer-merchantid-domain-associationand then registering the domain through the Merchant API (register domain for Apple Pay). Google Pay needs no extra step.
One honest caveat that will save you an afternoon: Apple Pay cannot be tested in the sandbox, so it has to be validated with a careful check in production. Knowing that in advance is the difference between a smooth launch and a confusing one.
Doing the plumbing right, so it stays unbuggy
The reason the custom version is not buggy is not magic, it is owning the full flow and following the documented path rather than a wrapper's assumptions. Briefly, and grounded in Revolut's docs:
- Order first, on the server. The order is created server-side with create order, with the amount in the minor currency unit, and the short-lived token is handed to the browser to initialize the field above.
- 3D Secure handled in the field. Strong customer authentication, including any bank challenge, is handled inside Revolut's secure element, so there is nothing fragile for me to wire up on the page.
- The webhook is the source of truth. I treat the front-end
onSuccessas a UX signal only, and confirm the order from the authoritativeORDER_COMPLETED(orORDER_AUTHORISED) webhook, exactly as Revolut recommends, with the signature verified and the handler made idempotent. That is what kills the classic "paid but still pending" class of bug. The full serverless version of this, including the exact signature scheme, is in the companion piece on the Revolut Merchant API on Vercel.
This is the same integration discipline behind why connecting your stack beats copy and paste: when you control the seams, the bugs that live in the seams disappear.
How I build this so it earns trust and keeps it
A checkout is the last place you want surprises, so the way it gets built matters as much as the result:
- Discovery and a clear roadmap first. We agree on exactly what the checkout should look like and do, and where the current setup is costing you, before any code. You see the plan and a fixed price for the first phase.
- A fixed-scope first phase. Usually one clean card payment through the new, branded field, reconciled by webhook, before wallets and extras are layered on.
- Sandbox first, then a deliberate production pass. The whole flow is proven in the sandbox, then the production-only paths like Apple Pay get a controlled live check, so nothing reaches a real customer untested.
- You own the code, the keys, and the experience. It is your Revolut account, your WooCommerce store, and your checkout, with no lock-in and no wrapper deciding how your brand looks at the most important moment.
- Direct access to the developer. When you want to adjust the field, the wallets, or the copy, that is a quick conversation with the person who built it, not a wait for a third-party plugin update.
Notice what that does to the fear that usually surrounds touching a live checkout: every step is small, proven in a safe environment first, and reversible, so confidence is built rather than gambled.
Proof, not promises
This is the kind of work we do every day. We run the WooSmiths WooCommerce studio, we ship headless commerce with full payments like the LeO-Optic store, and we build money-sensitive, rules-heavy systems like customs-invoice.com. A trustworthy checkout that keeps card data safely inside the provider's secure field while looking and behaving like your brand is exactly the sort of thing custom does better than any drop-in plugin.
If your Revolut checkout on WooCommerce feels generic, jumps around, or lets you down on wallets, you do not have to live with it, and you do not have to take on card-data risk to fix it. Tell me what your checkout is doing today and I will give you a straight read on what a safe first phase to rebuild it would look like.
Have a project in mind?
Let's turn it into custom software that moves your business forward.