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.
<!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
Section titled “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)
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 contextsSecure=true- Requires HTTPS (mandatory when usingSameSite=None)
Example configuration:
// PHP Examplesession_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'domain' => '.yourdomain.com', 'secure' => true, 'httponly' => true, 'samesite' => 'None']);session_start();// ASP.NET Core Exampleservices.AddSession(options =>{ options.Cookie.SameSite = SameSiteMode.None; options.Cookie.SecurePolicy = CookieSecurePolicy.Always;});// Node.js/Express Exampleapp.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized: false, cookie: { secure: true, httpOnly: true, sameSite: 'none' }}));# Django Example (settings.py)SESSION_COOKIE_SECURE = TrueSESSION_COOKIE_SAMESITE = 'None'SESSION_COOKIE_HTTPONLY = True2. X-Frame-Options Header Blocking
Section titled “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 (if safe for your use case)
# Apache (.htaccess)Header unset X-Frame-Options# Nginx# Remove or comment out any add_header X-Frame-Options directivesOption B: Allow specific origin
# ApacheHeader set X-Frame-Options "ALLOW-FROM https://paynkolaytest.nkolayislem.com.tr"# Nginxadd_header X-Frame-Options "ALLOW-FROM https://paynkolaytest.nkolayislem.com.tr";Option C: Use Content-Security-Policy (modern recommended approach)
# ApacheHeader set Content-Security-Policy "frame-ancestors 'self' https://paynkolaytest.nkolayislem.com.tr https://paynkolay.com.tr"# Nginxadd_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();});// PHPheader("Content-Security-Policy: frame-ancestors 'self' https://paynkolaytest.nkolayislem.com.tr https://paynkolay.com.tr");Checklist for iframe Integration
Section titled “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
Section titled “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.