Bir oturumla başlayın.
İşletme başvurunuzu gönderin. Test erişimi onaylandıktan sonra panelden test API anahtarı oluşturun. Sunucunuz ödeme oturumu oluşturur, müşteriniz SANPAY’in ödeme ekranına yönlenir.
Anahtarınız sunucunuzda kalır.
Her istekte Authorization: Bearer svp_test_… başlığını kullanın. Anahtarı tarayıcıya, mobil istemciye, URL’ye veya loglara koymayın. Anahtarlar yalnızca bir kez gösterilir; veri tabanında SHA-256 özeti saklanır.
Scope’lar: checkout:write ve payments:read. İptal edilen anahtar bir sonraki istekte reddedilir. Yeni anahtar oluşturup eski anahtarı iptal ederek döndürün. Sınır: anahtar başına dakikada 60 istek.
Ödeme oturumu oluşturma
POST /api/v1/checkout/sessions. Tutar tam dolar olarak, pozitif integer gönderilir; en çok $100.000. Para birimi yalnızca $.
curl https://pay.santos-v.com/api/v1/checkout/sessions \
-H 'Authorization: Bearer YOUR_SECRET_KEY' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-2026-0001' \
-d '{
"amount": 120,
"currency": "$",
"order_id": "order-2026-0001",
"description": "Siparişiniz",
"success_url": "https://isletmeniz.com/pay/success",
"cancel_url": "https://isletmeniz.com/pay/cancel",
"metadata": {"reference": "your-reference"}
}'Yanıttaki checkout_url müşteriyi SANPAY’e yönlendirmek içindir. Oturum 30 dakika geçerlidir. Bağlantı gizli kabul edilir. Karakter veya müşteri hesap kimliği merchant isteğinden alınmaz; müşterinin güvenli girişle doğrulanır.
Idempotency-Key zorunludur. Aynı anahtar ve aynı içerik aynı yanıtı döndürür; farklı içerik 409 verir. Aynı sipariş için başka anahtarla ikinci oturum oluşturulamaz.
Yönlendirme adresleri yalnızca işletmenin kayıtlı HTTPS origin’i üzerinde olabilir. Alan adı sahipliği manuel başvuru incelemesinde doğrulanmalıdır.
Komisyon, vergi ve toplam tutar
amount siparişin asıl tutarıdır ve entegrasyon doğrulamalarında bu anlamını korur. total_amount müşterinin ücretler dahil toplamıdır. pricing içindeki base_minor, commission_minor, tax_minor, total_minor ve merchant_net_minor tam sayı sent değerleridir (100 sent = $1).
Oranlar commission_bps ve tax_bps alanlarında tutulur (100 = %1). commission_payer ve tax_payer, merchant veya customer değerini alır. İki oran sipariş tutarı üzerinden ayrı hesaplanır; yarım sent yukarı yuvarlanır. %100 sınırında bir sentlik toplam yuvarlama farkı vergiden azaltılır. İşlem oluşturulduğunda hesap sabitlenir; sonradan değişen ayarlar mevcut işlemi değiştirmez.
Test ortamında bu tutarlar yalnızca hesaplamadır. Müşteriden, işletmeden veya banka hesabından tahsilat yapılmaz.
Sonuç sunucunuzda doğrulanır.
GET /api/v1/payments/{id} veya GET /api/v1/checkout/sessions/{id} ile kayıt durumunu okuyun. Liste için GET /api/v1/payments?limit=20&offset=0; üst sınır 50 kayıt. Durumlar: created, succeeded, failed, cancelled.
Müşterinin dönüş sayfasına gelmesi ödeme kanıtı değildir. Olayı sunucunuzda doğrulayın; beklediğiniz merchant, sipariş, tutar ve ortamı karşılaştırın. Aynı event veya payment kimliğini ikinci kez işlemeyin. Test ortamındaki succeeded sonucu hiçbir gerçek ürünü etkinleştirmemelidir.
İmzalı sonuç bildirimleri
Endpoint’inizi panelden ekleyin. HTTPS origin’i platform yöneticisinin allowlist’inde olmalıdır. Private, loopback ve reserved IP’ler reddedilir; DNS çözümü bağlantıya sabitlenir. Redirect takip edilmez.
Başlıklar: X-SVPay-Event-ID, X-SVPay-Timestamp, X-SVPay-Signature. HMAC-SHA256, aşağıdaki byte dizisinin hex imzasıdır: timestamp + '.' + eventId + '.' + rawBody.
import { createHmac, timingSafeEqual } from 'node:crypto';
const expected = createHmac('sha256', secret)
.update(stamp + '.' + eventId + '.' + rawBody)
.digest();
const supplied = /^[a-f0-9]{64}$/i.test(signature)
? Buffer.from(signature, 'hex') : Buffer.alloc(0);
if (!/^\d+$/.test(stamp) ||
Math.abs(Date.now()/1000 - Number(stamp)) > 300 ||
supplied.length !== expected.length ||
!timingSafeEqual(supplied, expected)) {
throw new Error('Invalid webhook');
}
// Persist eventId once in the same transaction as fulfillment.
// Reject data.mode !== 'live' for real activation.$raw = file_get_contents('php://input');
$stamp = $_SERVER['HTTP_X_SVPAY_TIMESTAMP'] ?? '';
$event = $_SERVER['HTTP_X_SVPAY_EVENT_ID'] ?? '';
$given = $_SERVER['HTTP_X_SVPAY_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256',
$stamp . '.' . $event . '.' . $raw, $secret);
if (!ctype_digit($stamp) || abs(time() - (int)$stamp) > 300
|| !hash_equals($expected, $given)) {
http_response_code(401); exit;
}
// event ID must be unique in your transaction.
// Test events must never fulfill real orders.Etkin olaylar: payment.created, payment.succeeded, payment.failed, payment.cancelled. Teslimat en fazla 8 defa, sınırlı exponential backoff ile denenir. HTTP 2xx teslimatı onaylar. Olaylar tekrar gelebilir; aynı event ID ile idempotent davranın. Kuyruk ayrı worker ile çalışır. İşlemin tamamlanması webhook yanıtına bağlı değildir.
Açık hata sözleşmesi
Hatalar code, message, request_id ve doğrulama hatalarında details alanlarını döndürür. 401 kimlik, 403 yetki, 409 çakışma, 410 süresi dolmuş oturum, 422 alan doğrulama, 429 oran sınırı, 503 hizmet veya kapalı özellik.
Test yetersiz bakiye senaryosu için metadata’da test_outcome: insufficient_funds gönderin. Bu bir test sonucudur; banka bakiyesi okunmaz veya yazılmaz.
Tek bakiye kaynağı.
Bakiyeler bağlı bankacılık hizmetinde tutulur. SANPAY yalnızca ödeme oturumu ve işlem referansı tutar; harcanabilir bakiye oluşturmaz.
Canlı tahsilat, iadeler, uyuşmazlıklar, ekip davetleri ve otomatik Soundify Premium aktivasyonu henüz açık değildir. POST /api/v1/refunds ve iade sorgusu 503 REFUNDS_UNAVAILABLE döndürür. Canlı API anahtarı oluşturulmaz. Canlı durumu bir environment flag ile açılamaz.
UCP, mevcut authorization code ve confidential client akışıyla kullanılır ve S256 PKCE ile bağlanır. Pay girişi açılmadan önce eşlik eden UCP PKCE değişikliği dağıtılmalıdır.
Hizmet kapsamını incele ↗