ArvonaPay
Merchant entegrasyonu
Sözleşme 1.8.0 · 22 Ekim 2026 · Sandbox
Müşteri tutarı ArvonaPay’de seçer. Siz yalnız kendi referansınızı ve sabit müşteri UID’sini iletir, doğrulanmış TL işlem sonucunu alırsınız.
1. Bağlantı bilgileri
ArvonaPay, firmanıza bağlı API anahtarı ve ayrı bir callback sırrı oluşturur. Siz sabit çıkış IP/IP’lerinizi ve sonuçları alacak HTTPS callback adresinizi iletirsiniz. Bu bilgiler tamamlanmadan işlem kabulü açılmaz.
Anahtar yalnız kendi sunucunuzda tutulur. Tarayıcıya, mobil uygulamaya, URL’ye ve günlük dosyalarına eklenmez. Bu rehberdeki anahtar ve kayıtlar örnektir; kullanılabilir gerçek anahtar içermez.
Ortam: sandbox. Gerçek tahsilat kapalı. API anahtarı avp_test_ ile başlar. Gereken kapsamlar: payments:create, payments:read. Bu müşteri akışı için simülasyon yetkisi gerekmez.
2. Müşteri için oturum açın
POST https://api.arvonapay.com/v1/checkout-sessions
Authorization: Bearer <ARVONAPAY_SANDBOX_API_KEY>
Idempotency-Key: xxxxpays-order-2026-0001
Content-Type: application/json
{
"reference": "xxxxpays-order-2026-0001",
"customer": { "id": "customer-stable-uid-001" }
}reference ve customer.id zorunludur, 1–120 karakterdir. Referans her işlem için benzersiz; UID ise kendi sisteminizdeki gerçek müşteriye ait sabit kimlik olmalıdır. Her işlemde yeni UID üretmeyin.
İsteğe bağlı alanlar customer.firstName, lastName, email ve ülke kodlu phone alanlarıdır. İletilen değerler yalnız merchant beyanıdır; doğrulanmış kabul edilmez. Müşteri bilgilerini ArvonaPay’de kendisi girer ve telefon/e-posta erişimini doğrular.
Tutar göndermeyin. amount, currency, rate, markup, commission, verified ve ek alanlar reddedilir. Ulusal kimlik numarası, kart bilgileri veya OTP göndermeyin.
201 örnek yanıt
{
"id": "5ef35d23-d880-4ba2-86e1-0a744461cb7a",
"reference": "xxxxpays-order-2026-0001",
"state": "AWAITING_VERIFICATION",
"customerCheckout": {
"url": "https://arvonapay.com/checkout/<PRIVATE_TOKEN>",
"expiresAt": "2026-10-22T16:30:00.000Z"
},
"amount": null,
"currency": null,
"verification": {
"verified": false,
"phoneVerified": false,
"emailVerified": false,
"identityVerified": false
},
"paymentId": null,
"environment": "sandbox",
"livePayment": false
}3. Müşteriyi ArvonaPay’e yönlendirin
customerCheckout.url bağlantısını üst sayfa olarak açın. iframe kullanmayın. Oturum kimliğini kendi referansınızla kaydedin. Bağlantı kişiye özeldir ve başlangıçta 30 dakika geçerlidir; açık günlüklere yazmayın.
- Müşteri adını, soyadını, e-posta ve telefonunu girer.
- Alanların altındaki Doğrula düğmeleriyle SMS ve e-posta kodlarını ister; iki doğrulamayı da tamamlar.
- Yatırım tutarını TL olarak kendisi girer ve işlem koşullarını görür.
- Güncel ödeme toplamını onaylar ve ödeme adımına geçer.
- Sonuç ArvonaPay tarafından doğrulanınca merchant’a bildirilir.
SMS ve e-posta kodları ilgili iletişim kanalına erişimi doğrular; kişinin hukuki kimliğini veya kart sahipliğini kanıtlamaz. Oturum açılması, doğrulamanın bitmesi veya tutarın onaylanması başarılı ödeme değildir.
4. Tekrar ve zaman aşımı yönetimi
İlk istekten önce Idempotency-Key değerini kendi veritabanınıza kaydedin. 8–128 karakter; harf, rakam ve - _ . : kabul edilir. UUID uygundur.
- Aynı anahtar + aynı gövde: tek oturum, güncel durum.
- Aynı anahtar + farklı gövde:
409 IDEMPOTENCY_CONFLICT. - Ağ zaman aşımı: aynı anahtar ve gövdeyle artan bekleme süresiyle tekrar edin. Yeni işlem üretmeyin.
429: varsaRetry-Afterbaşlığına veerror.retryAtzamanına uyun.
Ödeme sonucu belirsizse müşteriye kesin ret vermeyin ve ikinci ödeme açmayın. Önce mevcut oturum ve ödeme kaydını sorgulayın. Tarayıcının kapanması veya geri dönmesi finansal sonuç değildir.
5. Durumu sorgulayın
GET https://api.arvonapay.com/v1/checkout-sessions/{id}
Authorization: Bearer <ARVONAPAY_SANDBOX_API_KEY>Müşteri devam ederken 3–5 saniyede bir sorgulama yeterlidir. AWAITING_VERIFICATION: iletişim doğrulaması; AWAITING_AMOUNT: tutar; QUOTED: müşteri onayı; PENDING: doğrulanmış sonuç bekleniyor. paymentId, müşteri tutarı onayladıktan sonra dolar.
amount ve currency alanları tutar onayına kadar boştur. Onaydan sonra müşterinin seçtiği özgün TL tutarı döner. verification.verified, iki OTP’nin birlikte tamamlandığını belirtir; identityVerified bu akışta false kalır.
GET https://api.arvonapay.com/v1/payments/{paymentId}
Authorization: Bearer <ARVONAPAY_SANDBOX_API_KEY>{
"id": "e68c5c19-55c4-4e28-83a4-e992a4c39b76",
"reference": "xxxxpays-order-2026-0001",
"amount": "1000.00",
"currency": "TRY",
"status": "SUCCEEDED",
"environment": "sandbox",
"createdAt": "2026-10-22T16:05:00.000Z",
"finalizedAt": "2026-10-22T16:07:00.000Z"
}Sonuç alanları: id, reference, amount, currency, status, environment, createdAt, finalizedAt. Ödeme SUCCEEDED ise örnekteki müşteri için 1.000,00 TL bir kez işlenir. FAILED veya EXPIRED için bakiye yazılmaz. PENDING terminal sonuç değildir.
Bu akışta tutar önceden sizden alınmadığından, callback ilk geldiğinde kayıtlı ödeme kimliği/tutarı henüz yoksa yetkili oturum ve ödeme sorgusuyla referans–ödeme ilişkisini doğrulayın. Müşteri bakiyesine yazılacak tutarı yalnız ArvonaPay’in doğrulanmış özgün amount/currency alanlarından alın.
6. İmzalı callback’i karşılayın
X-Arvona-Event-Id: <event-id>
X-Arvona-Timestamp: <Unix saniyesi>
X-Arvona-Signature: <küçük harf hex imza>
imza = HMAC-SHA256(callback_secret, timestamp + "." + rawBody){
"id": "1e1aac73-fad4-47c3-95f8-c9cf9784c7f0",
"type": "payment.succeeded",
"createdAt": "2026-10-22T16:07:00.000Z",
"data": {
"id": "e68c5c19-55c4-4e28-83a4-e992a4c39b76",
"reference": "xxxxpays-order-2026-0001",
"amount": "1000.00",
"currency": "TRY",
"status": "SUCCEEDED",
"environment": "sandbox",
"createdAt": "2026-10-22T16:05:00.000Z",
"finalizedAt": "2026-10-22T16:07:00.000Z"
}
}- Gövdeyi JSON’a çevirmeden önce ham baytları saklayın. JSON’u yeniden üretip imzalamayın.
- Zaman damgasını ±300 saniye içinde kontrol edin; sunucunuzun saat eşitlemesi açık olsun.
- İmzayı callback sırrıyla hesaplayın, sabit süreli karşılaştırma kullanın.
- Başlıktaki olay kimliğini imzalı gövdedeki
idile eşleştirin. - Referans, ödeme kimliği, ortam, durum ve özgün TL tutarını doğrulayın.
- Tek veritabanı işlemi içinde olay kimliğini benzersiz kaydedin; ödeme kimliği için de tek bakiye hareketi garantileyin. Sorgu ve callback aynı anda gelse de ikinci kez bakiye yazmayın.
- Kalıcı kayıt tamamlandıktan sonra hızlıca
200dönün. Aynı içerikli tekrar bildirimde yeniden bakiye yazmadan yine200dönün.
Olaylar: payment.succeeded, payment.failed, payment.expired. Gövde tipi ile data.status eşleşmelidir. Teslimat 5 saniyede yanıt bekler, en fazla 8 defa artan beklemeyle denenir. Teslim edilmemiş sonuçları yetkili sorguyla telafi edin.
İmzayı doğrulamayan bir 200 alıcısı kurmayın. İade veya ters ibraz bu olay türlerinde otomatik bakiye düzeltmesi olarak tanımlanmamıştır; ayrı mutabakat gerekir.
7. Müşteri sınırları ve engeller
Bir müşteri son 24 saatte en fazla 5 ödeme girişimi açabilir; iki girişim arasında en az 60 dakika bulunur. Tutar onayıyla ödeme açıldığında sayılır. Başarısız ve süresi dolmuş girişimler de sayımda kalır. Aynı oturumun tekrarı yeni girişim sayılmaz.
Doğrulanmış telefon/e-posta üzerinden UID veya merchant değiştirerek sınır aşımı da kontrol edilir. Yeni UID veya referansla otomatik tekrar yapmayın. Engel listesi ve risk kontrolü geçilmeden ödeme açılmaz.
8. Hata tablosu
| Kod | Yapılacak işlem |
|---|---|
| 401 INVALID_API_KEY | Anahtarın, kullanıcı ve firmanın etkinliğini kontrol edin. |
| 403 IP_NOT_ALLOWED | Sunucunuzun gerçek çıkış IP’sini izin listesiyle karşılaştırın. |
| 400 UNKNOWN_FIELD | İstekten tutar, fiyat, doğrulama ve ek alanları çıkarın. |
| 409 REFERENCE_USED / IDEMPOTENCY_CONFLICT | Kayıtlı işlem ve tekrar anahtarıyla eşleştirin; yeni tahsilat açmayın. |
| 409 CUSTOMER_CHECKOUT_REQUIRED | Eski ödeme ucu yerine müşteri oturumu açın. |
| 410 CHECKOUT_EXPIRED | Bağlı bir ödeme var mı sorgulayın; sonuç belirsizse yeni ödeme açmayın. |
| 429 CUSTOMER_COOLDOWN / CUSTOMER_24H_LIMIT | Retry-After / retryAt değerine uyun. |
| 403 RISK_REJECTED | İşlem engellendi. Farklı kimlikle tekrar etmeyin. |
| 503 PAYMENT_CHANNEL_UNAVAILABLE | Yeni işlem bekletilir; mevcut ödeme sonucunu sorgulayın. |
Hata gövdesi error.code, message, requestId içerir. Destek için yalnız referans, işlem kimliği ve requestId paylaşın; anahtar, OTP veya özel müşteri bağlantısı paylaşmayın.
9. Sunucu örneği ve kabul kontrolü
import {ArvonaPay, verifyCallback} from './merchant-client.mjs';
const arvona = new ArvonaPay(process.env.ARVONAPAY_API_KEY);
// Referans ve idempotencyKey ilk istekten ÖNCE veritabanına kaydedilir.
const session = await arvona.createCheckout({
reference: order.reference,
uid: customer.stableUid
}, order.idempotencyKey);
// session.id saklanır, müşteri session.customerCheckout.url adresine yönlenir.
// Callback: JSON middleware'inden önce raw Buffer alınır.
const event = verifyCallback(rawBody, request.headers,
process.env.ARVONAPAY_CALLBACK_SECRET);
// verifyCallback yalnız imza/sözleşmeyi doğrular.
// UNIQUE(event.id) ve UNIQUE(payment_id) ile kalıcı ve TEK bakiye kaydı
// kendi veritabanı işleminizde tamamlanır; sonra HTTP 200 dönülür.Node.js 22+ sunucu yardımcısını indir · OpenAPI 1.8.0
- İzinli/izinsiz IP, kapsam ve farklı merchant erişimi.
- Aynı anahtarla eşzamanlı tekrar ve farklı gövde çatışması.
- Telefon/e-posta doğrulanmadan ilerlemenin engellenmesi.
- Başarı, ret, bekleyen işlem ve bağlantı kesilmesi.
- Bozuk imza, eski zaman damgası, değişmiş olay kimliği.
- Tekrarlanan callback ve sorgu+callback yarışında tek bakiye kaydı.
- Özgün müşteri TL tutarıyla sonuç eşleşmesi.
Bu kontroller iki tarafın test ortamında geçmeden üretim anahtarıyla işlem açılmamalıdır. ArvonaPay tarafındaki kontroller, merchant’ın kendi bakiye kaydını ve callback uygulamasını ayrıca test etme gereğini kaldırmaz.