ArvonaPay Developers

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.

  1. Müşteri adını, soyadını, e-posta ve telefonunu girer.
  2. Alanların altındaki Doğrula düğmeleriyle SMS ve e-posta kodlarını ister; iki doğrulamayı da tamamlar.
  3. Yatırım tutarını TL olarak kendisi girer ve işlem koşullarını görür.
  4. Güncel ödeme toplamını onaylar ve ödeme adımına geçer.
  5. 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.

Ö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"
  }
}
  1. Gövdeyi JSON’a çevirmeden önce ham baytları saklayın. JSON’u yeniden üretip imzalamayın.
  2. Zaman damgasını ±300 saniye içinde kontrol edin; sunucunuzun saat eşitlemesi açık olsun.
  3. İmzayı callback sırrıyla hesaplayın, sabit süreli karşılaştırma kullanın.
  4. Başlıktaki olay kimliğini imzalı gövdedeki id ile eşleştirin.
  5. Referans, ödeme kimliği, ortam, durum ve özgün TL tutarını doğrulayın.
  6. 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.
  7. Kalıcı kayıt tamamlandıktan sonra hızlıca 200 dönün. Aynı içerikli tekrar bildirimde yeniden bakiye yazmadan yine 200 dö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

KodYapılacak işlem
401 INVALID_API_KEYAnahtarın, kullanıcı ve firmanın etkinliğini kontrol edin.
403 IP_NOT_ALLOWEDSunucunuzun 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_CONFLICTKayıtlı işlem ve tekrar anahtarıyla eşleştirin; yeni tahsilat açmayın.
409 CUSTOMER_CHECKOUT_REQUIREDEski ödeme ucu yerine müşteri oturumu açın.
410 CHECKOUT_EXPIREDBağlı bir ödeme var mı sorgulayın; sonuç belirsizse yeni ödeme açmayın.
429 CUSTOMER_COOLDOWN / CUSTOMER_24H_LIMITRetry-After / retryAt değerine uyun.
403 RISK_REJECTEDİşlem engellendi. Farklı kimlikle tekrar etmeyin.
503 PAYMENT_CHANNEL_UNAVAILABLEYeni 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

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.