Payment Flows
Tekrarlayan Ödeme
Cron tabanlı otomatik fatura kesme ve başarısız ödeme yeniden denemesi
Cron Zamanlaması
{
"crons": [{
"path": "/api/billing/cron",
"schedule": "0 8,14,20 * * *"
}]
}Her gün 08:00, 14:00 ve 20:00'de çalışır.
Cron Akışı
GET /api/billing/cron
Authorization: Bearer {CRON_SECRET}
handleCronRequest() çalışır:
│
▼
manager.processDuePayments(serverIp)
│
▼
adapter.findSubscribersDueToday()
→ nextBillingDate <= şimdi
VE status IN (active, past_due, trial)
│
│ Her abone için (try/catch — bir hata diğerlerini etkilemez):
▼
adapter.createPayment({ status: "pending" }) ← önce kayıt aç
│
▼
client.chargeStoredCard({ utoken, ... })
│
│ chargeStoredCard() içinde:
│ POST paytr.com/odeme/capi/list → ctoken alınır
│ POST paytr.com/odeme → utoken + ctoken ile ödeme
│
├── SUCCESS / WAIT_CALLBACK
│ Payment "pending" kalır (webhook onaylayacak)
│
└── FAILURE (senkron)
Payment → "failed"
failedAttempts++
│
├── failedAttempts < maxRetries
│ Subscriber → status="past_due"
│ nextBillingDate = şimdi + retryIntervalHours
│ onPaymentFailed() tetiklenir
│
└── failedAttempts >= maxRetries
Subscriber → status="cancelled"
cancelledAt = şimdi
onSubscriptionCancelled() tetiklenirWebhook İşleme (Tekrarlayan Ödeme)
POST /api/billing/webhook
├─ HMAC-SHA256 hash doğrulanır
├─ Tekrarlayan ödeme olarak tanımlanır (merchant_oid prefix: BP...)
│
│ Başarılı ise:
│ ├─ Payment → "success"
│ ├─ Subscriber → status="active", failedAttempts=0
│ └─ nextBillingDate += interval
│
│ Başarısız ise:
│ ├─ Payment → "failed"
│ ├─ failedAttempts++
│ ├─ failedAttempts < maxRetries → past_due + retry zamanla
│ └─ failedAttempts >= maxRetries → cancelled
│
└─ "OK" dönermerchantOid Formatı (Tekrarlayan Ödeme)
BP{subscriberId_truncated}{base36-timestamp}
Örnek: BPsub4f2a8b9cM3X7KQ2
Maks. 64 karakter (PayTR limiti)serverIp parametresi PayTR tarafından Non-3D işlemlerde doğrulanır. Sunucunuzun gerçek public IP'sini geçin. Test modunda "127.0.0.1" kullanabilirsiniz.