Kendi Faturalama Sisteminizi Bağlamak: merchant-provider/v1

Bu kılavuz, müşterilerini, ödemelerini ve aboneliklerini kendi sisteminde (bir faturalama sisteminde ya da tek bir sistemin arkasındaki birkaç ödeme sağlayıcısında) tutan işletmelerin mühendisleri içindir. Chargeless'ı kullanmak için merchant-provider/v1'i sunarsınız: Chargeless'ın bilgileri okumak ve politikasının onayladığı iadeleri ve iptalleri gerçekleştirmek için çağırdığı küçük bir API. REST ve MCP olmak üzere iki bağlantı türü vardır; ikisinde de operasyonlar ve kurallar aynıdır. Bu kılavuz neyi geliştirmeniz gerektiğini ve canlıya geçmeden önce çalıştığını nasıl kanıtlayacağınızı anlatır. Örneklerle REST bağlantısı ve MCP bağlantısı her bağlantıyı gerçek istek ve yanıtlarıyla gösterir; ikisinde de başlangıç noktası olarak kullanabileceğiniz eksiksiz bir sunucu bulunur.

Sözleşme, Chargeless'ın size verdiği dosyalardan oluşur. Bu kılavuzla dosyalar arasında bir fark varsa dosyalar esas alınır.

Dosya İçeriği
openapi/merchant-provider/v1.yaml REST bağlantısı (OpenAPI 3.1): yollar, başlıklar, durum kodları, sözleşme koşulları, test vektörleriyle imza, sonuç geri çağrısı (callback)
schemas/merchant-provider/v1/*.json Her nesne için bir JSON Schema (draft 2020-12). Her $id şu biçimdedir: https://schemas.supportroute.dev/merchant-provider/v1/<file>
schemas/merchant-provider/examples/v1/ Her nesnenin geçerli örnekleri ve Chargeless'ın reddettiği durumları içeren invalid.json
mcp/merchant-provider/v1.json MCP araç profili
CHANGELOG.md Sözleşmedeki tüm değişiklikler

1. Chargeless Sisteminizle Neler Yapar, Neler Yapmaz

  • Kararı Chargeless verir. Her iade ve iptal, Chargeless'ta yayımladığınız politikaya göre karara bağlanır: süreler, tutar üst sınırları, ödeme türleri, hız sınırları ve sisteminizin bildirdiği bilgilere dayalı kurallar. Uygunluk (eligibility) sorgulayan bir operasyon yoktur; sisteminiz hiçbir zaman karar vermez.
  • Sisteminiz bilgileri sağlar ve işlemleri gerçekleştirir. Chargeless her karardan önce müşteriyi, ödemeyi ya da aboneliği sisteminizden okur. refund veya cancel_subscription'ı yalnızca onayladığı ve bir idempotency anahtarıyla kaydettiği bir işlem için çağırır.
  • İşlem sırasında gelen bir ret bir sonuçtur, hiçbir zaman karar girdisi değildir. Sisteminiz onaylanmış bir işlemi reddederse o işlem durur. Retin sınıfına göre (bölüm 6) müşteriye hazır metinli bir ret yanıtı gider ya da vaka ekibinize devredilir. Kaydedilen karar değişmez ve bir ret hiçbir şeyi onaylayamaz. Belirli türdeki taleplerin tümünü reddettiğinizi fark ederseniz, bu kuralı ret yoluyla uygulamak yerine Chargeless politikanıza yazın.
  • Kararlar güncel veriyle verilir. Bir karar, son 60 saniye içinde sisteminizden okunmuş bir hedefe dayanır. Chargeless'ın karar verirken esas aldığı iade edilebilir tutar şöyle hesaplanır: ödeme tutarından, bildirdiğiniz iadeler ile Chargeless'ın gerçekleştirdiği iadelerden hangisi büyükse o düşülür, ardından Chargeless'ın henüz sonuçlanmamış kendi iadeleri düşülür. Arada başka bir yerden yapılan iadeleri sizin kendi aşırı iade reddiniz (aşağıdaki 3. koşul) karşılar.
  • Hiçbir süreç bir insanı beklemez. Her otomatik vaka üç sonuçtan biriyle biter: gerçekleştirilir, hazır metinli bir gerekçeyle reddedilir ya da ekibinize devredilir. Sisteminize ulaşılamadığında sohbet, hazır bir mesajla hemen devredilir. Bir talep 15 dakikaya kadar yeniden denenir, ardından devredilir. Güncel bir okuma yapılamadan verilecek bir karar da devredilir.
  • Chargeless'ın asla yapmadıkları:
    • bir dil modeli sisteminizi hiçbir zaman çağırmaz ve operasyonlarınızı hiçbir zaman görmez;
    • sözleşme dışındaki bir aracı ya da uç noktayı hiçbir zaman çağırmaz;
    • hiçbir zaman bir iade hedefi göndermez, çünkü iadeler asıl ödeme yöntemine yapılır;
    • disputed bir ödemeyi hiçbir zaman otomatik olarak iade etmez ve refund_route değeri unsupported olan bir ödemede hiçbir zaman iade denemez;
    • ödemeleriniz için ters ibraz ya da erken uyarı iş akışı çalıştırmaz; bildirdiğiniz ters ibrazlar politikanızın kullandığı bilgilerdir;
    • para birimi dönüştürmez: politikanızdakinden farklı bir para birimindeki ödeme ekibinize devredilir.
  • Acil durdurma. Çalışma alanınızın acil durdurma anahtarı da Chargeless'ınki de tüm otomatik iadeleri ve iptalleri durdurur. Biri açıkken sözleşme kontrolü çalışmaz.

2. Operasyonlar

Operasyon REST MCP aracı Zorunlu Chargeless ne zaman çağırır
describe GET /v1/describe sr_describe evet Sözleşme kontrolünde ve bağlantı ayarlarınız değiştiğinde
find_customers POST /v1/customers/search sr_find_customers evet Tanımlayıcılarla aday müşterileri daraltmak için. Bir eşleşme, yazan kişinin kim olduğunu hiçbir zaman kanıtlamaz
get_customer GET /v1/customers/{customer_ref} sr_get_customer evet Kimlik doğrulamada ve her kararda
list_transactions GET /v1/customers/{customer_ref}/transactions sr_list_transactions evet Doğrulanmış bir müşterinin ödemelerine her bakıldığında
get_transaction GET /v1/transactions/{transaction_ref} sr_get_transaction evet O ödemeyle ilgili her karardan önce
get_subscription GET /v1/subscriptions/{subscription_ref} sr_get_subscription cancel_subscription varsa O abonelikle ilgili her karardan önce
refund POST /v1/refunds sr_refund evet Yalnızca onaylanmış bir iade için, anahtarıyla birlikte
cancel_subscription POST /v1/subscriptions/{subscription_ref}/cancel sr_cancel_subscription cancel_subscription varsa Yalnızca onaylanmış bir iptal için, anahtarıyla birlikte
get_operation GET /v1/operations/{idempotency_key} sr_get_operation evet Açık kalan bir sonucu doğrulamak için ve bir sonuç geri çağrısının ardından
list_payment_attempts POST /v1/payment-attempts/list sr_list_payment_attempts payment_attempts varsa Canlıya geçtikten sonra, ödeme içgörülerini doldurmak için (revizyon 1.1; hiçbir zaman karar için kullanılmaz)

Yollar temel URL'nizin ardına eklenir; temel URL bir önek içerebilir (https://billing.example.com/supportroute → /supportroute/v1/refunds). Okumalar canlı sohbet ve talep akışlarının içinde çalışır, bu yüzden hızlı olmalıdır: sözleşme kontrolü 2,5 saniyeden yavaş bir okumayı başarısız sayar (bölüm 10).

Nesneler

Burada listelenen her alan yanıtlarınızda bulunmalıdır. "veya null", değerin null olabileceği ama anahtarın yine de yer alması gerektiği anlamına gelir. Kesin kalıplar şema dosyalarındadır.

  • describe:

    • contract_version: "1.0"; list_payment_attempts'ı uyguladığınızda "1.1"; revizyon 1.2'nin isteğe bağlı abonelik alanlarını gönderdiğinizde "1.2". Önceki revizyonlar değişmeden geçerliliğini korur;
    • capabilities: 1.0'dan gelen dört boolean ve 1.1 ile eklenen isteğe bağlı bir bayrak:
      • partial_refunds: bu olmadan Chargeless her zaman yalnızca kalanın tamamını ister;
      • cancel_subscription;
      • cancel_at_period_end: cancel_subscription gerektirir;
      • outcome_callbacks;
      • payment_attempts (1.1, isteğe bağlı; yoksa false sayılır): list_payment_attempts'ı uyguladığınızı belirtir. Bu bayrak olmadan Chargeless o operasyonu hiç çağırmaz ve panel, sisteminizin ödeme denemelerini göndermediğini gösterir;
    • currencies: ödeme alıp iade yaptığınız 1 ila 200 ISO para birimi kodu;
    • refunds_to_original_payment_method: true.
  • find_customers, email, phone (E.164), customer_ref, transaction_ref, order_ref ve card_last4 alanlarından bir veya birkaçını alır. Verilen tanımlayıcıların tümüne uyan müşterileri, en fazla 10 tane olmak üzere {"candidates": [{"customer_ref": …}]} biçiminde döndürür. E-postayı kayıtlı tüm adreslerle büyük/küçük harf ayırt etmeden eşleştirin. Eşleşme yoksa yanıt boş listeli bir 200'dür, hiçbir zaman 404 değildir. Chargeless her tanımlayıcıyı güncel veriler üzerinde kendisi yeniden karşılaştırır.

  • Müşteri (Customer):

    • customer_ref;
    • emails: müşterinin erişimi olan en fazla 10 adres, birincil adres ilk sırada;
    • phones: en fazla 10, E.164;
    • account_status: active, closed veya restricted;
    • account_created_at;
    • prior_refunds: son 365 güne ait iadeler; tüm ödemelerden ve kim yapmış olursa olsun, en yeniden eskiye, en fazla 50;
    • prior_chargebacks: son 365 gün, en fazla 50; her birinin durumu warning, open, won veya lost'tur;
    • isteğe bağlı attributes.

    Müşterinin kimliğini kanıtlayan e-posta kodu ve e-posta bağlantısı kayıtlı bir adrese gönderilir. İletişim bilgileri yalnızca bu doğrulamalar için kullanılır: hiçbir zaman bir modele, müşteriye ya da panelde gösterilmez. Doğruladığı adres artık kayıtlı olmayan bir müşteri, bir sonraki kararda bu doğrulamayı kaybeder.

  • Ödeme (Transaction):

    • transaction_ref ve ödemenin güncel sahibi olan customer_ref: sahiplik, güncel olarak okunan bu değere göre belirlenir;
    • order_ref veya null; subscription_ref veya null;
    • state: pending, succeeded veya failed; iadeleri değil, ödemenin kendisini tanımlar;
    • amount;
    • created_at: politikanın iade süresi bu andan itibaren sayılır;
    • description veya null: en fazla 200 karakter, yalnızca ekip üyelerine gösterilir;
    • product_type veya null, bir etiket;
    • charge_type: initial, renewal, trial_conversion, upgrade, one_time veya top_up;
    • processor: stripe veya in_house gibi bir etiket;
    • refund_route: provider veya unsupported;
    • card_last4 veya null; card_brand veya null;
    • disputed;
    • refunds: gerçekleşmiş tüm iadeler, en eskiden yeniye, en fazla 100. Her birinde at, amount, idempotency_key (Chargeless'ın anahtarı, bayt bayt aynı; başka bir yolla yapılmış iadelerde null) ve reversed_at (veya null) bulunur. Bekleyen bir iade gerçekleşene kadar listelenmez. Geri alınmış (reversed) bir iade listede kalır;
    • settlement veya null: ödemenin mutabakat para biriminizdeki tutarı. Yalnızca bilgi amaçlıdır; Chargeless bu değerle hiçbir zaman para birimi dönüştürmez;
    • isteğe bağlı attributes.
  • Abonelik (Subscription):

    • subscription_ref; customer_ref;
    • phase: trial, active, grace, past_due, paused, canceled veya expired. canceled ve expired nihai durumlardır;
    • cancel_at_period_end;
    • current_period_end veya null; trial_end veya null;
    • billing_interval, {unit, count} biçiminde;
    • plan_ref veya null;
    • renewal_count;
    • created_at;
    • last_charge veya null, {transaction_ref, at, amount} biçiminde;
    • isteğe bağlı attributes;
    • revizyon 1.2, isteğe bağlı (yoksa null sayılır): canceled_at, ended_at, price (billing_interval başına) ve plan_name (en fazla 120 karakter). İşletme panelinde gösterilir ve analiz için saklanır; hiçbir kararda kullanılmaz. İsteğe bağlı olmaları denetimin gevşek olduğu anlamına gelmez: geçersiz bir değer (120 karakteri aşan bir plan_name, hatalı biçimde bir canceled_at ya da ended_at), diğer tüm alanlarda olduğu gibi okumanın tamamını başarısız kılar.
  • İade isteği: transaction_ref, amount (ödemenin para biriminde, en az 1 en küçük birim), reason ve dry_run.

  • İade sonucu:

    • idempotency_key: alındığı gibi; yalnızca deneme çalıştırmasında (dry run) null;
    • status: succeeded, pending veya would_succeed;
    • transaction_ref ve amount: istekteki gibi;
    • refund_ref veya null;
    • processed_at: succeeded durumunda zorunludur.
  • İptal isteği: at_period_end, reason ve dry_run.

  • İptal sonucu:

    • idempotency_key;
    • status;
    • subscription_ref ve at_period_end: istekteki gibi;
    • effective_at: succeeded durumunda zorunludur; deneme çalıştırmasında ya da sonuç beklenirken null.
  • Operasyon (get_operation): idempotency_key ve status (unknown, pending, succeeded veya failed). Diğer alanlar duruma göre değişir:

    Durum Ek olarak taşıdığı alanlar
    unknown başka alan yok
    pending veya succeeded operation, target_ref, result, updated_at
    ret nedeniyle failed operation, target_ref, refusal: {code, message}, updated_at
    geri alma nedeniyle failed operation: refund, target_ref, result, reversed_at, updated_at
  • attributes: [a-z][a-z0-9_]{0,39} kalıbına uyan en fazla 20 anahtar. Her değer en fazla 200 karakterlik bir dize, bir tamsayı ya da bir boolean'dır. Politikanızın kuralları bu alanları okuyabilir; bir modele ya da müşteriye hiçbir zaman gösterilmezler. İçlerine iletişim ya da kart verisi koymayın.

  • reason: duplicate, forgot_to_cancel, unrecognized, not_as_described, service_issue veya other değerlerinden biri. Yalnızca sizin muhasebe kayıtlarınız içindir ve operasyonun ne yaptığını hiçbir zaman değiştirmez. Değer listesi kapalı değildir; bilinmeyen bir değeri other olarak değerlendirin.

get_customer, list_transactions, get_transaction ve get_subscription bilinmeyen bir nesne için 404 döndürür. Her yanıt istenen nesneye ait olmalı; list_transactions'ın her öğesi de istenen müşteriye ait olmalıdır. list_payment_attempts bu okumalardan biri değildir: yetenek yoksa 404 döndürün; yetenek varsa boş bir sayfa 200 ile döner.

Ödeme Denemeleri (İsteğe Bağlı, Revizyon 1.1)

payment_attempts'ı yalnızca işlemcinizin bildirdiği tüm kart denemelerini (başarılı, başarısız ve hâlâ bekleyen) listeleyebiliyorsanız beyan edin. Chargeless bunları ödeme içgörüleri sayfasında kullanır (ülke, kart markası, kart türü (funding), kartı çıkaran banka ve BIN kırılımları ile yalnızca bildirim gönderen izleyiciler). Bu veriler hiçbir zaman bir iade ya da iptal kararına girmez ve bir model onları hiçbir zaman görmez.

  • Sorgu, POST /v1/payment-attempts/list isteğinin imzalı gövdesidir (sorgu parametresi kullanılmaz): updated_since (RFC 3339, zorunlu, sınır dahil), cursor (isteğe bağlı, önceki sayfanın next_cursor değeri) ve limit (1–200, varsayılan 100).
  • Sıralama. updated_at değeri updated_since'e eşit ya da ondan sonra olan denemeleri (updated_at, attempt_ref) sırasına göre artan biçimde, en fazla limit kadar döndürün. next_cursor yalnızca ve her zaman has_more true olduğunda bulunur; devamı olduğunu bildiren bir sayfada en az bir deneme yer alır. İmleç (cursor) opaktır; sözleşmenin imleç alfabesinden 1–512 karakterden oluşur ve aynı updated_since için en az 24 saat geçerli kalmalıdır. Bilinmeyen ya da süresi dolmuş bir imleç için 400 invalid_request döndürün: Chargeless bu durumda kendi başlangıç sınırından imleçsiz olarak yeniden okur. İlk sayfada (imleçsiz) gelen bir 400 ise süresi dolmuş imleç değil, reddedilmiş bir istek olarak değerlendirilir.
  • Bir deneme, tek bir attempted_at. attempt_ref deneme boyunca değişmez. attempted_at hiçbir zaman değişmez: aynı deneme için farklı bir attempted_at içeren sonraki bir bildirim sözleşme ihlalidir. Başka bir şey değiştiğinde (bekleyen bir denemenin sonuçlanması, bir kodun eklenmesi gibi) updated_at'i daha ileri bir zamana, attempted_at'e eşit ya da ondan sonra olacak şekilde ayarlayın ve değişikliğin 60 saniye içinde bu okumada görünmesini sağlayın. succeeded ve failed durumları ise bir kez ulaşıldıktan sonra değişmemelidir.
  • Her denemenin içeriği. Tüm anahtarlar bulunur; bilmediğiniz bir değer null'dır. status: succeeded, failed veya pending. amount: denenen tutar, denenen para biriminde. card: kartsız bir denemede null; aksi halde brand, network, funding (credit, debit, prepaid veya unknown), country, bin (6–8 hane, asla daha fazla değil), pan_length (12–19 ya da null), last4, issuer (en fazla 200 karakter, kontrol karakteri içermez), wallet ve three_ds_result alanlarını içerir. failure_category başarısız denemeler dışında null'dır; başarısız bir denemede de null olabilir, bu durumda Chargeless onu ret kodlarından türetir. Ret (decline), ağ reddi (network decline) ve tavsiye (advice) kodları en fazla 64 karakterdir. risk.score 0–99 arasında ya da null'dır. Konum bilgisi olarak yalnızca billing_country ve ip_country bulunur.
  • Kart numarası asla yer almaz. Hiçbir alanda PAN, son kullanma tarihi, güvenlik kodu, kart sahibinin adı, e-posta, posta adresi ya da IP adresi bulunmamalıdır. 13 veya daha fazla rakamdan oluşan bir dizi içeren (aralarında en fazla üç karakterlik ayırıcılar olsa da) bir referans, kod ya da imleç card_number_in_field olarak reddedilir. Chargeless bin'i kısaltarak saklar: yalnızca pan_length 16 veya üzerindeyse 8 hane, aksi halde 6 hane; issuer değerini de saklamadan önce içindeki kart numarası benzeri dizileri maskeler.
  • Hız. Chargeless sayfaları hiçbir zaman paralel değil, art arda okur: canlıya geçişte geriye dönük 13 ay, ardından çalışma alanı başına dakikada en fazla 10 sayfa (X-SR-Channel: system, her senkronizasyon çalıştırması için tek bir korelasyon kimliği). Hızı düşürmek için Retry-After ile 429 yanıtı verin. Buradaki korelasyon kimliği bir işlemin ya da talebin değil, senkronizasyon çalıştırmasının kimliğidir.
  • Yetenek yoksa operasyon hiç çağrılmaz. 1.0 sürümündeki bir describe geçerliliğini korur.

Para

  • amount_minor, para biriminin ISO 4217'deki en küçük biriminde ifade edilen bir JSON tamsayısıdır (üs: JPY 0, KWD 3, diğerlerinin çoğu 2). Kendi kuralınızı değil, her zaman ISO üssünü kullanın.
  • 1999 geçerlidir. 1999.0, 19.99, 1.999e3, "1999" ve negatif tutarlar, değer tam sayı olsa bile reddedilir.
  • currency, en küçük birimi tanımlı, büyük harfle yazılmış ve yürürlükte olan bir ISO 4217 kodudur. Değerli metaller, fon kodları, test kodları ve yürürlükten kalkmış kodlar (örneğin 2026-01-01'den beri BGN) reddedilir.
  • Chargeless önce para birimlerini, sonra tutarları karşılaştırır. Bir sonuç, isteğin tutarını ve para birimini birebir aynı şekilde geri döndürmelidir.

Boyutlar ve Süre Sınırları

Ne Sınır
Zaman aşımlarımız Okumalar, describe ve get_operation için 5 sn; değişiklik yapan çağrılar (mutation) için 20 sn
Yanıt gövdesi 1 MiB
Referans 1 ila 128 karakter (bölüm 7)
find_customers adayları 10
list_transactions 50 ödeme ve 50 abonelik
Bir ödemedeki refunds[] 100
prior_refunds, prior_chargebacks Her biri 50, son 365 gün
Bir müşterinin emails, phones alanları Her biri 10
Bir müşteri, ödeme veya abonelikteki attributes 20 girdi
describe para birimleri 200
list_payment_attempts sayfası 200 deneme
description 200 karakter
Hata message alanı 500 karakter
Bir sayı 32 karakter, üs ±400 içinde (1e400)
İç içe yapı 64 düzey nesne ve dizi
Diğer tüm diziler ve nesneler (eklediğiniz alanlar dahil) 256 öğe veya üye

Chargeless her yanıtı yayımlanmış şemalara göre doğrular ve her değeri ayrıca kodda yeniden denetler. Tanımadığı alanları yok sayar; böylece sonraki bir 1.x revizyonuna göre verilmiş bir yanıt da çalışır. Her özellik yalnızca bir kez yer almalı ve şemadakiyle birebir aynı yazılmalıdır: tekrarlanan bir anahtar ya da yalnızca büyük/küçük harf farkı olan bir anahtar (Status, CARD_LAST4) yanıtın tamamını geçersiz kılar.

Chargeless, yanıtı doğrulamadan önce yukarıdaki boyut sınırlarını okuma sırasında uygular. Bu sınırlar tanımadığı alanlar için de geçerlidir: yanıtın herhangi bir yerindeki 257 öğeli ek bir dizi, 257 alanlı ek bir nesne ya da 65 düzeylik iç içe yapı yanıtın tamamını geçersiz kılar; şema kabul etse bile 33 karakterlik bir sayı ya da 1e401 de aynı sonucu doğurur. Böyle bir yanıt sözleşme ihlalidir (schema_invalid; MCP üzerinden float64'e sığmayacak kadar büyük bir sayı daha erken bir aşamada mcp_protocol olarak reddedilir). Her geçersiz yanıtta olduğu gibi güvenli tarafta kalınır (fail closed): okuma başarısız olur; iade ya da iptal ise get_operation sonucu doğrulayana kadar bilinmeyen sonuç olarak ele alınır (bölüm 5). Müşteriye hizmet eden bir çağrıda ayrıca Sözleşme ihlali uyarısı açılır (bölüm 3). Şemaların izin verdiği her değer bu sınırların içinde kalır: bir tutar en fazla 20 karakterlik bir tamsayıdır; Go, JavaScript ve Python da her float64 değerini 24 karakter veya daha kısa yazar.

Tablodaki dizi ve eşlem (map) sınırları, şemaların bunları tanımladığı yerlerde geçerlidir. Diğer tüm dizi ve nesnelere 256'lık genel sınır uygulanır; sonraki 1.x revizyonlarının yeni alan eklediği tanımlı nesnelerin alanları da buna dahildir.

3. Kimlik Doğrulama ve İmzalama

İmza (Her Zaman)

Her istek X-SupportRoute-Timestamp (Unix saniyesi) ve X-SupportRoute-Signature: v1=<hex> başlıklarını taşır. Onaltılık (hex) değer, imzalama anahtarınızla (signing secret) hesaplanan küçük harfli HMAC-SHA256 değeridir; girdi, satır sonuyla (\n) birleştirilmiş altı alandır:

text
{timestamp}\n{METHOD}\n{host}\n{path}\n{idempotency_key}\n{body}
Alan Değer
timestamp Gönderildiği haliyle X-SupportRoute-Timestamp başlığı
METHOD Büyük harfle: GET veya POST
host Gönderildiği haliyle authority (host ve port), küçük harfle; :port yalnızca port varsayılan değilse yer alır. Canlı ortamdaki bir çağrı billing.example.com değerini imzalar. Host başlığını yeniden yazan bir proxy arkasındaysanız, herkese açık host adınızla doğrulayın
path Gönderildiği haliyle yol: temel yol dahil, yüzde kodlaması (percent-encoding) gönderildiği gibi, sorgu dizesi hariç
idempotency_key Gönderildiği haliyle Idempotency-Key başlığı; başlık yoksa (okumalar, get_operation, deneme çalıştırmaları) boş dize. Boş dize, boş bir satır olarak kalır
body Ham istek baytları; gövdesiz bir istekte boş

Bir isteği doğrulamak için:

  1. herhangi bir ayrıştırma yapmadan önce HMAC'i aldığınız baytlar üzerinden hesaplayın;
  2. sabit zamanlı (constant-time) karşılaştırma yapın;
  3. eksik ya da yanlış imzayı ve saatinizden 5 dakikadan fazla sapan zaman damgasını 401 ile reddedin.

Sözleşme kontrolü, yanlış anahtarla imzalanmış bir describe isteği ve 10 dakika önce doğru imzalanmış bir describe isteği gönderir. İkisi de reddedilmelidir (bölüm 10).

python
import hmac, hashlib, time

def verify(secret, ts, method, host, path, idem_key, body, header):
    if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
        return False
    msg = b"\n".join([ts.encode(), method.upper().encode(), host.lower().encode(),
                      path.encode(), idem_key.encode(), body])
    want = "v1=" + hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest()
    return hmac.compare_digest(want, header)

Test vektörü (diğerleri OpenAPI dosyasında x-supportroute-test-vectors altındadır):

text
secret     srmp_test_4f7c1e9a2b6d
timestamp  1760520000
method     POST
host       billing.example.com
path       /v1/refunds
key        0199a3c1-0a0b-7c0d-8e0f-101112131415:ticket:0199e2c4-5b6a-7c8d-9e0f-a1b2c3d4e5f6:refund:0199e2c4-7777-7c8d-9e0f-a1b2c3d4e5f6
body       {"transaction_ref":"ch_1001","amount":{"amount_minor":2000,"currency":"USD"},"reason":"service_issue","dry_run":false}
signature  v1=1b03ea29388ff9f1dd2bbf894f1e6e359f0fa1003ca246c678ad485249503070

Host imzaya dahil edilir; böylece bir uç noktaya (test ortamınıza ya da kontrol edilen yeni bir URL'ye) gönderilen istek hiçbir zaman başka bir uç noktada doğrulanmaz. Idempotency anahtarı da imzaya dahildir; böylece hiçbir aracı onu değiştiremez.

Üç Gizli Anahtarınız

Üçünü de Chargeless üretir ve Ayarlar → Ödeme sağlayıcısı sayfasında yalnızca bir kez gösterir. Kaydetme işlemini çalışma alanınızın bir sahibi (owner), yöneticisi (admin) ya da geliştiricisi (developer), doğrulama uygulamasından aldığı kodla yapabilir.

Önek Ad Kullanımı
srmp_ İmzalama anahtarı Chargeless canlı ortamdaki her çağrıyı bununla imzalar. Bağlantıyı ilk kaydettiğinizde üretilir. Yeni anahtar önce hazırlanır, siz dağıtırsınız, ardından etkinleştirilir (aşağıda)
srmps_ Test ortamı imzalama anahtarı Bununla yalnızca uyumluluk kiti imzalar (bölüm 10). Yalnızca test ortamınızda (sandbox) tanımlayın: canlı uç noktanız bu anahtarı reddetmelidir. İlk kayıtta ve talep ettiğinizde yeniden verilir. Chargeless bu anahtarı saklamaz
srmpc_ Geri çağrı anahtarı Sonuç geri çağrılarını bununla siz imzalarsınız (bölüm 8). Geri çağrıları ilk açtığınızda ve her yenilemede üretilir. Yenilemeden sonra önceki anahtar 7 gün boyunca ya da siz kullanımdan kaldırana kadar çalışmaya devam eder

Bir Gizli Anahtarı Yenilemek

İmzalama anahtarı üç adımda yenilenir. Chargeless son adıma kadar her çağrıyı mevcut anahtarla imzalamaya devam eder.

  1. Hazırlayın. Ayarlar → Ödeme sağlayıcısı → İmzalama anahtarı → "Yeni gizli anahtar hazırla". Yeni srmp_ anahtarı bir kez gösterilir. Uç noktanız için henüz hiçbir şey değişmez.

  2. Dağıtın. Doğrulayıcınızın iki anahtarı da kabul etmesini sağlayın ve yeni anahtarı dağıtın.

  3. Etkinleştirin. "Etkinleştir", tüm çağrıları yeni anahtarla imzalayarak sözleşme kontrolünü (bölüm 10) çalıştırır.

    • Kontrol geçerse Chargeless bundan sonra yeni anahtarla imzalar.
    • Uç noktanız yeni anahtarı reddederse hiçbir şey değişmez ve rapor başarısız satırları gösterir. Dağıtılmamış bir anahtar describe adımında başarısız olur.

    Etkinleştirdikten sonra en az 10 dakika boyunca eski anahtarı da kabul etmeye devam edin; böylece o sırada süren çağrılar eski anahtarla tamamlanabilir. Ardından eski anahtarı kaldırın.

  • Hazırlanan anahtarın süresi dolmaz. Yeniden hazırlarsanız yenisi onun yerini alır. "Vazgeç" onu siler; Chargeless o anahtarla hiç imza atmamıştır.
  • Etkinleştirme bir sözleşme kontrolüdür. Acil durdurma açıkken çalışmaz ve 10 dakikada 10 kontrol sınırından düşülür. Kontrol sürerken acil durdurma devreye girerse etkinleştirme reddedilir.
  • Etkinleştirme, bağlantınızın yapılandırma sürümünü değiştirir. Chargeless'ın etkinleştirmeden önce gönderdiği bir işlem unknown yanıtı alırsa yeniden gönderilmez; yoklama (polling) sonucu yine de doğrular (bölüm 5).
  • "Hemen yenile" sızdırılmış bir anahtar içindir. Yeni anahtar kontrol yapılmadan hemen geçerli olur ve hazırlanmış anahtarı iptal eder. Siz yeni anahtarı dağıtana kadar uç noktanız Chargeless'ın çağrılarını 401 ile reddeder ve bu çağrıların hizmet ettiği vakalar ekibinize devredilir.

Geri çağrı anahtarı bir geçiş süresiyle yenilenir. "Geri çağrı anahtarını yenile" yeni srmpc_ anahtarını bir kez gösterir. Önceki anahtar 7 gün boyunca ya da siz onu kullanımdan kaldırana ("Kullanımdan Kaldır") kadar geri çağrılarınızı doğrulamaya devam eder; yeni anahtarı bu süre içinde dağıtın.

  • "Hemen yenile (eskisini kullanımdan kaldır)", sızdırılmış bir anahtar için önceki anahtarı aynı adımda kullanımdan kaldırır.
  • Aynı anda en fazla iki geri çağrı anahtarı geçerlidir; bu yüzden yeni bir yenileme, hâlâ geçerli olan önceki anahtarı kullanımdan kaldırır.
  • Bölüm 10'daki doğrulanmış test olayı olarak yalnızca mevcut anahtarla imzalanmış bir geri çağrı sayılır.

Gizli anahtarları kim değiştirebilir? Her anahtar değişikliği, doğrulama uygulaması koduyla onay veren bir sahip, yönetici ya da geliştirici gerektirir. Hazırlanmış bir imzalama anahtarından vazgeçmek ve önceki bir geri çağrı anahtarını kullanımdan kaldırmak yalnızca erişimi kısıtlar; bu yüzden ikisi de Chargeless çalışma alanınızı askıya almışken de yapılabilir.

Kendi kimlik bilgileriniz (aşağıdaki bearer token ve edge başlıkları) kaydettiğiniz anda geçerli olur. Yeni değeri önce kendi tarafınızda kabul edilir hale getirin, sonra kaydedin.

İsteğe Bağlı Kimlik Bilgileri

  • Bearer token. Chargeless için oluşturduğunuz ve her çağrıda Authorization: Bearer <token> olarak gönderilen bir token. Hiçbir zaman imzanın yerini tutmaz.
  • Edge başlıkları. Kendi zero-trust edge katmanınızın ya da tünelinizin istediği, her çağrıda gönderilen en fazla 3 başlık.
    • Adlar: [A-Za-z0-9-] karakterlerinden 1 ila 64 karakter. Şu adlar ayrılmıştır: Authorization, Host, Accept, User-Agent, Idempotency-Key, Content-*, X-SupportRoute-*, X-SR-*, MCP üzerinden ayrıca Mcp-* ve Last-Event-ID.
    • Değerler: en fazla 1.024 yazdırılabilir ASCII karakter.
  • Kimlik bilgileri yalnızca kendi host'larına gönderilir. Temel URL'yi başka bir şemaya, host'a ya da porta taşıdığınızda bearer token'ı ve edge başlıklarını aynı kayıtta yeniden girin ya da temizleyin. Kayıtlı bir kimlik bilgisi hiçbir zaman yeni bir host'a gönderilmez.

Ağ

  • Uç noktanız.
    • Temel URL, 443 portunda https://host[/base path] biçimindedir; host adı herkese açık olmalı, sertifika da herkesçe güvenilen bir sertifika otoritesinden (CA) alınmış olmalıdır. TLS 1.2 veya üstü.
    • URL'de sorgu dizesi, parça (fragment) ya da kullanıcı bilgisi bulunmaz.
    • Çağrılar yönlendirmeleri hiçbir zaman izlemez: 3xx yanıtı verirseniz çağrı başarısız olur.
  • Çıkış IP adresleri.
    • Çağrılar Chargeless'ın yayımladığı IPv4 adreslerinden gelir: test ortamında bir, canlı ortamda üç adres; her ortamın kendi listesi vardır. Bağlandığınız ortamın tüm adreslerini izin listesine ekleyin.
    • Listeyi Ayarlar → Ödeme sağlayıcısı sayfasının Çıkış IP adresleri bölümünden kopyalayın; duyurulan yeni bir adres de kullanılmaya başlanmadan önce orada görünür.
    • Değişiklikler en az 30 gün önceden panelde ve sahiplerinize ve yöneticilerinize e-postayla duyurulur.
    • Liste yalnızca size kimlerin ulaşabileceğini sınırlar: imzayı her durumda ayrıca doğrulayın.
  • mTLS (isteğe bağlı).
    • "İstemci sertifikası (mTLS)" seçeneğini açtığınızda Chargeless, ortama özel istemci sertifikasını sunar; sertifikanın konusu (subject) O=Chargeless, CN=supportroute-<env>-egress'tir.
    • İstemci sertifikasının kendisini değil, Çıkış bölümünde gösterilen CA'yı sabitleyin (pin). İstemci sertifikası her yıl duyuru yapılmadan yenilenir; CA değişikliği ise en az 90 gün önceden duyurulur.
    • Sertifika, çağrının Chargeless'tan geldiğini gösterir. Hangi Chargeless çalışma alanının çağırdığını ise imza gösterir; bu yüzden mTLS kullansanız da kullanmasanız da imzayı doğrulayın.

Korelasyon

Her çağrı aşağıdaki başlıkları taşır. Bunları loglayın; panelin sağlayıcı çağrı kaydı (Ayarlar → Ödeme sağlayıcısı, 90 gün saklanır) aynı kimlikleri gösterir.

Başlık Değer
X-SR-Request-Id Her deneme için yeni bir UUID
X-SR-Correlation-Id Değişiklik yapan çağrılarda işlem kimliği; diğerlerinde çağrının hizmet ettiği vaka, talep ya da sohbet oturumu. list_payment_attempts için ilgili senkronizasyon çalıştırmasının kimliği
X-SR-Channel chat, ticket, helpdesk, staff veya system. Bilinmeyen bir değeri system olarak değerlendirin
X-SR-External-Ticket Kaynak bir yardım masası talebiyse, yardım masasındaki talep kimliği

User-Agent değeri Chargeless (merchant-provider/v1)'dir. Kimlik bilgisi değildir.

Sağlayıcı Uyarıları

Chargeless sisteminize yaptığı çağrıları kendisi izler. Her dakika, müşterilere hizmet eden çağrıların (bir işlem, vaka, talep ya da sohbet için yapılan çağrılar) son 15 dakikasını değerlendirir. Şu durumlarda uyarı açar:

Uyarı Ne zaman açılır Ne zaman kapanır
Kimlik bilgileri reddedildi Tek bir çağrı 401 veya 403 ile reddedildiğinde. Ödeme denemesi senkronizasyonları da sayılır Sonraki bir çağrı başarılı olduğunda ya da son retten sonra bir sözleşme kontrolü geçtiğinde. Bunlar olmazsa, 24 saat boyunca yeni ret gelmediğinde
Sözleşme ihlali Tek bir yanıt sözleşmeye uymadığında: doğrulamadan geçmediğinde (bölüm 2) ya da 409 idempotency_conflict olduğunda 24 saat boyunca yeni bir ihlal olmadığında
Sağlayıcıya ulaşılamıyor En az 5 çağrı 5xx, 429, zaman aşımı, bağlantı hatası ya da yönlendirme nedeniyle başarısız olduğunda ve bunlar penceredeki çağrıların en az dörtte biri olduğunda Üst üste iki değerlendirmede oran sekizde birin altında kaldığında ve en az bir çağrı başarıyla tamamlandığında. Bunlar olmazsa, 24 saat boyunca başarısız çağrı olmadığında
  • Hiçbir zaman sayılmayanlar. Sözleşme kontrolünün kendi çağrıları hiçbir zaman uyarı açmaz: raporları kontrolü çalıştıran kişiye gider. Chargeless'ın kendi tarafındaki zaman aşımları da sayılmaz. Böyle bir çağrı, çağrı kaydında validation_busy ayrıntısıyla timeout olarak, özet sayımlarda ise "Meşgul (Chargeless)" olarak görünür: Chargeless yanıtınızı zamanında okuyamamıştır. Bu durumda okuma, zaman aşımındaki gibi başarısız olur; iade ya da iptalin sonucu ise anahtarıyla doğrulanır (bölüm 5).
  • Kimler bilgilendirilir?
    • E-posta, çalışma alanınızın etkin ve doğrulanmış sahiplerine, yöneticilerine ve geliştiricilerine gider. Bir uyarı açıldığında e-posta alırlar; aynı anda açılan uyarılar tek e-postada birleştirilir. Her uyarı için en fazla bir e-posta gönderilir ve aynı türden bir uyarı için 6 saat içinde yeniden e-posta gönderilmez.
    • Chargeless çalışma alanınızı askıya aldığı sürece e-posta gönderilmez. Çalışma alanı yeniden etkinleştiğinde hâlâ açık olan uyarılar o zaman e-postayla bildirilir.
    • Panel; açık uyarıları, son 7 günde kapanan uyarıları ve son 24 saatteki çağrıların sonuca göre dağılımını Ayarlar → Ödeme sağlayıcısı → Sağlayıcı sağlığı bölümünde gösterir. Ayarlar menüsünde bir rozet, Ana Sayfa'da bir banner görünür.
    • Her uyarı, loglarınızda arayabilmeniz için onu tetikleyen çağrılardan en fazla 3'ünün istek kimliğini (X-SR-Request-Id) gösterir.
    • Sağlayıcı sağlığı, retryable bayrağı durum koduyla uyuşmayan hata yanıtlarını da sayar (bölüm 5). Bunlar sapma olarak kaydedilir, hiçbir zaman uyarı açmaz.
  • Uyarılar yalnızca bilgilendirir. Chargeless bir uyarı nedeniyle bağlantınızı hiçbir zaman duraklatmaz, yeniden deneme davranışını değiştirmez, bir devri kaydırmaz ya da herhangi bir karar vermez. Reddedilen ya da hatalı bir çağrı tam olarak bölüm 5'te anlatıldığı gibi sonuçlanır.
  • İzleme. Bir izleme sistemi aynı durumu çalışma alanınızın API anahtarlarından biriyle yoklayabilir: sr.cases.v1.CasesService/GetProviderHealth. Yanıt en fazla 30 saniye eski olabilir ve çalışma alanınızdaki tüm çağıranlar aynı yanıtı paylaşır; bu yüzden daha sık yoklamak aynı yanıtı döndürür. resource_exhausted yanıtı, kısa bir süre bekleyip yeniden denemeniz gerektiğini belirtir.

4. Idempotency

  • Anahtar. Deneme çalıştırması olmayan her refund ve cancel_subscription çağrısı Idempotency-Key: {workspace_id}:{action key} başlığını taşır; anahtar [A-Za-z0-9:_-] karakterlerinden en fazla 255 karakterdir, örneğin 0199a3c1-…-101112131415:ticket:0199e2c4-…:refund:0199e2c4-…. Önek, tek bir uç nokta birden fazla Chargeless çalışma alanına hizmet ettiğinde anahtarların benzersiz kalmasını sağlar.
    • Anahtarı opak kabul edin: bütün olarak, bayt bayt saklayın ve karşılaştırın.
    • Deneme çalıştırması olmayan ve anahtar taşımayan bir değişiklik çağrısına 400 invalid_request yanıtı verilir.
  • Aynı anahtar, aynı parametreler. İlk sonucu döndürün ve işlemi hiçbir zaman iki kez gerçekleştirmeyin. Operasyonun güncel durumunu döndürmek de olur; örneğin ilk çağrıda pending olan bir iade için succeeded.
  • Aynı anahtar, farklı parametreler. idempotency_conflict koduyla 409 yanıtı verin ve hiçbir şey gerçekleştirmeyin. Chargeless bunu nihai kabul eder ve güvenlik olayı olarak kaydeder.
  • İlk çağrı sürerken aynı anahtar. in_progress koduyla 409 yanıtı verin. Chargeless aynı anahtarla yeniden dener.
  • Ödeme başına değil, anahtar başına. Aynı ödemede bilinçli olarak yapılan ikinci bir kısmi iade farklı bir anahtarla gelir.
  • İzlenebilirlik. Sözleşme üzerinden yapılan bir iadenin anahtarı, ödemenin refunds[] listesinde ve müşterinin prior_refunds listesinde alındığı haliyle görünür. Chargeless kendi iadelerini bu sayede yalnızca bir kez sayar.
  • Anahtarları en az 30 gün saklayın. get_operation, bu süre içinde aldığınız her anahtar için yanıt verebilmelidir.
  • Deneme çalıştırmaları ("dry_run": true) anahtar taşımaz. Tam doğrulamadan geçer, would_succeed ya da bir retle yanıtlanır; hiçbir şeyi değiştirmez ve hiçbir şey saklamaz. Bunları yalnızca sözleşme kontrolü ve uyumluluk kiti gönderir; karar akışı hiçbir zaman göndermez.
  • Chargeless'ın yeniden denemeleri. Chargeless tek bir çağrı içinde aynı anahtarla ve her seferinde yeni bir X-SR-Request-Id ile en fazla 3 deneme yapar. Bağlantı hatası, 429, 5xx ya da 409 in_progress sonrasında, bekleme süresini 200 ms'den 2 sn'ye kadar artırarak yeniden dener. Retry-After değerine (saniye cinsinden) 2 sn'ye kadar uyar; daha uzun bir bekleme sonraki bir yeniden denemeye bırakılır. Zaman aşımına uğrayan bir değişiklik çağrısı aynı çağrı içinde hiçbir zaman yeniden denenmez: sonucu bilinmez ve Chargeless onu anahtarıyla doğrular (bölüm 5).

5. Sonuçlar ve Nihailik

Chargeless Yanıtınızı Nasıl Yorumlar

Yanıtınız Okumada Değişiklik çağrısında
Geçerli gövdeli 2xx (201 ve 202, 200 olarak değerlendirilir) Değer succeeded veya pending
Gövdesi geçersiz olan ya da anahtarı, hedefi veya tutarı aynen döndürmeyen 2xx Başarısız (sözleşme ihlali) Bilinmeyen sonuç; get_operation ile doğrulanır
400 invalid_request Nihai başarısızlık Nihai: yeniden denenmez, vaka ekibinize devredilir
401 / 403 credentials_rejected Nihai başarısızlık Nihai, yukarıdaki gibi
404 not_found Bulunamadı Koruma sınıfı ret (bölüm 6)
409 idempotency_conflict — Nihai, hiçbir şey gerçekleştirilmez
409 in_progress — Yeniden denenir, ardından bilinmeyen
Ret kodlu 422 — Ret (bölüm 6)
429, 5xx, zaman aşımı, bağlantı hatası Yeniden denenir, ardından başarısız Yeniden denenir, ardından bilinmeyen
3xx, diğer tüm durum kodları, okunamayan hata gövdesi Başarısız Bilinmeyen

Hatalar {"error": {"code", "message", "retryable"}} zarfıyla döner. retryable durum koduyla tutarlı olmalıdır; 422'de her zaman false'tur:

  • 400, 401, 403, 404, 409 idempotency_conflict ve 422 için false;
  • 409 in_progress, 429 ve 5xx için true.

Chargeless yalnızca durum koduna göre davranır: tutarsız bir bayrak sonucu, yeniden denemeyi ya da ret sınıfını hiçbir zaman değiştirmez. Bayrak her hata yanıtında kaydedilir ve çağrı kaydı tutarsızlığı gösterir. Sözleşme kontrolü ve kit, bilerek tetikledikleri hatalarda daha katıdır (bölüm 10): durum koduyla tutarsız ya da eksik bir bayrak o satırı retryable_mismatch ile başarısız kılar. Canlı trafikte eksik bayrak yalnızca kaydedilir ve çağrı kaydında tire olarak görünür.

Bir deneme size ulaşmış olabiliyorsa sonuç açık kalır. Sonucu yalnızca sonraki bir denemede gelen geçerli bir 2xx ya da okunabilir bir ret kesinleştirir. Bir yeniden denemede gelen 400, 401 ya da zaman aşımı önceki denemenin ne yaptığını göstermez; bu yüzden Chargeless bunun yerine get_operation ile sorgular. Daha önce gerçekleştirdiğiniz bir anahtara hiçbir zaman 401 ya da başka bir yanıt vermeyin: sonucunu aynen yeniden döndürün.

Kabul Ettiğiniz Nihailik Koşulları

  1. succeeded ve failed bir anahtar için nihaidir. Ret (422) ya da failed, o anahtarla hiç para hareket etmediği ve hiçbir zaman etmeyeceği anlamına gelir.
  2. Sonradan izin verilen tek değişiklik geri almadır (reversal): başarılı bir iadeyi geri almışsınızdır. Bunu get_operation'da reversed_at ve iadenin result değeriyle birlikte failed olarak bildirin. İadeyi, reversed_at dolu olarak ödemenin refunds[] listesinde tutmaya devam edin. Chargeless bundan sonra iadeyi yapılmış olarak göstermez ve ekibinize bildirir. İade ödeme üzerinde sayılmaya devam eder; böylece Chargeless o tutarı kendiliğinden yeniden iade etmez.
  3. unknown yalnızca hiç almadığınız bir anahtar içindir. get_operation hiçbir zaman 404 döndürmez.

Önce failed, sonra succeeded yanıtı veren bir anahtar 1. koşulu ihlal eder. Chargeless başarı yanıtını yok sayar ve sözleşme ihlali kaydeder; bu arada iade edilebilir tutar hesabı ve hız sınırları bildirdiğiniz iadeyi saymaya devam eder. succeeded bir anahtarı geri alma dışında başka bir duruma çevirmek ya da herhangi bir yanıttan sonra unknown döndürmek de ihlaldir.

Yoklama

Açık kalan bir değişiklik çağrısı (pending, zaman aşımına uğramış ya da okunamayan bir yanıt almış) çağrıdan sonra şu takvimle get_operation ile doğrulanır:

  • 30 sn, 2 dk, 10 dk ve 30 dk;
  • ardından 24 saate kadar saatte bir.

Nihai bir yanıt yoklamayı sonlandırır. Sonuç geri çağrısı (bölüm 8) yalnızca bir sonraki okumayı öne çeker.

  • Bu 24 saat içinde unknown. Chargeless değişikliği aynı anahtarla yeniden gönderir; 1. koşul sayesinde bu güvenlidir. İlk denemeden bu yana acil durdurma açılmışsa ya da bağlantı ayarlarınız değişmişse yeniden göndermez; bu durumda vaka ekibinize devredilir.
  • 24 saatten sonra. İşlem doğrulanmamış olarak ekibinize devredilir. İade hâlâ sonuçlanmamış sayılır; böylece hiçbir zaman iki kez iade edilmez. Chargeless ardından 30. güne kadar anahtarı günde bir kez sorgular, geç gelen yanıtı uygular ve bir daha hiçbir şey göndermez.

6. Retler

Ret, refund ya da cancel_subscription çağrısına verilen 422 yanıtıdır:

json
{"error": {"code": "merchant_hold", "message": "Finance hold on this account", "retryable": false}}

Başarısız bir operasyon aynı reddi get_operation yanıtında bildirir. Her kodun bir sınıfı vardır.

Sınıf Kodlar Ne olur
Durum: kayıtlarınız, Chargeless'ın karar verirken dayandığı olgularla çelişiyor already_refunded, amount_exceeds_refundable, not_refundable, subscription_not_active, already_canceled, currency_mismatch İşlem reddedildi (denied) olarak sonuçlanır ve karar kayıtlı kalır. Chargeless hedefi yeniden okur ve müşteriye hazır metinli ret yanıtı gider
Koruma: sizin kendi işlem korumanız account_restricted, merchant_hold, tüm özel x_ kodları, listede olmayan tüm kodlar ve hedef için verilen 404 İşlem başarısız (failed) olarak sonuçlanır ve vaka, kod ve mesajınızla birlikte ekibinize devredilir (gerekçe provider_refused)
  • Özel kodlar, x_ ve ardından [a-z0-9_] karakterlerinden 1 ila 62 karakterden oluşur. Her zaman koruma sınıfındadır.
  • Mesajlar en fazla 500 karakterlik düz metindir. Kart numaraları maskelenerek yalnızca ekip üyelerinize gösterilir; hiçbir zaman bir modele ya da müşteriye gösterilmez. İçlerine kart verisi, iletişim bilgisi ya da gizli bilgi koymayın.
  • Okunamayan bir 422 (zarf yok, tekrarlanan anahtar) ret olarak kabul edilmez: sonuç bilinmeyen olarak kalır ve get_operation ile netleşir.
  • Aşırı iadeler. Sizin hesabınıza göre iade edilebilir tutarı aşan bir iadeyi amount_exceeds_refundable ile reddedin. Hem sözleşme kontrolü hem uyumluluk kiti bunu test eder.

7. Referanslar

Müşteri, ödeme, abonelik, sipariş, plan, iade ve olay kimlikleri aynı kurala uyar:

  • Harf ya da rakamla başlayan; harf, rakam, ., _, : ve - karakterlerinden oluşan 1 ila 128 karakter. Nesnenin ömrü boyunca değişmez; hiçbir zaman e-posta adresi, telefon numarası ya da kart numarası olamaz.
  • 13 veya daha fazla rakamlık dizi bulunamaz; rakamlar ister bitişik olsun ister aralarında ., _, : ve - karakterlerinden en fazla üçü bulunsun, dizinin çevresinde harf olsun ya da olmasın. Kart numaraları 13 ila 19 rakamdan oluştuğu için böyle bir referans, kontrol hanesi ne olursa olsun kart numarası sayılarak reddedilir ve hiçbir zaman saklanmaz.
    • Reddedilenler: 4528730562594, 4242-4242-4242-4242, ord_2026101500012, 112-3456789-1234567.
    • Kabul edilenler: ch_1001, gp.4031-2290, ord-2026-10-15-0001 (12 rakam).
  • İstisna: kanonik UUID'ler. 8-4-4-4-12 biçiminde, tamamı küçük ya da tamamı büyük harfli, sürümü 1 ila 8, varyantı 8, 9, a veya b olan bir UUID, rakamları böyle bir dizi oluştursa bile kabul edilir.
  • Sayısal kimlikler. Bunları base32 (RFC 4648) ya da base62 gibi az rakam içeren bir alfabeyle kodlayın. Önek eklemek işe yaramaz, başka bir onaltılık (hexadecimal) gösterim de: SHA-256 hex özetlerinin yaklaşık 23'te biri böyle bir dizi içerir.

Sözleşme kontrolü test nesnesi referanslarınızı ve okumalarınızın listelediği tüm referansları test eder; uyumluluk kiti de aynısını yapar. Böylece referans sorunları bir müşterinin talebinde değil, canlıya geçişten önce ortaya çıkar.

8. Sonuç Geri Çağrıları (İsteğe Bağlı)

Güvence yoklamadır. Geri çağrı yalnızca Chargeless'a sonucu daha erken okumasını söyler.

  1. Beyan edin. describe içinde "outcome_callbacks": true değerini beyan edin.

  2. Açın. Ayarlar → Ödeme sağlayıcısı sayfasında Sonuç geri çağrıları seçeneğini açın. Geri çağrı anahtarını (srmpc_…, bir kez gösterilir) ve geri çağrı URL'sini (https://<Chargeless's webhook host>/webhooks/merchant/{workspace_id}) alırsınız.

  3. Olay gönderin. Chargeless'ın anahtarlarından biriyle yapılan operasyon değiştiğinde (sonuçlandığında, reddedildiğinde ya da başarılı bir iade geri alındığında) şu gövdeyle POST isteği gönderin:

    json
    {"event_id": "evt_01JAB7Q3W2XKZ8M4N6P0R5S9TV", "type": "operation.updated",
     "idempotency_key": "0199a3c1-0a0b-7c0d-8e0f-101112131415:ticket:0199e2c4-5b6a-7c8d-9e0f-a1b2c3d4e5f6:refund:0199e2c4-7777-7c8d-9e0f-a1b2c3d4e5f6",
     "occurred_at": "2026-10-17T09:41:12Z"}
    • idempotency_key, Chargeless'ın gönderdiği anahtarın birebir aynısıdır.
    • event_id, bölüm 7'deki kurala uyan bir referanstır; her olay için benzersizdir ve o olayın her yeniden denemesinde bayt bayt aynı gönderilir.
    • Gövde durum ya da tutar taşımaz, çünkü bunlar hiçbir zaman uygulanmaz.
  4. İmzalayın. İsteği geri çağrı anahtarıyla, bölüm 3'teki yöntemle imzalayın:

    text
    {timestamp}\nPOST\n{Chargeless's host}\n/webhooks/merchant/{workspace_id}\n\n{body}
    • Anahtar alanı boştur.
    • Başlıklar X-SupportRoute-Timestamp ve X-SupportRoute-Signature'dır.
    • OpenAPI dosyasında iki test vektörü bulunur.

Chargeless ardından isteği sırasıyla şöyle denetler:

  • gövde en fazla 16 KiB'dir;
  • imza, 5 dakikalık zaman damgası toleransıyla doğrulanır;
  • gövde şemaya göre geçerlidir;
  • event_id yenidir (tekrarlar en az 30 gün boyunca atılır).

Ancak bundan sonra anahtar için get_operation çağırır ve gelen yanıtı uygular. Chargeless'ta bulunmayan ya da başka bir çalışma alanına ait bir anahtar kabul edilir ve yok sayılır.

Yanıt Anlamı Ne yapmalı
204 Kabul edildi, tekrar ya da bizde bulunmayan bir anahtar Bir şey yapmanız gerekmez
400 Gövde geçerli bir operasyon olayı değil Göndereni düzeltin; yeniden denemeyin
401 Yanlış ya da eksik imza, tolerans dışı zaman damgası, kapalı geri çağrılar ya da bilinmeyen çalışma alanı. Panel son reddin nedenini gösterir Yeniden denemeden önce mevcut anahtarla yeniden imzalayın. Yenilemenin 7 günlük geçiş süresinde önceki anahtar da geçerlidir (bölüm 3)
413 Gövde 16 KiB'yi aşıyor Yeniden denemeyin
429, 5xx Hız sınırına takıldı ya da kaydedilmedi Aynı gövdeyi ve event_id'yi yeniden imzalayarak, 24 saate kadar üstel geri çekilmeyle (exponential backoff) yeniden gönderin. Retry-After'a uyun

Sınırlar:

  • 30 günden eski anahtarlar için gelen geri çağrılar yok sayılır.
  • İşlem başına en fazla 20 geri çağrı okuması yapılır. Bundan sonra sonucu yalnızca yoklama doğrular.
  • Chargeless tek bir adresten dakikada en fazla 600, tek bir adresten tek bir çalışma alanı için dakikada en fazla 120 geri çağrı kabul eder.
  • Bir adres doğrulanmış bir geri çağrı ilettikten sonra, çalışma alanının doğrulanmış göndericileri dakikada 240'lık ortak bir sınırı paylaşır.
  • Bir geri çağrının yanıtını beklemek için hiçbir şeyi bekletmeyin: kaybolan bir geri çağrının tek maliyeti zamandır.

Geri çağrı, REST ve MCP bağlantılarında aynı şekilde çalışır.

9. MCP Bağlantısı

Sisteminiz REST yerine MCP araçları sunuyorsa, Ayarlar → Ödeme sağlayıcısı sayfasında MCP aktarımını (transport) seçin. Bölüm 1 ila 8'deki her şey geçerlidir; yalnızca iletişim biçimi farklıdır:

  • Aktarım. Temel URL'nizde, /v1/… yolları olmadan, Streamable HTTP üzerinden bir MCP sunucusu çalıştırırsınız; Chargeless istemci tarafındadır. Her deneme kendi oturumunu açar, tek bir tools/call çağrısı yapar ve oturumu kapatır.
  • İmzalama. Oturumdaki her HTTP isteği, anahtar alanı boş bırakılarak bölüm 3'teki gibi imzalanır. Idempotency anahtarı imzalı gövdenin içinde, aracın idempotency_key argümanında taşınır; Idempotency-Key başlığı kullanılmaz.
  • Korelasyon. Bölüm 3'teki kimlikler params._meta içinde taşınır (dev.supportroute/request_id, dev.supportroute/correlation_id, dev.supportroute/channel, dev.supportroute/external_ticket).
  • Sonuçlar. Nesne structuredContent içinde döner ve bir REST gövdesiyle tamamen aynı şekilde doğrulanır. Hata, isError: true taşıyan ve structuredContent değeri hata zarfı olan bir sonuçtur; kodu bir REST durum koduna karşılık gelir. JSON-RPC hatası 5xx sayılır.
  • Şemalar. Profildeki her araç inputSchema ve outputSchema değerlerini sözleşmedeki $id'yi gösteren bir $ref olarak beyan eder. Profil dışındaki araçlar yok sayılır ve hiçbir zaman çağrılmaz.

MCP bağlantısı bağlantının tamamını anlatır: argümanlarıyla birlikte araçlar, gerçek istek ve yanıtlarıyla bir oturum, hata eşlemesi, şema tablosu ve sınırlar ile uyumluluk kitinden geçen, Go ile yazılmış eksiksiz bir sunucu. Örneklerle REST bağlantısı her REST operasyonunu gerçek istek ve yanıtlarıyla, Node ile yazılmış eksiksiz bir sunucuyla birlikte gösterir.

10. Uyumluluğu Kanıtlamak

Canlıya geçiş iki adımdan oluşur ve hiçbiri canlı veride para hareketine yol açmaz.

Adım 1: Test Ortamınızda Uyumluluk Kiti

Uyumluluk kiti providercheck, canlı bir sistemin para hareket ettirmeden gösteremeyeceği davranışları kanıtlar. Önce canlı kontrolün satırlarını, ardından test ortamında gerçek değişiklik çağrılarını çalıştırır. macOS, Linux veya Windows sürümünü providercheck sayfasından indirin; dosyayı nasıl doğrulayacağınız ve çıktıyı nasıl okuyacağınız da orada anlatılır. Dilerseniz Chargeless, test ortamı kimlik bilgilerinizle kiti sizinle birlikte çalıştırabilir.

  1. Test ortamını yapılandırın. Test ortamı imzalama anahtarını (srmps_…) test ortamınıza ve yalnızca oraya tanımlayın.

  2. Yeni test nesneleri seçin. Test ortamında bir müşteri, o müşterinin iade edilebilir bir ödemesini ve cancel_subscription destekliyorsanız o müşterinin etkin bir aboneliğini seçin. Çalıştırma ödemeyi iade eder (partial_refunds ile en küçük birimde 1, aksi halde kalanın tamamı) ve aboneliği iptal eder; bu yüzden her çalıştırmada yeni test nesneleri kullanın.

  3. Kiti çalıştırın. Gizli anahtarlar yalnızca ortam değişkenlerinden okunur.

    sh
    export PROVIDERCHECK_SANDBOX_SIGNING_SECRET=srmps_…
    # optional: PROVIDERCHECK_BEARER_TOKEN=…  PROVIDERCHECK_EDGE_HEADERS='[{"name":"…","value":"…"}]'  (at most 3)
    
    # REST
    providercheck -sandbox \
      -base-url https://sandbox.billing.example.com/supportroute \
      -tenant <your workspace id> \
      -customer cus_… -transaction ch_… -subscription sub_… \
      -out providercheck-report.json
    
    # MCP: the same, with your sandbox's MCP endpoint as -base-url
    providercheck -sandbox -transport mcp \
      -base-url https://sandbox.billing.example.com/mcp \
      -tenant <your workspace id> \
      -customer cus_… -transaction ch_… -subscription sub_… \
      -out providercheck-report.json
  4. Sonucu okuyun.

    • Çıkış kodu 0 tüm kontrollerin geçtiği, 1 bir kontrolün başarısız olduğu, 2 ise çalıştırmanın başlayamadığı anlamına gelir.
    • Her kontrol için bir satır yazdırır; başarısız bir çağrının X-SR-Request-Id değeri de satırda yer alır.
    • Test ortamı anahtarından türetilmiş bir anahtarla mühürlenmiş bir rapor yazar.
  5. Raporu yükleyin. Mühürlü raporu Ayarlar → Ödeme sağlayıcısı → Uyumluluk kiti bölümünden yükleyin: dosyayı seçin, "Bu dosya, kitin bu çalışma alanı için değiştirilmemiş çıktısıdır" kutusunu işaretleyin, ardından "Raporu Beyan Et" düğmesine basın (istenirse ek doğrulamayla (step-up)). Canlıya geçmek için aktarımınıza ait, son 30 gün içinde geçmiş bir rapor gerekir; sonradan aktarımı değiştirmek de aynı şartı taşır. Temel URL ya da mTLS değişikliği için bu gerekmez.

    • Chargeless'ın kaydettikleri. Dosya en fazla 64 KiB olmalı ve kitin yazdığı haliyle bayt bayt değiştirilmemiş olmalıdır. Chargeless dosyanın SHA-256 özetini, kit sürümünü, çalıştırmanın kimliğini ve zamanını, aktarımı, sözleşme sürümünü, test ortamının origin'ini, her satırın adını, sonucunu ve kodunu ve beyanı yapan üyeyi kaydeder. Gösterilen SHA-256 değerini shasum -a 256 providercheck-report.json çıktısıyla karşılaştırın. Dosyanın kendisi saklanmaz; bu yüzden onu siz saklayın.

    • Beyan, üyenizin sözüne dayanır. Chargeless mührü doğrulayamaz: mührün anahtarı, Chargeless'ın saklamadığı test ortamı anahtarınızdan türetilir. Beyan, üyenizin dosyanın kitin çıktısı olduğunu bildirmesidir.

    • cancel_subscription yoksa abonelik kontrolleri (cancel_* satırları ve one_effect_per_call) atlanabilir. Varsa geçmeleri zorunludur. Canlıdaki bir sistem cancel_subscription beyan etmeye başladığında Chargeless henüz yeni bir rapor istemiyor. Yine de kiti bir abonelik test nesnesiyle çalıştırıp o raporu yükleyin.

    • Neler reddedilir? Yükleme şu durumlarda gerekçesiyle birlikte reddedilir:

      • beyan kutusu işaretlenmemişse;
      • dosya okunamıyorsa ya da mühürsüzse;
      • kit providercheck/2'den eskiyse;
      • rapor başka bir çalışma alanına, rest veya mcp dışında bir aktarıma ya da 1.x dışında bir sözleşme sürümüne aitse;
      • çalıştırma 30 günden eskiyse ya da 5 dakikadan fazla ileri tarihliyse;
      • bir satır başarısız olmuşsa ya da bir test ortamı kontrolü eksikse;
      • henüz kaydedilmiş bir bağlantı yoksa.

      Bir çalışma alanı 10 dakikada en fazla 10 dosya yükleyebilir.

Diğer bayraklar:

Bayrak Kullanımı
-client-cert, -client-key mTLS isteyen bir test ortamı için kendi test istemci sertifikanız
-allow-private Düz http üzerinden, farklı bir portta ya da özel (private) bir adreste çalışan bir test ortamı
-settle-timeout pending bir sonucun ne kadar bekleneceği: varsayılan 2 dk, en fazla 30 dk
-v Her çağrıyı loglar

Kitte üç güvenlik önlemi vardır:

  • yalnızca srmps_ anahtarıyla imzalar, srmp_ anahtarını reddeder;
  • -sandbox bayrağı olmadan çalışmaz;
  • Chargeless'ın kendi yapılandırmasının bulunduğu bir ortamda çalışmayı reddeder.

Rapor test ortamınızı origin'iyle tanımlar; bu yüzden kit, raporun taşıyamayacağı bir origin'i ya da test nesnesini daha hiçbir istek göndermeden reddeder:

  • Origin, http(s)://host[:port] biçiminde olmalı; bir DNS adı ya da köşeli parantez içinde bir IPv6 adresi içermeli ve 13 veya daha fazla rakamlık dizi barındırmamalıdır. Rakamları portla birleşince böyle bir dizi oluşturan bir IPv4 adresi (örneğin 192.168.100.200:12112) reddedilir: bunun yerine bir host adı kullanın.
  • Test nesnesi referansları bölüm 7'ye uymalıdır.

Canlı satırlardan sonra çalışan test ortamı kontrolleri:

Kontrol Geçme koşulu
refund_over_refundable Kalanı en küçük birimde 1 aşan gerçek bir iade amount_exceeds_refundable ile reddedilir
refused_key_final Aynı anahtar tekrar gönderildiğinde yine ret döner, get_operation failed yanıtı verir ve hiç para hareket etmez
refund_executes İade bir kez gerçekleştirilir ve refunds[] onu Chargeless'ın anahtarıyla listeler
refund_replay Tekrar gönderim ilk sonucu döndürür ve ek bir iade yapmaz
refund_conflict Aynı anahtar farklı bir tutarla gönderildiğinde 409 idempotency_conflict döner ve hiçbir şey gerçekleştirilmez
cancel_executes, cancel_replay, cancel_conflict Anında iptal için aynı kontroller
cancel_refused_key İkinci bir iptal already_canceled ile reddedilir, tekrar gönderildiğinde yine ret döner ve failed olarak okunur
one_effect_per_call İade aboneliğe, iptal de ödemeye dokunmaz
operation_states Yeniden okunan her anahtar nihai durumunu korur ve hiç gönderilmemiş bir anahtar unknown döner

retryable bayrağı durum koduyla tutarsız olan ya da bayrak içermeyen, bilerek tetiklenmiş bir hata, ilgili satırı retryable_mismatch ile başarısız kılar (bölüm 5). Bilerek tetiklenen hatalar şunlardır:

  • aşırı iade ve tekrar gönderimi (refund_over_refundable, refused_key_final);
  • çakışmalar (refund_conflict, cancel_conflict);
  • reddedilen iptal (cancel_refused_key).

Kit sonuç geri çağrılarını test etmez. MCP üzerinden test ortamı kontrolleri yalnızca araç profili kontrolü geçtikten sonra çalışır.

Adım 2: Canlı Sözleşme Kontrolü

Canlı kontrol, Ayarlar → Ödeme sağlayıcısı → Sözleşme kontrolü → "Kontrolü Çalıştır" ile, kayıtlı yapılandırmanız üzerinde ve Chargeless'ın çıkış adreslerinden çalışır. Canlıya geçiş sırasında kontrol yeniden çalıştırılır; canlıya yalnızca o anda kayıtlı yapılandırma kontrolden geçerse geçilir.

  • Ne yapar? Yalnızca okuma yapar ve deneme çalıştırmaları gönderir. Hiçbir şey iade ya da iptal edilmez.

  • Test nesneleri. Canlı sisteminizde test nesneleri belirleyin ("Test nesneleri"): hareketi az bir müşteri, bir ödeme ve cancel_subscription destekliyorsanız bir abonelik. Test ödemesinde bekleyen bir iade varsa kontrol onu göremez ve kalan tutar için yapılan deneme çalıştırması başarısız olabilir; bu yüzden bekleyen iadesi olmayan bir ödeme seçin.

  • Ne zaman çalışır? Acil durdurma açıkken kontrol çalışmaz. Aynı anda yalnızca bir kontrol çalışır ve 10 dakikada en fazla 10 kontrol çalıştırılabilir.

  • Gecikme. Okumada 2,5 sn'den, deneme çalıştırmasında 10 sn'den yavaş gelen doğru bir yanıt, ilgili satırı latency_budget_exceeded ile başarısız kılar. Her çağrı bir kez ölçülür; bu yüzden soğuk başlatma (cold start) bir satırı başarısız kılabilir: bu durumda kontrolü yeniden çalıştırın.

  • Deneme çalıştırmalarının sırası. Deneme çalıştırmaları en az zararlı olandan başlayarak gönderilir ve her birinden sonra test nesnesi yeniden okunur:

    1. dönem sonunda iptal (cancel_at_period_end ile);
    2. kalanı en küçük birimde 1 aşan bir iade; reddedilmelidir;
    3. en küçük birimde 1 tutarında bir iade (partial_refunds ile);
    4. kalanın tamamı;
    5. anında iptal.

    Kontrol, gördüğü ilk değişiklikte durur (dry_run_changed_state). Deneme çalıştırmalarınızın hiçbir zaman gerçek işlem yapmadığından emin olun.

  • Ne zaman yeniden çalıştırmalı? Canlı bir çalışma alanında aktarım, temel URL ya da mTLS değişikliği kaydedilmeden önce kontrol edilir; aktarım değişikliği ayrıca yeni aktarım için yüklenmiş bir kit raporu gerektirir (adım 1). Hazırlanmış bir imzalama anahtarını etkinleştirmek de kontrolü çalıştırır (bölüm 3). describe'ı değiştirdikten sonra (örneğin yeni bir yetenek eklediğinizde) kontrolü yeniden çalıştırın: Chargeless, en son geçen kontrolün kaydettiği yetenekleri kullanır.

Satır Geçme koşulu Sık görülen hata kodları
reachability TLS bağlantısı kurulur ve yönlendirme olmayan bir HTTP yanıtı alınır timeout, redirect_refused, tls_handshake_failed, dns_failed, connection_failed, private_address
describe 1.x sürümlü, beyanı (attestation) ve bilinen para birimlerini içeren imzalı bir describe yanıtı; ardından yanlış imzalı ve 10 dakika önceki zaman damgalı istekler 401 veya 403 ile reddedilir signature_not_verified, stale_timestamp_accepted, auth_probe_unexpected, schema_invalid
find_customers Test nesnesinin customer_ref değeriyle yapılan arama onu döndürür fixture_not_found, fixture_ref_invalid, card_number_in_field
get_customer Şemaya uygun test müşterisi döner fixture_not_found, schema_invalid
list_transactions Şemaya uygun; listelenen tüm referanslar kabul edilir schema_invalid, card_number_in_field
get_transaction Test ödemesi test müşterisine aittir, describe'ın listelediği bir para birimindedir, refunds[] toplamı tutarı aşmaz; ödeme başarılıdır, itirazlı değildir, refund_route: provider değerine sahiptir ve iade edilecek kalanı vardır fixture_mismatch, currency_not_declared, refunds_exceed_amount, fixture_not_refundable
get_subscription cancel_subscription varsa: test aboneliği test müşterisine aittir ve hâlâ iptal edilebilir fixture_mismatch, fixture_not_cancellable
refund_dry_run Aşırı iade deneme çalıştırması amount_exceeds_refundable ve retryable: false ile reddedilir, diğerleri would_succeed döner ve ödeme değişmez over_refund_not_refused, refusal_code_mismatch, retryable_mismatch, dry_run_refused, dry_run_changed_state
cancel_dry_run cancel_subscription varsa: deneme çalıştırmaları would_succeed döner ve abonelik değişmez dry_run_changed_state
unknown_operation Hiç gönderilmemiş bir anahtar için get_operation unknown döner not_unknown
outcome_callback Geri çağrılar kapalıyken atlanır. Açıkken: describe outcome_callbacks'ı beyan eder ve mevcut srmpc_ anahtarı verildikten sonra bu anahtarla imzalanmış bir geri çağrı doğrulanmıştır. Geri çağrı URL'sine bir test olayı gönderin (herhangi bir anahtarla; bizde bulunmayan bir anahtar kabul edilir ve yok sayılır) capability_not_declared, no_verified_callback
mcp_profile Yalnızca MCP'de, describe'ın hemen ardından: zorunlu her araç ve describe'ın beyan ettiği yeteneklere ait araçlar birer kez ve uyumlu şemalarla listelenir (bölüm 9). Başarısız olursa hiçbir deneme çalıştırması gönderilmez mcp_tool_missing, mcp_tool_duplicated, mcp_schema_incompatible, mcp_schema_too_complex, mcp_tool_list_too_long
payment_attempts Yetenek varsa: son 24 saate ait, şemaya uygun ve doğru sıralı, en fazla 10 denemelik bir sayfa. describe payment_attempts'ı beyan etmiyorsa atlanır schema_invalid, card_number_in_field

11. Referans Test Sağlayıcısını (Fake) Yerelde Çalıştırmak

merchantfake, iki bağlantı türünü de demo verisi ve hata enjeksiyonuyla (fault injection) uygulayan, Chargeless'ın kendi testlerinde kullandığı çalışan bir sağlayıcıdır. Yalnızca geliştirme içindir (SR_ENV=development olmadan başlamaz) ve hiçbir ortama dağıtılmamalıdır. Chargeless kaynak kodunun yerel kopyasında, sr-platform dizininden:

sh
SR_ENV=development FAKEMERCHANT_SIGNING_SECRET=srmps_dev_secret_0123456789 go run ./cmd/fakemerchant
Ne Nerede
REST http://localhost:12112
MCP http://localhost:12112/mcp
Gösterge paneli (müşteriler, ödemeler, devreye alınmış hatalar, gelen çağrılar) http://localhost:12112/

İsteğe bağlı ortam değişkenleri:

Değişken Amacı
FAKEMERCHANT_ADDR Dinleme adresi (varsayılan 127.0.0.1:12112)
FAKEMERCHANT_BASE_PATH /supportroute gibi bir temel yol
FAKEMERCHANT_BEARER_TOKEN Zorunlu kılınacak bir bearer token
FAKEMERCHANT_EDGE_HEADER_NAME, _VALUE Zorunlu kılınacak bir edge başlığı
FAKEMERCHANT_PENDING_DELAY Bekleyen bir sonucun ne kadar sürede sonuçlanacağı (varsayılan 3 sn)
FAKEMERCHANT_MCP_JSON=true Olay akışı (event stream) yerine JSON biçiminde MCP yanıtları

Fake'in describe yanıtı kısmi iadeleri ve iki iptal yeteneğini de beyan eder, ancak sonuç geri çağrılarını beyan etmez. Tek başına çalışan fake geri çağrı göndermez.

Kiti bu sağlayıcıya karşı çalıştırın:

sh
export PROVIDERCHECK_SANDBOX_SIGNING_SECRET=srmps_dev_secret_0123456789
go run ./cmd/providercheck -sandbox -allow-private -base-url http://localhost:12112 \
  -tenant 0199a3c1-0a0b-7c0d-8e0f-101112131415 -customer cus_1001 -transaction ch_1001 -subscription sub_1001
# MCP: add -transport mcp and use -base-url http://localhost:12112/mcp

Kit sub_1001'i iptal ettiği için çalıştırmalar arasında fake'i sıfırlayın.

Kontrol API'si Content-Type: application/json başlığıyla JSON gövdeleri kabul eder:

sh
curl -s -X POST localhost:12112/_fake/reset  -H 'Content-Type: application/json' -d '{}'
curl -s -X POST localhost:12112/_fake/faults -H 'Content-Type: application/json' \
  -d '{"operation":"refund","kind":"refuse","code":"merchant_hold","message":"held by finance"}'
  • POST /_fake/faults tek bir operasyon ya da tümü için (*) bir hata devreye alır. Hata türleri arasında latency, timeout, rate_limited, server_error, in_progress, redirect, refuse, pending, server_error_after_execute, wrong_amount, invalid_body, decimal_amount, card_number_in_field, unknown_operation, succeed_after_failure, retryable_mismatch (sonraki hata yanıtının bayrağı tersine çevrilir) ve kitin yakalaması gereken sözleşme ihlalleri (accept_bad_signature, dry_run_executes, replay_executes, over_refund ve diğerleri) bulunur.
  • DELETE /_fake/faults hepsini temizler.
  • {"signing_secret": "…"} gövdesiyle POST /_fake/signing-secrets, bir yenilemede olduğu gibi (bölüm 3) fake'in tuttuğu anahtarın yanına başka bir imzalama anahtarı dağıtır. {"id": n} gövdesiyle DELETE /_fake/signing-secrets, n numaralı anahtarın kabul edilmesini durdurur. GET /_fake/state anahtarları değerleriyle değil, numaralarıyla listeler.
  • POST /_fake/settle bekleyen sonuçları hemen sonuçlandırır.
  • POST /_fake/operations/{key}/reverse başarılı bir iadeyi geri alır.
  • GET /_fake/state güncel durumu gösterir.

Chargeless'ın bu sağlayıcıyla nasıl çalıştığını görmek için yerel demoyu (docs/local-demo.md) çalıştırın.

12. Canlıya Geçiş Öncesi Kontrol Listesi

  • Zorunlu tüm operasyonlar yanıt veriyor. cancel_subscription destekliyorsanız get_subscription ve cancel_subscription da yanıt veriyor.
  • describe tam olarak desteklediklerinizi, "1.0", "1.1" veya "1.2" sürümünü, para birimlerinizi ve beyanı bildiriyor. payment_attempts varsa list_payment_attempts (updated_at, attempt_ref) sırasına göre sayfalıyor, attempted_at'i değiştirmiyor ve kart numarası taşımıyor.
  • Her isteğin imzası ham baytlar üzerinden, herkese açık host adınıza göre, 5 dakikalık toleransla ve sabit zamanlı karşılaştırmayla doğrulanıyor. Başarısız doğrulamalara 401 dönüyor.
  • Canlı uç noktanız srmps_ test ortamı anahtarını reddediyor.
  • Idempotency anahtar başına çalışıyor: tekrar gönderim, 409 idempotency_conflict, 409 in_progress ve en az 30 gün saklanan anahtarlar.
  • Sisteminiz aşırı iadeleri kendisi reddediyor, her çağrıda tek bir etki üretiyor ve yalnızca asıl ödeme yöntemine iade yapıyor.
  • Deneme çalıştırmaları hiçbir şeyi değiştirmiyor ve anahtar saklamıyor.
  • get_operation hiçbir zaman 404 döndürmüyor. unknown yalnızca hiç alınmamış anahtarlar için kullanılıyor, succeeded ve failed nihai; geri almalar reversed_at ile failed olarak bildiriliyor.
  • refunds[] ve prior_refunds, Chargeless'ın anahtarını bayt bayt aynı şekilde, başka yerde yapılan iadeler için ise null taşıyor.
  • Tutarlar ISO en küçük biriminde tamsayı. Referanslar bölüm 7'ye uyuyor.
  • Okumalar 2,5 sn'nin epey altında, deneme çalıştırmaları 10 sn'nin altında yanıt veriyor.
  • Ortamın tüm çıkış IP adresleri izin listesinde. Sertifikanız herkese açık bir CA'dan, 443 portunda ve yönlendirme yok. mTLS kullanıyorsanız CA'yı sabitlediniz.
  • Hata zarfları retryable değerini bölüm 5'teki eşlemeye göre taşıyor.
  • Kit son 30 gün içinde test ortamınızda geçti ve mühürlü raporunu yüklediniz.
  • Test nesneleri belirlendi ve canlı sözleşme kontrolü canlıya geçeceğiniz ortamda geçti.
  • Kurallarınız ret olarak uygulanmıyor; Chargeless politikanıza yazıldı ve gerçek işlemler üzerinde denendi.
  • X-SR-Request-Id ve X-SR-Correlation-Id değerlerini logluyor ve 401 yanıtlarını izliyorsunuz. Chargeless da bunlar için uyarı veriyor (bölüm 3).
  • İsteğe bağlı: sonuç geri çağrıları beyan edildi, srmpc_ anahtarı dağıtıldı ve bir test olayı doğrulandı.

13. Sürümleme ve Değişiklik Bildirimleri

  • Sözleşme sürümleri.
    • Bu kılavuz 1.2 sözleşmesini kapsar. 1.0 ve 1.1 uygulamaları geçerliliğini korur: 1.1 yalnızca isteğe bağlı list_payment_attempts okumasını ve payment_attempts yeteneğini, 1.2 ise yalnızca isteğe bağlı abonelik alanlarını (canceled_at, ended_at, price, plan_name) ekler. Sonraki 1.x revizyonları da yalnızca ekleme yapar.
    • Chargeless yalnızca describe'da beyan ettiğiniz revizyonun tanımladığı alanları gönderir ve yanıtlarınızda tanımadığı alanları yok sayar.
    • Bir v1 uygulamasını bozacak bir değişiklik hiçbir zaman v1 altında yapılmaz.
    • Yalnızca açıklama metnini değiştiren düzenlemeler dahil her değişiklik CHANGELOG.md dosyasına kaydedilir. Bu da şemaları kopyalamak yerine $ref ile başvurmanız için bir neden daha.
  • Chargeless'ın yaptığı bildirimler.
    • Çıkış IP adresi değişiklikleri: en az 30 gün önceden, panelde ve sahiplerinize ve yöneticilerinize e-postayla.
    • İstemci sertifikası CA değişiklikleri: en az 90 gün önceden.
    • İstemci sertifikasının kendisi her yıl duyurusuz yenilenir. Sertifikayı değil, CA'yı sabitleyin.
  • Sizin yaptığınız değişiklikler.
    • İmzalama anahtarı yenilemesi önce hazırlanır ve siz etkinleştirdiğinizde geçerli olur. Geri çağrı anahtarı yenilendikten sonra önceki değer 7 gün boyunca çalışmaya devam eder. "Hemen yenile" sızdırılmış bir anahtar için hemen uygulanır (bölüm 3).
    • Canlı bir çalışma alanında yeni bir aktarım, temel URL ya da mTLS ayarı kaydedilmeden önce sözleşme kontrolünden geçmelidir. Yeni bir aktarım ayrıca o aktarım için yüklenmiş bir kit raporu gerektirir (bölüm 10).
    • Yeni bir yetenek ancak geçen bir kontrol onu kaydettikten sonra kullanılır.
    • Ödeme sağlayıcısı olarak kendi sisteminizi seçtiyseniz, çalışma alanı canlıya geçtikten sonra bu seçim değiştirilemez.