Sanal POS API Dokümantasyonu

Payment Hub, sanal POS entegrasyonlarını tek noktadan yönetmenizi sağlayan ödeme altyapı servisidir. 3D Secure, NonSecure, PreAuth/Capture ve taksitli ödeme işlemlerini destekler. Tüm işlemler REST tabanlı JSON API üzerinden gerçekleştirilir.

REST API JSON 3D Secure NonSecure PreAuth İptal / İade Taksitli Ödeme
🚀
Hızlı Başlangıç: Sandbox ortamında hemen test etmeye başlamak için hazır Postman collection'larımızı kullanabilirsiniz.
Postman Workspace'i Aç →

Erişim Adresleri

Tüm API istekleri HTTPS üzerinden yapılmalıdır.

API Version Prefix
/api/v1
HTTP Port
443 (HTTPS)
Content-Type
application/json

Sandbox Test Kullanıcısı

API Key
00000000-0000-0000-0000-000000000000
Secret Key
sandbox-secret-key-for-testing-purposes-only
ℹ️
Tüm endpoint'ler /api/v1/vpos/payments/ prefix'i ile başlar. Tüm istek ve yanıtlar UTF-8 kodlu JSON formatındadır.

Endpoint Listesi

Metod Endpoint Açıklama
POST /api/v1/vpos/payments/payment Ödeme başlatma (3D / NonSecure / PreAuth)
POST /api/v1/vpos/payments/capture-pre-authorization PreAuth capture işlemi
POST /api/v1/vpos/payments/refund İade işlemi
POST /api/v1/vpos/payments/void İptal işlemi
GET /api/v1/vpos/payments/query/{transaction_id} İşlem sorgulama
GET /api/v1/vpos/payments/query-history/{transaction_id} İşlem geçmişi sorgulama
GET /api/v1/payments/transactions İşlem listeleme ve filtreleme
GET /api/v1/payments/balance Hakediş sorgulama

Kimlik Doğrulama

Tüm API istekleri için X-API-Key header'ı zorunludur. Ayrıca her istekte hash imzası (X-Hash) gönderilmelidir.

Zorunlu Header'lar

Header Zorunlu Açıklama
X-API-Key Zorunlu Merchant servisinden alınan API anahtarı
X-Hash Zorunlu İstek gövdesinden hesaplanan hash imzası (bkz. Hash Doğrulama)
Content-Type Zorunlu application/json
HTTP Request Example
POST /api/v1/vpos/payments/payment HTTP/1.1
Host: api.payment-hub.example.com
Content-Type: application/json
X-API-Key: your-api-key-here
X-Hash: 7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d906

Hash Doğrulama

Payment Hub, isteğin bütünlüğünü ve kaynağını doğrulamak için HMAC-SHA512 tabanlı hash imzası kullanır.

⚠️
Hash hesaplanmadan gönderilen istekler 401 Unauthorized hatası alır. Her istek için ayrı hash hesaplanmalıdır.

Hash Hesaplama Adımları

Parametre map'i oluşturun

İstek gövdesindeki tüm alanları string değerlerine dönüştürün:

  • Sayısal (int ve float): %.2f formatında (örn. 100.00, 1.00, 2025.00)
  • Boolean: true / false string
  • Nested obje: JSON string olarak serialize edilir; obje key'leri alfabetik sıraya göre sıralanır (örn. {"email":"[email protected]","first_name":"John","last_name":"Doe","phone":"+90..."})
  • Dizi (array): JSON array string olarak serialize edilir; dizi içindeki objelerin key'leri de alfabetik sıralanır (örn. [{"name":"Ürün 1","price":"299.90"},{"name":"Ürün 2","price":"149.90"}])
  • Null / boş string: dahil edilmez
Parametreleri alfabetik sıraya göre sıralayın ve JSON'a çevirin

Tüm parametreler key'lerine göre alfabetik olarak sıralanır ve kompakt (boşluksuz) JSON.stringify ile tek bir string'e dönüştürülür. Örn: {"amount":"250.00","currency":"TRY","order_id":"ORDER-001"}

HMAC-SHA512 ile hash hesaplayın

Oluşturulan JSON string'i üzerinden merchant secret key ile HMAC-SHA512 hash hesaplanır. Sonuç Base64 olarak encode edilip X-Hash header'ında gönderilir.

Kod Örnekleri

PHP
function sortKeysRecursive(array $data): array {
    ksort($data);
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            $data[$key] = sortKeysRecursive($value);
        }
    }
    return $data;
}

function toHashParam(mixed $value): ?string {
    if ($value === null || $value === '') return null;
    if (is_float($value) || is_int($value)) return number_format((float)$value, 2, '.', '');
    if (is_bool($value)) return $value ? 'true' : 'false';
    if (is_array($value)) return json_encode(sortKeysRecursive($value), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    return (string)$value;
}

function calculateHash(array $params, string $secretKey): string {
    $strParams = [];
    foreach ($params as $key => $value) {
        $v = toHashParam($value);
        if ($v !== null) $strParams[$key] = $v;
    }

    ksort($strParams); // alfabetik sırala

    // Kompakt JSON string'e çevir (boş array'i {} olarak encode et)
    $jsonString = empty($strParams)
        ? '{}'
        : json_encode($strParams, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

    // HMAC-SHA512, Base64 encode
    return base64_encode(hash_hmac('sha512', $jsonString, $secretKey, true));
}

// Kullanım
$requestBody = [
    'transaction_type' => 'Auth',
    'order_id'         => 'ORDER-12345',
    'amount'           => 100.00,
    'currency'         => 'TRY',
    'installment'      => 1,
    'card_number'      => '4355084355084358',
    'card_holder_name' => 'John Doe',
    'exp_year'         => 2025,
    'exp_month'        => 12,
    'cvv'              => '000',
    'is_3d'            => false,
    'customer_info'    => [
        'first_name' => 'John',
        'last_name'  => 'Doe',
        'email'      => '[email protected]',
        'phone'      => '+905551234567',
    ],
];

$hash = calculateHash($requestBody, 'your-secret-key');
// Header: X-Hash: {$hash}
Go
package main

import (
	"crypto/hmac"
	"crypto/sha512"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"sort"
)

// Nested map'leri key'lere göre alfabetik sıralanmış şekilde JSON'a çevirir
func sortedJSON(v interface{}) ([]byte, error) {
	switch val := v.(type) {
	case map[string]interface{}:
		keys := make([]string, 0, len(val))
		for k := range val {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		buf := []byte{'{'}
		for i, k := range keys {
			keyBytes, _ := json.Marshal(k)
			valBytes, err := sortedJSON(val[k])
			if err != nil {
				return nil, err
			}
			buf = append(buf, keyBytes...)
			buf = append(buf, ':')
			buf = append(buf, valBytes...)
			if i < len(keys)-1 {
				buf = append(buf, ',')
			}
		}
		return append(buf, '}'), nil
	case []interface{}:
		buf := []byte{'['}
		for i, item := range val {
			itemBytes, err := sortedJSON(item)
			if err != nil {
				return nil, err
			}
			buf = append(buf, itemBytes...)
			if i < len(val)-1 {
				buf = append(buf, ',')
			}
		}
		return append(buf, ']'), nil
	default:
		return json.Marshal(v)
	}
}

// Parametreleri string map'e dönüştüren yardımcı fonksiyon
func buildParams(body map[string]interface{}) map[string]string {
	result := make(map[string]string)
	for k, v := range body {
		switch val := v.(type) {
		case string:
			if val != "" {
				result[k] = val
			}
		case float64:
			result[k] = fmt.Sprintf("%.2f", val)
		case int:
			result[k] = fmt.Sprintf("%.2f", float64(val))
		case int32:
			result[k] = fmt.Sprintf("%.2f", float64(val))
		case int64:
			result[k] = fmt.Sprintf("%.2f", float64(val))
		case bool:
			result[k] = fmt.Sprintf("%t", val)
		case map[string]interface{}:
			// Nested obje: key'leri alfabetik sırala, JSON string'e çevir
			b, err := sortedJSON(val)
			if err == nil {
				result[k] = string(b)
			}
		case []interface{}:
			// Dizi: JSON string'e çevir (içindeki objelerin key'leri sıralanır)
			b, err := sortedJSON(val)
			if err == nil {
				result[k] = string(b)
			}
		}
	}
	return result
}

func calculateHash(params map[string]string, secretKey string) string {
	// Anahtarları alfabetik sıraya göre sırala
	keys := make([]string, 0, len(params))
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	// Sıralı map oluştur ve kompakt JSON'a çevir
	ordered := make(map[string]string)
	for _, k := range keys {
		ordered[k] = params[k]
	}
	jsonBytes, _ := json.Marshal(ordered)

	// HMAC-SHA512 hesapla, Base64 encode et
	mac := hmac.New(sha512.New, []byte(secretKey))
	mac.Write(jsonBytes)
	return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}

func main() {
	body := map[string]interface{}{
		"transaction_type": "Auth",
		"order_id":         "ORDER-12345",
		"amount":           100.00,
		"currency":         "TRY",
		"installment":      float64(1),
		"card_number":      "4355084355084358",
		"card_holder_name": "John Doe",
		"exp_year":         float64(2025),
		"exp_month":        float64(12),
		"cvv":              "000",
		"is_3d":            false,
		"customer_info": map[string]interface{}{
			"first_name": "John",
			"last_name":  "Doe",
			"email":      "[email protected]",
			"phone":      "+905551234567",
		},
	}

	params := buildParams(body)
	hash := calculateHash(params, "your-secret-key")
	fmt.Println("X-Hash:", hash)
}
C#
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;

public class PaymentHashHelper
{
    // JSON serialize ederken unicode escape kullanmamak için gerekli ayar
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
    };

    // Herhangi bir değeri kompakt JSON string'e çevirir (nested obje/dizi desteği)
    private static string ToJsonValue(object value)
    {
        if (value is Dictionary<string, object> dict)
            return SortedDictToJson(dict);
        if (value is List<object> list)
            return ListToJson(list);
        return "\"" + value + "\"";
    }

    // Nested Dictionary'yi key'leri alfabetik sıralı kompakt JSON string'e çevirir
    private static string SortedDictToJson(Dictionary<string, object> dict)
    {
        var sorted = new SortedDictionary<string, object>(dict);
        var sb = new StringBuilder("{");
        bool first = true;
        foreach (var kvp in sorted)
        {
            if (!first) sb.Append(",");
            sb.Append("\"").Append(kvp.Key).Append("\":");
            sb.Append(ToJsonValue(kvp.Value));
            first = false;
        }
        sb.Append("}");
        return sb.ToString();
    }

    // List'i kompakt JSON array string'e çevirir
    private static string ListToJson(List<object> list)
    {
        var sb = new StringBuilder("[");
        bool first = true;
        foreach (var item in list)
        {
            if (!first) sb.Append(",");
            sb.Append(ToJsonValue(item));
            first = false;
        }
        sb.Append("]");
        return sb.ToString();
    }

    private static string ToHashParam(object value)
    {
        if (value == null) return null;
        return value switch
        {
            double d  => d.ToString("F2", System.Globalization.CultureInfo.InvariantCulture),
            float f   => f.ToString("F2", System.Globalization.CultureInfo.InvariantCulture),
            int i     => ((double)i).ToString("F2", System.Globalization.CultureInfo.InvariantCulture),
            long l    => ((double)l).ToString("F2", System.Globalization.CultureInfo.InvariantCulture),
            bool b    => b.ToString().ToLower(),
            Dictionary<string, object> dict => SortedDictToJson(dict),
            List<object> list => ListToJson(list),
            string s when string.IsNullOrEmpty(s) => null,
            _         => value.ToString()
        };
    }

    public static string CalculateHash(Dictionary<string, object> parameters, string secretKey)
    {
        // Parametreleri string'e dönüştür ve alfabetik sırala
        var strParams = new SortedDictionary<string, string>();
        foreach (var kvp in parameters)
        {
            var v = ToHashParam(kvp.Value);
            if (v != null) strParams[kvp.Key] = v;
        }

        // Kompakt JSON string'e çevir (unicode escape olmadan)
        var jsonString = JsonSerializer.Serialize(strParams, JsonOptions);

        // HMAC-SHA512 hesapla, Base64 encode et
        using var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(secretKey));
        var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(jsonString));
        return Convert.ToBase64String(hashBytes);
    }
}

// Kullanım
var parameters = new Dictionary<string, object>
{
    { "transaction_type", "Auth" },
    { "order_id",         "ORDER-12345" },
    { "amount",           100.00 },
    { "currency",         "TRY" },
    { "installment",      1 },
    { "card_number",      "4355084355084358" },
    { "card_holder_name", "John Doe" },
    { "exp_year",         2025 },
    { "exp_month",        12 },
    { "cvv",              "000" },
    { "is_3d",            false },
    { "customer_info",    new Dictionary<string, object>
        {
            { "first_name", "John" },
            { "last_name",  "Doe" },
            { "email",      "[email protected]" },
            { "phone",      "+905551234567" },
        }
    },
};

string hash = PaymentHashHelper.CalculateHash(parameters, "your-secret-key");
// Header: X-Hash: {hash}
Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Base64;

public class PaymentHashHelper {

    // Herhangi bir değeri kompakt JSON string'e çevirir (nested obje/dizi desteği)
    @SuppressWarnings("unchecked")
    private static String toJson(Object value) {
        if (value instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) value;
            TreeMap<String, Object> sorted = new TreeMap<>(map);
            StringBuilder sb = new StringBuilder("{");
            boolean first = true;
            for (Map.Entry<String, Object> e : sorted.entrySet()) {
                if (!first) sb.append(",");
                sb.append("\"").append(e.getKey()).append("\":").append(toJson(e.getValue()));
                first = false;
            }
            sb.append("}");
            return sb.toString();
        } else if (value instanceof List) {
            List<?> list = (List<?>) value;
            StringBuilder sb = new StringBuilder("[");
            boolean first = true;
            for (Object item : list) {
                if (!first) sb.append(",");
                sb.append(toJson(item));
                first = false;
            }
            sb.append("]");
            return sb.toString();
        } else if (value instanceof String) {
            return "\"" + value + "\"";
        } else if (value instanceof Boolean) {
            return value.toString();
        } else if (value instanceof Integer || value instanceof Long) {
            return String.valueOf(((Number) value).longValue());
        } else if (value instanceof Double || value instanceof Float) {
            double d = ((Number) value).doubleValue();
            if (d == Math.floor(d) && !Double.isInfinite(d))
                return String.valueOf((long) d);
            return String.valueOf(d);
        }
        return "\"" + value + "\"";
    }

    @SuppressWarnings("unchecked")
    private static String toHashParam(Object value) {
        if (value == null) return null;
        if (value instanceof Double || value instanceof Float)
            return String.format("%.2f", value);
        if (value instanceof Integer || value instanceof Long)
            return String.format("%.2f", ((Number) value).doubleValue());
        if (value instanceof Boolean)
            return value.toString();
        if (value instanceof Map || value instanceof List)
            return toJson(value);
        String s = value.toString();
        return s.isEmpty() ? null : s;
    }

    public static String calculateHash(Map<String, Object> params, String secretKey) throws Exception {
        // Parametreleri String map'e dönüştür, TreeMap alfabetik sıralar
        Map<String, String> strParams = new TreeMap<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String v = toHashParam(entry.getValue());
            if (v != null) strParams.put(entry.getKey(), v);
        }

        // Kompakt JSON string'e çevir (value içindeki " ve \ karakterlerini escape et)
        StringBuilder json = new StringBuilder("{");
        boolean first = true;
        for (Map.Entry<String, String> e : strParams.entrySet()) {
            if (!first) json.append(",");
            String escaped = e.getValue().replace("\\", "\\\\").replace("\"", "\\\"");
            json.append("\"").append(e.getKey()).append("\":\"").append(escaped).append("\"");
            first = false;
        }
        json.append("}");
        String jsonString = json.toString();

        // HMAC-SHA512 hesapla, Base64 encode et
        Mac mac = Mac.getInstance("HmacSHA512");
        SecretKeySpec keySpec = new SecretKeySpec(
            secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA512"
        );
        mac.init(keySpec);
        byte[] hashBytes = mac.doFinal(jsonString.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(hashBytes);
    }

    public static void main(String[] args) throws Exception {
        Map<String, Object> requestBody = new LinkedHashMap<>();
        requestBody.put("transaction_type", "Auth");
        requestBody.put("order_id",         "ORDER-12345");
        requestBody.put("amount",           100.00);
        requestBody.put("currency",         "TRY");
        requestBody.put("installment",      1);
        requestBody.put("card_number",      "4355084355084358");
        requestBody.put("card_holder_name", "John Doe");
        requestBody.put("exp_year",         2025);
        requestBody.put("exp_month",        12);
        requestBody.put("cvv",              "000");
        requestBody.put("is_3d",            false);

        Map<String, Object> customerInfo = new LinkedHashMap<>();
        customerInfo.put("first_name", "John");
        customerInfo.put("last_name",  "Doe");
        customerInfo.put("email",      "[email protected]");
        customerInfo.put("phone",      "+905551234567");
        requestBody.put("customer_info", customerInfo);

        String hash = calculateHash(requestBody, "your-secret-key");
        System.out.println("X-Hash: " + hash);
    }
}
JavaScript (Node.js)
const crypto = require('crypto');

// Nested objelerin key'lerini recursive olarak alfabetik sıralar
function sortObjectRecursively(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    if (Array.isArray(obj)) return obj.map(sortObjectRecursively);
    const sorted = {};
    Object.keys(obj).sort().forEach(k => { sorted[k] = sortObjectRecursively(obj[k]); });
    return sorted;
}

function toHashParam(value) {
    if (value === null || value === undefined || value === '') return null;
    if (typeof value === 'number') return value.toFixed(2);
    if (typeof value === 'boolean') return String(value);
    if (typeof value === 'object') return JSON.stringify(sortObjectRecursively(value));
    return String(value);
}

function calculateHash(params, secretKey) {
    // Parametreleri string'e dönüştür ve null/boş değerleri çıkar
    const strParams = {};
    for (const [key, value] of Object.entries(params)) {
        const v = toHashParam(value);
        if (v !== null) strParams[key] = v;
    }

    // Alfabetik sıraya göre sırala ve kompakt JSON'a çevir
    const sortedKeys = Object.keys(strParams).sort();
    const sorted = {};
    sortedKeys.forEach(k => { sorted[k] = strParams[k]; });
    const jsonString = JSON.stringify(sorted);

    // HMAC-SHA512 hesapla, Base64 encode et
    return crypto
        .createHmac('sha512', secretKey)
        .update(jsonString)
        .digest('base64');
}

// Kullanım
const requestBody = {
    transaction_type: 'Auth',
    order_id:         'ORDER-12345',
    amount:           100.00,
    currency:         'TRY',
    installment:      1,
    card_number:      '4355084355084358',
    card_holder_name: 'John Doe',
    exp_year:         2025,
    exp_month:        12,
    cvv:              '000',
    is_3d:            false,
    customer_info: {
        first_name: 'John',
        last_name:  'Doe',
        email:      '[email protected]',
        phone:      '+905551234567',
    },
};

const hash = calculateHash(requestBody, 'your-secret-key');
console.log('X-Hash:', hash);

// Fetch ile kullanım örneği
async function makePayment(body, apiKey, secretKey) {
    const hash = calculateHash(body, secretKey);

    const response = await fetch('https://api.payment-hub.example.com/api/v1/vpos/payments/payment', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-API-Key': apiKey,
            'X-Hash': hash,
        },
        body: JSON.stringify(body),
    });

    return response.json();
}

Request Parametreleri

Ödeme İsteği – PaymentRequest

POST /api/v1/vpos/payments/payment endpoint'i için kullanılır.

Alan Tip Zorunlu Açıklama Örnek
transaction_type string Evet Auth (satış) veya PreAuth (ön otorizasyon) Auth
order_id string Evet Benzersiz sipariş numarası ORDER-12345
amount float64 Evet Ödeme tutarı (0'dan büyük olmalı) 100.00
currency string Evet TRY, USD, EUR, GBP, CHF, JPY TRY
installment int32 Evet Taksit sayısı (1 = peşin, 2-12 = taksitli) 1
card_number string Evet 16 haneli kart numarası 4355084355084358
card_holder_name string Evet Kart üzerindeki isim John Doe
exp_year int32 Evet Son kullanma yılı (4 haneli) 2025
exp_month int32 Evet Son kullanma ayı (1–12) 12
cvv string Evet Kart güvenlik kodu (3 hane) 000
is_3d bool Hayır true = 3D Secure, false = NonSecure (varsayılan: true) true
ok_url string Hayır 3D başarı dönüş URL'si (is_3d=true ise önerilir) https://site.com/ok
fail_url string Hayır 3D hata dönüş URL'si (is_3d=true ise önerilir) https://site.com/fail
sub_merchant_id string Hayır Alt üye işyeri ID'si (terminal bazı alt merchant gerektiriyorsa zorunlu) SUBM-12345
customer_info object Hayır Müşteri bilgileri (detay aşağıda)

Müşteri Bilgileri – CustomerInfo

customer_info objesi içinde gönderilebilecek alanlar:

AlanTipZorunluAçıklamaÖrnek
first_name string Hayır Müşteri adı John
last_name string Hayır Müşteri soyadı Doe
email string Hayır Müşteri e-posta adresi [email protected]
phone string Hayır Müşteri telefon numarası +905551234567

İptal İsteği – VoidRequest

AlanTipZorunluAçıklama
order_id string Evet İptal edilecek siparişin order_id değeri
transaction_id string (UUID) Evet İptal edilecek işlem ID'si
sub_merchant_id string Hayır Alt üye işyeri ID'si

İade İsteği – RefundRequest

AlanTipZorunluAçıklama
order_id string Evet İade edilecek siparişin order_id değeri
transaction_id string (UUID) Evet İade edilecek işlem ID'si
amount float64 Hayır İade tutarı. Belirtilmezse tam iade yapılır
sub_merchant_id string Hayır Alt üye işyeri ID'si

Capture İsteği – CapturePreAuthorizationRequest

AlanTipZorunluAçıklama
order_id string Evet Sipariş numarası
transaction_id string (UUID) Evet PreAuth işlem ID'si
amount float64 Evet Capture edilecek tutar (PreAuth tutarını aşamaz)
sub_merchant_id string Hayır Alt üye işyeri ID'si

BIN Sorgulama

GET /api/v1/vpos/bins/query – Kartın ilk 8 hanesiyle BIN bilgisi sorgulanır.

AlanTipZorunluAçıklama
binstringEvetKartın ilk 8 hanesi (query parameter)

Taksit Seçenekleri ve Komisyonlar

POST /api/v1/vpos/payments/payment-options-with-amounts – BIN ve tutar bilgisiyle taksit seçenekleri sorgulanır.

AlanTipZorunluAçıklama
binstringEvetKartın ilk 8 hanesi
amountfloat64Evetİşlem tutarı (0'dan büyük olmalı)
mcc_codestringHayırMCC kodu filtresi
apply_surcharge_singleboolHayırPeşin ödemede vade farkı uygula
apply_surcharge_installmentboolHayırTaksitli ödemede vade farkı uygula

İşlem Sorgulama

GET /api/v1/vpos/payments/query/{transaction_id} ve GET /api/v1/vpos/payments/query-history/{transaction_id} – İşlem durumu veya geçmişi sorgulanır.

AlanTipZorunluAçıklama
transaction_idstring (UUID)EvetSorgulanacak işlemin ID'si (path parameter)

İşlem Listeleme

GET /api/v1/payments/transactions – İşlemleri filtreler ve listeler. X-API-Key + X-Hash gerektirir.

ParametreTipZorunluAçıklama
offsetintHayırBaşlangıç indeksi (varsayılan: 0)
limitintHayırSayfa başına kayıt (maks 100, varsayılan: 50)
start_datestring (ISO 8601)HayırBaşlangıç tarihi filtresi
end_datestring (ISO 8601)HayırBitiş tarihi filtresi
statusstringHayırAPPROVED, DECLINED, ERROR, CANCELLED, PENDING
transaction_typestringHayırSALE_SECURE, SALE_NON_SECURE, PRE_AUTH_SECURE, PRE_AUTH_NON_SECURE, POST_AUTH, REFUND, VOID
amount_minstringHayırMinimum tutar filtresi
amount_maxstringHayırMaksimum tutar filtresi
currencystringHayırPara birimi filtresi (TRY, USD, EUR, vb.)
order_idstringHayırSipariş numarası ile arama
card_maskstringHayırMaskelenmiş kart numarası ile arama
rrnstringHayırRetrieval Reference Number ile arama
auth_codestringHayırProvizyon kodu ile arama

Hakediş Sorgulama

GET /api/v1/payments/balance – Merchant hakediş bilgisini sorgular. X-API-Key + X-Hash gerektirir.

ParametreTipZorunluAçıklama
start_datestringEvetBaşlangıç tarihi (YYYY-MM-DD)
end_datestringEvetBitiş tarihi (YYYY-MM-DD)
currencystringHayırPara birimi filtresi (TRY, USD, EUR, vb.)
sourcestringHayırİşlem kaynağı filtresi (VPOS vb.)

Oturum Oluşturma – Payment Session

POST /api/v1/sessions – Tek kullanımlık ödeme oturumu oluşturur. X-API-Key + X-Hash gerektirir.

AlanTipZorunluAçıklama
amountfloat64EvetÖdeme tutarı
currencystringEvetTRY, USD, EUR, GBP, CHF, JPY
order_idstringEvetBenzersiz sipariş numarası
ok_urlstringHayırBaşarı dönüş URL'si
fail_urlstringHayırHata dönüş URL'si
customer_infoobjectHayırfirst_name, last_name, email, phone
metadataobjectHayırSerbest formatta ek veri
installmentboolHayırTaksitli ödemeye izin ver (varsayılan: false)
allowed_installmentsarray<int>Hayırİzin verilen taksit sayıları (ör. [2, 3, 6, 9, 12]). installment: true olduğunda geçerlidir

POST /api/v1/merchant/payment-links – Yeni ödeme linki oluşturur. X-API-Key + X-Hash gerektirir.

AlanTipZorunluAçıklama
titlestringEvetLink başlığı
currencystringEvetTRY, USD, EUR, GBP, CHF, JPY
productsarrayEvetEn az 1 ürün zorunludur
products[].pricefloat64EvetÜrün birim fiyatı
products[].default_quantityintHayırVarsayılan miktar (min 1)
products[].display_orderintHayırÜrünün görüntüleme sırası
products[].namestringHayırÜrün adı
products[].skustringHayırStok kodu
products[].image_urlstringHayırÜrün görseli URL'si
descriptionstringHayırLink açıklaması
expires_atdatetimeHayırSon geçerlilik tarihi (ISO 8601)
max_usesintHayırMaksimum kullanım sayısı
ok_urlstringHayırBaşarı dönüş URL'si
fail_urlstringHayırHata dönüş URL'si
require_3dsboolHayır3D Secure zorunlu mu?
allow_non_3dsboolHayır3D Secure olmadan ödemeye izin ver
installmentboolHayırTaksitli ödemeye izin ver (varsayılan: false)
allowed_installmentsarray<int>Hayırİzin verilen taksit sayıları (ör. [2, 3, 6, 9, 12]). installment: true olduğunda geçerlidir

GET /api/v1/merchant/payment-links – Ödeme linklerini listeler. X-API-Key + X-Hash gerektirir.

ParametreTipZorunluAçıklama
pageintHayırSayfa numarası (varsayılan: 1)
limitintHayırSayfa başına kayıt (maks 100)
statusstringHayırACTIVE, INACTIVE, EXPIRED, COMPLETED
searchstringHayırBaşlık veya link kodu ile arama
currencystringHayırPara birimi filtresi

Koleksiyon Oluşturma

POST /api/v1/merchant/collections – Serbest tutarlı ödeme sayfası oluşturur. X-API-Key + X-Hash gerektirir.

AlanTipZorunluAçıklama
titlestringEvetKoleksiyon başlığı
currencystringEvetTRY, USD, EUR, GBP, CHF, JPY
descriptionstringHayırAçıklama metni
min_amountfloat64HayırMinimum ödeme tutarı
max_amountfloat64HayırMaksimum ödeme tutarı
expires_atdatetimeHayırSon geçerlilik tarihi (ISO 8601)
max_usesintHayırMaksimum kullanım sayısı
ok_url / fail_urlstringHayırDönüş URL'leri
require_3dsboolHayır3D Secure zorunlu mu?
allow_non_3dsboolHayır3D Secure olmadan ödemeye izin ver
installmentboolHayırTaksitli ödemeye izin ver (varsayılan: false)
allowed_installmentsarray<int>Hayırİzin verilen taksit sayıları (ör. [2, 3, 6, 9, 12]). installment: true olduğunda geçerlidir

Koleksiyon Listeleme

GET /api/v1/merchant/collections – Koleksiyonları listeler. X-API-Key + X-Hash gerektirir.

ParametreTipZorunluAçıklama
pageintHayırSayfa numarası (varsayılan: 1)
limitintHayırSayfa başına kayıt (maks 100)
statusstringHayırACTIVE, INACTIVE, EXPIRED
searchstringHayırBaşlık veya link kodu ile arama
currencystringHayırPara birimi filtresi

Response Parametreleri

Ödeme Yanıtı – PaymentResponse

AlanTipAçıklama
success boolean İşlem başarı durumu
payload object Yanıt verilerini içeren ana nesne
payload.transaction_id string (UUID) Payment Hub tarafından atanan benzersiz işlem ID'si
payload.order_id string İstekte gönderilen order_id değeri
payload.html string 3D Secure işlemlerde banka 3D form HTML'i. Bu içerik sayfaya embed edilmelidir
payload.html_url string 3D Secure için yönlendirme URL'si (15 dakika geçerli)
payload.amount_info object İşlem tutar bilgileri (bkz. AmountInfo)
payload.gateway_response object Payment Hub gateway yanıtı (code, message_tr, message_en)
payload.bank_response object Banka yanıtı (code, message, auth_code, rrn)
payload.date string İşlem tarihi ve saati (ISO 8601)

AmountInfo

AlanTipAçıklama
amountfloat64İşlem tutarı
currencystringİşlem para birimi
installmentintTaksit sayısı
original_amountfloat64Orijinal tutar
original_currencystringOrijinal para birimi
exchange_ratefloat64Döviz kuru (TRY bazlı)
base_amountfloat64TRY cinsinden tutar
base_currencystringTRY

GatewayResponse

AlanTipAçıklama
codestringGateway yanıt kodu (00 = başarılı)
message_trstringTürkçe mesaj
message_enstringİngilizce mesaj
detail_trstringTürkçe detay mesajı
detail_enstringİngilizce detay mesajı

BankResponse

AlanTipAçıklama
codestringBanka yanıt kodu
messagestringBanka mesajı
auth_codestringProvizyon / otorizasyon kodu
rrnstringRetrieval Reference Number

3D Secure Callback Parametreleri

3D doğrulama tamamlandıktan sonra aşağıdaki alanlar application/x-www-form-urlencoded olarak ok_url (başarı) veya fail_url (başarısızlık) adresine HTTP POST ile gönderilir. Bu yapı hem 3D Secure Ödeme hem de PreAuth 3D işlemleri için geçerlidir.

AlanFormatAçıklama
successstringtrue veya false
transaction_idstring (UUID)İşlem ID'si
order_idstringSipariş numarası
amountstring (%.4f)İşlem tutarı — örn. 150.0000
currencystringİşlem para birimi
installmentstring (%d)Taksit sayısı
gateway_response_codestringGateway yanıt kodu (00 = başarılı)
gateway_response_messagestringGateway mesajı (Türkçe)
bank_response_codestringBanka yanıt kodu
bank_response_messagestringBanka mesajı
rrnstringRetrieval Reference Number
auth_codestringProvizyon kodu
bank_codestringBanka kodu
datestring (RFC3339)İşlem tamamlanma zamanı

Oturum Oluşturma Yanıtı

POST /api/v1/sessions başarılı yanıtı.

AlanTipAçıklama
successbooleanİşlem başarı durumu
payloadobjectYanıt verilerini içeren ana nesne
payload.session_idstringOluşturulan oturum ID'si
payload.session_urlstringMüşteriye gönderilecek ödeme sayfası URL'si
payload.expires_atstring (ISO 8601)Oturumun son geçerlilik zamanı

POST /api/v1/merchant/payment-links ve tekil getirme endpoint'lerinin yanıt yapısı.

AlanTipAçıklama
idstring (UUID)Link benzersiz ID'si
merchant_namestringMerchant adı
link_codestringBenzersiz link kodu (ör. PAY-XZ7Y3K)
link_urlstringMüşteriye gönderilecek ödeme linki URL'si
titlestringLink başlığı
descriptionstringLink açıklaması
total_amountfloat64Toplam tutar
currencystringPara birimi
statusstringACTIVE, INACTIVE, EXPIRED, COMPLETED
expires_atstringSon geçerlilik tarihi
max_usesintMaksimum kullanım sayısı
used_countintKaç kez kullanıldı
require_3dsboolean3D Secure zorunlu mu?
allow_non_3dsboolean3D olmadan ödemeye izin var mı?
installmentbooleanTaksitli ödemeye izin var mı?
allowed_installmentsarray<int>İzin verilen taksit sayıları (ör. [2, 3, 6, 9, 12])
productsarrayÜrün listesi (id, name, price, default_quantity, sku, subtotal)
qr_code_urlstringQR kod görseli URL'si
created_atstringOluşturulma tarihi (ISO 8601)

Koleksiyon Yanıtı

POST /api/v1/merchant/collections ve tekil getirme endpoint'lerinin yanıt yapısı.

AlanTipAçıklama
idstring (UUID)Koleksiyon benzersiz ID'si
merchant_namestringMerchant adı
link_codestringBenzersiz link kodu (ör. COL-AB3CD9)
link_urlstringMüşteriye gönderilecek koleksiyon URL'si
titlestringKoleksiyon başlığı
descriptionstringAçıklama
currencystringPara birimi
min_amountfloat64Minimum ödeme tutarı
max_amountfloat64Maksimum ödeme tutarı
statusstringACTIVE, INACTIVE, EXPIRED
expires_atstringSon geçerlilik tarihi
max_usesintMaksimum kullanım sayısı
used_countintKaç kez kullanıldı
require_3dsboolean3D Secure zorunlu mu?
allow_non_3dsboolean3D olmadan ödemeye izin var mı?
installmentbooleanTaksitli ödemeye izin var mı?
allowed_installmentsarray<int>İzin verilen taksit sayıları (ör. [2, 3, 6, 9, 12])
qr_code_urlstringQR kod görseli URL'si
created_atstringOluşturulma tarihi (ISO 8601)

İşlem Listesi Yanıtı

GET /api/v1/payments/transactions yanıt yapısı.

Temel Bilgiler

AlanTipAçıklama
payload[]arrayİşlem kayıtları listesi
payload[].idstring (UUID)İşlem ID'si
payload[].order_idstringSipariş numarası
payload[].merchant_idstring (UUID)Merchant ID
payload[].merchant_namestringMerchant adı
payload[].parent_idstring (UUID)Üst işlem ID'si (iade/iptal için)
payload[].statusstringAPPROVED, DECLINED, ERROR, CANCELLED, PENDING
payload[].transaction_typestringSALE_SECURE, SALE_NON_SECURE, PRE_AUTH_SECURE, PRE_AUTH_NON_SECURE, POST_AUTH, REFUND, VOID
payload[].transaction_sourcestringİşlem kaynağı (VIRTUAL_POS vb.)
payload[].transaction_channelstringİşlem kanalı (VIRTUAL_LINK, VIRTUAL_API, VIRTUAL_COLLECTION vb.)
payload[].fraud_statusstringFraud kontrol durumu (ACCEPT, REJECT vb.)

Tutar & Döviz

AlanTipAçıklama
payload[].amountfloat64İşlem tutarı
payload[].currencystringİşlem para birimi
payload[].original_amountfloat64Orijinal tutar (döviz çevrimi öncesi)
payload[].original_currencystringOrijinal para birimi
payload[].base_amountfloat64TRY cinsinden tutar
payload[].base_currencystringBaz para birimi (TRY)
payload[].exchange_ratefloat64Uygulanan döviz kuru
payload[].installmentintTaksit sayısı
payload[].is_installmentbooleanTaksitli işlem mi?

Kart Bilgileri

AlanTipAçıklama
payload[].card_number_maskedstringMaskelenmiş kart numarası
payload[].card_holder_namestringKart sahibi adı
payload[].card_brandstringKart markası (SHOPFLY, MAXIMUM, BONUS, AXESS, BANKART_COMBO vb.)
payload[].card_typestringKart tipi (KREDI_KARTI, BANKA_KARTI)
payload[].card_bank_codestringKartı veren banka kodu
payload[].card_bank_namestringKartı veren banka adı
payload[].bin_numberstringBIN numarası

Banka & Provizyon

AlanTipAçıklama
payload[].rrnstringRetrieval Reference Number
payload[].auth_codestringProvizyon kodu
payload[].bank_response_codestringBanka yanıt kodu
payload[].bank_response_messagestringBanka yanıt mesajı
payload[].payment_gateway_codestringPayment gateway yanıt kodu
payload[].payment_gateway_messagestringPayment gateway yanıt mesajı

Finansal Bilgiler

AlanTipAçıklama
payload[].merchant_commission_ratefloat64Uygulanan komisyon oranı (%)
payload[].merchant_payout_amountfloat64Merchant hakediş tutarı
payload[].transaction_feefloat64İşlem ücreti

Müşteri & Terminal

AlanTipAçıklama
payload[].customer_first_namestringMüşteri adı
payload[].customer_last_namestringMüşteri soyadı
payload[].customer_emailstringMüşteri e-posta
payload[].customer_phonestringMüşteri telefon
payload[].terminal_nostringTerminal numarası
payload[].terminal_bank_codestringTerminal banka kodu
payload[].terminal_bank_namestringTerminal banka adı
payload[].webhook_statusstringWebhook gönderim durumu

Tarihler

AlanTipAçıklama
payload[].created_atstring (ISO 8601)Oluşturulma zamanı
payload[].updated_atstring (ISO 8601)Son güncelleme zamanı
payload[].processed_atstring (ISO 8601)İşlenme zamanı
payload[].completed_atstring (ISO 8601)Tamamlanma zamanı

Detay Objeleri (opsiyonel)

AlanTipAçıklama
payload[].virtual_pos_detailsobjectSanal POS detayları (sub_merchant_id, ok_url, fail_url, link_code, collection_code)
payload[].physical_pos_detailsobjectFiziksel POS detayları (device_serial_no, batch_number, entry_mode vb.)
payload[].soft_pos_detailsobjectSoftPOS detayları (device_id, sdk_version, os_type vb.)

Hakediş Sorgulama Yanıtı

GET /api/v1/payments/balance yanıt yapısı.

AlanTipAçıklama
start_datestringSorgulanan başlangıç tarihi
end_datestringSorgulanan bitiş tarihi
balances[]arrayPara birimi ve kaynak bazında hakediş listesi
balances[].currencystringPara birimi
balances[].sourcestringİşlem kaynağı (VPOS vb.)
balances[].saleobjectSatış toplamları (count, amount, base_amount)
balances[].post_authobjectÖn provizyon kapama toplamları (count, amount, base_amount)
balances[].refundobjectİade toplamları (count, amount, base_amount)
balances[].voidobjectİptal toplamları (count, amount, base_amount)
balances[].pre_auth_pendingobjectBekleyen ön provizyon toplamları (count, amount, base_amount)
balances[].failedobjectBaşarısız işlem toplamları (count, amount, base_amount)
balances[].net_amountfloat64Net tutar (işlem para biriminde)
balances[].net_base_amountfloat64Net tutar (baz para biriminde)
balances[].total_countintToplam işlem adedi
balances[].success_ratefloat64Başarı oranı (%)
balances[].financialobjectFinansal özet
balances[].financial.total_commissionfloat64Toplam komisyon
balances[].financial.total_merchant_payoutfloat64Toplam merchant hakediş
balances[].financial.total_transaction_feefloat64Toplam işlem ücreti
totalsobjectGenel toplamlar
totals.total_countintToplam işlem adedi
totals.net_base_amountfloat64Toplam net tutar (baz para biriminde)
totals.total_merchant_payout_basefloat64Toplam merchant hakediş (baz para biriminde)
totals.success_ratefloat64Genel başarı oranı (%)

Sayfalama (Pagination)

Liste endpoint'lerinin (GET .../payment-links, GET .../collections) yanıtında pagination nesnesi döner.

AlanTipAçıklama
totalintToplam kayıt sayısı
limitintSayfa başına kayıt sayısı
offsetintBaşlangıç kayıt indeksi
current_pageintMevcut sayfa numarası
total_pagesintToplam sayfa sayısı

GET /api/v1/payments/transactions endpoint'i farklı bir pagination yapısı kullanır:

AlanTipAçıklama
totalint64Toplam kayıt sayısı
limitintSayfa başına kayıt sayısı
offsetintBaşlangıç kayıt indeksi
hasNextbooleanSonraki sayfa var mı?
hasPrevbooleanÖnceki sayfa var mı?

3D Secure Ödeme

3D Secure işlemlerde müşteri, banka tarafından kimlik doğrulamasına yönlendirilir. İlk yanıt olarak dönen html alanı sayfaya eklenmeli veya html_url adresine yönlendirme yapılmalıdır. Ödeme sonucu, 3D doğrulama tamamlandıktan sonra ok_url veya fail_url'e HTTP POST (form) olarak iletilir.

ℹ️
ok_url ve fail_url gönderilmezse sistem varsayılan callback URL'ini kullanır. Bu URL'lerde application/x-www-form-urlencoded POST verisi alacak şekilde hazır olunmalıdır.
⚠️
html_url 15 dakika geçerlidir. Süresi dolduktan sonra erişilemez.
POST /api/v1/vpos/payments/payment is_3d: true
JSON
{
  "transaction_type": "Auth",
  "order_id": "ORDER-12345",
  "amount": 150.00,
  "currency": "TRY",
  "installment": 1,
  "card_number": "4355084355084358",
  "card_holder_name": "John Doe",
  "exp_year": 2026,
  "exp_month": 12,
  "cvv": "000",
  "is_3d": true,
  "ok_url": "https://yoursite.com/payment/success",
  "fail_url": "https://yoursite.com/payment/fail",
  "customer_info": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+905551234567"
  }
}
JSON
{
  "success": true,
  "payload": {
    "transaction_id": "d4de0c6a-c51f-4aff-bf75-4989c9204bdc",
    "order_id": "ORDER-12345",
    "html": "<!DOCTYPE html><html>...3D Secure Form HTML...</html>",
    "html_url": "https://payment-hub.example.com/api/v1/vpos/payments/3d-secure/a8f2e4b1-7c3d-49e5-b6a0-1d2f3e4a5b6c",
    "date": "2024-01-15T14:30:00Z"
  }
}
⚠️
Bu yanıt yalnızca 3D formunu içerir; gateway_response ve bank_response bu aşamada dönmez. Ödeme sonucu, 3D doğrulama tamamlandıktan sonra ok_url / fail_url'e iletilir.

3D Secure Akış Diyagramı

Flow
1. Müşteri ödeme formunu doldurur
2. Sizin sunucunuz → POST /api/v1/vpos/payments/payment  (is_3d: true, ok_url, fail_url)
3. Payment Hub     → { success: true, payload: { transaction_id, html, html_url, ... } }
4. Sizin sunucunuz → html_url'e yönlendirme yapar veya html içeriğini render eder
   ⚠ html_url token-based'dir (15 dk geçerli), transaction ID içermez
5. Tarayıcı        → Bankanın 3D sayfasına yönlendirilir
6. Müşteri         → OTP / 3D doğrulamayı tamamlar
7. Payment Hub     → 3D sonucunu işler ve ödemeyi tamamlar
8. Tarayıcı        → ok_url veya fail_url'e HTTP POST (application/x-www-form-urlencoded)

NonSecure Ödeme

3D doğrulama olmaksızın gerçekleştirilen ödeme işlemidir. Yanıt senkron olarak döner.

POST /api/v1/vpos/payments/payment is_3d: false
JSON
{
  "transaction_type": "Auth",
  "order_id": "ORDER-67890",
  "amount": 250.00,
  "currency": "TRY",
  "installment": 1,
  "card_number": "4355084355084358",
  "card_holder_name": "Jane Doe",
  "exp_year": 2026,
  "exp_month": 6,
  "cvv": "000",
  "is_3d": false,
  "customer_info": {
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+905551234567"
  }
}
JSON
{
  "success": true,
  "payload": {
    "transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "order_id": "ORDER-67890",
    "amount_info": {
      "amount": 250.00,
      "currency": "TRY",
      "installment": 1,
      "original_amount": 250.00,
      "original_currency": "TRY",
      "exchange_rate": 1,
      "base_amount": 250.00,
      "base_currency": "TRY"
    },
    "gateway_response": {
      "code": "00",
      "message_tr": "İŞLEM BAŞARILI",
      "message_en": "APPROVED",
      "detail_tr": "İşlem başarıyla tamamlandı",
      "detail_en": "Transaction successfully completed."
    },
    "bank_response": {
      "code": "00",
      "message": "000 ONAY KODU 091322",
      "auth_code": "091322",
      "rrn": "603125844346"
    },
    "date": "2024-01-15T14:32:00Z"
  }
}

PreAuth & Capture

Ön otorizasyon işlemi, müşterinin kartında belirli bir tutarı bloke eder. İşlem tamamlandığında capture ile gerçek ödeme alınır. PreAuth hem NonSecure (is_3d: false) hem de 3D Secure (is_3d: true) olarak yapılabilir.

ℹ️
Capture tutarı, PreAuth tutarını aşamaz. PreAuth zaten capture edilmişse tekrar capture yapılamaz.

Adım 1: PreAuth Başlatma – 3D Secure

POST /api/v1/vpos/payments/payment transaction_type: PreAuth, is_3d: true
JSON
{
  "transaction_type": "PreAuth",
  "order_id": "ORDER-PREAUTH-3D-001",
  "amount": 500.00,
  "currency": "TRY",
  "installment": 1,
  "card_number": "4355084355084358",
  "card_holder_name": "John Doe",
  "exp_year": 2026,
  "exp_month": 12,
  "cvv": "000",
  "is_3d": true,
  "ok_url": "https://yoursite.com/preauth/success",
  "fail_url": "https://yoursite.com/preauth/fail",
  "customer_info": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+905551234567"
  }
}
JSON
{
  "success": true,
  "payload": {
    "transaction_id": "d4de0c6a-c51f-4aff-bf75-4989c9204bdc",
    "order_id": "ORDER-PREAUTH-3D-001",
    "html": "<!DOCTYPE html><html>...3D Secure Form HTML...</html>",
    "html_url": "https://payment-hub.example.com/api/v1/vpos/payments/3d-secure/b7e3f5a2-9d1c-48f6-a4b8-2c6d8e0f1a3b",
    "date": "2024-01-15T14:30:00Z"
  }
}
⚠️
Bu yanıt yalnızca 3D formunu içerir; gateway_response ve bank_response bu aşamada dönmez. Ödeme sonucu 3D doğrulama tamamlandıktan sonra ok_url / fail_url'e iletilir.

Adım 1: PreAuth Başlatma – NonSecure

POST /api/v1/vpos/payments/payment transaction_type: PreAuth
JSON
{
  "transaction_type": "PreAuth",
  "order_id": "ORDER-PREAUTH-001",
  "amount": 500.00,
  "currency": "TRY",
  "installment": 1,
  "card_number": "4355084355084358",
  "card_holder_name": "John Doe",
  "exp_year": 2026,
  "exp_month": 12,
  "cvv": "000",
  "is_3d": false,
  "customer_info": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+905551234567"
  }
}
JSON
{
  "success": true,
  "payload": {
    "transaction_id": "d4de0c6a-c51f-4aff-bf75-4989c9204bdc",
    "order_id": "ORDER-PREAUTH-001",
    "amount_info": {
      "amount": 500.00,
      "currency": "TRY",
      "installment": 1,
      "original_amount": 500.00,
      "original_currency": "TRY",
      "exchange_rate": 1,
      "base_amount": 500.00,
      "base_currency": "TRY"
    },
    "gateway_response": {
      "code": "00",
      "message_tr": "İŞLEM BAŞARILI",
      "message_en": "APPROVED",
      "detail_tr": "İşlem başarıyla tamamlandı",
      "detail_en": "Transaction successfully completed."
    },
    "bank_response": {
      "code": "00",
      "message": "000 ONAY KODU 091322",
      "auth_code": "091322",
      "rrn": "603125844346"
    },
    "date": "2024-01-15T14:30:00Z"
  }
}

Adım 2: Capture

POST /api/v1/vpos/payments/capture-pre-authorization
JSON
{
  "order_id": "ORDER-PREAUTH-001",
  "transaction_id": "d4de0c6a-c51f-4aff-bf75-4989c9204bdc",
  "amount": 450.00
}
JSON
{
  "payload": {
    "transaction_id": "e5f6a7b8-c9d0-1234-abcd-ef5678901234",
    "order_id": "ORDER-PREAUTH-001",
    "original_transaction_id": "d4de0c6a-c51f-4aff-bf75-4989c9204bdc",
    "amount_info": {
      "amount": 450.00,
      "currency": "TRY",
      "installment": 1,
      "original_amount": 450.00,
      "original_currency": "TRY",
      "exchange_rate": 1,
      "base_amount": 450.00,
      "base_currency": "TRY"
    },
    "gateway_response": {
      "code": "00",
      "message_tr": "CAPTURE BAŞARILI",
      "message_en": "CAPTURE APPROVED"
    },
    "date": "2024-01-15T16:00:00Z"
  }
}

Taksitli Ödeme

Taksitli ödeme akışı üç adımdan oluşur: önce kartın BIN bilgisi sorgulanır, ardından o karta özel taksit seçenekleri ve komisyon oranları alınır, son olarak seçilen taksit sayısıyla ödeme gerçekleştirilir.

⚠️
Merchant için taksitli ödeme aktif değilse ErrInstallmentNotAllowed hatası döner.

Adım 1: Kart BIN Sorgulama

Kartın ilk 8 hanesi ile BIN sorgusu yapılır. Dönen yanıttaki banka (member_name), kart şeması (scheme_name) ve marka (brand_name) bilgileri; taksit seçeneklerini görüntülemek ve ödeme ekranını kişiselleştirmek için kullanılır.

GET /api/v1/vpos/bins/query ?bin=43550843
HTTP
GET /api/v1/vpos/bins/query?bin=43550843 HTTP/1.1
X-API-Key: your-api-key
X-Hash: {hash}
JSON
{
  "success": true,
  "payload": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "bin_range_min": "43550800",
      "bin_range_max": "43550899",
      "main": true,
      "card_no_length": 16,
      "validate_for_check_digit": true,
      "card_type_no": "1",
      "card_type_full": "DEBIT",
      "scheme_name": "VISA",
      "type_name": "DEBIT",
      "segment_name": "CONSUMER",
      "brand_name": "VISA CLASSIC",
      "member_no": 15,
      "member_name": "Ziraat Bankası",
      "active_for_clearing": true,
      "active_for_fraud": true
    }
  ]
}

Adım 2: Taksit Seçenekleri ve Komisyonlar

BIN ve tutar bilgisiyle birlikte taksit seçenekleri sorgulandığında her taksit için müşterinin ödeyeceği toplam tutar (customer_pays) ve aylık taksit tutarı (installment_amount) hesaplanmış olarak döner.

POST /api/v1/vpos/payments/payment-options-with-amounts
JSON
{
  "bin": "43550843",
  "amount": 1200.00
}
JSON
{
  "amount": 1200.00,
  "single_payment": {
    "installment_count": 1,
    "merchant_commission_rate": 1.50,
    "customer_pays": 1218.00,
    "installment_amount": 1218.00,
    "apply_surcharge": true
  },
  "installment_options": [
    {
      "bank": {
        "name": "Ziraat Bankası",
        "code": "0015",
        "member_no": 15
      },
      "bank_card_brands": [
        {
          "card_brand": {
            "name": "VISA CLASSIC",
            "code": "VC"
          },
          "installments": [
            {
              "installment_count": 3,
              "merchant_commission_rate": 2.50,
              "customer_pays": 1230.00,
              "installment_amount": 410.00,
              "apply_surcharge": false
            },
            {
              "installment_count": 6,
              "merchant_commission_rate": 3.50,
              "customer_pays": 1242.00,
              "installment_amount": 207.00,
              "apply_surcharge": false
            },
            {
              "installment_count": 9,
              "merchant_commission_rate": 4.50,
              "customer_pays": 1254.00,
              "installment_amount": 139.33,
              "apply_surcharge": false
            },
            {
              "installment_count": 12,
              "merchant_commission_rate": 5.50,
              "customer_pays": 1266.00,
              "installment_amount": 105.50,
              "apply_surcharge": false
            }
          ],
          "max_installment_with_mcc": 12
        }
      ]
    }
  ]
}
ℹ️
Karta göre taksit seçenekleri sorgulamadan genel seçenekleri listelemek için GET /api/v1/vpos/payments/payment-options endpoint'ini kullanabilirsiniz (BIN veya tutar gerektirmez).

Adım 3: Taksitli Ödemeyi Gerçekleştir

Önceki adımda seçilen taksit sayısı installment alanına yazılarak ödeme isteği gönderilir. 3D Secure akışı için is_3d: true ve ok_url / fail_url eklenmelidir.

POST /api/v1/vpos/payments/payment installment ≥ 2
JSON
{
  "transaction_type": "Auth",
  "order_id": "ORDER-INST-001",
  "amount": 1200.00,
  "currency": "TRY",
  "installment": 6,
  "card_number": "4355084355084358",
  "card_holder_name": "John Doe",
  "exp_year": 2026,
  "exp_month": 12,
  "cvv": "000",
  "is_3d": false,
  "customer_info": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+905551234567"
  }
}
JSON
{
  "success": true,
  "payload": {
    "transaction_id": "c3d4e5f6-a7b8-9012-cdef-gh3456789012",
    "order_id": "ORDER-INST-001",
    "amount_info": {
      "amount": 1200.00,
      "currency": "TRY",
      "installment": 6,
      "original_amount": 1200.00,
      "original_currency": "TRY",
      "exchange_rate": 1,
      "base_amount": 1200.00,
      "base_currency": "TRY"
    },
    "gateway_response": {
      "code": "00",
      "message_tr": "İŞLEM BAŞARILI",
      "message_en": "APPROVED",
      "detail_tr": "İşlem başarıyla tamamlandı",
      "detail_en": "Transaction successfully completed."
    },
    "bank_response": {
      "code": "00",
      "message": "000 ONAY KODU 183447",
      "auth_code": "183447",
      "rrn": "612034912876"
    },
    "date": "2024-01-15T14:35:00Z"
  }
}

İptal (Void)

İptal işlemi yalnızca aynı gün yapılan işlemlere uygulanabilir. Farklı günlerdeki işlemler için İade (Refund) kullanılmalıdır.

Farklı günde gerçekleştirilmiş işleme iptal uygulanmaya çalışılırsa ErrVoidNotAllowedDifferentDay hatası alınır.
POST /api/v1/vpos/payments/void
JSON
{
  "order_id": "ORDER-12345",
  "transaction_id": "d4de0c6a-c51f-4aff-bf75-4989c9204bdc"
}
JSON
{
  "payload": {
    "transaction_id": "f1g2h3i4-j5k6-7890-mnop-qr1234567890",
    "order_id": "ORDER-12345",
    "original_transaction_id": "d4de0c6a-c51f-4aff-bf75-4989c9204bdc",
    "amount_info": {
      "amount": 150.00,
      "currency": "TRY",
      "installment": 1,
      "original_amount": 150.00,
      "original_currency": "TRY",
      "exchange_rate": 1,
      "base_amount": 150.00,
      "base_currency": "TRY"
    },
    "gateway_response": {
      "code": "00",
      "message_tr": "İPTAL BAŞARILI",
      "message_en": "VOID APPROVED"
    },
    "date": "2024-01-15T15:00:00Z"
  }
}

İade (Refund)

İade işlemi önceki günlerde gerçekleştirilen ödemeler için kullanılır. Kısmi iade yapmak için amount alanı gönderin; tam iade için belirtmeyebilirsiniz.

Maksimum İade Süresi
30 gün
Aynı Gün İşlem
İptal (Void) kullanın
Kısmi İade
amount alanıyla desteklenir
POST /api/v1/vpos/payments/refund
JSON – Tam İade
{
  "order_id": "ORDER-67890",
  "transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
JSON – Kısmi İade
{
  "order_id": "ORDER-67890",
  "transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "amount": 100.00
}
JSON
{
  "payload": {
    "transaction_id": "g7h8i9j0-k1l2-3456-mnop-qr7890123456",
    "order_id": "ORDER-67890",
    "original_transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "amount_info": {
      "amount": 250.00,
      "currency": "TRY",
      "installment": 1,
      "original_amount": 250.00,
      "original_currency": "TRY",
      "exchange_rate": 1,
      "base_amount": 250.00,
      "base_currency": "TRY"
    },
    "gateway_response": {
      "code": "00",
      "message_tr": "İADE BAŞARILI",
      "message_en": "REFUND APPROVED"
    },
    "date": "2024-01-16T10:00:00Z"
  }
}

İşlem Sorgulama

Bir işlemin güncel durumunu veya geçmiş kayıtlarını sorgulayabilirsiniz.

GET /api/v1/vpos/payments/query-history/{transaction_id} Geçmiş kayıtlar
HTTP
GET /api/v1/vpos/payments/query-history/d4de0c6a-c51f-4aff-bf75-4989c9204bdc HTTP/1.1
Host: api.payment-hub.example.com
X-API-Key: your-api-key-here
X-Hash: <hash-of-transaction_id>
JSON
{
  "payload": [
    {
      "response_code": "00",
      "response_message": "İşlem başarılı",
      "transaction_status": "SUCCESS",
      "auth_code": "091322",
      "order_id": "ORDER-12345",
      "amount": "150.00",
      "bank_response_code": "00",
      "bank_response_message": "000 ONAY KODU 091322"
    }
  ]
}

İşlem Listesi

Geçmiş işlemlerinizi filtreler, sayfalama ile listeler. Tekil sorgulama için İşlem Sorgulama bölümüne bakınız.

GET /api/v1/payments/transactions İşlem listeleme ve filtreleme
HTTP
GET /api/v1/payments/transactions?offset=0&limit=50&start_date=2024-01-01T00:00:00Z&end_date=2024-01-31T23:59:59Z&status=APPROVED¤cy=TRY HTTP/1.1
Host: api.payment-hub.example.com
X-API-Key: your-api-key-here
X-Hash: <hash-of-query-params>
JSON
{
  "success": true,
  "payload": [
    {
      "id": "c00970da-dcaf-4baa-9486-1ae35cd76179",
      "order_id": "PL-f3f5533afe2236550280a54f-94067de0",
      "merchant_id": "01997898-66c6-731b-9f00-fabaf3e470c4",
      "merchant_name": "ÖRNEK İŞYERİ A.Ş.",
      "amount": 3.44,
      "original_amount": 3.44,
      "original_currency": "TRY",
      "base_amount": 3.44,
      "currency": "TRY",
      "installment": 1,
      "is_installment": false,
      "status": "APPROVED",
      "transaction_type": "SALE_SECURE",
      "transaction_source": "VIRTUAL_POS",
      "transaction_channel": "VIRTUAL_LINK",
      "fraud_status": "ACCEPT",
      "card_number_masked": "5381********0019",
      "card_holder_name": "John Doe",
      "card_brand": "SHOPFLY",
      "card_type": "KREDI_KARTI",
      "card_bank_code": "62",
      "card_bank_name": "T.GARANTİ BANKASI A.Ş.",
      "bin_number": "53819651",
      "rrn": "608925129544",
      "auth_code": "797499",
      "bank_response_code": "00",
      "bank_response_message": "İŞLEM BAŞARILI",
      "payment_gateway_code": "00",
      "payment_gateway_message": "İŞLEM BAŞARILI / APPROVED",
      "exchange_rate": 1,
      "base_currency": "TRY",
      "merchant_commission_rate": 3,
      "merchant_payout_amount": 3.3368,
      "transaction_fee": 0.1032,
      "terminal_no": "S1804Y01",
      "terminal_bank_code": "64",
      "terminal_bank_name": "T.İŞ BANKASI A.Ş.",
      "customer_first_name": "John",
      "customer_last_name": "Doe",
      "customer_phone": "05551234567",
      "customer_email": "[email protected]",
      "created_at": "2026-03-30T22:22:55.612003+03:00",
      "updated_at": "2026-03-30T22:23:18.076433+03:00",
      "processed_at": "2026-03-30T22:22:55.418741+03:00",
      "completed_at": "2026-03-30T22:23:18.075784+03:00",
      "virtual_pos_details": {
        "ok_url": "https://example.com/callback/ok",
        "fail_url": "https://example.com/callback/fail",
        "link_code": "f3f5533afe2236550280a54f"
      }
    },
    {
      "id": "95cd303f-f296-4654-b1cc-4941512d8e27",
      "order_id": "PL-ne5oAtv3YYV40cxM-lcNTw-a4a993d3",
      "merchant_id": "01997898-66c6-731b-9f00-fabaf3e470c4",
      "merchant_name": "ÖRNEK İŞYERİ A.Ş.",
      "amount": 1,
      "original_amount": 1,
      "original_currency": "TRY",
      "base_amount": 1,
      "currency": "TRY",
      "installment": 1,
      "is_installment": false,
      "status": "DECLINED",
      "transaction_type": "SALE_SECURE",
      "transaction_source": "VIRTUAL_POS",
      "transaction_channel": "VIRTUAL_LINK",
      "fraud_status": "ACCEPT",
      "card_number_masked": "5381********0019",
      "card_holder_name": "John Doe",
      "card_brand": "SHOPFLY",
      "card_type": "KREDI_KARTI",
      "card_bank_code": "62",
      "card_bank_name": "T.GARANTİ BANKASI A.Ş.",
      "bin_number": "53819651",
      "rrn": "608420206421",
      "bank_response_code": "51",
      "bank_response_message": "Limit Yetersiz.",
      "payment_gateway_code": "51",
      "payment_gateway_message": "YETERSİZ BAKİYE / INSUFFICIENT FUNDS",
      "exchange_rate": 1,
      "base_currency": "TRY",
      "merchant_commission_rate": 3,
      "merchant_payout_amount": 0.97,
      "transaction_fee": 0.03,
      "terminal_no": "S1804Y01",
      "terminal_bank_code": "64",
      "terminal_bank_name": "T.İŞ BANKASI A.Ş.",
      "customer_first_name": "John",
      "customer_last_name": "Doe",
      "customer_phone": "+905551234567",
      "customer_email": "[email protected]",
      "created_at": "2026-03-25T19:41:38.682781+03:00",
      "updated_at": "2026-03-25T19:42:04.143005+03:00",
      "processed_at": "2026-03-25T19:41:38.557268+03:00",
      "completed_at": "2026-03-25T19:41:39.648308+03:00",
      "virtual_pos_details": {
        "ok_url": "https://example.com/callback/ok",
        "fail_url": "https://example.com/callback/fail",
        "link_code": "ne5oAtv3YYV40cxM-lcNTw",
        "collection_code": "adfdd7ca72b88173d124e915"
      }
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "hasNext": true,
    "hasPrev": false
  }
}
⚠️
Hash hesaplamasında query parametreleri JSON objesi olarak kullanılır. Detaylar için Hash Doğrulama bölümüne bakınız.

Hakediş Sorgulama

Belirli bir tarih aralığında merchant hesabınıza ait hakediş bilgilerini para birimi ve kaynak bazında sorgulayabilirsiniz.

GET /api/v1/payments/balance Hakediş sorgulama
HTTP
GET /api/v1/payments/balance?start_date=2024-01-01&end_date=2024-01-31¤cy=TRY HTTP/1.1
Host: api.payment-hub.example.com
X-API-Key: your-api-key-here
X-Hash: <hash-of-query-params>
JSON
{
  "start_date": "2024-01-01",
  "end_date": "2024-01-31",
  "balances": [
    {
      "currency": "TRY",
      "source": "VPOS",
      "sale": {
        "count": 100,
        "amount": 50000.00,
        "base_amount": 50000.00
      },
      "post_auth": {
        "count": 5,
        "amount": 2500.00,
        "base_amount": 2500.00
      },
      "refund": {
        "count": 3,
        "amount": 1000.00,
        "base_amount": 1000.00
      },
      "void": {
        "count": 2,
        "amount": 200.00,
        "base_amount": 200.00
      },
      "pre_auth_pending": {
        "count": 10,
        "amount": 5000.00,
        "base_amount": 5000.00
      },
      "failed": {
        "count": 8,
        "amount": 3000.00,
        "base_amount": 3000.00
      },
      "net_amount": 51300.00,
      "net_base_amount": 51300.00,
      "total_count": 128,
      "success_rate": 93.75,
      "financial": {
        "total_commission": 4800.00,
        "total_merchant_payout": 46500.00,
        "total_transaction_fee": 500.00
      }
    }
  ],
  "totals": {
    "total_count": 128,
    "net_base_amount": 51300.00,
    "total_merchant_payout_base": 46500.00,
    "success_rate": 93.75
  }
}
ℹ️
Her bir balances[] öğesi para birimi ve kaynak bazında gruplanır. İşlem tipleri: sale (satış), post_auth (ön provizyon kapama), refund (iade), void (iptal), pre_auth_pending (bekleyen ön provizyon), failed (başarısız). Her birinde count, amount ve base_amount değerleri bulunur.
⚠️
Hash hesaplamasında query parametreleri JSON objesi olarak kullanılır. Detaylar için Hash Doğrulama bölümüne bakınız.


Ödeme Oturumu (Payment Session)

Sunucu tarafında oluşturulan, tek kullanımlık ödeme bağlantısı. Müşteriye session_url gönderilir; müşteri bu URL üzerinden kart bilgilerini girerek ödeme yapar.

ℹ️
Oturum oluşturma endpoint'i X-API-Key + X-Hash doğrulaması gerektirir. Hash hesaplaması için Hash Doğrulama bölümüne bakın.

Oturum Oluştur

POST /api/v1/sessions X-API-Key + X-Hash
JSON
{
  "amount": 250.00,
  "currency": "TRY",
  "order_id": "ORDER-SESSION-001",
  "ok_url": "https://yoursite.com/payment/success",
  "fail_url": "https://yoursite.com/payment/fail",
  "customer_info": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "+905551234567"
  },
  "metadata": {
    "internal_ref": "REF-123"
  },
  "installment": true,
  "allowed_installments": [2, 3, 6, 9, 12]
}
JSON
{
  "success": true,
  "payload": {
    "session_id": "sess_5lnohiu4pvokvzsu",
    "session_url": "http://localhost:3002/api/v1/public/session/sess_5lnohiu4pvokvzsu",
    "expires_at": "2026-03-04T12:01:08.797663+03:00"
  }
}


Koleksiyon – Merchant API

Serbest tutarlı ödeme sayfaları yönetimi. API Key + Hash doğrulamasıyla kendi sisteminizden koleksiyon oluşturup yönetebilirsiniz. Sadece kendi merchant'ınıza ait koleksiyonlar görünür.

🔑
Her istekte X-API-Key ve X-Hash header'ları zorunludur. Hash hesaplama için Hash Doğrulama bölümüne bakın.

Koleksiyon Oluştur

POST /api/v1/merchant/collections X-API-Key + X-Hash
JSON
{
  "title": "Bağış Toplama",
  "description": "Okul yararına bağış kampanyası",
  "currency": "TRY",
  "min_amount": 10.00,
  "max_amount": 10000.00,
  "expires_at": "2024-12-31T00:00:00Z",
  "max_uses": 500,
  "ok_url": "https://yoursite.com/donation/thanks",
  "fail_url": "https://yoursite.com/donation/fail",
  "require_3ds": false,
  "allow_non_3ds": true
}
JSON
{
  "success": true,
  "payload": {
    "id": "c1d2e3f4-a5b6-7890-cdef-gh1234567890",
    "merchant_name": "Örnek Mağaza",
    "link_code": "COL-AB3CD9",
    "link_url": "https://api.payment-link.example.com/api/v1/public/collections/COL-AB3CD9/page",
    "title": "Bağış Toplama",
    "description": "Okul yararına bağış kampanyası",
    "currency": "TRY",
    "min_amount": 10.00,
    "max_amount": 10000.00,
    "status": "ACTIVE",
    "expires_at": "2024-12-31T00:00:00Z",
    "max_uses": 500,
    "used_count": 0,
    "require_3ds": false,
    "allow_non_3ds": true,
    "qr_code_url": "https://api.payment-link.example.com/api/v1/merchant/collections/c1d2e3f4.../qr",
    "created_at": "2024-01-15T10:00:00Z"
  }
}

Koleksiyonları Listele

GET /api/v1/merchant/collections Sadece kendi merchant'ınıza ait koleksiyonlar
HTTP
GET /api/v1/merchant/collections?page=1&limit=20&status=ACTIVE HTTP/1.1
X-API-Key: your-api-key
X-Hash: {hash}
JSON
{
  "success": true,
  "payload": {
    "data": [
      {
        "id": "c1d2e3f4-a5b6-7890-cdef-gh1234567890",
        "merchant_name": "Örnek Mağaza",
        "link_code": "COL-AB3CD9",
        "link_url": "https://api.payment-link.example.com/api/v1/public/collections/COL-AB3CD9/page",
        "title": "Bağış Toplama",
        "description": "Okul yararına bağış kampanyası",
        "currency": "TRY",
        "min_amount": 10.00,
        "max_amount": 10000.00,
        "status": "ACTIVE",
        "expires_at": "2024-12-31T00:00:00Z",
        "max_uses": 500,
        "used_count": 42,
        "require_3ds": false,
        "allow_non_3ds": true,
        "qr_code_url": "https://api.payment-link.example.com/api/v1/merchant/collections/c1d2e3f4.../qr",
        "created_at": "2024-01-15T10:00:00Z"
      }
    ],
    "pagination": {
      "total": 12,
      "limit": 20,
      "offset": 0,
      "current_page": 1,
      "total_pages": 1
    }
  }
}

Tekil Koleksiyon Getir

GET /api/v1/merchant/collections/:id X-API-Key + X-Hash
JSON
{
  "success": true,
  "payload": {
    "id": "c1d2e3f4-a5b6-7890-cdef-gh1234567890",
    "merchant_name": "Örnek Mağaza",
    "link_code": "COL-AB3CD9",
    "link_url": "https://api.payment-link.example.com/api/v1/public/collections/COL-AB3CD9/page",
    "title": "Bağış Toplama",
    "description": "Okul yararına bağış kampanyası",
    "currency": "TRY",
    "min_amount": 10.00,
    "max_amount": 10000.00,
    "status": "ACTIVE",
    "expires_at": "2024-12-31T00:00:00Z",
    "max_uses": 500,
    "used_count": 42,
    "require_3ds": false,
    "allow_non_3ds": true,
    "qr_code_url": "https://api.payment-link.example.com/api/v1/merchant/collections/c1d2e3f4.../qr",
    "created_at": "2024-01-15T10:00:00Z"
  }
}

Koleksiyon Durumunu Güncelle

PATCH /api/v1/merchant/collections/:id/status X-API-Key + X-Hash
JSON
{ "status": "INACTIVE" }

Geçerli değerler: ACTIVE, INACTIVE, EXPIRED

JSON
{
  "success": true,
  "payload": {
    "message": "Collection status updated successfully"
  }
}

QR Kod Görseli

GET /api/v1/merchant/collections/:id/qr PNG görsel döner
HTTP Headers
HTTP/1.1 200 OK
Content-Type: image/png
Content-Disposition: inline; filename="qr.png"

<binary PNG data>

Test İşlemleri

Geliştirme ve entegrasyon testleri için aşağıdaki test kartlarını kullanabilirsiniz. Test işlemleri gerçek bankacılık sistemine gönderilmez.

⚠️
Test kartları yalnızca test ortamında geçerlidir. Production ortamında gerçek kart bilgileri kullanılmalıdır.

Sandbox Test Kartları

Aşağıdaki kartlar sandbox ortamında farklı ödeme senaryolarını test etmek için kullanılır. Tüm kartlar için CVV: 000, SKT: 12/2026, kart sahibi herhangi bir isim olabilir.

ℹ️
Sandbox ortamında CVV ve son kullanma tarihi doğrulaması yapılmaz. Herhangi bir CVV (3-4 haneli) ve herhangi bir son kullanma tarihi kabul edilir. Aşağıdaki değerler yalnızca önerilen standart test değerleridir.
ℹ️
Tüm ödeme yanıtları HTTP 200 döner. Başarılı işlemler "success": true, başarısız işlemler "success": false ile ayrılır. Hata detayları error.details içinde gateway_response ve bank_response olarak döner.
Başarılı Ödeme
4000 0000 0000 0001
HTTP 200  |  ISO: 00
✓ ONAY
Yetersiz Bakiye
4000 0000 0000 0002
HTTP 200  |  ISO: 51
✗ YETERSİZ BAKİYE
İşlem Onaylanmadı
4000 0000 0000 0003
HTTP 200  |  ISO: 05
✗ DO NOT HONOR
Geçersiz Kart Numarası
4000 0000 0000 0004
HTTP 200  |  ISO: 14
✗ GEÇERSİZ KART
Fraud Şüphesi
4000 0000 0000 0005
HTTP 200  |  ISO: 34
✗ FRAUD ŞÜPHESİ
Sistem Hatası
4000 0000 0000 0006
HTTP 200  |  ISO: 96
✗ SİSTEM HATASI
Gateway Timeout
4000 0000 0000 0007
HTTP 200  |  ISO: 91
✗ TIMEOUT
3D Secure Akışı
4000 0000 0000 0008
HTTP 200  |  ISO: 00
✓ 3D ONAY
Süresi Dolmuş Kart
4000 0000 0000 0009
HTTP 200  |  ISO: 54
✗ SÜRESİ DOLMUŞ
Ön Provizyon
4000 0000 0000 0010
HTTP 200  |  ISO: 00
✓ PRE-AUTH ONAY
Döviz İşlem (USD → TRY)
4000 0000 0000 0011
HTTP 200  |  ISO: 00  |  Kur: 42.00
✓ USD ONAY
Döviz İşlem 3D Secure (USD → TRY)
4000 0000 0000 0012
HTTP 200  |  ISO: 00  |  Kur: 42.00
✓ USD 3D ONAY

Postman Collection

Sandbox API'lerini hızlıca test etmek için hazır Postman collection'larını kullanabilirsiniz. Collection'lar hash hesaplama script'lerini içerir, ekstra kurulum gerekmez.

Sandbox Kimlik Bilgileri

ParametreDeğer
API Key 00000000-0000-0000-0000-000000000000
Secret Key sandbox-secret-key-for-testing-purposes-only
⚠️
Bu kimlik bilgileri yalnızca sandbox ortamında geçerlidir. Production ortamında size özel olarak sağlanan API Key ve Secret Key kullanılmalıdır.

Test Ortamı Bilgileri

ParametreDeğer
CVV 000 (herhangi bir 3-4 haneli değer kabul edilir)
Son Kullanma Tarihi 12/2026 (herhangi bir tarih kabul edilir, süresi dolmuş dahil)
Kart Sahibi Herhangi bir isim
3D OTP (test) 123456

Örnek Test İsteği (cURL)

cURL
curl -X POST https://api.payment-hub.example.com/api/v1/vpos/payments/payment \
  -H "Content-Type: application/json" \
  -H "X-API-Key: 00000000-0000-0000-0000-000000000000" \
  -H "X-Hash: your-calculated-hash" \
  -d '{
    "transaction_type": "Auth",
    "order_id": "TEST-ORDER-001",
    "amount": 100.00,
    "currency": "TRY",
    "installment": 1,
    "card_number": "4000000000000001",
    "card_holder_name": "Test User",
    "exp_year": 2026,
    "exp_month": 12,
    "cvv": "000",
    "is_3d": false,
    "customer_info": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "phone": "+905551234567"
    }
  }'

Gateway Response Kodları

Bankadan dönen yanıt kodları Payment Hub tarafından ISO 8583 standardına göre normalize edilir. Tüm ödeme yanıtlarındaki gateway_response.code ve gateway_response.message_tr / message_en alanları aşağıdaki tablodaki değerleri alır.

ℹ️
gateway_response.code değeri "00" olan işlemler başarılıdır. Tanımlanamayan banka hata kodları "99" olarak döner. 3D Secure doğrulama başarısızlıkları "98" koduyla işaretlenir.
Kod Mesaj TR Mesaj EN Açıklama
00İŞLEM BAŞARILIAPPROVEDİşlem başarıyla tamamlandı.
01BANKADAN ONAY ALINIZREFER TO CARD ISSUERBanka onayı gerekiyor; kart sahibi bankasıyla iletişime geçilmeli.
02BANKADAN ONAY ALINIZ (ÖZEL DURUM)REFER TO CARD ISSUER, SPECIAL CONDITIONBanka özel durum onayı gerekiyor.
03GEÇERSİZ ÜYE İŞYERİINVALID MERCHANT OR SERVICE PROVIDERÜye işyeri banka sisteminde kapalı olabilir; sanal POS bankasıyla iletişime geçilmeli.
04KARTA EL KOYUNUZPICK UP CARDKart güvenlik nedeniyle alıkonulmalı.
05REDDO NOT HONORİşlem reddedildi; kart sahibi bankasıyla iletişime geçilmeli.
07KARTA EL KOYUNUZ (ÖZEL DURUM)PICK UP CARD, SPECIAL CONDITIONKart özel durum nedeniyle alıkonulmalı.
08ONAY VE KİMLİK DOĞRULAHONOR WITH IDENTIFICATIONİşlem onayı için kart sahibinin kimliği doğrulanmalı.
10KISMİ ONAYPARTIAL APPROVALİşlem tutarının bir kısmı onaylandı; daha düşük tutarda işlem yapılabilir.
11VIP ONAYVIP APPROVALVIP müşteri işlemi onaylandı; özel limitler uygulandı.
12GEÇERSİZ İŞLEMINVALID TRANSACTIONİşlem geçersiz; işlem tipi veya parametreler kontrol edilmeli.
13GEÇERSİZ TUTARINVALID AMOUNTİşlem tutarı geçersiz; tutar formatı veya limitleri kontrol edilmeli.
14GEÇERSİZ KART NUMARASIINVALID CARD NUMBERKart numarası geçersiz.
19GİRİŞ TEKRAR EDİNİZRE-ENTER TRANSACTIONGeçici sistem sorunu; işlem tekrar denenebilir.
21İŞLEM YAPILMADINO ACTION TAKENİşlem gerçekleştirilemedi; sistem yanıt vermedi.
25KAYIT BULUNAMADIUNABLE TO LOCATE RECORDİşlem kaydı sistemde bulunamadı.
30FORMAT HATASIFORMAT ERRORMesaj formatı hatalı; mesaj yapısı kontrol edilmeli.
34SAHTEKARLIKTAN ŞÜPHELENİLİYORFRAUD SUSPICIONİşlem sahtekarlık şüphesi nedeniyle reddedildi.
36KISITLI KARTRESTRICTED CARDKart kısıtlı; kart sahibi bankasıyla iletişime geçilmeli.
38PIN DENEMESİ AŞILDIALLOWABLE PIN TRIES EXCEEDEDPIN deneme sayısı aşıldı; kart geçici olarak bloke edildi.
41KAYIP KARTLOST CARDKart kayıp olarak işaretlenmiş; alıkonulmalı.
43ÇALINTI KARTSTOLEN CARDKart çalıntı olarak işaretlenmiş; alıkonulmalı.
51YETERSİZ BAKİYEINSUFFICIENT FUNDSHesapta yeterli bakiye yok; daha düşük tutarda denenebilir.
52HESAP NUMARASI BULUNAMADINO CHECKING ACCOUNTVadesiz hesap bulunamadı.
53HESAP NUMARASI BULUNAMADINO SAVINGS ACCOUNTVadeli hesap bulunamadı.
54KART SÜRESİ DOLMUŞ / SON KULLANMA TARİHİ HATALIEXPIRED CARD / INVALID EXPIRY DATEKart süresi dolmuş veya son kullanma tarihi hatalı.
55HATALI PININCORRECT PINPIN kodu hatalı.
57İŞLEME İZİN YOKTRANSACTION NOT PERMITTED TO CARDHOLDERKart sahibi bu işlem tipini gerçekleştiremez.
58İŞLEME İZİN YOKTRANSACTION NOT PERMITTED TO TERMINALTerminal bu işlem tipini gerçekleştiremez.
59SAHTEKARLIK ŞÜPHESİSUSPECTED FRAUDİşlem sahtekarlık riski nedeniyle reddedildi.
61PARA ÇEKME TUTAR LİMİTİ AŞILDIEXCEEDS WITHDRAWAL AMOUNT LIMITPara çekme limiti aşıldı; daha düşük tutarda denenebilir.
62YASAKLANMIŞ KARTRESTRICTED CARDKart yasaklanmış; kart sahibi bankasıyla iletişime geçilmeli.
63GÜVENLİK İHLALİSECURITY VIOLATIONGüvenlik ihlali tespit edildi.
65GÜNLÜK İŞLEM LİMİTİ AŞILDIEXCEEDS WITHDRAWAL FREQUENCY LIMITGünlük işlem limiti aşıldı; limit ertesi gün sıfırlanır.
75PIN DENEMESİ AŞILDIALLOWABLE PIN TRIES EXCEEDEDPIN deneme sayısı aşıldı; kart geçici olarak bloke edildi.
76HENÜZ AKTİF OLMAYAN KARTINACTIVE CARDKart henüz aktif değil; aktivasyon gerekiyor.
77ORJİNAL İŞLEM VERİLERİ EŞLEŞMİYORORIGINAL TRANSACTION DATA NOT MATCHEDİşlem verileri eşleşmiyor; orijinal işlem kontrol edilmeli.
78SİSTEMDE KAYITLI OLMAYAN KARTNO ACCOUNTKart sistemde kayıtlı değil.
82GEÇERSİZ CVVINVALID CVVCVV kodu hatalı.
83PIN DOĞRULAMASI YAPILAMADICANNOT VERIFY PINPIN doğrulaması yapılamadı.
85RED DEĞİLNOT DECLINEDİşlem reddedilmedi; onay bekliyor.
86PIN KONTROLÜ YAPILAMADICANNOT VERIFY PINPIN kontrolü yapılamadı; sistem hatası oluştu.
88KRİPTO HATASICRYPTOGRAPHIC FAILUREŞifreleme hatası; güvenlik doğrulaması başarısız.
89KİMLİK DOĞRULAMA BAŞARISIZAUTHENTICATION FAILUREKimlik doğrulama başarısız.
91İŞLEM BANKAYA GÖNDERİLEMEDİISSUER OR SWITCH INOPERATIVEBanka sistemi çalışmıyor; işlem tekrar denenebilir.
92İŞLEM BANKAYA GÖNDERİLEMEDİFINANCIAL INSTITUTION CANNOT BE FOUND FOR ROUTINGBanka yönlendirmesi yapılamadı; sistem hatası oluştu.
93KART ÜYESİNİN KAYDI YOKTRANSACTION CANNOT BE COMPLETED - VIOLATION OF LAWKart üyesi kaydı bulunamadı veya yasal kısıtlama mevcut.
95EŞLEŞTİRME HATASIRECONCILE ERRORİşlem eşleştirme hatası; sistem kontrolü gerekiyor.
96SİSTEM HATASISYSTEM MALFUNCTIONSistem hatası veya zaman aşımı; işlem tekrar denenebilir.
983D DOĞRULAMA BAŞARISIZ3D SECURE AUTHENTICATION FAILEDKart sahibi 3D Secure doğrulama sürecini tamamlayamadı.
99GENEL BANKA HATASIGENERAL BANK ERRORTanımlanamayan genel bir banka hatası oluştu.

Uygulama Hata Kodları

Payment Hub'ın döndürdüğü uygulama seviyesi hata kodları. Hata yanıtı success: false ile birlikte error.code, error.subCode ve error.message alanlarını içerir. subCode sayesinde istemciler message string'ini parse etmeden programatik hata yönetimi yapabilir.

HTTP Durum Kodları

HTTP KoduAçıklama
200 OKİşlem başarıyla tamamlandı
400 Bad RequestGeçersiz istek parametresi veya eksik zorunlu alan
401 UnauthorizedGeçersiz API key, geçersiz hash imzası veya yetkisiz erişim
409 ConflictÇakışan kayıt (ör. aynı order_id, zaten iptal edilmiş işlem)
422 Unprocessable Entityİş kuralı ihlali (ör. aynı gün iptal, limit aşımı)
500 Internal Server ErrorSunucu tarafı beklenmedik hata (dahili servis hatası, gateway sorgu hatası vb.)
503 Service UnavailableÖdeme gateway'ine bağlantı kurulamadı veya uygun terminal bulunamadı

İşlem Hataları

error.codesubCodeerror.messageHTTPAçıklama
NOT_FOUNDTRANSACTION_NOT_FOUNDTransaction not found404Belirtilen transaction_id bulunamadı
BAD_REQUESTINVALID_TRANSACTION_IDInvalid transaction ID format400transaction_id geçerli bir UUID formatında değil
BAD_REQUESTINVALID_MERCHANTInvalid merchant or merchant not active400Merchant bulunamadı veya aktif değil
CONFLICTDUPLICATE_ORDER_IDOrder ID already exists for this merchant409Bu order_id ile daha önce işlem yapılmış
BAD_REQUESTINVALID_CARD_NUMBERInvalid card number400Kart numarası geçersiz (Luhn kontrolü başarısız)
BAD_REQUESTINVALID_EXPIRY_DATEInvalid or expired card expiry date400Kartın son kullanma tarihi geçmiş veya geçersiz
BAD_REQUESTINVALID_CVVInvalid CVV400CVV kodu geçersiz
INTERNAL_SERVER_ERRORPAYMENT_GATEWAY_ERRORPayment gateway error500Ödeme gateway'inden hata yanıtı alındı
INTERNAL_SERVER_ERRORAn unexpected error occurred500Dahili servis hatası (gateway sorgu hatası, bağımlı servis erişilemiyor vb.); yeniden deneyin
SERVICE_UNAVAILABLEPAYMENT_GATEWAY_CONNECTION_FAILEDPayment gateway connection failed503Ödeme gateway'ine bağlantı kurulamadı

Terminal Hataları

error.codesubCodeerror.messageHTTPAçıklama
SERVICE_UNAVAILABLENO_ELIGIBLE_TERMINALSNo eligible terminals found, please contact operations team503İsteği karşılayabilecek hiçbir terminal yok; operasyon ekibiyle iletişime geçin
BAD_REQUESTTERMINAL_VOID_NOT_SUPPORTEDTerminal does not support void400İşlemin bağlı olduğu terminal iptal işlemini desteklemiyor
BAD_REQUESTTERMINAL_REFUND_NOT_SUPPORTEDTerminal does not support refund400İşlemin bağlı olduğu terminal iade işlemini desteklemiyor
BAD_REQUESTSUB_MERCHANT_ID_REQUIREDsub_merchant_id is required for selected terminal400Seçilen terminal için sub_merchant_id zorunludur

İptal (Void) Hataları

error.codesubCodeerror.messageHTTPAçıklama
BAD_REQUESTVOID_NOT_ALLOWED_DIFFERENT_DAYVoid not allowed for transactions created on different day400Farklı günde yapılan işlem iptal edilemez; iade kullanın
BAD_REQUESTVOID_NOT_ALLOWED_TYPETransaction type not allowed for void400İşlem tipi iptal için uygun değil
BAD_REQUESTVOID_NOT_ALLOWED_STATUSTransaction status not allowed for void400İşlem durumu iptal için uygun değil
CONFLICTTRANSACTION_ALREADY_VOIDEDTransaction already voided409İşlem zaten iptal edilmiş

İade (Refund) Hataları

error.codesubCodeerror.messageHTTPAçıklama
BAD_REQUESTREFUND_NOT_ALLOWED_SAME_DAYRefund not allowed in same day, use void400Aynı gün işlemler için iptal (void) kullanın
BAD_REQUESTREFUND_NOT_ALLOWED_AFTER_30_DAYSRefund not allowed after 30 days40030 günden eski işlemlere iade yapılamaz
BAD_REQUESTREFUND_NOT_ALLOWED_TYPETransaction type not allowed for refund400İşlem tipi iade için uygun değil
BAD_REQUESTREFUND_NOT_ALLOWED_STATUSTransaction status not allowed for refund400İşlem durumu iade için uygun değil
BAD_REQUESTREFUND_NOT_ALLOWED_VOIDEDVoided transaction cannot be refunded400İptal edilmiş işleme iade yapılamaz
BAD_REQUESTREFUND_AMOUNT_EXCEEDS_LIMITRefund amount exceeds available limit400İade tutarı mevcut iadesiz tutarı aşıyor
BAD_REQUESTINVALID_REFUND_AMOUNTInvalid refund amount400Geçersiz iade tutarı (0 veya negatif)

Capture (PreAuth) Hataları

error.codesubCodeerror.messageHTTPAçıklama
BAD_REQUESTCAPTURE_NOT_ALLOWED_TYPETransaction type not allowed for capture400Sadece PreAuth işlemlerine capture uygulanabilir
BAD_REQUESTCAPTURE_NOT_ALLOWED_STATUSTransaction status not allowed for capture400İşlem durumu capture için uygun değil
BAD_REQUESTCAPTURE_AMOUNT_EXCEEDS_LIMITCapture amount exceeds pre-auth amount400Capture tutarı PreAuth tutarını aşamaz
CONFLICTPRE_AUTH_ALREADY_CAPTUREDPre-authorization already captured409Bu PreAuth işlemi zaten capture edilmiş

Limit & Kural Hataları

error.codesubCodeerror.messageHTTPAçıklama
BAD_REQUESTMIN_AMOUNT_NOT_METTransaction amount is below minimum limit400İşlem tutarı minimum sınırın altında
BAD_REQUESTMAX_AMOUNT_EXCEEDEDTransaction amount exceeds maximum limit400İşlem tutarı maksimum sınırı aşıyor
BAD_REQUESTDAILY_LIMIT_EXCEEDEDDaily transaction limit exceeded400Günlük işlem tutarı limiti aşıldı
BAD_REQUESTMONTHLY_LIMIT_EXCEEDEDMonthly transaction limit exceeded400Aylık işlem tutarı limiti aşıldı
BAD_REQUESTDAILY_COUNT_EXCEEDEDDaily transaction count exceeded400Günlük işlem adedi limiti aşıldı
BAD_REQUESTMONTHLY_COUNT_EXCEEDEDMonthly transaction count exceeded400Aylık işlem adedi limiti aşıldı
BAD_REQUESTINSTALLMENT_NOT_ALLOWEDInstallment sales not allowed for this merchant400Merchant için taksitli ödeme aktif değil

Hata Yanıtı Örneği

JSON – BAD_REQUEST örneği
{
  "success": false,
  "error": {
    "code": "BAD_REQUEST",
    "subCode": "INVALID_CARD_NUMBER",
    "message": "Invalid card number"
  }
}
JSON – CONFLICT örneği
{
  "success": false,
  "error": {
    "code": "CONFLICT",
    "subCode": "DUPLICATE_ORDER_ID",
    "message": "Order ID already exists for this merchant"
  }
}