Başlarken API v2
api_key
api_secret
store_id
Entegrasyon adımları
-
1
Oturum oluşturun — Backend'inizden müşteri bilgilerini ve HMAC-SHA256 hash'ini
/checkout/token.phpadresine POST edin. Başarılı olursa imzalı birtokenveredirectURL'si döner. Token 2 saat geçerlidir. -
2
Kullanıcıyı yönlendirin — Tarayıcıyı 1. adımda gelen
redirectadresine hemen gönderin (önerilen yöntem). Aynı adresi bir iframe içinde de açabilirsiniz. Token'ı saklamayın, tekrar kullanmayın. - 3 Ödeme sayfası — Müşteri Dodopin sayfasında ürünü seçer ve ödemeyi tamamlar. Kart ve hassas ödeme verisi sizin sunucunuza gelmez.
-
4
Webhook alın — Ödeme başarılı olunca Dodopin, kayıtlı Webhook URL adresinize imzalı bir HTTP POST gönderir.
hashimzasını doğrulayın,status === "success"olduğundan emin olun ve siparişiorder_refile kaydedin. HTTP 200 ve gövde olarakOKdönün.
api_secret değerini JavaScript'e veya mobil uygulamaya koymayın. /checkout/token.php istekleri backend'inizden gitmelidir. iframe entegrasyonu
En temiz yöntem tam sayfa yönlendirmedir. Ürün seçimini kendi sayfanızda göstermek istiyorsanız ödeme URL'sini bir iframe içinde de açabilirsiniz. Sayfa çerçevelemeye izin verir (frame-ancestors *).
Nasıl çalışır
-
1
Sunucunuzda Oturum oluşturma adımındaki gibi bir oturum alın. Dönen
redirectURL'sini iframesrcolarak kullanın. -
2
URL'de geçerli bir oturum
token'ı varsa Dodopin kendi üst ve alt çubuğunu gizler; ödeme sayfanızın içine sığar. Geri butonu, başlık veya “tarayıcıda aç” gibi dış çerçeve size aittir — Dodopin bunları eklemez. -
3
Müşteri ödeme yöntemini onayladığında (ör. Devam et) Dodopin önce ödeme sağlayıcısını üst pencerede açmayı dener. Buna izin yoksa yeni bir pencere (sistem tarayıcısı) açılır; o da engellenirse iframe içinde kalır. Bu yüzden gömme ortamınızın üst sayfaya yönlendirmeye veya popup'a izin vermesi gerekir.
sandboxkullanıyorsanız en az şunları ekleyin:allow-scripts allow-same-origin allow-forms allow-top-navigation allow-popups. Hem üst yönlendirmeyi hem popup'ı kesen oyun motoru / uygulama içi WebView ortamlarında ödemeyi sistem tarayıcısında açın — aksi halde ödeme butonu tıklanınca hiçbir şey olmuyor gibi görünür. - 4 Siparişi iframe'deki olaylara veya dönüş sayfasındaki JavaScript'e bakarak tamamlamayın. Kaynak imzalı webhook'tur. Müşteri ödemeyi çerçevenizin dışında da bitirebilir.
Örnek
<!-- redirect = value from Create Session JSON -->
<!-- Do not omit allow-top-navigation if you add sandbox="" -->
<iframe
id="dodopin-checkout"
src="https://dodopin.com/tr/store/your-store-slug?token=…&cur=TRY"
title="Dodopin Checkout"
style="width:100%;min-width:1024px;height:900px;border:0;overflow:auto;"
scrolling="yes"
allow="payment *"
referrerpolicy="strict-origin-when-cross-origin"
></iframe>
<script>
window.addEventListener("message", function (e) {
if (!e.data || e.data.source !== "dodopin") return;
var f = document.getElementById("dodopin-checkout");
if (!f) return;
if (e.data.type === "embed-height" && e.data.height) {
f.style.height = e.data.height + "px";
}
if (e.data.type === "embed-scroll-into-view") {
try { f.scrollIntoView({ block: "nearest", inline: "nearest" }); } catch (err) {}
}
});
</script>
scrolling="no" veya overflow:hidden). Ödeme sayfası çerçevenin içinde kayar; ayrıca {source:"dodopin", type:"embed-height", height} mesajı gönderir, böylece iframe yüksekliğini içeriğe göre büyütebilirsiniz. Sipariş formu açılınca {source:"dodopin", type:"embed-scroll-into-view"} da gelir; çerçeveyi görünür tutmak için kullanın. Yaklaşık 992px'in altında ödeme sayfası mobil görünüme geçer. X-Frame-Options / frame-ancestors ile iframe içine alınmayı reddeder. Dodopin sırayla dener: window.top → yeni pencere → aynı iframe. Gömme ortamınız (özellikle oyun motoru WebView) hem üst yönlendirmeyi hem popup'ı kesiyorsa ödeme iframe içinde ilerleyemez — sistem tarayıcısında açın veya tam sayfa yönlendirme kullanın. Ödeme onayı için postMessage'e güvenmeyin; webhook kullanın. Kimlik doğrulama
API iki yerde HMAC-SHA256 kullanır: (1) Oturum oluşturma isteğini siz imzalarsınız; böylece api_secret istek gövdesine girmez. (2) Platform her webhook'u imzalar; böylece bildirimin sahte olmadığını doğrularsınız.
İstek hash'i (oturum oluşturma)
|) koyarak birleştirin. base64_encode için HMAC'in ham (binary) çıktısını kullanın — önce hex'e çevirmeyin. api_secret imza anahtarıdır; istek gövdesinde asla gönderilmez. Webhook imza formülü
Webhook doğrulama örneği
$API_KEY = 'YOUR_API_KEY';
$API_SECRET = 'YOUR_API_SECRET';
// All fields come directly from the flat POST body
$hash_string =
($_POST['merchant_id'] ?? '') .
($_POST['order_ref'] ?? '') .
($_POST['user_fullname'] ?? '') .
($_POST['invoice_mail'] ?? '') .
($_POST['gateway_name'] ?? '') .
($_POST['status'] ?? '') .
$API_KEY;
$expected = base64_encode(
hash_hmac('sha256', $hash_string, $API_SECRET, true)
);
// hash_equals() prevents timing attacks
if (!hash_equals($expected, $_POST['hash'] ?? '')) {
http_response_code(403);
die('invalid_hash');
}
const crypto = require('crypto');
// All fields come directly from the flat POST body
const hashString =
String(req.body.merchant_id ?? '') +
String(req.body.order_ref ?? '') +
String(req.body.user_fullname ?? '') +
String(req.body.invoice_mail ?? '') +
String(req.body.gateway_name ?? '') +
String(req.body.status ?? '') +
API_KEY;
const expected = Buffer
.from(crypto.createHmac('sha256', API_SECRET).update(hashString).digest())
.toString('base64');
// timingSafeEqual prevents timing attacks
const a = Buffer.from(req.body.hash ?? '');
const b = Buffer.from(expected);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(403).send('invalid_hash');
}
import hmac, hashlib, base64
from flask import request
API_KEY = 'YOUR_API_KEY'
API_SECRET = 'YOUR_API_SECRET'
# All fields come directly from the flat POST body
f = lambda k: request.form.get(k, '')
hash_string = (
f('merchant_id') +
f('order_ref') +
f('user_fullname') +
f('invoice_mail') +
f('gateway_name') +
f('status') +
API_KEY
)
expected = base64.b64encode(
hmac.new(API_SECRET.encode(), hash_string.encode(), hashlib.sha256).digest()
).decode()
# compare_digest prevents timing attacks
if not hmac.compare_digest(f('hash'), expected):
abort(403)
Ödeme oturumu oluşturma
API bilgilerinizi ve müşteri verilerini sunucunuzdan token endpoint'ine POST edin. Başarılı yanıtta tek kullanımlık, imzalı bir redirect URL'si gelir. Ödemeyi başlatmak için müşterinin tarayıcısını bu adrese yönlendirin.
Kod örnekleri
<?php
$API_KEY = 'YOUR_API_KEY';
$API_SECRET = 'YOUR_API_SECRET';
$store_id = 12345;
$user_id = 678;
$username = 'username';
$user_email = '[email protected]';
$hash = base64_encode(
hash_hmac('sha256', $API_KEY . '|' . $store_id . '|' . $user_id . '|' . $username . '|' . $user_email, $API_SECRET, true)
);
$post_data = [
'api_key' => $API_KEY,
'hash' => $hash,
'store_id' => $store_id,
'user_id' => $user_id,
'username' => $username,
'user_email' => $user_email,
'user_ip' => $_SERVER['REMOTE_ADDR'] ?? '',
'user_fullname' => 'John Doe',
'user_phone' => '+13125550100',
'lang' => 'tr', // page opening language (default: tr)
'currency' => 'TRY', // page opening currency (default: TRY)
];
$ch = curl_init('https://dodopin.com/checkout/token.php');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_data,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($response['success'] ?? false) {
header('Location: ' . $response['redirect']);
exit;
}
throw new RuntimeException('Token error: ' . ($response['message'] ?? 'unknown'));
?>
const https = require('https');
const qs = require('querystring');
const crypto = require('crypto');
const API_KEY = 'YOUR_API_KEY';
const API_SECRET = 'YOUR_API_SECRET';
const store_id = 12345;
const user_id = 678;
const username = 'username';
const user_email = '[email protected]';
const hash = Buffer
.from(crypto.createHmac('sha256', API_SECRET)
.update(String(API_KEY) + '|' + String(store_id) + '|' + String(user_id) + '|' + username + '|' + user_email)
.digest())
.toString('base64');
const body = qs.stringify({
api_key: API_KEY,
hash: hash,
store_id: store_id,
user_id: user_id,
username: username,
user_email: user_email,
user_ip: '1.2.3.4',
user_fullname: 'John Doe',
user_phone: '+393331234567',
lang: 'tr', // page opening language (default: tr)
currency: 'TRY', // page opening currency (default: TRY)
});
const url = new URL('https://dodopin.com/checkout/token.php');
const req = https.request({
hostname: url.hostname,
path: url.pathname,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(body),
},
}, (res) => {
let data = '';
res.on('data', c => data += c);
res.on('end', () => {
const json = JSON.parse(data);
if (json.success) console.log('Redirect →', json.redirect);
else throw new Error(json.message);
});
});
req.on('error', err => { throw err; });
req.write(body);
req.end();
import requests, hmac, hashlib, base64
API_KEY = 'YOUR_API_KEY'
API_SECRET = 'YOUR_API_SECRET'
store_id = 12345
user_id = 678
username = 'username'
user_email = '[email protected]'
hash_string = API_KEY + '|' + str(store_id) + '|' + str(user_id) + '|' + username + '|' + user_email
hash_val = base64.b64encode(
hmac.new(API_SECRET.encode(), hash_string.encode(), hashlib.sha256).digest()
).decode()
resp = requests.post(
'https://dodopin.com/checkout/token.php',
data={
'api_key': API_KEY,
'hash': hash_val,
'store_id': store_id,
'user_id': user_id,
'username': username,
'user_email': user_email,
'user_ip': '1.2.3.4',
'user_fullname': 'John Doe',
'user_phone': '+201001234567',
'lang': 'tr', # page opening language (default: tr)
'currency': 'TRY', # page opening currency (default: TRY)
},
timeout=30,
)
resp.raise_for_status()
data = resp.json()
if data.get('success'):
redirect_url = data['redirect'] # redirect user here
else:
raise RuntimeError(data.get('message'))
# Compute hash first (shell)
HASH=$(printf '%s' 'YOUR_API_KEY|12345|678|username|[email protected]' \
| openssl dgst -sha256 -hmac 'YOUR_API_SECRET' -binary | base64)
curl -X POST 'https://dodopin.com/checkout/token.php' \
-d 'api_key=YOUR_API_KEY' \
--data-urlencode "hash=$HASH" \
-d 'store_id=12345' \
-d 'user_id=678' \
-d 'username=username' \
-d '[email protected]' \
-d 'user_ip=1.2.3.4' \
-d 'user_fullname=John+Doe' \
-d 'user_phone=%2B13125550100' \
-d 'lang=tr' \
-d 'currency=TRY'
Yanıt
{
"success": true,
"token": "eyJzIjoxMjM0NX0...",
"redirect": "https://dodopin.com/tr/store/your-store-slug?token=eyJzIjoxMjM0NX0...&cur=TRY"
}
{
"success": false,
"message": "Invalid API credentials or store is not active."
}
İstek parametreleri
| Alan | Tip | Açıklama | Doğrulama | Zorunlu |
|---|---|---|---|---|
api_key |
String | Mağaza API anahtarınız. Mağazalarım → Mağaza Düzenle → Mağazanın API Bilgileri bölümünde. | Boş olamaz | zorunlu |
hash |
String | HMAC-SHA256 istek imzası. Formül için Kimlik doğrulama bölümüne bakın. api_secret imza anahtarıdır — istek gövdesinde göndermeyin. |
base64_encode(HMAC-SHA256(api_key|store_id|user_id|username|user_email, api_secret)) — alanlar pipe | ile birleştirilir |
zorunlu |
store_id |
Integer | Mağazanızın sayısal ID'si. Mağazalarım → Mağaza Düzenle → Mağazanın API Bilgileri bölümünde. | Pozitif tam sayı | zorunlu |
user_id |
String / Int | Müşterinin sizin sisteminizdeki benzersiz kimliği. Webhook'ta alıcıyı bu değerle eşlersiniz. | En fazla 64 karakter. Kontrol karakterleri silinir. | zorunlu |
username |
String | Müşterinin kullanıcı adı. Ödeme sayfasında gösterilir. | Yalnızca harf, rakam, _ ve -. En fazla 64 karakter. Boşluk ve özel karakter kabul edilmez. |
zorunlu |
user_email |
String | Müşterinin e-posta adresi. Faturada kullanılır. | Geçerli e-posta adresi (RFC 5321). | zorunlu |
user_ip |
String | Müşterinin IP adresi. Kendi sunucu IP'nizi değil, gerçek istemci IP'sini gönderin. | Geçerli IPv4 veya IPv6 adresi. | zorunlu |
user_fullname |
String | Müşterinin adı soyadı. Faturada kullanılır. | En fazla 128 karakter. Kontrol karakterleri silinir. | zorunlu |
user_phone |
String | Ülke kodu dahil telefon numarası. | Yalnızca rakam ve +. En fazla 20 karakter. En az bir rakam içermeli(ör. +905551234567, +393331234567). |
zorunlu |
lang |
String | Sayfanın açılacağı dil. Varsayılan: tr |
tr, en, de, fr, es, it, pt, nl, pl, ro, cs |
isteğe bağlı |
currency |
String | Sayfanın açılacağı para birimi. Varsayılan: TRY |
AED, AMD, ARS, AUD, AZN, BGN, BHD, BRL, CAD, CHF, CLP, CNY, COP, CZK, DKK, EGP, EUR, GBP, GEL, GHS, HKD, HUF, IDR, ILS, INR, ISK, JOD, JPY, KES, KRW, KWD, KZT, MAD, MXN, MYR, NGN, NOK, NZD, OMR, PEN, PHP, PKR, PLN, QAR, RON, RUB, SAR, SEK, SGD, THB, TND, TRY, UAH, USD, UYU, VND, ZAR, HRK |
isteğe bağlı |
Webhook (IPN) API v2
Her başarılı ödemeden sonra platform, kayıtlı Webhook URL adresinize sipariş, müşteri ve ödeme bilgilerini imzalı HTTP POST ile gönderir. Endpoint'iniz hash imzasını doğrulamalı, status = success ise siparişi işlemeli ve HTTP 200 + gövde OK dönmelidir. Farklı bir yanıt otomatik yeniden denemeyi başlatır.
username alanı gönderir (user_name yok) ve api_version değeri 2 olur. İmza formülü aynıdır. Mağazalarım → Mağaza Düzenle ekranından v2 seçin. Mevcut mağazalar siz değiştirene kadar v1'de kalır. Örnek POST gövdesi
{
"order_ref": "O14092026ABCDEF1",
"merchant_id": "12345",
"status": "success",
"gateway_name": "payop",
"product_id": "42",
"product_name": "13000 Diamonds",
"quantity": "1",
"product_topup_amount": "13000.00",
"total_topup_amount": "13000.00",
"product_currency": "EUR",
"unit_price": "50.00",
"total_price": "50.00",
"net_merchant_earning": "47.50",
"user_fullname": "John Doe",
"invoice_mail": "[email protected]",
"user_id": "678",
"user_phone": "+13125550100",
"username": "username",
"api_version": "2",
"hash": "oIJlok5zdmQtIK19QKqEL9uGo/xQGI/ArQNq1lwVg=="
}
Canlı istek düz form POST'tur (application/x-www-form-urlencoded), JSON gövde değil. Aşağıdaki nesne aynı alanların JSON görünümüdür — sipariş ekranındaki giden webhook paneliyle aynıdır. api_key gövdede gelmez; hash doğrularken kendi kayıtlı anahtarınızı kullanın.
Örnek handler
<?php
$API_KEY = 'YOUR_API_KEY';
$API_SECRET = 'YOUR_API_SECRET';
// Payload is a flat POST body — all fields at root level
$merchant_id = $_POST['merchant_id'] ?? '';
$order_ref = $_POST['order_ref'] ?? '';
$user_fullname = $_POST['user_fullname'] ?? '';
$invoice_mail = $_POST['invoice_mail'] ?? '';
$gateway_name = $_POST['gateway_name'] ?? '';
$status = $_POST['status'] ?? '';
$received_hash = $_POST['hash'] ?? '';
$expected = base64_encode(hash_hmac('sha256',
$merchant_id . $order_ref . $user_fullname .
$invoice_mail . $gateway_name . $status . $API_KEY,
$API_SECRET, true
));
if (!hash_equals($expected, $received_hash)) {
http_response_code(403);
die('invalid_hash');
}
if ($status === 'success') {
$topup = (float) ($_POST['total_topup_amount'] ?? '0');
$user = $_POST['username'] ?? '';
// Credit $topup to the player's in-game balance
// e.g. addBalance($user, $topup);
}
header('Content-Type: text/plain');
echo 'OK';
?>
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.post('/webhook', (req, res) => {
// Payload is a flat POST body — all fields at root level
const {
merchant_id = '',
order_ref = '',
user_fullname = '',
invoice_mail = '',
gateway_name = '',
status = '',
hash = '',
} = req.body;
const expected = Buffer.from(crypto
.createHmac('sha256', process.env.API_SECRET)
.update(merchant_id + order_ref + user_fullname + invoice_mail + gateway_name + status + process.env.API_KEY)
.digest()
).toString('base64');
const hBuf = Buffer.from(hash);
const eBuf = Buffer.from(expected);
if (hBuf.length !== eBuf.length || !crypto.timingSafeEqual(hBuf, eBuf))
return res.status(403).send('invalid_hash');
if (status === 'success') {
const topup = parseFloat(req.body.total_topup_amount || '0');
const user = req.body.username || '';
// Credit topup to the player's in-game balance
// e.g. addBalance(user, topup);
}
res.type('text').send('OK');
});
app.listen(3000);
import hmac, hashlib, base64
from flask import Flask, request, abort
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
# Payload is a flat POST body — all fields at root level
f = lambda k: request.form.get(k, '')
hash_string = (
f('merchant_id') +
f('order_ref') +
f('user_fullname') +
f('invoice_mail') +
f('gateway_name') +
f('status') +
API_KEY
)
expected = base64.b64encode(
hmac.new(API_SECRET.encode(), hash_string.encode(), hashlib.sha256).digest()
).decode()
if not hmac.compare_digest(f('hash'), expected):
abort(403)
if f('status') == 'success':
topup = float(f('total_topup_amount') or '0')
user = f('username')
# Credit topup to the player's in-game balance
# e.g. add_balance(user, topup)
return 'OK', 200, {'Content-Type': 'text/plain'}
Gelen alanlar
| Alan | Tip | Açıklama | Hash'te |
|---|---|---|---|
merchant_id | String | Mağaza / satıcı ID'niz | evet — 1. sıra |
order_ref | String | Dodopin tarafından üretilen benzersiz sipariş numarası | evet — 2. sıra |
user_fullname | String | Müşteri adı soyadı | evet — 3. sıra |
invoice_mail | String | Müşteri e-posta adresi | evet — 4. sıra |
gateway_name | String | Ödeme yöntemi (ör. stripe, tazapay, lidio) | evet — 5. sıra |
status | String | Otomatik webhook'larda her zaman success | evet — 6. sıra |
api_key | String | Mağaza API anahtarınız — POST gövdesinde gelmez, hash metninin 7. alanıdır. İmzayı doğrularken kendi kayıtlı api_key değerinizi kullanın. | evet — 7. sıra |
user_phone | String | Ülke kodu dahil telefon | hayır |
product_id | Integer | Ürün ID'si — siparişte yoksa gönderilmez | hayır |
product_name | String | Ödeme anındaki ürün adı (product_name_snapshot) — boşsa gönderilmez | hayır |
quantity | String | Adet (en az 1) | hayır |
product_topup_amount | String | Ürün başına yükleme / kredi tutarı (ör. 1.00) | hayır |
total_topup_amount | String | Kullanıcıya eklenecek toplam kredi. quantity × product_topup_amount (ör. 250.00). Oyunda veya platformunuzda bakiyeyi bu değerle artırın. | hayır |
product_currency | String | Ürün para birimi (ör. TRY, USD, EUR) | hayır |
unit_price | String | Birim fiyat (ör. 49.90) | hayır |
total_price | String | Sipariş tutarı: quantity × unit_price (ör. 149.70) | hayır |
net_merchant_earning | String | Komisyon düşüldükten sonra net kazancınız (ör. 127.25) | hayır |
user_id | String | Oturum isteğindeki müşteri kimliği — yoksa gönderilmez | hayır |
username | String | Varsa oyun / hesap kullanıcı adı (oturum isteğindeki username ile aynı) | hayır |
api_version | String | v2 teslimlerinde her zaman 2. Hash'te yer almaz. | hayır |
hash | String | HMAC-SHA256 base64 imza — işlemeden önce her zaman doğrulayın | — |
total_topup_amount alanına bakın. Bu tutarı username (veya oturum isteğindeki user_id) ile eşleşen kullanıcıya ekleyin. Müşterinin satın aldığı kesin miktar budur. Hata kodları
Token endpoint her zaman HTTP 200 döner. Sonucu success alanından okuyun. Hata yanıtında ayrıca bir message metni vardır.
invalid_hash ile reddedin — bu bildirimi işlemeyin. Hata listesi
| Durum | HTTP | success | message | Sık görülen neden |
|---|---|---|---|---|
| Zorunlu bir alan boş veya eksik | 200 | false | Missing required field: <field_name>. |
Alan POST gövdesine eklenmemiş |
username geçersiz karakter içeriyor |
200 | false | Invalid value for username. |
Kullanıcı adında boşluk, Türkçe karakter veya sembol var. Yalnızca a-z A-Z 0-9 _ - kabul edilir. |
user_email geçerli bir adres değil |
200 | false | Invalid value for user_email. |
E-posta formatı bozuk |
user_ip geçerli bir IP değil |
200 | false | Invalid value for user_ip. |
İstemci IP yerine sunucu IP'si gönderilmiş veya format hatalı |
Yanlış api_key / store_id çifti veya mağaza aktif değil |
200 | false | Invalid API credentials or store is not active. |
api_key store_id ile eşleşmiyor veya mağaza durumu approved_admin değil |
| Hash imzası tutmuyor | 200 | false | Invalid hash. Please recalculate… |
Alan sırası yanlış, api_secret yanlış veya pipe eksik. Alanlar tam sırada | ile birleştirilmelidir. |
| Webhook imzası tutmuyor | 403 | — | Düz metin: invalid_hash |
Endpoint imzayı reddetti — bu bildirimi işlemeyin |
Rate limit
Token endpoint üç ayrı rate limit uygular. Oturum ancak üçünü de geçerseniz oluşur. Herhangi biri aşılırsa HTTP 429 ve ne kadar bekleyeceğinizi söyleyen Retry-After başlığı döner.
Limit katmanları
| Katman | Kapsam | Varsayılan limit | Süre | HTTP |
|---|---|---|---|---|
| Hızlı IP limiti | İstemci IP başına | 60 istek | 60 saniye | 429 |
| Token IP limiti | İstemci IP başına | 30 istek | 1 dakika | 429 |
| Token API Key limiti | api_key başına |
60 istek | 1 dakika | 429 |
Öneriler
- 1 Oturumu ihtiyaç anında oluşturun — token'ı yalnızca kullanıcı ödeme yapmak üzereyken üretin. Toplu ön üretim yapmayın.
-
2
Retry-Afterdeğerine uyun — başlığı okuyun ve tam o kadar saniye bekleyin. Hemen tekrar denemek hem reddedilir hem kotanızı yer. - 3 Token'ı saklayıp tekrar kullanmayın — token tek kullanımlıktır ve 2 saat sonra dolar. Kullanıcılar arasında paylaşılmaz.
-
4
Üstel bekleme kullanın —
429alırsanız rastgele gecikmeli (jitter) exponential backoff uygulayın. Hep birlikte aynı anda denemeyin.