Genel Bilgiler
Base URL
https://api.metalpay.net/api
Content-Type
Tüm isteklerde Content-Type: application/json header'ı gönderilmelidir.
API, JSON formatında yanıt döner. Başarılı işlemlerde result: true, hatalı işlemlerde result: false döner.
Kimlik Doğrulama (Authentication)
MetalPay API, hash-based authentication kullanır. Her istekte aşağıdaki header'lar gönderilmelidir:
| Header | Açıklama | Örnek |
|---|
requestId | Benzersiz istek ID'si | req-1234567890 |
swtId | Merchant'ın Switch ID'si | AB9900EFA5EA4E89AEC05D554B98297D |
hashedData | Hesaplanmış hash değeri | A1B2C3D4E5F6... |
timestamp | İşlem zamanı | 2025-01-15T10:30:00.0000000 |
| Header | Açıklama | Örnek |
|---|
userId | Kullanıcı ID'si | user-123 |
Not: Header'lar HTTP header olarak gönderilebileceği gibi, request body içinde header objesi içinde de gönderilebilir.
Hash Hesaplama
Hash değeri, aşağıdaki formül kullanılarak hesaplanır:
Hash = SHA256(requestId + swtId + userId + timestamp + switchPassword).toUpperCase()
Hash Hesaplama Adımları
-
Değerleri birleştirin: Aşağıdaki değerleri sırayla birleştirin (aralarında boşluk veya ayırıcı karakter olmadan):
requestId + swtId + userId + timestamp + switchPassword
Birleştirilecek değerler:
| Değer | Tip | Açıklama |
|---|
requestId | string | Benzersiz istek ID'si |
swtId | string | Merchant'ın Switch ID'si |
userId | string | Kullanıcı ID'si (boş olabilir) |
timestamp | string | İşlem zamanı |
switchPassword | string | Merchant'a verilen şifre |
-
Hash hesaplayın: Birleştirilmiş string'i SHA256 algoritması ile hash'leyin
-
Büyük harfe çevirin: Hash sonucunu büyük harfe çevirin (uppercase)
Hash Hesaplama Örneği
const crypto = require('crypto');
const requestId = "req-1234567890";
const swtId = "AB9900EFA5EA4E89AEC05D554B98297D";
const userId = "";
const timestamp = "2025-01-15T10:30:00.0000000";
const switchPassword = "your-switch-password";
const concatenated = requestId + swtId + userId + timestamp + switchPassword;
const hash = crypto.createHash('sha256').update(concatenated, 'utf8').digest('hex').toUpperCase();
console.log(hash);
Önemli: Hash hesaplamasında request body içeriği kullanılmaz. Sadece header bilgileri kullanılır.
Endpoint'ler
Ödeme İşlemleri
1. 3D'siz Satış (Kart Bilgileriyle)
Kart bilgileriyle direkt ödeme işlemi yapar.
Endpoint: POST /api/payment/auth
Header'lar:
requestId: <benzersiz-istek-id>
swtId: <merchant-switch-id>
hashedData: <hesaplanmış-hash>
timestamp: <işlem-zamanı>
userId: <opsiyonel-kullanıcı-id>
Request Body:
Format 1: Standart Format
{
"txnAmount": "100.00",
"currencyNumber": 949,
"card": {
"number": "4506347052345678",
"expireMonth": "12",
"expireYear": "2025",
"cvv": "123"
},
"orderId": "ORDER-123456"
}
Format 2: Alternatif Format
{
"amount": "100.00",
"currency": "TRY",
"cardNumber": "4506347052345678",
"expiryMonth": "12",
"expiryYear": "2025",
"cvv": "123",
"orderId": "ORDER-123456"
}
Request Parametreleri:
Standart Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
txnAmount | string/number | Evet | Ödeme tutarı |
currencyNumber | number | Hayır | Para birimi (949=TRY, 840=USD, 978=EUR) |
card.number | string | Evet | Kart numarası (16 haneli) |
card.expireMonth | string/number | Evet | Son kullanma ayı (1-12) |
card.expireYear | string/number | Evet | Son kullanma yılı (2 veya 4 haneli) |
card.cvv | string | Hayır | CVV kodu (3-4 haneli) |
orderId | string | Hayır | Sipariş ID'si |
acquirer.bankId | string | Hayır | Virtual POS ID'si |
Alternatif Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
amount | string/number | Evet | Ödeme tutarı |
currency | string | Hayır | Para birimi (TRY, USD, EUR) |
cardNumber | string | Evet | Kart numarası (16 haneli) |
expiryMonth | string/number | Evet | Son kullanma ayı (1-12) |
expiryYear | string/number | Evet | Son kullanma yılı (2 veya 4 haneli) |
cvv | string | Hayır | CVV kodu (3-4 haneli) |
orderId | string | Hayır | Sipariş ID'si |
acquirer.bankId | string | Hayır | Virtual POS ID'si |
Response (Başarılı):
{
"result": true,
"transactionId": "txn-1234567890",
"amount": "100.00",
"currency": "TRY",
"status": "approved",
"timestamp": "2025-01-15T10:30:00.0000000"
}
Response (Hata):
{
"result": false,
"errorCode": "INSUFFICIENT_FUNDS",
"errorMessage": "Yetersiz bakiye"
}
2. 3D'siz Satış (Token ile)
Kaydedilmiş kart token'ı ile ödeme işlemi yapar.
Endpoint: POST /api/payment/token/auth
Header'lar:
requestId: <benzersiz-istek-id>
swtId: <merchant-switch-id>
hashedData: <hesaplanmış-hash>
timestamp: <işlem-zamanı>
userId: <opsiyonel-kullanıcı-id>
Request Body:
Format 1: Standart Format
{
"txnAmount": "150.00",
"currencyNumber": 949,
"card": {
"token": "550e8400-e29b-41d4-a716-446655440000"
},
"orderId": "ORDER-123457"
}
Format 2: Alternatif Format
{
"amount": "150.00",
"currency": "TRY",
"token": "550e8400-e29b-41d4-a716-446655440000",
"orderId": "ORDER-123457"
}
Request Parametreleri:
Standart Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
txnAmount | string/number | Evet | Ödeme tutarı |
currencyNumber | number | Hayır | Para birimi (949=TRY, 840=USD, 978=EUR) |
card.token | string | Evet | Kart token'ı |
orderId | string | Hayır | Sipariş ID'si |
acquirer.bankId | string | Hayır | Virtual POS ID'si |
Alternatif Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
amount | string/number | Evet | Ödeme tutarı |
currency | string | Hayır | Para birimi (TRY, USD, EUR) |
token | string | Evet | Kart token'ı |
orderId | string | Hayır | Sipariş ID'si |
acquirer.bankId | string | Hayır | Virtual POS ID'si |
Response (Başarılı):
{
"result": true,
"transactionId": "txn-1234567891",
"amount": "150.00",
"currency": "TRY",
"status": "approved",
"timestamp": "2025-01-15T10:31:00.0000000"
}
3. PostAuth İşlemi
Önceden yapılmış bir işlemin tutarını artırma işlemi.
Endpoint: POST /api/payment/postauth
Header'lar:
requestId: <benzersiz-istek-id>
swtId: <merchant-switch-id>
hashedData: <hesaplanmış-hash>
timestamp: <işlem-zamanı>
userId: <opsiyonel-kullanıcı-id>
Request Body:
{
"txnAmount": "200.00",
"currencyNumber": 949
}
Request Parametreleri:
Standart Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
txnAmount | string/number | Evet | Artırılacak tutar |
currencyNumber | number | Hayır | Para birimi (949=TRY, 840=USD, 978=EUR) |
Alternatif Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
amount | string/number | Evet | Artırılacak tutar |
currency | string | Hayır | Para birimi (TRY, USD, EUR) |
Response (Başarılı):
{
"result": true,
"transactionId": "txn-1234567892",
"amount": "200.00",
"currency": "TRY",
"status": "approved"
}
Token İşlemleri
4. Token Oluşturma (Kart Saklama)
Kart bilgilerini saklayarak token oluşturur. Bu token ile daha sonra ödeme yapılabilir.
Endpoint: POST /api/token/generate
Header'lar:
requestId: <benzersiz-istek-id>
swtId: <merchant-switch-id>
hashedData: <hesaplanmış-hash>
timestamp: <işlem-zamanı>
userId: <opsiyonel-kullanıcı-id>
Request Body:
Format 1: Standart Format
{
"card": {
"number": "4506347052345678",
"expireMonth": "12",
"expireYear": "2025",
"holderName": "Test User",
"cvv": "123"
}
}
Format 2: Alternatif Format
{
"cardNumber": "4506347052345678",
"expiryMonth": "12",
"expiryYear": "2025",
"cardHolderName": "Test User",
"cvv": "123"
}
Request Parametreleri:
Standart Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
card.number | string | Evet | Kart numarası (16 haneli) |
card.expireMonth | string/number | Evet | Son kullanma ayı (1-12) |
card.expireYear | string/number | Evet | Son kullanma yılı (2 veya 4 haneli) |
card.holderName | string | Hayır | Kart sahibi adı |
card.cvv | string | Hayır | CVV kodu (PCI DSS gereği saklanmaz) |
Alternatif Format:
| Parametre | Tip | Zorunlu | Açıklama |
|---|
cardNumber | string | Evet | Kart numarası (16 haneli) |
expiryMonth | string/number | Evet | Son kullanma ayı (1-12) |
expiryYear | string/number | Evet | Son kullanma yılı (2 veya 4 haneli) |
cardHolderName | string | Hayır | Kart sahibi adı |
cvv | string | Hayır | CVV kodu (PCI DSS gereği saklanmaz) |
Response (Başarılı):
{
"header": {
"requestId": "req-1234567890",
"swtId": "AB9900EFA5EA4E89AEC05D554B98297D",
"returnCode": "00",
"reasonCode": "00",
"message": "Başarılı",
"timestamp": "2025-01-15T10:30:00.0000000",
"hashedData": "A1B2C3D4E5F6..."
},
"card": {
"token": "550e8400-e29b-41d4-a716-446655440000",
"last4": "5678",
"brand": "VISA",
"expireMonth": "12",
"expireYear": "2025"
},
"result": true
}
Response (Hata):
{
"header": {
"requestId": "req-1234567890",
"swtId": "AB9900EFA5EA4E89AEC05D554B98297D",
"returnCode": "99",
"reasonCode": "99",
"message": "Kart bilgileri geçersiz",
"timestamp": "2025-01-15T10:30:00.0000000",
"hashedData": "A1B2C3D4E5F6..."
},
"result": false,
"errorMessage": "Kart bilgileri geçersiz"
}
Kart İşlemleri
5. Kart Saklama (Legacy Endpoint)
Not: Bu endpoint geriye uyumluluk için mevcuttur. Yeni entegrasyonlarda /api/token/generate kullanılmalıdır.
Endpoint: POST /api/card/save
Header'lar:
requestId: <benzersiz-istek-id>
swtId: <merchant-switch-id>
hashedData: <hesaplanmış-hash>
timestamp: <işlem-zamanı>
userId: <opsiyonel-kullanıcı-id>
Request Body:
{
"cardNumber": "4506347052345678",
"expiryMonth": "12",
"expiryYear": "2025",
"cardHolderName": "Test User",
"cvv": "123"
}
Response: /api/token/generate ile aynı format.
6. Kaydedilmiş Kartları Listeleme
Merchant'a ait kaydedilmiş kartları listeler.
Endpoint: GET /api/card/list
Header'lar:
requestId: <benzersiz-istek-id>
swtId: <merchant-switch-id>
hashedData: <hesaplanmış-hash>
timestamp: <işlem-zamanı>
userId: <opsiyonel-kullanıcı-id>
Request Body: Yok (GET isteği)
Response (Başarılı):
{
"result": true,
"cards": [
{
"token": "550e8400-e29b-41d4-a716-446655440000",
"last4": "5678",
"brand": "VISA",
"expireMonth": "12",
"expireYear": "2025",
"holderName": "Test User",
"createdAt": "2025-01-15T10:30:00.000Z"
}
]
}
Hata Kodları
| Hata Kodu | Açıklama |
|---|
VALIDATION_ERROR | İstek validasyon hatası |
MISSING_REQUEST_ID | Request ID eksik |
MISSING_SWT_ID | Switch ID eksik |
MISSING_HASHED_DATA | Hash değeri eksik |
MISSING_TIMESTAMP | Timestamp eksik |
INVALID_SWT_ID | Geçersiz Switch ID |
INVALID_HASH | Geçersiz hash değeri |
INSUFFICIENT_FUNDS | Yetersiz bakiye |
INVALID_CARD | Geçersiz kart bilgileri |
CARD_EXPIRED | Kartın süresi dolmuş |
TRANSACTION_DECLINED | İşlem reddedildi |
NO_VIRTUAL_POS | Aktif Virtual POS bulunamadı |
Örnek İstekler
cURL Örneği - Token Oluşturma
curl -X POST https://api.metalpay.net/api/token/generate \
-H "Content-Type: application/json" \
-H "requestId: req-1234567890" \
-H "swtId: AB9900EFA5EA4E89AEC05D554B98297D" \
-H "hashedData: A1B2C3D4E5F6..." \
-H "timestamp: 2025-01-15T10:30:00.0000000" \
-d '{
"card": {
"number": "4506347052345678",
"expireMonth": "12",
"expireYear": "2025",
"holderName": "Test User",
"cvv": "123"
}
}'
JavaScript (Node.js) Örneği
const crypto = require('crypto');
const axios = require('axios');
function calculateHash(requestId, swtId, userId, timestamp, switchPassword) {
const concatenated = requestId + swtId + (userId || '') + timestamp + switchPassword;
return crypto.createHash('sha256').update(concatenated, 'utf8').digest('hex').toUpperCase();
}
async function generateToken() {
const requestId = `req-${Date.now()}`;
const swtId = 'AB9900EFA5EA4E89AEC05D554B98297D';
const userId = '';
const timestamp = new Date().toISOString().replace(/[-T:]/g, '').substring(0, 15);
const switchPassword = 'your-switch-password';
const hashedData = calculateHash(requestId, swtId, userId, timestamp, switchPassword);
try {
const response = await axios.post(
'https://api.metalpay.net/api/token/generate',
{
card: {
number: '4506347052345678',
expireMonth: '12',
expireYear: '2025',
holderName: 'Test User',
cvv: '123'
}
},
{
headers: {
'Content-Type': 'application/json',
'requestId': requestId,
'swtId': swtId,
'hashedData': hashedData,
'timestamp': timestamp
}
}
);
console.log('Token:', response.data.card.token);
return response.data;
} catch (error) {
console.error('Hata:', error.response?.data || error.message);
throw error;
}
}
Python Örneği
import hashlib
import requests
from datetime import datetime
def calculate_hash(request_id, swt_id, user_id, timestamp, switch_password):
"""Hash hesaplama fonksiyonu"""
concatenated = request_id + swt_id + (user_id or '') + timestamp + switch_password
return hashlib.sha256(concatenated.encode('utf-8')).hexdigest().upper()
def generate_token():
request_id = f"req-{int(datetime.now().timestamp() * 1000)}"
swt_id = 'AB9900EFA5EA4E89AEC05D554B98297D'
user_id = ''
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
switch_password = 'your-switch-password'
hashed_data = calculate_hash(request_id, swt_id, user_id, timestamp, switch_password)
headers = {
'Content-Type': 'application/json',
'requestId': request_id,
'swtId': swt_id,
'hashedData': hashed_data,
'timestamp': timestamp
}
data = {
'card': {
'number': '4506347052345678',
'expireMonth': '12',
'expireYear': '2025',
'holderName': 'Test User',
'cvv': '123'
}
}
response = requests.post(
'https://api.metalpay.net/api/token/generate',
json=data,
headers=headers
)
if response.status_code == 200:
result = response.json()
print(f"Token: {result['card']['token']}")
return result
else:
print(f"Hata: {response.json()}")
raise Exception(f"API hatası: {response.status_code}")
Önemli Notlar
Güvenlik
- CVV bilgisi kart saklama işlemlerinde saklanmaz (PCI DSS uyumluluğu)
- Tüm kart bilgileri şifrelenmiş olarak saklanır
- Hash hesaplamasında switch password asla açık metin olarak gönderilmez
Para Birimi Kodları
949 = TRY (Türk Lirası)
840 = USD (Amerikan Doları)
978 = EUR (Euro)
826 = GBP (İngiliz Sterlini)
392 = JPY (Japon Yeni)
- ISO 8601 formatı:
2025-01-15T10:30:00.0000000
- Unix timestamp (milisaniye):
1705315800000
- Her iki format da kabul edilir
Request ID
- Her istek için benzersiz olmalıdır
- Aynı request ID ile tekrar istek gönderilmemelidir
- UUID veya timestamp-based ID kullanılabilir
Virtual POS
- Eğer
acquirer.bankId parametresi gönderilmezse, merchant'a ait aktif Virtual POS otomatik seçilir
- Öncelik sırası: Ziraat > İş Bankası > Diğer
Destek
Sorularınız için lütfen destek ekibi ile iletişime geçin.
Son Güncelleme: 2025-01-15