This guide is intended for merchant developers who want to display Paycombat Checkout on their website's payment page. The integration consists of creating a transaction through the merchant backend, displaying the checkout URL in an iframe, and updating the order status from the backend.
Use the checkout domain, transaction creation API, and webhook verification mechanism specified in the API documentation and production configuration provided during Paycombat onboarding.
01Prepare the production integration
Before adding the iframe, make sure:
- The merchant website and checkout use HTTPS.
- The merchant backend can create transactions and receive production checkout URLs from Paycombat.
- The merchant website origin, including the scheme, hostname, and port if applicable, is allowed to embed the checkout in an iframe.
- The merchant backend handles webhooks or transaction status checks according to the Paycombat contract.
API keys and secret credentials must only be used on the merchant backend. Do not include them in HTML, browser JavaScript, or merchant page URLs.
02Create a transaction through the merchant backend
The integration flow is as follows:
- The customer clicks the payment button on the merchant website.
- The browser sends a payment creation request to the merchant backend.
- The merchant backend validates the order, calculates the amount using server-side data, and creates a transaction through the Paycombat API according to the production contract.
- The backend receives a checkout URL from Paycombat.
- The backend sends the checkout URL to the browser for display in an iframe.
The backend must ensure that the transaction is associated with the correct order and customer. Do not trust amounts or payment statuses sent by the browser.
Example data used by the frontend code in this guide:
{
"checkoutUrl": "CHECKOUT_URL_FROM_BACKEND"
}checkoutUrl is an example field name for the merchant integration, not a declaration of the Paycombat API response format. Adjust the mapping to match the API contract you use.
03Add a checkout container
Add the following elements to the merchant payment page:
<section aria-label="Payment">
<div id="checkout-container"></div>
<p id="checkout-message" role="status" aria-live="polite"></p>
</section>Add CSS to make the iframe follow the page width:
#checkout-container {
width: 100%;
max-width: 960px;
margin-inline: auto;
}
.paycombat-checkout {
display: block;
width: 100%;
height: 780px;
border: 0;
background: #fff;
}
@media (max-width: 600px) {
.paycombat-checkout {
height: 85vh;
min-height: 560px;
}
}Adjust the height based on checkout testing on supported devices. The parent cannot directly read the content height of a cross-origin iframe.
04Load the checkout URL received from the backend
Use the following function in the merchant JavaScript:
function mountPaycombatCheckout(checkoutUrl, allowedCheckoutOrigin) {
const container = document.querySelector('#checkout-container');
const message = document.querySelector('#checkout-message');
if (!container || !message) {
throw new Error('Checkout container not found.');
}
const url = new URL(checkoutUrl);
const allowedOrigin = new URL(allowedCheckoutOrigin);
if (
url.protocol !== 'https:' ||
url.username ||
url.password ||
allowedOrigin.protocol !== 'https:' ||
url.origin !== allowedOrigin.origin
) {
throw new Error('Checkout URL is not allowed.');
}
const iframe = document.createElement('iframe');
iframe.className = 'paycombat-checkout';
iframe.title = 'Paycombat payment';
iframe.referrerPolicy = 'no-referrer';
iframe.src = url.href;
message.textContent = 'Opening the payment page…';
iframe.addEventListener('load', () => {
message.textContent =
'Please continue your payment on the checkout page.';
});
container.replaceChildren(iframe);
}Call the function after the browser receives the payment creation result from the merchant backend:
// payment is the result returned by the merchant backend.
// merchantConfig comes from the merchant application's trusted configuration.
mountPaycombatCheckout(
payment.checkoutUrl,
merchantConfig.paycombatCheckoutOrigin,
);Set merchantConfig.paycombatCheckoutOrigin to the production checkout origin confirmed by Paycombat. This value must come from the merchant configuration, not a query parameter or customer input.
Do not save checkout URLs containing tokens to analytics, logs, localStorage, or the repository. The load event only indicates that iframe navigation has completed; it does not prove that the checkout was displayed successfully or that payment succeeded.
This basic example does not set a sandbox attribute. Adding sandbox, popup permissions, or top-level navigation must be agreed upon based on checkout and provider requirements, then tested with the payment methods in use. Inappropriate restrictions can interfere with forms, redirects, or opening payment apps.
05Allow checkout on the merchant website
If your website uses Content Security Policy (CSP), add the production checkout origin to the frame-src directive in the existing policy. The following example uses an illustrative domain; replace https://checkout.example with the origin provided by Paycombat:
Content-Security-Policy: frame-src https://checkout.example;Merge this directive into your website's CSP without removing other directives. If there are multiple CSP policies, make sure all of them allow the checkout origin.
Provide your website origins to the Paycombat team during onboarding so embedding permissions can be confirmed. Include the scheme, hostname, and port if applicable, for example https://shop.merchant.example.
If the browser displays Refused to frame due to the checkout's frame-ancestors or X-Frame-Options, contact the Paycombat team with the merchant origin and browser error message. Restrictions set by the checkout server cannot be changed through merchant JavaScript. Avoid including checkout URLs containing tokens in error reports.
06Confirm payment through the backend
After the customer completes the payment process:
- The merchant backend receives a Paycombat webhook and verifies it according to the integration contract, or checks the status through a supported server-to-server API.
- The backend matches the transaction reference, order, amount, currency, and relevant final status.
- The backend processes notifications idempotently to prevent repeated order fulfillment.
- The merchant page requests the order status from the merchant backend and updates the display based on that result.
Do not mark an order as paid based solely on a load event, browser redirect, URL parameter, or iframe message.
The parent cannot read the cross-origin checkout DOM. This guide also does not assume that checkout already provides postMessage events. If Paycombat provides an official event contract, validate event.origin, event.source, and the message structure. Use these events as triggers to check the status through the backend.
07Test before enabling production
- Make sure checkout displays the correct transaction on the merchant origin that will be used.
- Check Console and Network for CSP or
X-Frame-Optionsrejections. - Test desktop and real mobile devices, including scrolling, keyboard behavior, and orientation changes.
- Test every enabled payment method, including bank redirects, popups, e-wallet apps, and returning to the merchant.
- Test successful, failed, canceled, and expired payments.
- Make sure repeated webhooks do not process an order twice and that the page status follows the backend status.
- Make sure there is a flow to open hosted checkout directly if a payment method does not support embedding.
The ability to display checkout in an iframe and support for each provider must be confirmed through testing. Displaying the initial page does not guarantee that the entire provider flow supports iframes.