Skip to content

Using Virtual POS in iframe

You can embed the Virtual POS in an iframe as shown in the example code below. The website loaded within the iframe must be your own domain. For testing purposes, you can use the example form from page 3 on your website.

example.html
<!doctype html>
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>iframe</title>
</head>
<body>
<div class="container">
<script src="https://paynkolaytest.nkolayislem.com.tr/VPos/js/paynkolay-iframe-resizer.js"></script>
<!-- iframe içinde çağırdığınız web sitesi sizin web siteniz olmalıdır. Burada sayfa 3'teki örnek formu kullanabilirsiniz. -->
<iframe src="https://paynkolay.com.tr/entegrasyon/sanal-pos-test-ortam-iframe" id="paynkolayiframe" frameborder="0" scrolling="no" style="width: 100%;"></iframe>
<script>iFrameResize({},'#paynkolayiframe');</script>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>

After payment completion, you may experience issues where the redirect to your successUrl doesn’t work properly or user sessions are terminated unexpectedly. These problems are typically caused by modern browser security policies. Below are the most common technical causes and their solutions.

Section titled “1. SameSite Cookie Restrictions (Most Common)”

Problem:

Modern browsers (especially Chrome and Safari) block cookies (session cookies) by default when redirects occur from different domains within an iframe. When Pay N Kolay posts to your successUrl, the browser treats this as a “third-party (cross-site)” request and blocks existing session cookies (such as PHPSESSID) for security reasons. This causes your application to perceive the user as “logged out” or having no active session.

Solution:

Your application must configure session cookies with the following parameters:

  • SameSite=None - Allows cookies to be sent in cross-site contexts
  • Secure=true - Requires HTTPS (mandatory when using SameSite=None)

Example configuration:

// PHP Example
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '.yourdomain.com',
'secure' => true,
'httponly' => true,
'samesite' => 'None'
]);
session_start();
// ASP.NET Core Example
services.AddSession(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
// Node.js/Express Example
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
sameSite: 'none'
}
}));
# Django Example (settings.py)
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_HTTPONLY = True

Problem:

Your server or application may be configured to prevent pages from being embedded in iframes for security reasons. If your successUrl page returns an X-Frame-Options: DENY or X-Frame-Options: SAMEORIGIN header in the server response, the browser will refuse to display the page within an iframe.

Solution:

You need to either remove this restriction or allow the specific domain for your payment return page (successUrl).

Option A: Remove the header entirely (if safe for your use case)

# Apache (.htaccess)
Header unset X-Frame-Options
# Nginx
# Remove or comment out any add_header X-Frame-Options directives

Option B: Allow specific origin

# Apache
Header set X-Frame-Options "ALLOW-FROM https://paynkolaytest.nkolayislem.com.tr"
# Nginx
add_header X-Frame-Options "ALLOW-FROM https://paynkolaytest.nkolayislem.com.tr";

Option C: Use Content-Security-Policy (modern recommended approach)

# Apache
Header set Content-Security-Policy "frame-ancestors 'self' https://paynkolaytest.nkolayislem.com.tr https://paynkolay.com.tr"
# Nginx
add_header Content-Security-Policy "frame-ancestors 'self' https://paynkolaytest.nkolayislem.com.tr https://paynkolay.com.tr";
// ASP.NET Core (Startup.cs or Program.cs)
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Content-Security-Policy",
"frame-ancestors 'self' https://paynkolaytest.nkolayislem.com.tr https://paynkolay.com.tr");
await next();
});
// PHP
header("Content-Security-Policy: frame-ancestors 'self' https://paynkolaytest.nkolayislem.com.tr https://paynkolay.com.tr");

Before deploying iframe integration to production, ensure you have:

  • Configured session cookies with SameSite=None and Secure=true
  • Enabled HTTPS on your website (required for SameSite=None)
  • Removed or configured X-Frame-Options headers to allow iframe embedding
  • Set appropriate Content-Security-Policy with frame-ancestors directive
  • Tested the complete payment flow including success and failure scenarios
  • Verified that user sessions persist after payment completion
  • Tested across multiple browsers (Chrome, Safari, Firefox, Edge)

The issues described above stem from security enhancements implemented by browser vendors to protect users from clickjacking attacks and cross-site data leakage. While these protections improve web security overall, they require careful configuration when implementing legitimate iframe-based integrations like payment gateways.

The SameSite cookie attribute was introduced to prevent Cross-Site Request Forgery (CSRF) attacks. By default, browsers now treat cookies as SameSite=Lax, which blocks them in cross-site POST requests within iframes. Setting SameSite=None explicitly opts into the previous behavior but requires the Secure flag to ensure cookies are only transmitted over encrypted connections.

Similarly, X-Frame-Options and Content-Security-Policy headers protect against clickjacking by controlling which sites can embed your pages in frames. For payment integrations, you need to selectively allow embedding from trusted payment provider domains while maintaining protection against unauthorized framing.