WISECP'te bir iletişim formunu destek talebine çevirmek için Yönetim API'sinin POST /api/v1/admin/tickets ucu (Tickets/CreateTicket) kullanılır. Bu uç client_id, subject ve message alanlarını zorunlu tutar; yani talep mutlaka kayıtlı bir müşteriye açılır. Belgelenmiş bir misafir talebi ucu yoktur. Formu dolduran kişi kayıtlı değilse ya önce müşteri kaydı oluşturursunuz ya da WISECP'nin kendi iletişim formunu ve Destek Talebine Dönüştür akışını kullanırsınız.
Bu rehberde sitenizdeki formdan gelen veriyi sunucu tarafında doğrulayıp, e-postayla müşteriyi bulan ve talebi açan kısa bir PHP betiği yazıyoruz. API anahtarı hiçbir zaman tarayıcıya gitmez. API'nin genel yapısı, anahtar üretimi ve hata kodları için önce WISECP API kullanımı yazısını okumanızı öneririz. Panel tarafındaki destek sistemi için WISECP destek talebi sistemi yazısına bakabilirsiniz.
Akış: formdan talebe

- Ziyaretçi sitenizdeki formu doldurur; form kendi sunucunuzdaki bir betiğe POST eder.
- Betik CSRF, honeypot ve hız kontrollerini yapar, girdileri doğrular.
- Betik WISECP'de bu e-postaya ait müşteriyi arar (
GET /clients?search=...). - Müşteri varsa
POST /ticketsile talep açılır; WISECP talebi açtığı için müşteriye bildirim gider. - Müşteri yoksa belgelenmiş iki yoldan birini seçersiniz (aşağıda).
API anahtarını hazırlama: en dar izin
Panelde Ayarlar > Genel Ayarlar > API sekmesinde yeni bir kimlik bilgisi oluşturun ve yalnızca bu iş için gereken izinleri işaretleyin. İzin verilen IP adresleri alanına formu işleyen web sunucunuzun IP'sini yazın; böylece anahtar sızsa bile başka bir yerden kullanılamaz.
| İzin | Neden gerekli |
|---|---|
| Tickets/CreateTicket | Talebi açmak için |
| Clients/GetClients | E-postaya göre müşteriyi bulmak için |
| Tickets/GetTicketDepartments | Departman numarasını bir kez okumak için (kurulumda kullanılır, sonra kaldırılabilir) |
| Clients/CreateClient | Yalnızca kayıtsız ziyaretçiye hesap açmayı seçerseniz |
Departman numarasını koda gömmeden önce listeden okuyun. Belge, departmanların kurulumdan kuruluma değiştiğini ve koda gömülmemesi gerektiğini söyler:
curl 'https://panel.ornek.com/api/v1/admin/tickets/departments' \
-H "Authorization: Bearer $WISECP_API_KEY"
# data[]: id, name, description, icon, icon_typeÖncelik değerleri için GET /api/v1/admin/tickets/priorities ucu value ve label çiftleri döndürür. Bulduğunuz departman numarasını WISECP_DEPT_ID gibi bir ortam değişkenine yazın.
Talep açma ucu: alanlar ve yanıt

POST /api/v1/admin/tickets belgeye göre personel adına bir müşteriye talep açar ve ilk mesajı yazar. Gövde alanları şunlardır:
| Alan | Tip | Açıklama |
|---|---|---|
| client_id | int, zorunlu | Talebin sahibi müşteri |
| subject | string, zorunlu | Talebin konusu |
| message | string, zorunlu | İlk mesaj; müşteri verisiyle dolan yer tutucular kullanılabilir |
| department_id | int | Talebin departmanı |
| priority | int | Öncelik (tickets/priorities listesinden) |
| status | string | open, waiting, process, replied, solved |
| service_id | int | İlişkili hizmet; müşterinin kendi hizmeti olmalı |
| assigned_id | int | Atanacak personel; atanırsa ona da haber gider |
| custom_status_id | int | Kuruluma özel durum |
| locked | bool | Talebi kilitli açar; müşteri yanıt yazamaz |
| encrypt | bool | İlk mesajı şifreli saklar |
| attachments | string / object / array | Eklenecek dosyalar |
Başarılı istek 201 ile döner ve data içinde açılan talebin detayını (detay ucuyla aynı şekilde) taşır; talep numarası data.id alanındadır. Belgede sayılan hatalar: invalid_client, subject_required, message_required, invalid_department, invalid_service, invalid_assigned, invalid_custom_status, bir kanca açmayı reddederse blocked_by_gate, create_failed (hepsi 422) ve izin eksikse 403 insufficient_scope.
Mesaj alanında yer tutucular ({FULL_NAME} gibi) çalıştığı için ziyaretçinin yazdığı metindeki süslü parantezleri gönderimden önce başka bir karaktere çevirmek, metnin beklenmedik şekilde değiştirilmesini önlemek için basit bir önlemdir.
Sunucu tarafı PHP betiği
Aşağıdaki betik sitenizin kendi sunucusunda çalışır; WISECP çekirdeğinde hiçbir dosyaya dokunmaz. Formun gösterildiği sayfa oturumda csrf ve form_ts değerlerini üretir, formda website adlı görünmez bir honeypot alanı bulunur. Anahtar getenv() ile okunur.
<?php
// iletisim.php: sitenizin sunucusunda çalışır. API anahtarı tarayıcıya hiç gitmez.
session_start();
header('Content-Type: application/json; charset=utf-8');
const PANEL = 'https://panel.ornek.com/api/v1/admin';
function wisecp(string $method, string $path, ?array $body = null, array $query = [], string $idem = ''): array
{
$ch = curl_init(PANEL . $path . ($query ? '?' . http_build_query($query) : ''));
$headers = ['Authorization: Bearer ' . getenv('WISECP_API_KEY'), 'Accept: application/json'];
$opts = [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_CUSTOMREQUEST => $method];
if ($body !== null) {
$headers[] = 'Content-Type: application/json';
if ($idem !== '') $headers[] = 'Idempotency-Key: ' . $idem;
$opts[CURLOPT_POSTFIELDS] = json_encode($body);
}
$opts[CURLOPT_HTTPHEADER] = $headers;
curl_setopt_array($ch, $opts);
$raw = curl_exec($ch);
$status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['status' => $status, 'body' => json_decode((string) $raw, true) ?? []];
}
function bitir(int $kod, string $mesaj): never
{
http_response_code($kod);
echo json_encode(['ok' => $kod < 300, 'mesaj' => $mesaj]);
exit;
}
// 1. Temel kapılar: yöntem, CSRF, honeypot, çok hızlı gönderim
if ($_SERVER['REQUEST_METHOD'] !== 'POST') bitir(405, 'Geçersiz istek.');
if (!hash_equals($_SESSION['csrf'] ?? '', (string) ($_POST['csrf'] ?? ''))) bitir(403, 'Oturum süresi doldu, sayfayı yenileyin.');
if (($_POST['website'] ?? '') !== '') bitir(200, 'Mesajınız alındı.'); // bota başarı gibi görünür
if (time() - (int) ($_SESSION['form_ts'] ?? 0) < 3) bitir(429, 'Lütfen tekrar deneyin.');
// 2. Doğrulama
$ad = trim(strip_tags((string) ($_POST['ad'] ?? '')));
$email = filter_var(trim((string) ($_POST['email'] ?? '')), FILTER_VALIDATE_EMAIL);
$konu = trim(strip_tags((string) ($_POST['konu'] ?? '')));
$mesaj = trim(strip_tags((string) ($_POST['mesaj'] ?? '')));
$onay = ($_POST['aydinlatma'] ?? '') === '1';
if (!$email || mb_strlen($ad) < 2 || mb_strlen($ad) > 100
|| mb_strlen($konu) < 3 || mb_strlen($konu) > 150
|| mb_strlen($mesaj) < 10 || mb_strlen($mesaj) > 5000 || !$onay) {
bitir(422, 'Lütfen tüm alanları doğru doldurun.');
}
$mesaj = str_replace(['{', '}'], ['(', ')'], $mesaj); // yer tutucu çakışmasını önler
// 3. Müşteriyi bul: search kısmi eşleşir, e-postayı birebir karşılaştırın
$r = wisecp('GET', '/clients', null, ['search' => $email, 'limit' => 25]);
if ($r['status'] !== 200) bitir(502, 'Şu an mesajınızı iletemiyoruz.');
$musteri = null;
foreach ($r['body']['data'] ?? [] as $c) {
if (strcasecmp((string) $c['email'], $email) === 0) { $musteri = $c; break; }
}
if (!$musteri) bitir(404, 'Bu e-posta ile kayıtlı hesap bulunamadı. Lütfen müşteri panelinden talep açın.');
// 4. Talebi aç. Aynı içerik tekrar gönderilirse ikinci talep açılmaz.
$idem = 'web-' . hash('sha256', $email . '|' . $konu . '|' . $mesaj);
$t = wisecp('POST', '/tickets', [
'client_id' => (int) $musteri['id'],
'department_id' => (int) getenv('WISECP_DEPT_ID'),
'subject' => '[Web formu] ' . $konu,
'message' => "Web sitesi iletişim formundan gelen mesaj\nAd: {$ad}\nE-posta: {$email}\n\n" . $mesaj,
], [], $idem);
if ($t['status'] === 201) {
unset($_SESSION['csrf']);
bitir(201, 'Talebiniz oluşturuldu. Numara: ' . (int) $t['body']['data']['id']);
}
error_log('wisecp talep hatasi: ' . $t['status'] . ' ' . ($t['body']['error']['code'] ?? '-'));
bitir(502, 'Şu an mesajınızı iletemiyoruz, lütfen daha sonra tekrar deneyin.');Betikte dikkat edilecek noktalar:
Clients/GetClientsucundakisearchparametresi belgeye göre ad veya e-postada arama yapar; tam eşleşme garantisi yoktur. Bu yüzden dönen listede e-postayı birebir karşılaştırıyoruz.Idempotency-Keybaşlığı sayesinde ziyaretçi butona iki kez basarsa ya da ağ hatasında istek tekrarlanırsa ikinci bir talep açılmaz; WISECP saklanan yanıtı döndürür.- WISECP'den dönen hata kodunu ziyaretçiye göstermiyoruz, yalnızca sunucu günlüğüne yazıyoruz. Ziyaretçiye genel bir mesaj yeterlidir.
neverdönüş tipi PHP 8.1 ve üzeri gerektirir; daha eski sürümde tipi kaldırın. PHP sürümleri için PHP nedir yazısına bakabilirsiniz.
Kayıtlı olmayan ziyaretçi ne olacak?

Belgelerde misafir adına talep açan bir yönetim ucu bulunmuyor. Betik bu durumda ziyaretçiyi müşteri paneline yönlendiriyor. Başka iki belgelenmiş seçeneğiniz var:
- Müşteri kaydı oluşturmak:
POST /api/v1/admin/clients(Clients/CreateClient)full_name,emailvepasswordalanlarını zorunlu tutar; e-posta kurulumda benzersiz olmalıdır, aksi haldeemail_existsdöner. Başarıda201ile yeni müşterinindata.iddeğerini alır, ardından talebi o numarayla açarsınız. Ancak bir iletişim formu gönderimini kendiliğinden hesap açmaya çevirmek, ziyaretçinin beklemediği bir işlemdir ve kişisel veri işleme amacını genişletir. Bunu yalnızca formda açıkça belirtir ve ziyaretçiden bu yönde onay alırsanız düşünün. - WISECP iletişim mesajlarını kullanmak: WISECP'nin kendi iletişim formundan gelen mesajlar gelen kutusuna düşer. Panelde Destek Talebine Dönüştür ile, API'de ise
POST /api/v1/admin/website/messages/{id}/convert-to-ticket(Website/ConvertMessageToTicket) ucuyla talebe çevrilir. Bu uçdepartmentalanını zorunlu tutar, isteğe bağlıpriority,staffvenotesalır veticket_idilemessage_iddöndürür. Belge, mesajın hangi talebe dönüştüğünüconverted_to_ticket_idalanında taşıdığını ve ikinci kez dönüştürmeden önce ona bakılması gerektiğini not eder.
curl -X POST 'https://panel.ornek.com/api/v1/admin/website/messages/20/convert-to-ticket' \
-H "Authorization: Bearer $WISECP_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"department":1,"priority":2}'
# data: { "ticket_id": ..., "message_id": 20 }Spam ve kötüye kullanım koruması
Herkese açık bir form, doğrudan destek kuyruğunuza yazan bir kapıdır. Yukarıdaki betik birkaç temel katman içeriyor; bunları kendi ortamınıza göre genişletin:
- CSRF jetonu: formun sizin sayfanızdan gönderildiğini doğrular.
- Honeypot alanı: CSS ile gizlenen bir alan; insanlar doldurmaz, basit botlar doldurur.
- Zaman kontrolü: sayfa açıldıktan birkaç saniye içinde gelen gönderimleri reddeder.
- IP başına hız sınırı: aynı adresten dakikada çok sayıda gönderimi keser. Yöntemler için rate limiting stratejileri yazısına bakın.
- CAPTCHA: yoğun spam alıyorsanız sunucu tarafında doğrulanan bir CAPTCHA ekleyin.
WISECP kendi formları için İşlem Kısıtlama ve BotShield gibi korumalar sunar; bunlar WISECP'nin kendi sitesindeki formlarda çalışır, sizin ayrı sitenizdeki betiği korumaz. Ayrıntılar için WISECP güvenlik ayarları ve BotShield yazısına bakabilirsiniz. Bir şey ters giderse Ayarlar > Genel Ayarlar > API > Kayıtlar sekmesi formdan gelen her isteği başlığı, gövdesi ve yanıtıyla gösterir.
KVKK notu
İletişim formu ad, e-posta ve mesaj içeriği gibi kişisel veriler toplar ve bu veriler WISECP'ye aktarılır. Formun yanında bir aydınlatma metni bulundurmanız, yalnızca amaç için gerekli alanları istemeniz ve açık rıza gerektiren işlemleri (ör. pazarlama izni) aydınlatmadan ayırmanız gerekir. Bu konuyu ayrıntılı olarak iletişim formu KVKK aydınlatma ve açık rıza yazısında anlattık. Yukarıdaki betikteki aydinlatma kutusu bir örnektir; metnin içeriğini hukuk danışmanınızla birlikte belirleyin.
Sık Sorulan Sorular
WISECP API ile müşteri olmayan birine destek talebi açabilir miyim?
Belgelenmiş yönetim ucu client_id alanını zorunlu tutar; misafir talebi ucu yoktur. Kayıtsız ziyaretçi için ya müşteri kaydı oluşturursunuz ya da WISECP'nin iletişim mesajlarını talebe dönüştürme akışını kullanırsınız.
Talep açıldığında müşteriye e-posta gider mi?
Evet. Belge, talep açmanın müşteriye bildirim gönderdiğini ve personel atanırsa atanan kişiye de haber gittiğini belirtir.
Form iki kez gönderilirse iki talep açılır mı?
Aynı Idempotency-Key ile gönderilen ikinci POST işi tekrar yapmaz, ilk yanıtı döndürür. Anahtarı mesaj içeriğinden türetirseniz çift tıklama ikinci talep açmaz.
Müşteri API (wck_) anahtarıyla bu iş yapılamaz mı?
Müşteri API'sinde de talep uçları var, ama anahtar tek bir müşteriye bağlıdır ve yalnızca o hesap adına çalışır. Sitenize gelen farklı ziyaretçiler için yönetim API'si ve sunucu tarafında tutulan bir wak_ anahtarı gerekir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: WISECP nedir · WISECP API kullanımı · WISECP destek talebi sistemi · WISECP güvenlik ayarları · İletişim formu ve KVKK · REST API güvenliği · .env dosyası