Using Virtual POS in iframe
We do not recommend using iframe integration. However, if you need to implement it, you must configure specific server and page settings to ensure proper functionality. Please review the technical requirements below carefully.
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.
<!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>Common Issues and Solutions #
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.
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 Paynkolay 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 contextsSecure=true- Requires HTTPS (mandatory when usingSameSite=None)
Example configuration:
// PHP Example
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '.domain.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 = TrueSameSite=None to work. HTTP connections will not work with this configuration.2. X-Frame-Options Header Blocking #
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
# Apache (.htaccess)
Header unset X-Frame-Options# Nginx
# Remove or comment out any add_header X-Frame-Options directivesOption 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");You can check your current headers using browser developer tools:
1. Open Developer Tools (F12)
2. Go to the Network tab
3. Reload your page and click on the document request
4. Look for
X-Frame-Options or Content-Security-Policy headers in the Response Headers sectionIf you see blocking headers, apply the appropriate solution above based on your server configuration.
Checklist for iframe Integration #
Before deploying iframe integration to production, ensure you have:
- Configured session cookies with
SameSite=NoneandSecure=true - Enabled HTTPS on your website (required for
SameSite=None) - Removed or configured
X-Frame-Optionsheaders to allow iframe embedding - Set appropriate
Content-Security-Policywithframe-ancestorsdirective - 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)
Technical Background #
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.