Online Payment Checkout Component
The Online Payment Checkout Component is a lightweight, embeddable checkout solution that integrates directly into your website using an iframe. With just a few lines of code, you can deliver a seamless, mobile-friendly payment experience.
Examples
Choose the code snippet that best fits your implementation. We’ve provided ready-to-use examples to suit different frontend setups.
- JavaScript
- React
- Vue3
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>KodyPay Online Payment Checkout Component Demo</title>
<style>
iframe {
border: 0;
display: block;
margin: 0 auto;
}
.payment-status-hidden {
display: none;
}
.payment-status-expired {
display: block;
color: blue;
}
.payment-status-success {
display: block;
color: green;
}
.payment-status-error {
display: block;
color: red;
}
</style>
<script type="text/javascript">
// Script to handle payment completion
window.addEventListener("DOMContentLoaded", () => {
window.addEventListener("message", (event) => {
// Check if message is payment complete
if (event.data && event.data.type === "PAYMENT_COMPLETE") {
// Find and hide the iframe
const iframe = document.getElementById("kody-iframe");
iframe.style.display = "none";
const h2 = document.getElementById("payment-status");
h2.textContent = `Payment ${event.data.outcome}`;
// Add class based on outcome
h2.classList.remove("payment-status-hidden");
h2.classList.add(`payment-status-${event.data.outcome}`);
}
});
});
</script>
</head>
<body>
<h1>Demo</h1>
<iframe
id="kody-iframe"
width="500px"
height="620px"
src="https://p.kody.com/P.JAYOHONE.6TtnbJn?isEmbeddedInIframe=1"
></iframe>
<h2 id="payment-status" class="payment-status-hidden"></h2>
</body>
</html>
import { useState, useEffect, useCallback } from "react";
/**
<style>
iframe {
border: 0;
display: block;
margin: 0 auto;
}
.payment-status-expired {
color: blue;
}
.payment-status-success {
color: green;
}
.payment-status-error {
color: red;
}
</style>
**/
const Demo = () => {
// Save payment status
const [paymentStatus, setPaymentStatus] = useState();
const [iframeVisible, setIframeVisible] = useState(true);
const handleMessage = useCallback((event) => {
// Check if message is payment complete
if (event.data && event.data.type === "PAYMENT_COMPLETE") {
setIframeVisible(false);
setPaymentStatus(event.data.outcome);
}
}, []);
useEffect(() => {
window.addEventListener("message", handleMessage);
return () => {
window.removeEventListener("message", handleMessage);
};
}, []);
return (
<>
<h1>Demo</h1>
{iframeVisible && (
<iframe
width="500px"
height="620px"
src="https://p.kody.com/P.JAYOHONE.1vt3soe?isEmbeddedInIframe=1"
></iframe>
)}
{paymentStatus && (
<h2 className={`payment-status-${paymentStatus}`}>
Payment {paymentStatus}
</h2>
)}
</>
);
};
<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
// Save payment status
const paymentStatus = ref();
const iframeVisible = ref(true);
const handleMessage = (event) => {
// Check if message is payment complete
if (event.data && event.data.type === "PAYMENT_COMPLETE") {
iframeVisible.value = false;
paymentStatus.value = event.data.outcome;
}
};
onMounted(() => {
window.addEventListener("message", handleMessage);
});
onBeforeUnmount(() => {
window.removeEventListener("message", handleMessage);
});
</script>
<template>
<div>
<h1>Demo</h1>
<iframe
v-if="iframeVisible"
width="80%"
height="620px"
src="https://p.kody.com/P.JAYOHONE.1vt3soe?isEmbeddedInIframe=1"
></iframe>
<h2 v-if="paymentStatus" :class="`payment-status-${paymentStatus}`">
Payment {{ paymentStatus }}
</h2>
</div>
</template>
<style scoped>
iframe {
border: 0;
display: block;
margin: 0 auto;
}
.payment-status-expired {
color: blue;
}
.payment-status-success {
color: green;
}
.payment-status-error {
color: red;
}
</style>
Overview
Embed a secure, mobile-friendly checkout on your page using an iframe. Generate a unique link per order, embed it, and listen for the payment outcome via postMessage
. Redirect the customer to your confirmation page after success.
-
Generate the checkout link (server): Create a new checkout session for each order and get back the iframe URL.
-
Embed the iframe (client): Place the component on your checkout page. The iframe should blend into your layout and resize to its content.
-
Handle payment outcomes with message event: Listen for the result and take action (e.g., redirect to your confirmation page).
Flow (high level)
-
Create session (server) → receive iframe URL (unique).
-
Render iframe (client) with
isEmbeddedInIframe=1
, which must be included.// for example, 1vt3soe is the session id
<iframe
width="80%"
height="620px"
src="https://p.kody.com/P.JAYOHONE.1vt3soe?isEmbeddedInIframe=1"
></iframe> -
Customer pays inside iframe.
-
Component sends
PAYMENT_COMPLETE
viapostMessage
. The message format is:{
"type": "PAYMENT_COMPLETE",
"outcome": "success" // One of: success, expired, error
} -
Your page redirects or updates UI based on
outcome
.window.addEventListener("message", (event) => {
if (event.data.type === "PAYMENT_COMPLETE") {
// Handle payment outcome
if (event.data.outcome === "success") {
// Redirect to success page
} else if (event.data.outcome === "expired") {
// Redirect to expired page
} else if (event.data.outcome === "error") {
// Redirect to error page
}
}
});