API Kullanım Kılavuzu
Tranigo ağındaki havalimanı ve şehir içi transferleri kendi sisteminizden aramak, satmak ve takip etmek için.
https://api.citytransferturkey.comcamelCase, enum'lar metin ("OnAccount").YYYY-MM-DD; alış saati Türkiye yerel saati HH:mm; zaman damgaları ISO-8601 (UTC)./v1 · Mobil müşteri API'si: /mobile/v1Bu sayfa akışı ve kuralları anlatır. Her alanın tam tanımı için Swagger sayfasına bakın; oradan istekleri doğrudan deneyebilirsiniz.
Kimlik doğrulama
Sunucudan sunucuya entegrasyonda API anahtarı kullanılır. Anahtarı acenta panelinde API & Webhook sayfasından üretirsiniz; anahtar yalnızca bir kez gösterilir, bizde saklanmaz.
| Anahtar | Mod | Ne olur |
|---|---|---|
ctt_live_… | Canlı | Gerçek rezervasyon açılır, sağlayıcıya iletilir, cari hesabınıza yazılır. |
ctt_test_… | Sandbox | Hiçbir şey gerçek değildir: transfer oluşmaz, cariye yazılmaz, ödeme taklit edilir. |
Anahtarı iki şekilde gönderebilirsiniz:
Authorization: Bearer ctt_live_xxxxxxxxxxxxxxxx
# ya da
X-Api-Key: ctt_live_xxxxxxxxxxxxxxxx
Bağlantıyı denemek için:
curl https://api.citytransferturkey.com/v1/me \
-H "Authorization: Bearer ctt_test_xxxxxxxx"
Yanıtta firma bilginiz, modunuz (live/test), komisyon oranınız ve cari hesabınızın açık olup olmadığı döner.
Hızlı başlangıç
Bir rezervasyon dört çağrıdır. Önce ctt_test_ anahtarıyla deneyin.
- Konum bulun — havalimanı ya da otel bölgesinin kimliği:
curl "https://api.citytransferturkey.com/v1/locations?q=antalya" \ -H "Authorization: Bearer $CTT_KEY" - Teklif alın — güzergah, tarih ve yolcu sayısına göre araçlar ve fiyatlar (30 dakika geçerli):
curl -X POST https://api.citytransferturkey.com/v1/quotes \ -H "Authorization: Bearer $CTT_KEY" -H "Content-Type: application/json" \ -d '{"fromRegionId":"…","toRegionId":"…","date":"2026-11-20","passengers":2}' - Rezervasyon açın — seçtiğiniz teklif, yolcu bilgisi ve kendi rezervasyon numaranızla:
curl -X POST https://api.citytransferturkey.com/v1/bookings \ -H "Authorization: Bearer $CTT_KEY" -H "Content-Type: application/json" \ -d '{ "quoteId": "…", "paymentMethod": "OnAccount", "externalReference": "ACN-2026-0042", "pickupDate": "2026-11-20", "pickupTime": "14:30", "passenger": { "firstName": "Ayşe", "lastName": "Yılmaz", "phoneCode": "+90", "phone": "5551112233", "email": "ayse@example.com" }, "passengerCount": 2, "flightCode": "TK2412", "hotelAddress": "Lara Cd. No:1, Antalya" }' - Takip edin —
GET /v1/bookings/{code}ile ya da webhook'larla durum değişikliklerini alın.
Konumlar ve teklif
GET /v1/locations?q=… en az 2 karakterle havalimanı/bölge arar. GET /v1/locations/{regionId}/destinations o bölgeden fiyatı olan varış noktalarını verir.
POST /v1/quotes uygun araçları döner. Her teklifte:
| Alan | Açıklama |
|---|---|
quoteId | Rezervasyonda kullanılır. 30 dakika geçerli, tek kullanımlık, size ve bu güzergah/tarihe bağlı. |
price, currency | Yolcuya satış fiyatı (yön başına). |
commission, netPrice | Komisyonunuz ve net tutar (satış − komisyon). Net fiyat modundaki partnerler için netPrice bize ödenecek tutardır. |
passengerCapacity, luggageCapacity | Araç kapasitesi. Yolcu sayısı kapasiteyi aşamaz. |
Sağlayıcının kapalı günü olan ya da en az rezervasyon süresine (ör. 12 saat önceden) yetişmeyen araçlar teklifte hiç görünmez. İsteğe "currency": "EUR" ekleyerek fiyat dövizini seçebilirsiniz (TRY, EUR, USD); verilmezse hesabınızın dövizi kullanılır.
Rezervasyon açma
POST /v1/bookings — yeni rezervasyon 201, aynı externalReference ile daha önce açılmış rezervasyon 200 döner.
Tekrar deneme güvenliği (idempotency)
externalReference sizin rezervasyon numaranızdır ve hesabınızda benzersizdir. Ağ hatasında isteği aynı numarayla tekrar göndermeniz yeterli: ikinci kez rezervasyon açılmaz, mevcut olan döner. Bu alanı her zaman göndermenizi öneririz.
Dönüş transferi
İsteğe "return": {"date":"2026-11-25","time":"10:00","flightCode":"TK2413","hotelAddress":"…"} ekleyin. Dönüş ayrı bir rezervasyon kodu (…-R) alır; yanıtta return alanında gelir. Gidişi iptal etmek dönüşü de iptal eder.
Yanıt
{
"booking": { "code": "CTT7K2M9Q", "externalReference": "ACN-2026-0042", "status": "Pending",
"scheduledDate": "2026-11-20", "scheduledTime": "14:30", "price": 120.00, "currency": "EUR",
"commission": 12.00, "commissionCurrency": "EUR", "isTest": false, … },
"return": null,
"payment": { "method": "OnAccount", "status": "Paid", "online": null }
}
Ödeme seçenekleri
paymentMethod | Kim öder | Nasıl işler |
|---|---|---|
OnAccount | Siz (cari) | Net tutar cari hesabınıza borç yazılır. Kredi limiti tanımlı olmalı; limit ya da vadesi geçmiş borç aşılırsa 422. |
OnAccount + "partnerPaysByCard": true | Siz (kart) | Net tutarı kendi kartınızla ödersiniz; kredi limiti gerekmez. Yanıttaki payment.online.url sayfasında ödeyin. Ödeme gelince cariye borç ve tahsilat birlikte yazılır. |
CreditCard | Yolcu (kart) | Yanıttaki payment.online.url linkini yolcunuza iletin; yolcu satış fiyatını kartla öder. Komisyonunuz transfer tamamlanınca carinize alacak yazılır. Net fiyat modunda yoktur. |
Cash | Yolcu (nakit) | Sürücü yolcudan tahsil eder; komisyonunuz transfer tamamlanınca carinize yazılır. Net fiyat modunda yoktur. |
Kartla ödeme beklenen rezervasyon
"payment": {
"method": null, "status": null,
"online": {
"url": "https://citytransferturkey.com/en/Pay/Ab3dEf7hJk9m",
"paidBy": "passenger", // "passenger" | "partner"
"amount": 120.00, "currency": "EUR",
"dueAt": "2026-11-12T09:14:00Z",
"status": "awaiting_payment", // awaiting_payment | paid | cancelled | expired
"paidAt": null
}
}
booking.cancelled webhook'u gider). Transfere 75 dakikadan az kaldıysa kartlı seçenekler kabul edilmez (422). Ödeme gelince booking.paid webhook'u gider.Durumlar ve iptal
| Durum | Anlamı |
|---|---|
Pending | Alındı, sağlayıcı onayı bekleniyor. |
Confirmed | Sağlayıcı onayladı. |
Completed | Transfer yapıldı. |
Cancelled | İptal (cancellationReason alanında neden). |
POST /v1/bookings/{code}/cancel gövde: {"reason":"Müşteri vazgeçti"} (isteğe bağlı). Sözleşmenizdeki ücretsiz iptal süresi geçtiyse (ör. alıştan 24 saat öncesine kadar) geç iptal ücreti cari hesabınıza yazılır; cari rezervasyonun borcu ters kaydedilir. Tamamlanmış ya da zaten iptal edilmiş rezervasyon iptal edilemez (422).
GET /v1/bookings listeleme: status, dateFrom, dateTo, search, page, pageSize (en fazla 100).
Sandbox (test)
ctt_test_ anahtarıyla her şeyi gerçek veri üretmeden deneyin. Test rezervasyonları canlı kayıtlarınızla karışmaz (ayrı listelenir), sağlayıcıya gitmez, cariye yazılmaz. Webhook'lar "livemode": false ile gönderilir.
Kartlı test rezervasyonunda gerçek ödeme linki oluşmaz (payment.online.url = null). Ödemeyi taklit etmek için:
curl -X POST https://api.citytransferturkey.com/v1/bookings/CTT7K2M9Q/simulate-payment \
-H "Authorization: Bearer ctt_test_xxxxxxxx"
Bu uç nokta canlı anahtarla 403 döner.
Webhook'lar
Panelde API & Webhook sayfasından bir HTTPS adresi girin; rezervasyonlarınızdaki her değişiklik bu adrese imzalı POST olarak gelir. İmza sırrı (whsec_…) yalnızca oluşturulduğunda bir kez gösterilir.
| Olay | Ne zaman |
|---|---|
booking.created | Rezervasyon açıldı |
booking.paid | Kartla ödemesi beklenen rezervasyonun ödemesi alındı |
booking.confirmed | Sağlayıcı onayladı |
booking.completed | Transfer tamamlandı |
booking.cancelled | İptal edildi (siz, biz ya da ödeme süresi dolduğu için) |
İstek
POST /ctt-webhook HTTP/1.1
Content-Type: application/json
User-Agent: CityTransferTurkey-Webhooks/1.0
X-CTT-Event: booking.confirmed
X-CTT-Delivery: 6f1c… (her gönderimin kimliği — tekrarları ayıklamak için)
X-CTT-Signature: t=1763630000,v1=5a0d…
{ "id": "…", "event": "booking.confirmed", "createdAt": "2026-11-12T08:00:00Z",
"livemode": true, "data": { "code": "CTT7K2M9Q", "status": "Confirmed", … } }
İmzayı doğrulama
v1 = hex( HMAC-SHA256( sır, t + "." + ham_gövde ) ). Gövdeyi JSON olarak çözmeden önce, ham haliyle doğrulayın ve t'nin son 5 dakika içinde olduğunu kontrol edin (tekrar saldırısına karşı).
const crypto = require("crypto");
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
static bool Verify(string rawBody, string header, string secret)
{
var parts = header.Split(',').Select(p => p.Split('=', 2)).ToDictionary(p => p[0], p => p[1]);
if (Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - long.Parse(parts["t"])) > 300) return false;
var hash = HMACSHA256.HashData(Encoding.UTF8.GetBytes(secret), Encoding.UTF8.GetBytes($"{parts["t"]}.{rawBody}"));
var expected = Convert.ToHexString(hash).ToLowerInvariant();
return CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes(expected), Encoding.ASCII.GetBytes(parts["v1"]));
}
function verify(string $rawBody, string $header, string $secret): bool {
parse_str(str_replace(',', '&', $header), $parts);
if (abs(time() - (int)$parts['t']) > 300) return false;
$expected = hash_hmac('sha256', $parts['t'] . '.' . $rawBody, $secret);
return hash_equals($expected, $parts['v1']);
}
Teslim ve tekrar
Adresiniz 10 saniye içinde 2xx dönmelidir; dönmezse 1 dk, 5 dk, 15 dk, 30 dk, 1 sa, 3 sa, 6 sa, 12 sa aralıklarla 8 kez tekrar denenir. Yönlendirmeler (3xx) izlenmez. Aynı olay birden fazla gelebilir — X-CTT-Delivery ya da gövdedeki id ile ayıklayın; olaylar sırasız gelebilir, karar verirken data.status'a bakın. Başarısız gönderimleri panelden tekrar kuyruğa alabilirsiniz.
Cari hesap
GET /v1/account — bakiye (pozitif: bize borcunuz, negatif: alacağınız), kredi limiti, kullanılabilir tutar, vadesi geçmiş borç.
GET /v1/account/statement?from=…&to=…&page=1&pageSize=100 — hareket dökümü: rezervasyon borcu, komisyon alacağı, ödeme, geç iptal ücreti, ters kayıtlar ve yürüyen bakiye. Aylık ekstre ayrıca e-postanıza gönderilir.
Hatalar
Hatalar RFC 9457 application/problem+json biçimindedir; detail alanı insan için açıklamadır.
{ "type": "https://api.citytransferturkey.com/errors/business_rule",
"title": "Business rule violation", "status": 422,
"detail": "Kredi limiti aşılıyor. Kullanılabilir: 40,00 EUR, gereken: 108,00 EUR.",
"traceId": "00-…" }
| Kod | Ne zaman | Ne yapmalı |
|---|---|---|
| 400 | Eksik / hatalı alan (errors alanında ayrıntı) | İsteği düzeltin. |
| 401 | Anahtar/token yok, hatalı, iptal edilmiş ya da süresi dolmuş | Anahtarı kontrol edin; token'ı yenileyin. |
| 403 | Bu kimlikle bu işlem yapılamaz (ör. canlı anahtarla simulate-payment) | Doğru anahtar/token'ı kullanın. |
| 404 | Rezervasyon yok ya da size ait değil | Kodu kontrol edin. |
| 422 | İş kuralı: kredi limiti, süresi dolmuş teklif, kapalı gün, kapasite, iptal edilemez durum… | detail'ı kullanıcıya gösterin; teklif süresi dolduysa yeniden teklif alın. |
| 429 | Hız sınırı | Retry-After saniye kadar bekleyin. |
| 5xx | Bizim tarafta geçici sorun | Aynı externalReference ile güvenle tekrar deneyin. |
Hız sınırları
| Kimlik | Sınır |
|---|---|
| API anahtarı / acenta token'ı | Partner başına dakikada 120 istek |
| Mobil müşteri token'ı | Müşteri başına dakikada 120 istek |
| Kimliksiz istekler (arama vb.) | IP başına dakikada 30 istek |
| Giriş / kayıt / yenileme / şifre sıfırlama | IP başına dakikada 10 istek |
Sınır aşılınca 429 ve Retry-After başlığı döner. Teklif sonuçlarını kısa süre (≤30 dk) önbelleğe alarak istek sayınızı azaltabilirsiniz.
Acenta kullanıcı girişi
Kendi mobil uygulamanız ya da panel arayüzünüz için API anahtarı yerine acenta panelindeki kullanıcı e-posta/şifresiyle token alın. Token'la bütün /v1 uç noktaları aynı çalışır (yalnızca canlı mod).
POST /v1/auth/login { "email": "ops@acenta.com", "password": "…", "deviceName": "iPhone" }
→ 200 { "accessToken": "cttm_…", "tokenType": "Bearer", "expiresAt": "…",
"refreshToken": "cttr_…", "refreshTokenExpiresAt": "…" }
GET /v1/bookings Authorization: Bearer cttm_…
POST /v1/auth/refresh { "refreshToken": "cttr_…" } → yeni token çifti
POST /v1/auth/logout { "refreshToken": "cttr_…" } → 204
Mobil müşteri API'si
Tranigo mobil uygulaması içindir; web sitesindeki müşteri hesabıyla aynı hesap kullanılır. Tam referans: Swagger · Mobile API.
| Uç nokta | Açıklama | |
|---|---|---|
| POST | /mobile/v1/auth/register | Hesap aç → token çifti (e-posta kayıtlıysa 409) |
| POST | /mobile/v1/auth/login | Giriş → token çifti |
| POST | /mobile/v1/auth/refresh · /logout | Token yenile / çıkış |
| POST | /mobile/v1/auth/forgot-password · /reset-password | 6 haneli e-posta koduyla şifre sıfırlama |
| GET PUT | /mobile/v1/me | Profil; POST /mobile/v1/me/password şifre değiştir |
| GET | /mobile/v1/locations?q= | Konum arama (giriş gerekmez) |
| GET | /mobile/v1/search?fromRegionId&toRegionId&date&passengers¤cy | Fiyatlı araçlar, priceId ve kabul edilen ödeme yöntemleri (giriş gerekmez) |
| POST | /mobile/v1/bookings | Rezervasyon; yanıttaki payment.url ödeme sayfasıdır. İsteğe bağlı couponCode (geçersizse 422) ve useWallet: true (sadakat cüzdanı bakiyesi indirim olarak kullanılır) |
| GET | /mobile/v1/bookings · /{code} | Rezervasyonlarım |
| GET | /mobile/v1/tours/suggest?q&language | Tur araması (en az 3 harf): turu olan şehirler, kategoriler, turlar (giriş gerekmez) |
| GET | /mobile/v1/tours?cityId&areaId&date¤cy&language&sort&page&pageSize | Şehrin turları; filtreler priceMin, priceMax, durations, themes, guideLanguages (çok değerde parametre tekrarlanır) (giriş gerekmez) |
| GET | /mobile/v1/tours/{tourId}?date¤cy&language | Tur detayı ve rezervasyon seçenekleri: kalkış saatleri, rehber dilleri, alış noktaları (giriş gerekmez) |
| GET | /mobile/v1/tours/{tourId}/quote?date&adults&childAges¤cy | Kesin fiyat, kalem kalem; status Ok değilse rezervasyon açılamaz (giriş gerekmez) |
| POST | /mobile/v1/tour-bookings | Tur rezervasyonu; yanıttaki payment.url tur ödeme sayfasıdır. Kural ihlalinde 422, nedeni reason alanında |
| GET | /mobile/v1/tour-bookings · /{code} | Tur rezervasyonlarım |
| POST | /mobile/v1/auth/apple | Apple ile giriş (iOS): identityToken, authorizationCode, nonce, ilk girişte ad/soyad → token çifti. Hesap Apple kimliği ya da Apple'ın doğruladığı e-postayla eşleşir, yoksa açılır. 401 geçersiz token, 422 e-posta yok, 503 kapalı |
| POST | /mobile/v1/me/delete | Hesabı sil: { "password": "…" } (şifresiz Apple/Google hesabında boş). Kişisel bilgiler silinir, oturumlar kapanır, Apple token'ı iptal edilir; rezervasyon kayıtları kalır. 422 reason: WrongPassword, ActiveReservations |
| GET | /mobile/v1/app/config?platform&version | Açılış ayarları: updateRequired (bu sürüm artık kullanılamaz), updateAvailable, mağaza linki, destek telefonu / e-posta / WhatsApp (giriş gerekmez) |
| POST | /mobile/v1/app/installations | Kurulum bilgisi: installationId, platform, sürüm, dil, push token ve izin. Her açılışta, girişten sonra ve token değişince; müşteri token'ı varsa kurulum müşteriye bağlanır (giriş gerekmez) |
| POST | /mobile/v1/app/installations/{installationId}/sign-out | Çıkıştan önce: kurulumun müşteri bağı kaldırılır |
| POST | /mobile/v1/app/campaigns/{campaignId}/opened | Kampanya bildirimine dokunuldu: { "installationId": "…" }. Admin ekranındaki "Açılma" sayısı; aynı kurulumun tekrarı sayılmaz (giriş gerekmez) |
| GET | /mobile/v1/home?language¤cy | Ana sayfa: turu olan şehirler (tur sayısına göre) ve öne çıkan turlar, bugünün başlangıç fiyatıyla; 10 dk önbellek (giriş gerekmez) |
| POST | /mobile/v1/auth/google | Google ile giriş: { "idToken": "…", "deviceName": "…" } → token çifti. Token Admin → Ayarlar → Google ile Giriş'teki web ya da mobil Client ID'lerinden birine verilmiş olmalı. 401 geçersiz token, 422 e-posta doğrulanmamış, 503 kapalı |
| POST | /mobile/v1/me/email/verify · /email/resend | E-posta doğrulama: 6 haneli kod → güncel profil (isEmailVerified, pendingEmail). 422 reason: InvalidCode, Expired, TooManyAttempts. Doğrulanınca aynı e-postayla yapılmış misafir rezervasyonlar hesaba bağlanır |
| GET | /mobile/v1/links/reservation/{token} · /links/review/{token} | E-postadaki /{dil}/my-booking/{token} ve /{dil}/review/{token} bağlantılarının rezervasyonu: { kind, code }; geçersizse 404 (giriş gerekmez) |
| GET | /mobile/v1/bookings/{code}/manage | Transfer: iptal / değişiklik yapılabilir mi, son an (cancelDeadline), iptal ücreti (%), tahmini kart iadesi, cüzdana dönecek tutar, değiştirilebilir bilgiler |
| POST | /mobile/v1/bookings/{code}/cancel | Transfer iptali (gidiş-dönüşte kalan bacaklarla); kartla ödenmişse ücret düşülerek iade. refundPending: true = otomatik iade yapılamadı, ekip elle iade eder. 422 reason: Disabled, TooLate, NotCancellable, PartnerBooking |
| PUT | /mobile/v1/bookings/{code}/details | Yolcu, yolcu sayısı, tarih-saat (HH:mm), uçuş / otel değişikliği (iptal süresiyle aynı pencere; değişen alanlar admine bildirilir). 422 reason: TooLate, Invalid |
| GET | /mobile/v1/vouchers/{transfer|tour}/{code}?language | Voucher PDF adresi ve dosya adı (QR'lı; uygulama indirip saklar, çevrimdışı da açılır) |
| GET POST | /mobile/v1/messages/{transfer|tour}/{code} | Rezervasyon yazışması (açınca ekibin mesajları okundu sayılır) / mesaj gönder { "text": "…" }. 422 reason: Empty, TooLong, TooManyLinks, RateLimited. Ekip cevap yazınca e-posta + bildirim (data.url = /messages/{kind}/{code}) |
| GET | /mobile/v1/messages/unread | Okunmamış ekip cevapları: [{ kind, code, count }] |
| GET POST | /mobile/v1/reviews/{transfer|tour}/{code} | Değerlendirme formu (kriterler, mevcut yorum) / kaydet { comment, scores: [{ criterionId, stars }] }. Yalnızca tamamlanan rezervasyon; değilse 422 NotAllowed |
| POST | /mobile/v1/bookings/quote | Ödeme adımı önizlemesi: { priceId, currency, hasReturn, passengerCount, couponCode, useWallet } → ara toplam, kupon indirimi, cüzdan, ödenecek tutar, kupon red nedeni (couponRejection), cüzdan bakiyesi. Rezervasyonla aynı hesap |
| GET | /mobile/v1/me/wallet | Sadakat cüzdanı: bakiye (EUR), kazanç oranı ve hareketler (Earned, Spent, Refunded, Expired, Adjustment, ReviewReward) |
| GET | /mobile/v1/tours/{tourId}/request-availability?date&adults&childAges | Tarih online satılamıyorsa talep gönderilebilir mi: allowed, block (BookableOnline, TooLate, NotAvailable), leadHours |
| POST | /mobile/v1/tour-requests | Tur talebi (fiyat / kontenjan tutulmaz; ekip e-postayla teklif gönderir) → 201 requestCode. 422 reason: InvalidName, InvalidEmail, InvalidPhone, TooLong, BookableOnline, TooLate (leadHours), NotAvailable |
Dil: uygulama her isteğe X-App-Language: tr|en|de|es|fr başlığını ekler; sunucunun gönderdiği e-postalar (doğrulama kodu, şifre sıfırlama, talep onayı) bu dilde gider.
Uygulama bağlantıları: site /.well-known/apple-app-site-association (Apple Team ID + Bundle ID: Admin → Ayarlar → Apple ile Giriş) ve /.well-known/assetlinks.json (paket adı + imza SHA-256: Admin → Mobil Uygulama → Sürüm ayarları) dosyalarını yayınlar. E-postadaki rezervasyon ve değerlendirme bağlantıları uygulama kuruluysa uygulamada açılır.
Hız sınırı: uygulama her isteğe X-Installation-Id: <installationId> başlığını ekler. Giriş yapmamış mobil istekler IP yerine kurulum başına sınırlanır (dakikada 120; aynı IP için toplam 600 üst sınır). Başlık yoksa IP başına dakikada 30 geçerlidir.
Kurulum ve bildirimler: uygulama ilk açılışta bir installationId (GUID) üretip güvenli depoda saklar. Push token Firebase'den (FCM) alınır, iOS'ta da FCM token'ı gönderilir. Admin → Mobil Uygulama ekranı bu kayıtlarla hangi sürümde kimlerin olduğunu gösterir ve bildirim gönderir. Bildirimin data.url alanı uygulama içi adrestir (ör. /tours/…) ya da https bağlantısıdır.
Ödeme: rezervasyon yanıtındaki payment.url adresini uygulama içi tarayıcıda açın; müşteri kart, ön ödeme ya da nakit seçer. Durum payment.status alanındadır: awaiting_payment, paid, deposit_paid, pay_driver, refunded, none. Turda nakit seçilmişse pay_driver yerine pay_on_tour gelir (ücret turda ödenir).
Turlar
Akış: suggest ile şehir ya da kategori seçilir → tours listesi → tours/{id} detayı → quote ile kesin fiyat → tour-bookings. Fiyat her zaman sunucuda hesaplanır; rezervasyon da quote ile aynı hesabı kullanır. Tarih verilmezse bugün (Türkiye saati) kullanılır. Dil: en, tr, de, fr, es; tur o dilde yayında değilse İngilizcesi döner (fallbackCulture: "en").
Rezervasyonda tur birden çok kalkış saatine sahipse startTime (HH:mm), birden çok rehber diline sahipse guideLanguage zorunludur. Alış noktası olan turda pickupRegionId ya da pickupAddress verilmelidir. Ödenmemiş tur rezervasyonu kontenjanda 10 dakika yer tutar. 422 nedenleri: NotAvailable, InvalidPax, Closed, OverCapacity (remainingCapacity), TooLate, NoPrice, InvalidName, InvalidEmail, InvalidPhone, InvalidStartTime, InvalidGuideLanguage, InvalidPickup, TooLong, Busy (aynı anda başka rezervasyon işleniyor, tekrar deneyin), TooManyPending (müşterinin ödenmemiş 3 tur rezervasyonu var; birini ödeyin ya da 10 dakika bekleyin).
Uç nokta listesi (Partner API)
| Uç nokta | Açıklama | |
|---|---|---|
| GET | /v1/me | Hesap bilgisi ve mod |
| GET | /v1/locations · /v1/locations/{id}/destinations | Konumlar |
| POST | /v1/quotes | Teklif (30 dk) |
| POST | /v1/bookings | Rezervasyon aç |
| GET | /v1/bookings · /v1/bookings/{code} | Listele / getir |
| POST | /v1/bookings/{code}/cancel | İptal |
| POST | /v1/bookings/{code}/simulate-payment | Sandbox ödeme taklidi |
| GET | /v1/account · /v1/account/statement | Cari hesap |
| POST | /v1/auth/login · /refresh · /logout | Acenta kullanıcı token'ı |
Sorularınız ve canlıya geçiş için: support@citytransferturkey.com