Transfer/EFT iFrame API Step 2
The RESPONSE that the Callback URL gives to the PayTR system should be plain text OK
IMPORTANT: You should not display HTML or any other content before or after the “OK” response. Callback URL is not a page which users see during payment process, thus there will be no user SESSION at this page and no SESSION values can be used.For payments which the PayTR system does not receive an OK response from the Callback URL, the status will be displayed as "In Progress" (Devam Ediyor) on the Transactions (İşlemler) page on the Merchant Panel. When the PayTR system can not connect to the Callback URL or does not receive the OK response from the Callback URL, PayTR system will try again after a minute.
IMPORTANT: This may happen due to network issues, instant overloads on merchant stystems, etc. Thus, multiple notifications for the same payment transaction can be received on Callback URL. For this reason, in such cases, it is very important that recurring notifications should be handled correctly on Callback URL. Only the first notification should be taken into account to approve/cancel the order and the recurring ones should only be responded to by displaying OK. Recurring notifications should be checked based on “merhant_oid” value.
- In case of failure of the payment transaction, two more fields, “failed_reason_code” and “failed_reason_msg”, appear in the notification POST content. These fields are not used in hash calculation. If desired, these messages can be forwarded to the customer via e-mail or the store message system for the purpose of informing the customer.
failed_reason_code |
failed_reason_msg |
Description |
4 |
Transfer/EFT payment could not be detected |
The payment could not be reached with the information specified by the customer in the payment notification form |
5 |
Transfer/EFT payment amount is insufficient.Please notify as much as the amount you send |
Since the amount sent by the customer to the bank is less than the shopping amount (payment_amount), approval has not been given. |
6 |
The customer refused to pay and left the checkout page. |
The customer did not complete the transaction in the processing time (timeout_limit value defined in STEP 1) or the customer closed the payment page and ended the transaction. |
7 |
Your notification has not been received, please wait for your previous notification to be checked. |
While the Customer had a payment notification that had not yet been checked, made a notification again |
41 |
The first name and last name in the notification do not match the Transfer/EFT Payment |
The Name and Surname entered by the customer while making the notification did not match the Name and Surname in the bank records |
42 |
The transfer / EFT payment does not match the TCKN in the notification |
The TCKN entered by the customer while making the notification did not match the TCKN in the bank records |
43 |
This Transfer/EFT payment has been previously approved |
A check made after the customer's notification showed that this payment was previously reported and approved |
44 |
This Transfer/EFT payment has been refunded |
A check after the customer's notification showed that this payment had been refunded earlier |
45 |
Only one of the two different Name-Surnames on the receipt is written |
A check made after the customer's notification showed that only one of the two first and last names written on the receipt was entered |
<?php
$post = $_POST;
$merchant_key = 'YYYYYYYYYYYYYY';
$merchant_salt = 'ZZZZZZZZZZZZZZ';
$hash = base64_encode( hash_hmac('sha256', $post['merchant_oid'].$merchant_salt.$post['status'].$post['total_amount'], $merchant_key, true) );
if( $hash != $post['hash'] )
die('PAYTR notification failed: bad hash');
if( $post['status'] == 'success' ) {
} else {
}
echo "OK";
exit;
?>
# Python 3.6+
import base64
import hashlib
import hmac
import json
from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def callback(request):
if request.method != 'POST':
return HttpResponse(str(''))
post = request.POST
merchant_key = b'XXXXXXXXXXXXXXXX'
merchant_salt = 'XXXXXXXXXXXXXXXX'
hash_str = post['merchant_oid'] + merchant_salt + post['status'] + post['total_amount']
hash = base64.b64encode(hmac.new(merchant_key, hash_str.encode(), hashlib.sha256).digest())
if hash != post['hash']:
return HttpResponse(str('PAYTR notification failed: bad hash'))
if post['status'] == 'success':
else:
return HttpResponse(str('OK'))
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Net.Mail;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class bildirim_url_ornek : System.Web.UI.Page {
string merchant_key = "YYYYYYYYYYYYYY";
string merchant_salt = "ZZZZZZZZZZZZZZ";
protected void Page_Load(object sender, EventArgs e) {
string merchant_oid = Request.Form["merchant_oid"];
string status = Request.Form["status"];
string total_amount = Request.Form["total_amount"];
string hash = Request.Form["hash"];
string Birlestir = string.Concat(merchant_oid, merchant_salt, status, total_amount);
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(merchant_key));
byte[] b = hmac.ComputeHash(Encoding.UTF8.GetBytes(Birlestir));
string token = Convert.ToBase64String(b);
if (hash.ToString() != token) {
Response.Write("PAYTR notification failed: bad hash");
return;
}
if (status == "success") {
Response.Write("OK");
} else {
Response.Write("OK");
}
}
}
var express = require('express');
var ejsLayouts = require('express-ejs-layouts');
var microtime = require('microtime');
var crypto = require('crypto');
var app = express();
var nodeBase64 = require('nodejs-base64-converter');
var request = require('request');
var path = require('path');
app.set('views', path.join(__dirname, '/app_server/views'));
app.set('view engine', 'ejs');
app.use(ejsLayouts);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
var merchant_id = 'XXXXXX';
var merchant_key = 'YYYYYYYYYYYYYY';
var merchant_salt = 'ZZZZZZZZZZZZZZ';
var merchant_oid = "IN" + microtime.now();
var user_ip = '';
var email = 'musteri@saglayici.com';
var payment_amount = 100;
var payment_type ='eft';
var test_mode = '0';
var timeout_limit = 30;
var debug_on = 1;
app.get("/", function (req, res) {
var hashSTR = `${merchant_id}${user_ip}${merchant_oid}${email}${payment_amount}${payment_type}${test_mode}`;
var paytr_token = hashSTR + merchant_salt;
var token = crypto.createHmac('sha256', merchant_key).update(paytr_token).digest('base64');
var options = {
method: 'POST',
url: 'https://www.paytr.com/odeme/api/get-token',
headers:
{ 'content-type': 'application/x-www-form-urlencoded' },
formData: {
merchant_id: merchant_id,
user_ip: user_ip,
merchant_oid: merchant_oid,
email: email,
payment_amount: payment_amount,
payment_type: payment_type,
paytr_token: token,
debug_on: debug_on,
timeout_limit: timeout_limit,
test_mode: test_mode,
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
var res_data = JSON.parse(body);
if (res_data.status == 'success') {
res.render('layout', { iframetoken: res_data.token });
} else {
res.end(body);
}
});
});
app.post("/callback", function (req, res) {
var callback = req.body;
paytr_token = callback.merchant_oid + merchant_salt + callback.status + callback.total_amount;
var token = crypto.createHmac('sha256', merchant_key).update(paytr_token).digest('base64');
if (token != callback.hash) {
throw new Error("PAYTR notification failed: bad hash");
}
if (callback.status == 'success') {
} else {
}
res.send('OK');
});
var port = 3000;
app.listen(port, function () {
console.log("Server is running. Port:" + port);
});
Optional: Receive interim notifications
After your customer fills out the notification form in the IFrame, PayTR infrastructure will make an interim notification to the "Interim Notification URL" address you specify, if you request it. In the notification content, the order number you sent in the Transfer/EFT transfer request and the bank your customer selected for the transaction information is found.You can add the URL information you want to use as the “Interim Notification URL” from the Paytr Store Panel > Settings section.
Field name |
Description |
hash |
Hash: Hash information indicating the accuracy of the notification |
status |
Status: The "info" value comes in for the interim notification |
merchant_oid |
Merchant order id: The order number you sent when starting the Transfer/EFT Transfer notification |
bank |
Bank:The bank where the Transfer/EFT Transfer notification is made |
IMPORTANT NOTICE: Your notification URL is in the Paytr Merchant Panel > Settings > Notification URL settings section, if your site has SSL, you must set the notification URL protocol to HTTPS. If you do not have an SSL certificate,do not use an HTTPS link. If you have set up SSL after PayTR integration on your site, go to the notification URL settings section and save it by changing the protocol to HTTPS. If you cancel the SSL certificate on your site after installation, go to the notification URL settings section and save it by changing the protocol to HTTP.
<?php
$post = $_POST;
$merchant_key = 'YYYYYYYYYYYYYY';
$merchant_salt = 'ZZZZZZZZZZZZZZ';
if( $hash != $post['hash'] )
die('PAYTR notification failed: bad hash');
>
import base64
import hashlib
import hmac
import json
from django.shortcuts import render, HttpResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def callback(request):
if request.method != 'POST':
return HttpResponse(str(''))
post = request.POST
merchant_key = b'XXXXXXXXXXXXXXXX'
merchant_salt = 'XXXXXXXXXXXXXXXX'
hash_str = post['merchant_oid'] + post['bank']+ merchant_salt
hash = base64.b64encode(hmac.new(merchant_key, hash_str.encode(), hashlib.sha256).digest())
if hash != post['hash']:
return HttpResponse(str('PAYTR notification failed: bad hash'))
// Ara Bildirim URL için örnek kodlar
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Net.Mail;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class ara_bildirim_url_ornek : System.Web.UI.Page {
string merchant_key = "YYYYYYYYYYYYYY";
string merchant_salt = "ZZZZZZZZZZZZZZ";
protected void Page_Load(object sender, EventArgs e) {
string merchant_oid = Request.Form["merchant_oid"];
string merchant_oid = Request.Form["bank"];
string hash = Request.Form["hash"];
string Birlestir = string.Concat(merchant_oid, bank, merchant_salt);
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(merchant_key));
byte[] b = hmac.ComputeHash(Encoding.UTF8.GetBytes(Birlestir));
string token = Convert.ToBase64String(b);
if (hash.ToString() != token) {
Response.Write("PAYTR notification failed: bad hash");
return;
}
}
}
var express = require('express');
var ejsLayouts = require('express-ejs-layouts');
var microtime = require('microtime');
var crypto = require('crypto');
var app = express();
var nodeBase64 = require('nodejs-base64-converter');
var request = require('request');
var path = require('path');
app.set('views', path.join(__dirname, '/app_server/views'));
app.set('view engine', 'ejs');
app.use(ejsLayouts);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
var merchant_key = 'YYYYYYYYYYYYYY';
var merchant_salt = 'ZZZZZZZZZZZZZZ';
app.post("/callback", function (req, res) {
var callback = req.body;
paytr_token = callback.merchant_oid + callback.bank + merchant_salt
var token = crypto.createHmac('sha256', merchant_key).update(paytr_token).digest('base64');
if (token != callback.hash) {
throw new Error("PAYTR notification failed: bad hash");
}
});
var port = 3000;
app.listen(port, function () {
console.log("Server is running. Port:" + port);
});