What is Embedded Checkout?
Embedded checkout lets you include Revolv3’s secure payment form directly in your website using an iframe. Customers complete payment without leaving your site, but Revolv3 still handles all the sensitive payment data.
Benefits:
- ✅ Seamless experience: Customers stay on your site
- ✅ No card data handling: You never see sensitive payment information
- ✅ PCI compliance: Revolv3 handles all security requirements
- ✅ Brand consistency: Checkout appears within your site design
- ✅ Event-based updates: Your page is notified when payment completes
When to use it:
- You want customers to stay on your site
- You want a seamless checkout experience
- You’re okay with using an iframe
- You can handle postMessage events in JavaScript
Prerequisites
Before you begin, make sure you have:
- ✅ Revolv3 account: Active merchant account with configured processors
- ✅ API key: Developer static token for authentication
- ✅ Trusted hostnames: Your website domain added to Trusted Checkout Hostnames in the portal
Step 1: Create a Checkout Session
Create a checkout session by sending a POST request to the checkout endpoint.
API Endpoint
POST {{Api Root}}/api/Checkout
Replace {{Api Root}} with:
- Production:
api.revolv3.com
- Sandbox:
api-sandbox.revolv3.com
Origin HTTP header requiredYou must include the Origin HTTP header in your request. This header should match one of your trusted hostnames.If the Origin header is missing or doesn’t match a trusted hostname, you’ll get a 400 Bad Request error.
Include these headers:
Origin: Your website’s origin (e.g., https://mysite.com)
x-revolv3-token: Your API key
Content-Type: application/json
Sample Request
{
"OneTimePayment": {
"CheckoutLineItems": [
{
"Name": "Item 1",
"Description": "Product description",
"Value": 9.99,
"ValueType": "Standard"
},
{
"Name": "Item 2",
"Description": "Another product",
"Value": 21.99,
"ValueType": "Standard"
}
]
}
}
Note: For embedded checkout, you typically don’t need a ReturnUrl since the customer stays on your page. However, you can include one if needed.
For details on line items and value types, see Checkout Line Items Value Types.
Response
When you create a checkout session, you’ll get back a checkout link:
{
"checkoutId": "0584773e-47bf-4822-91de-06acb5de9358",
"checkoutLink": "https://portal.revolv3.com/checkout/0584773e-47bf-4822-91de-06acb5de9358"
}
Understanding the response:
checkoutId: Unique identifier for this checkout session (save this for tracking)
checkoutLink: The URL to embed in your iframe
Step 2: Embed the Checkout Page
Embed the checkout link in your website using an iframe:
HTML Example
<iframe
title="Revolv3 Checkout"
src="https://portal.revolv3.com/checkout/0584773e-47bf-4822-91de-06acb5de9358"
frameborder="0"
scrolling="no"
width="100%"
height="600">
</iframe>
Iframe attributes:
src: The checkoutLink from the API response
title: Descriptive title for accessibility
frameborder="0": Removes border for seamless integration
scrolling="no": Prevents scrollbars (adjust height as needed)
width and height: Set to fit your page layout
React Example
function CheckoutEmbed({ checkoutLink }) {
return (
<iframe
title="Revolv3 Checkout"
src={checkoutLink}
frameBorder="0"
scrolling="no"
style={{ width: '100%', height: '600px' }}
/>
);
}
Step 3: Listen for Payment Completion
When the customer completes payment, Revolv3 sends a message to your page using the postMessage API. You need to listen for this message to know when payment is done.
Add Event Listener
Add a message event listener to your page:
addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
// ⚠️ SECURITY: Always verify the message origin
if (event.origin === 'https://portal-sandbox.revolv3.com' ||
event.origin === 'https://portal.revolv3.com') {
// Message is from Revolv3 - safe to process
const data = event.data; // { checkoutId: string, checkoutStatus: string }
// Handle the payment result
if (data.checkoutStatus === 'PaymentCompleted') {
// Payment succeeded - show success message, update UI, etc.
showSuccessMessage();
hideCheckoutIframe();
} else if (data.checkoutStatus === 'PaymentFailed') {
// Payment failed - show error, allow retry, etc.
showErrorMessage();
}
}
// Ignore messages from other origins
return;
}
Always verify event.originSecurity requirement: You must verify that the message came from Revolv3 (either portal.revolv3.com or portal-sandbox.revolv3.com). Never process messages from unknown origins.This prevents malicious websites from sending fake payment completion messages to your page.
Understanding the Message Data
The message from Revolv3 contains:
{
checkoutId: string, // Unique checkout session ID (GUID format)
checkoutStatus: string // Current status of the checkout
}
Checkout Status Values
| Status | What It Means | What to Do |
|---|
Pending | Checkout created, payment not yet made | Keep showing the iframe, wait for payment |
PaymentCompleted | Payment was successful | Show success message, hide iframe, update order status |
PaymentFailed | Payment attempt failed | Show error message, allow customer to retry |
Step 4: Handle Payment Results
Based on the checkout status, update your page:
Payment Completed
if (data.checkoutStatus === 'PaymentCompleted') {
// Hide the checkout iframe
document.getElementById('checkout-iframe').style.display = 'none';
// Show success message
showSuccessMessage('Payment completed successfully!');
// Update order status in your system
updateOrderStatus(data.checkoutId, 'paid');
// Redirect or update UI as needed
}
Payment Failed
if (data.checkoutStatus === 'PaymentFailed') {
// Show error message
showErrorMessage('Payment failed. Please try again.');
// Optionally allow customer to retry
// (create a new checkout session)
}
You can check the checkout status at any time using the API:
GET {{Api Root}}/api/Checkout/{checkoutId}
Replace {checkoutId} with the checkout ID from the session response.
This is useful if:
- You need to verify payment status
- The customer refreshes the page
- You want to poll for status updates
Complete Integration Example
Here’s a complete example of embedded checkout:
HTML
<!DOCTYPE html>
<html>
<head>
<meta name="referrer" content="origin" />
<title>Checkout</title>
</head>
<body>
<div id="checkout-container">
<iframe
id="checkout-iframe"
title="Revolv3 Checkout"
src=""
frameborder="0"
scrolling="no"
width="100%"
height="600">
</iframe>
</div>
<div id="success-message" style="display: none;">
Payment completed successfully!
</div>
<div id="error-message" style="display: none;">
Payment failed. Please try again.
</div>
<script>
// Create checkout session (on page load)
async function createCheckout() {
const response = await fetch('{{Api Root}}/api/Checkout', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Origin': window.location.origin,
'x-revolv3-token': 'your-api-key'
},
body: JSON.stringify({
OneTimePayment: {
CheckoutLineItems: [
{
Name: "Product",
Value: 99.99,
ValueType: "Standard"
}
]
}
})
});
const data = await response.json();
document.getElementById('checkout-iframe').src = data.checkoutLink;
}
// Listen for payment completion
window.addEventListener("message", function(event) {
// Verify origin
if (event.origin === 'https://portal.revolv3.com' ||
event.origin === 'https://portal-sandbox.revolv3.com') {
const { checkoutId, checkoutStatus } = event.data;
if (checkoutStatus === 'PaymentCompleted') {
document.getElementById('checkout-iframe').style.display = 'none';
document.getElementById('success-message').style.display = 'block';
} else if (checkoutStatus === 'PaymentFailed') {
document.getElementById('error-message').style.display = 'block';
}
}
});
// Create checkout when page loads
createCheckout();
</script>
</body>
</html>
Best Practices
- Verify message origin: Always check
event.origin before processing messages
- Handle all statuses: Account for Pending, PaymentCompleted, and PaymentFailed
- User experience: Show loading states and clear success/error messages
- Iframe sizing: Set appropriate width and height for your layout
- Error handling: Handle cases where checkout creation fails
- Test thoroughly: Test the full flow in sandbox before production
Common Questions
Q: Can I style the iframe?
A: You can style the iframe container, but the content inside is controlled by Revolv3 for security reasons.
Q: What if the customer closes the iframe?
A: The checkout session remains valid. You can check its status or create a new one.
Q: How do I know if payment completed?
A: Listen for the postMessage event from Revolv3. The message includes the checkout status.
Q: Can I customize the payment page?
A: The embedded checkout uses Revolv3’s standard design. For more customization, you’d need to build your own form.
Q: What browsers support this?
A: All modern browsers support iframes and postMessage. Test in your target browsers.
Security Notes
- Always verify origin: Never process messages without checking
event.origin
- Use HTTPS: Always use HTTPS for your site when handling payments
- Trusted hostnames: Ensure your domain is in the trusted hostnames list
- Origin header: Always include the Origin header in API requests
Next Steps