Chargeless API'si: Arka Ucunuz için
Bu kılavuz, Chargeless'ı kendi sunucularınızdan çağıran mühendisler içindir. API ile sitenizde oturum açmış bir müşteri adına iade ya da iptal yapabilir, kendi destek formunuza gelen talepleri iletebilir veya politikayı, işlemleri ve vakaları kendi sistemlerinize aktarabilirsiniz.
Chargeless her iade ve iptal kararını, panelde yayımladığınız politikaya göre verir. Arka ucunuz (backend) bir işlem önerir; Chargeless, tıpkı sohbet widget'ında olduğu gibi, bu işlem hakkında karar verir, işlemi ödeme sağlayıcınızda gerçekleştirir ve kaydeder. Hiçbir çağrı politikayı, güvenlik limitlerini ya da devredeki bir acil durdurmayı aşamaz.
| Dosya | İçeriği |
|---|---|
openapi/backend-api/v1.yaml |
OpenAPI 3.1 biçiminde API: aşağıdaki tüm prosedürler, istekler ve yanıtlar, alanlarıyla birlikte |
proto/sr/**/v1/*.proto |
Aynı API'nin Protocol Buffers karşılığı; tipli bir istemci üretmek için (aşağıda) |
CHANGELOG.md |
Sözleşmelerdeki (contracts) tüm değişiklikler |
Tüm prosedürler, alanları ve örnek yanıtlarıyla birlikte API başvurusunda yer alır. İlgili kılavuzlar: Chargeless webhook'larını almak (çağrınızdan sonra neler olduğu), widget ve müşteri kimliği (imzalı kimlik token'ı) ve Kendi faturalama sisteminizi bağlamak (ters yön: Chargeless'ın sizin sisteminizi çağırması).
1. Temel Bilgiler
API Anahtarınız
Ayarlar → API Anahtarları bölümünden bir anahtar oluşturun (sahipler, yöneticiler ve
geliştiriciler oluşturabilir). Anahtar sr_live_ ile, test çalışma alanında (aşağıda) ise
sr_test_ ile başlar ve yalnızca bir kez gösterilir. Anahtarı sunucunuzun gizli bilgi deposunda
(secret store) saklayın; tarayıcıya, bir uygulamaya ya da kod deposuna (repository) asla koymayın.
Her çağrıda şu başlıkla gönderin:
Authorization: Bearer sr_live_…Her anahtar tek bir çalışma alanına aittir; bu yüzden API'nin hiçbir yerinde tenant ya da çalışma alanı belirten bir alan yoktur. Anahtarları aynı yerden iptal edebilirsiniz (revoke); Son kullanım sütunu hangi anahtarların hâlâ kullanıldığını gösterir.
Bir anahtarla şunları yapabilirsiniz: müşterileri doğrulayıp ödemelerini ve aboneliklerini
sorgulamak; iade ve iptal işlemleri göndermek; kendi formunuza gelen talepleri iletmek; politikayı
okumak ve bir kararın önizlemesini almak; işlemleri, vakaları, iadeleri, itirazları, dolandırıcılık
uyarılarını, abonelikleri ve sağlayıcı durumunu okumak. Şunları yapamazsınız: panelde oturum
açmak, politikayı yayımlamak; ayarları, ekibi, anahtarları ya da gizli bilgileri değiştirmek;
talepleri okumak veya yanıtlamak; politikayı, güvenlik limitlerini ya da bir acil durdurmayı aşmak.
Chargeless çalışma alanınızı askıya almışsa GetTenant dışındaki tüm çağrılar reddedilir.
Test Anahtarları ve Test Çalışma Alanları
Entegrasyonunuzu bir test çalışma alanında kurup deneyin. Çalışma alanı menüsünden (Çalışma Alanı Oluştur) Test çalışma alanı anahtarını açarak bir tane oluşturun. Test çalışma alanı diğer çalışma alanları gibi çalışır: kendi politikası, yardım sitesi, widget'ı, webhook'ları ve ekibi vardır; aynı prosedürler, kararlar ve güvenlik limitleri geçerlidir. İki fark vardır:
- API anahtarları
sr_test_ile başlar. - Yalnızca test modundaki ödeme hesapları bağlanabilir: Stripe test anahtarları, bir Paddle test
ortamı (sandbox), test modunda FastSpring, bir Adyen test hesabı, dLocal test ortamı ve bir
Ecommpay test projesi. Canlı bir hesap
failed_preconditionile reddedilir ve hiçbir bilgi saklanmaz. Kendi faturalama sisteminizi her zamanki gibi bağlayabilirsiniz; bağlantıyı test sisteminize yönlendirin.
Test çalışma alanındaki iadeler ve iptaller sağlayıcınızın test ortamında (sandbox) gerçekleşir; böylece sürecin tamamını (karar, yürütme, sonuç ve webhook'lar) gerçek para kullanmadan izleyebilirsiniz. Test çalışma alanını da canlı çalışma alanında yapacağınız gibi canlıya alın (ana sayfasındaki Canlıya Al): ikisinde de işlemler yalnızca canlıya geçtikten sonra çalışır.
Bir çalışma alanının test mi canlı mı olduğu oluşturulduğu anda belirlenir ve sonradan değişmez.
Bir sr_test_ anahtarı yalnızca kendi test çalışma alanına erişir: üretime (production)
geçtiğinizde canlı çalışma alanına ait bir sr_live_ anahtarı kullanın. GetTenant, test çalışma
alanları için "test": true döndürür.
Bir Prosedürü Çağırmak
API, HTTPS üzerinden Connect protokolünü kullanır: HTTP
üzerinden düz JSON; özel bir istemci gerekmez. Her prosedür, JSON gövdesinin şu adrese POST ile
gönderilmesiyle çağrılır:
https://api.chargeless.io/{package}.{Service}/{Method}İstekte Content-Type: application/json başlığı bulunur. Çalışma alanınızı okuyan ilk çağrı:
curl -sS https://api.chargeless.io/sr.tenant.v1.TenantService/GetTenant \
-H "Authorization: Bearer $CHARGELESS_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'JSON, Protocol Buffers JSON eşlemesine uyar:
- Alan adları lowerCamelCase'tir (proto'daki
customer_ids, JSON'dacustomerIdsolur). - Enum'lar adlarıyla, string olarak yazılır:
"ACTION_TYPE_REFUND". - 64 bitlik tamsayılar string'dir:
"amountMinor": "1999"(girdide sayı da kabul edilir). - Zamanlar UTC cinsinden RFC 3339 string'leridir:
"2026-11-06T09:30:00Z". - Para tutarı her zaman en küçük birim (kuruş, cent) cinsinden bir değer ve bir ISO 4217 kodudur:
{"amountMinor": "1999", "currency": "USD"}19,99 USD,{"amountMinor": "1500", "currency": "JPY"}1.500 JPY'dir. Kayan noktalı sayı (float) asla kullanılmaz. - Kimlikler (id) opak string'lerdir. API, defterin (ledger) kimliklerini (bir ödeme kaydı, bir abonelik, bir işlem) döndürür ve isteklerde de bunları bekler; sağlayıcınızın kendi kimlikleri yalnızca ilgili alan bunu belirtiyorsa kabul edilir.
- Göndermediğiniz alanlar varsayılan değerlerini alır; Chargeless'ın tanımadığı alanlar yok sayılır. Yanıtlar varsayılan değerdeki (boş, sıfır, false) alanları içermez; eksik bir alanı varsayılan değerinde kabul edin.
bytesalanları base64 ile kodlanmış olarak gelir;GetPublished'ın döndürdüğü politika belgesi de böyle bir alandır.
Aynı çağrı, aşağıda anlatılan yeniden denemelerle birlikte Node (18 veya üzeri, ek paket gerekmez) ve Go ile:
// chargeless.mjs
const API = 'https://api.chargeless.io';
const RETRY = new Set(['unavailable', 'deadline_exceeded', 'internal', 'resource_exhausted']);
export async function call(procedure, body = {}) {
for (let attempt = 0; ; attempt++) {
let res;
try {
res = await fetch(`${API}/${procedure}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CHARGELESS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
} catch (err) {
if (attempt >= 4) throw err; // a network error: send the same request again
await new Promise((r) => setTimeout(r, 1000 * 2 ** attempt));
continue;
}
// An error body that is not JSON (a proxy in between) is read from its status.
const answer = await res.json().catch(() => ({
code: res.status === 429 ? 'resource_exhausted' : res.status >= 500 ? 'unavailable' : 'unknown',
message: res.statusText,
}));
if (res.ok) return answer;
if (!RETRY.has(answer.code) || attempt >= 4) {
throw Object.assign(new Error(`${procedure}: ${answer.code}: ${answer.message}`), answer);
}
const wait = Number(res.headers.get('Retry-After') ?? 0) * 1000;
await new Promise((r) => setTimeout(r, Math.max(wait, 1000 * 2 ** attempt)));
}
}
// const { tenant } = await call('sr.tenant.v1.TenantService/GetTenant');// A plain net/http call; section 5 shows a generated, typed client.
func call(ctx context.Context, procedure string, in, out any) error {
body, err := json.Marshal(in)
if err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://api.chargeless.io/"+procedure, bytes.NewReader(body))
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("CHARGELESS_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
var e struct{ Code, Message string }
_ = json.NewDecoder(res.Body).Decode(&e)
return fmt.Errorf("%s: %s: %s", procedure, e.Code, e.Message)
}
return json.NewDecoder(res.Body).Decode(out)
}Hatalar
Başarısız bir çağrı, 2xx dışında bir durum kodu ve şu biçimde bir JSON gövdesi döndürür:
{"code": "failed_precondition", "message": "…", "details": [ … ]}code |
HTTP | Ne yapmalısınız |
|---|---|---|
invalid_argument |
400 | İstek hatalı biçimlendirilmiş; hangi alanın hatalı olduğunu mesaj belirtir. İsteği değiştirmeden yeniden denemeyin. |
failed_precondition |
400 | İstek doğru biçimlendirilmiş ama şu anda uygulanamıyor (başka bir amaç için yeniden kullanılmış bir idempotency anahtarı, var olmayan bir hedef, canlıya geçmemiş bir çalışma alanı). Nedeni details belirtir. |
unauthenticated |
401 | Anahtar eksik, iptal edilmiş ya da yanlış yazılmış. |
permission_denied |
403 | API anahtarları bu prosedürü çağıramaz. |
not_found |
404 | Çalışma alanınızda böyle bir nesne yok. |
already_exists |
409 | Nesne zaten var. |
aborted |
409 | Eşzamanlı bir değişiklik önce uygulandı; yeniden okuyup tekrar deneyin. |
resource_exhausted |
429 | Çok fazla istek: bekleme süresini artırarak yeniden deneyin. |
unavailable |
503 | Chargeless ya da ödeme sağlayıcınız yanıt veremedi: aynı idempotency anahtarıyla yeniden deneyin. |
deadline_exceeded |
504 | Çağrı çok uzun sürdü: aynı idempotency anahtarıyla yeniden deneyin. |
internal |
500 | Hata bizden kaynaklanıyor: daha sonra aynı idempotency anahtarıyla yeniden deneyin. |
Bir karar hiçbir zaman hata olarak dönmez. Politikanın reddettiği bir iade de başarılı bir
çağrıdır; dönen işlemin durumu ACTION_STATUS_DENIED olur ve nedeni de yanıtta yer alır.
Idempotency ve Yeniden Denemeler
Bir şeyi değiştiren her çağrı, sizin seçtiğiniz bir anahtar alır. Aynı anahtarla yapılan yeniden
deneme (retry) işlemi ikinci kez yapmaz, ilk sonucu döndürür (replayed: true):
ActionsService/Submit:idempotencyKey. Anahtar denemeyi değil, her zaman amacı (intent) adlandırmalıdır. İyi bir biçimbackend:{your request id}:{action}:{target}şeklindedir; örneğinbackend:ord_8812:refund:01a1aff4-53d6-7334-8e2d-9d3d35bfcff5. Aynı amaç için yapılan her yeniden denemede aynı anahtarı kullanın; anahtara asla zaman damgası ya da rastgele bir değer koymayın. Aynı anahtar başka bir tür ya da hedefle gelirsefailed_preconditionile reddedilir.RequestIntakeService/SubmitCustomerRequest:requestId, talebe sizin verdiğiniz kimlik.
unavailable, deadline_exceeded, internal ve resource_exhausted hatalarında aynı anahtarla,
bekleme süresini artırarak (1, 2, 4, 8 sn …) yeniden deneyin; Retry-After başlığının belirttiği
süreden önce asla denemeyin. İsteği gönderdikten sonra oluşan bir ağ hatası da aynı durumdur:
isteğin ulaşıp ulaşmadığını bilemezsiniz, bu yüzden aynı anahtarla yeniden gönderin.
Limitler
Her çalışma alanı, API anahtarlarıyla toplamda (tüm anahtarlar birlikte) dakikada 600 çağrı
yapabilir; kısa süreli yoğunluklarda (burst) art arda en fazla 100 çağrı gönderilebilir. Kota
sürekli olarak, saniyede on çağrı hızında yenilenir. Kotayı aşan bir çağrı hiçbir etki yaratmaz ve
Retry-After başlığıyla birlikte resource_exhausted (HTTP 429) yanıtı alır; bu başlık, bir
sonraki çağrının kabul edilmesi için beklemeniz gereken süreyi tam saniye olarak verir. Bir
anahtarın yaptığı her çağrı, yanıtı ne olursa olsun kotadan düşülür. Test çalışma alanlarının
kotası ayrıdır.
Bu sınırdan önce, API sunucusu tek bir istemci IP adresinden dakikada en fazla 1.200 istek kabul
eder ve fazlasını 429 ile yanıtlar. Listeler en fazla pageSize kadar öğe döndürür (her prosedürün
kendi varsayılan ve azami değeri vardır); nextPageToken değerini değiştirmeden pageToken olarak
geri gönderin ve içeriğini yorumlamayın (opak bir değerdir).
2. Oturum Açmış Bir Müşteri için İade veya İptal
Müşteri sitenizde oturum açmışsa sunucunuz, imzalı bir kimlik token'ıyla müşterinin kimliğine kefil olur ve ardından onun adına işlem yapar. Politika, widget'taki bir sohbette olduğu gibi karar verir.
Adım 1: Bir Kimlik Token'ı İmzalayın
Bu, widget'ın kullandığı token'ın aynısıdır: Widget İmza Anahtarı (srwgt_…, Ayarlar → Sohbet
Widget'ı) ile imzalanan ve yalnızca sunucunuzda oluşturulan bir HS256 JWT.
| Claim | Değer |
|---|---|
sub |
müşterinin ödeme sağlayıcınızdaki kimliği (Stripe cus_…, Paddle ctm_…, kendi sisteminizdeki kimlik) |
tenant |
Çalışma alanı kimliğiniz (Workspace ID) |
connection |
isteğe bağlı: müşterinin ait olduğu ödeme bağlantısı (Ayarlar → Entegrasyonlar); verilmezse ilk bağlantınız |
email |
isteğe bağlı |
iat, exp |
düzenlenme zamanı ve son geçerlilik zamanı; en fazla bir saat sonrası |
import jwt from 'jsonwebtoken';
const token = jwt.sign(
{ sub: customer.stripeCustomerId, tenant: process.env.CHARGELESS_WORKSPACE_ID },
process.env.CHARGELESS_WIDGET_SECRET, // srwgt_…
{ algorithm: 'HS256', expiresIn: '15m' },
);Adım 2: Token'ı Doğrulayın
curl -sS https://api.chargeless.io/sr.identity.v1.IdentityService/Verify \
-H "Authorization: Bearer $CHARGELESS_API_KEY" -H "Content-Type: application/json" \
-d '{"token": "eyJhbGciOiJIUzI1NiIs…"}'{
"customerId": "01a1aff4-5117-79a0-a966-68ed1a264ea1",
"providerCustomerId": "cus_Q8x…",
"method": "IDENTITY_METHOD_SIGNED_TOKEN",
"connectionId": "01a1aff4-50ab-74ce-9c05-b142b747606c",
"verifiedAt": "2026-11-06T09:30:00Z",
"expiresAt": "2026-11-06T09:45:00Z"
}customerId, müşterinin Chargeless defterindeki kimliğidir; sonraki adımlarda bu değeri kullanın.
Doğrulanamayan ya da süresi dolmuş bir token için unauthenticated döner (mesaj, sorunun API
anahtarınızda değil token'da olduğunu belirtir); defterde henüz kaydı olmayan bir müşteri için
not_found döner.
Adım 3: Ödemelerini ve Aboneliklerini Sorgulayın
curl -sS https://api.chargeless.io/sr.transactions.v1.TransactionsService/Lookup \
-H "Authorization: Bearer $CHARGELESS_API_KEY" -H "Content-Type: application/json" \
-d '{"customerIds": ["01a1aff4-5117-79a0-a966-68ed1a264ea1"], "limit": 20}'Her ödeme kaydında (transaction) defterdeki id değeri, sağlayıcıdaki kimliği, amount,
refunded, refundableRemainder ve state alanları, kartın markası ile son dört hanesi ve ödeme
bağlantısı bulunur; her abonelikte ise id değeri, durumu ve planı. Yalnızca gönderdiğiniz
müşterilerin kayıtları okunur.
Adım 4 (İsteğe Bağlı): Kararın Önizlemesini Alın
PolicyService/Evaluate, hiçbir şey kaydetmeden politikanın şu anda nasıl bir karar vereceğini
döndürür:
curl -sS https://api.chargeless.io/sr.policy.v1.PolicyService/Evaluate \
-H "Authorization: Bearer $CHARGELESS_API_KEY" -H "Content-Type: application/json" \
-d '{
"actionType": "ACTION_TYPE_REFUND",
"targetId": "01a1aff4-53d6-7334-8e2d-9d3d35bfcff5",
"reasonCode": "duplicate",
"source": "SOURCE_CHAT",
"identityIds": ["01a1aff4-5117-79a0-a966-68ed1a264ea1"],
"identityMethod": "IDENTITY_METHOD_SIGNED_TOKEN"
}'decision.outcome alanı OUTCOME_ALLOW, OUTCOME_DENY ya da OUTCOME_HANDOFF olur; yanında
reasons (her biri bir kod ve bir açıklama cümlesi) ve amount döner. Önizleme bir taahhüt
değildir: siz işlemi göndermeden önce kararın dayandığı bilgiler değişebilir ve gönderimde karar
yeniden verilir.
Adım 5: İşlemi Gönderin
curl -sS https://api.chargeless.io/sr.actions.v1.ActionsService/Submit \
-H "Authorization: Bearer $CHARGELESS_API_KEY" -H "Content-Type: application/json" \
-d '{
"idempotencyKey": "backend:ord_8812:refund:01a1aff4-53d6-7334-8e2d-9d3d35bfcff5",
"type": "ACTION_TYPE_REFUND",
"targetId": "01a1aff4-53d6-7334-8e2d-9d3d35bfcff5",
"reasonCode": "duplicate",
"identity": {
"customerId": "01a1aff4-5117-79a0-a966-68ed1a264ea1",
"customerIds": ["01a1aff4-5117-79a0-a966-68ed1a264ea1"],
"method": "IDENTITY_METHOD_SIGNED_TOKEN"
},
"requestedBy": "account-page",
"waitSeconds": 5
}'type:ACTION_TYPE_REFUND(hedef: bir ödeme kaydı) ya daACTION_TYPE_CANCEL_SUBSCRIPTION(hedef: bir abonelik).ACTION_TYPE_HANDOFFise hedef almaz; birhandoffReasonkoduyla, para konusunda karar vermeden vakayı ekibinize devreder.reasonCode:duplicate,forgot_to_cancel,unrecognized,not_as_described,service_issueya daother. Politika kararını buna göre verebilir.amount: isteğe bağlı; kısmi iade için, ödemenin para biriminde. Verilmezse iade edilebilir kalanın tamamı iade edilir.requestedBy: talebin nereden geldiğini gösteren, sizin belirlediğiniz etiket; işlemde görünür. Zorunludur.waitSeconds: yanıt vermeden önce sağlayıcının sonucunun ne kadar bekleneceği (varsayılan 5, en fazla 10).
Yanıt olarak işlemin kendisi döner:
{
"action": {
"id": "01a1aff5-427d-765f-a005-d2675fe290ab",
"type": "ACTION_TYPE_REFUND",
"status": "ACTION_STATUS_EXECUTED",
"targetId": "01a1aff4-53d6-7334-8e2d-9d3d35bfcff5",
"amount": {"amountMinor": "1900", "currency": "EUR"},
"decision": {"outcome": "OUTCOME_ALLOW", "policyVersion": "v7", "reasons": [ … ]},
"providerRef": "re_3Q…",
"createdAt": "2026-11-06T09:31:02Z",
"executedAt": "2026-11-06T09:31:03Z"
},
"replayed": false
}status |
Anlamı |
|---|---|
ACTION_STATUS_EXECUTED |
Sağlayıcıda gerçekleşti. |
ACTION_STATUS_PENDING |
Onaylandı ve yürütülüyor ya da sağlayıcının sonucu bekleniyor. |
ACTION_STATUS_DENIED |
Politika (ya da bir durdurma) reddetti; nedeni decision.reasons alanında. |
ACTION_STATUS_HANDOFF |
Ekibinize devredildi; nedeni decision.reasons alanında. |
ACTION_STATUS_FAILED |
Sağlayıcı yürütme sırasında reddetti; ayrıntısı failure alanında. İşlem ekibinize iletilir. |
Adım 6: Bekleyen Bir İşlemi Takip Edin
İşlemi ActionsService/Get ({"actionId": "…"}) ile yeniden okuyun ya da, daha iyisi,
action.executed ve action.failed webhook'larına abone olun (webhooks.md). Bazı
sağlayıcılar iadeyi diğerlerinden daha geç onaylar (Paddle iadeleri inceler; Adyen ve Ecommpay
bildirimle onaylar); 24 saat içinde sonuç gelmezse işlem ekibinize devredilir.
3. Kendi Destek Formunuzdan Gelen İstekler
Widget yerine kendi formunuzu kullanıyorsanız her isteği
RequestIntakeService/SubmitCustomerRequest prosedürüne gönderin. Prosedür bir talep (ticket)
açar ve politika isteği hemen karara bağlar; müşteri süreci kendi talep sayfasından izler.
curl -sS https://api.chargeless.io/sr.tickets.v1.RequestIntakeService/SubmitCustomerRequest \
-H "Authorization: Bearer $CHARGELESS_API_KEY" -H "Content-Type: application/json" \
-d '{
"requestId": "form-20261106-0042",
"action": "ACTION_TYPE_REFUND",
"targetId": "ch_3Q8x…",
"reasonCode": "duplicate",
"message": "I was charged twice for my order.",
"locale": "en",
"requesterName": "Kim Okafor",
"email": "[email protected]"
}'requestId: isteğe sizin verdiğiniz kimlik;[A-Za-z0-9_-]kümesinden 1–128 karakter. Idempotency anahtarı da budur: yeniden deneme, aynı talebireplayed: trueve isteğin güncel sonucuyla döndürür; bu yüzden durumu bu kimlikle yoklayabilirsiniz (polling).action:ACTION_TYPE_REFUNDya daACTION_TYPE_CANCEL_SUBSCRIPTION.targetId: bir defter kimliği ya da ödemenin veya aboneliğin sağlayıcınızdaki kimliği (Stripe'tach_…ya dasub_…); sağlayıcı kimliği verdiğinizdeconnectionIdbu kimliğin ait olduğu ödeme bağlantısını belirtir (boş bırakılırsa ilk bağlantınız).- Tam olarak bir kimlik kanıtı:
identityToken: oturum açmış müşteri için 2. bölümdeki imzalı token. İstek o müşteriyle eşleştirilir ve hemen karara bağlanır.email: formda girilen adres. Elle yazılmış bir adres hiçbir şey kanıtlamaz; bu yüzden istek doğrulanmamış kabul edilerek karara bağlanır (CUSTOMER_REQUEST_OUTCOME_IDENTITY_REQUIRED) ve bu adrese tek kullanımlık bağlantı içeren bir e-posta gönderilir. Adresin sahibi, adresin kendisine ait olduğunu kanıtlayıp isteği talep sayfasında onaylar; istek ancak bundan sonra yeniden karara bağlanır.
Yanıt, talebi ve isteğin hangi aşamada olduğunu belirtir:
{
"ticketId": "01a1b00b-…",
"ticketNumber": "1042",
"pageUrl": "https://acme.help.chargeless.io/t/9fK2…",
"outcome": "CUSTOMER_REQUEST_OUTCOME_IDENTITY_REQUIRED",
"reasonCode": "identity_required",
"actionId": "01a1b00b-…",
"replayed": false
}outcome değeri EXECUTED, PENDING, DENIED, HANDOFF ya da IDENTITY_REQUIRED olur (her
birinin başında CUSTOMER_REQUEST_OUTCOME_ öneki bulunur). Müşteriye pageUrl adresini gösterin:
bu adres talebi tanımlar ama tek başına hiçbir yetki vermez, çünkü sayfa önce kimlik kanıtı ister.
Onaydan sonra istek yeniden karara bağlandığında customer_request.decided webhook'u sizi
bilgilendirir.
4. Verileri Kendi Sistemlerinize Aktarmak
| Prosedür | Ne döndürür |
|---|---|
sr.tenant.v1.TenantService/GetTenant |
Çalışma alanınız: durumu (canlı, kurulumda, askıya alınmış), acil durdurma, yardım sitesi |
sr.policy.v1.PolicyService/GetPublished |
Yayımlanmış politika belgesi (base64) ve sürümü |
sr.policy.v1.PolicyService/ListVersions, GetVersion |
Politikanın sürüm geçmişi ve önceki herhangi bir sürüm |
sr.policy.v1.PolicyService/Evaluate |
Bir karar önizlemesi (2. bölüm, 4. adım) |
sr.cases.v1.CasesService/ListActions |
Tüm işlemler, en yeniden eskiye; zamana, türe, duruma ve kaynağa göre filtrelenebilir |
sr.cases.v1.CasesService/ListCases, GetCase |
Vakalar (sohbet, talep, dolandırıcılık uyarısı, itiraz) ve tek bir vakanın zaman çizelgesi ile karar olguları |
sr.cases.v1.CasesService/ListRefunds |
İadeler: Chargeless'ın yaptıkları, sağlayıcıda ya da kendi sisteminizde yapılanlar; para birimi başına toplamlarla |
sr.cases.v1.CasesService/ListDisputes |
İtirazlar ve sorgular, son tarihleriyle |
sr.cases.v1.CasesService/ListFraudWarnings |
Erken dolandırıcılık uyarıları ve her biri için yapılanlar |
sr.cases.v1.CasesService/ListSubscriptions |
Tüm ödeme bağlantılarınızdaki abonelikler |
sr.cases.v1.CasesService/ListProviderCalls |
Chargeless'ın kendi ödeme sisteminize yaptığı çağrılar (işletmenin barındırdığı bağlantılar) |
sr.cases.v1.CasesService/GetProviderHealth |
Kendi ödeme sisteminizin sağlık durumu, izleme için |
sr.identity.v1.IdentityService/LookupCustomer |
Bir e-posta adresinin ait olduğu müşteriler, ödeme bağlantısı bazında |
sr.actions.v1.ActionsService/Get |
Tek bir işlem |
Listeler bir zaman aralığına (from, to) ve kendi alanlarına göre filtrelenir; pageSize ve
pageToken ile sayfalanır. Her listenin sayfa boyutunu ve zaman aralığının zorunlu olup olmadığını
API başvurusu belirtir. Tüm alanlar openapi/backend-api/v1.yaml
dosyasında yer alır.
5. Tipli Bir İstemci
OpenAPI belgesi tüm OpenAPI araçlarıyla kullanılabilir. Alan tiplerini birebir koruyan tipli bir istemci için istemciyi proto dosyalarından, Buf ve dilinize uygun Connect kod üreticisiyle (Go, TypeScript, Kotlin, Swift, Python, Dart) üretin:
# buf.gen.yaml
version: v2
plugins:
- remote: buf.build/connectrpc/go
out: gen
opt: paths=source_relative
- remote: buf.build/protocolbuffers/go
out: gen
opt: paths=source_relativeclient := actionsv1connect.NewActionsServiceClient(http.DefaultClient, "https://api.chargeless.io")
req := connect.NewRequest(&actionsv1.SubmitRequest{ /* … */ })
req.Header().Set("Authorization", "Bearer "+os.Getenv("CHARGELESS_API_KEY"))
res, err := client.Submit(ctx, req)6. Sürümler ve Değişiklikler
Her paketin bir sürümü vardır (sr.actions.v1). v1 içinde alanlar ve prosedürler yalnızca
eklenir; bir alan asla yeniden adlandırılmaz, tipi değiştirilmez ya da başka amaçla yeniden
kullanılmaz. Mevcut bir entegrasyonu bozacak bir değişiklik, v1'in yanında v2 olarak yayımlanır.
Tüm değişiklikler CHANGELOG.md dosyasında yer alır. Tanımadığınız alanları yok sayın; bir alan
sıralı olduğunu belirtmedikçe alanların ya da liste öğelerinin sırasına güvenmeyin.