Dönüşümleri bildir
Sunucudan sunucuya postback, alanları ve yanıtları.
Sunucu postback'i, mağazanın cli.gs'ye bir satışı bildirme yoludur. Bu sayfada hangi isteği göndereceğini, hangi alanları aldığını ve yanıtı nasıl okuyacağını öğrenirsin. Sunucun her sipariş için sakladığı ref kodu ve sipariş bilgileriyle tek bir HTTPS isteği gönderir. Komisyonu tek başına kaydeden tek kanal budur, bu yüzden her entegrasyonun buna ihtiyacı var.
Kısaca:
- Sunucundan, API anahtarınla
POST https://cli.gs/api/v1/track/conversiongönder. - Her zaman
ref,orderIdve netamountgönder. Mümkün olduğundacurrencyvecustomerTypeekle. - Bildirimler idempotenttir: aynı
orderIdbir kez sayılır, bu yüzden yeniden denemek güvenlidir. 201kaydedildi,200zaten kayıtlı demektir.429ve5xxdurumunda yeniden dene;400,401ve422durumunda isteği düzelt.
İstek
POST https://cli.gs/api/v1/track/conversion
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonİsteği sunucundan gönder, asla tarayıcıdan değil. En iyi an, sipariş onaylandığında veya ödendiğinde. İstek ağ hatası, zaman aşımı, HTTP 5xx veya 429 ile başarısız olursa daha sonra yeniden dene. Bir bildirimi tekrarlamak zararsızdır.

Alanlar
| Alan | Zorunlu | Anlamı |
|---|---|---|
ref | evet | Açılış sayfasındaki ?ref= parametresinden gelen kod |
orderId | evet | Sipariş numaran, en fazla 190 karakter. Tekrarlanan bildirimleri zararsız kılar |
amount | SALE için | İndirim sonrası net ara toplam, vergi ve kargo hariç. basketValue da kabul edilir |
currency | önerilir | Üç harfli kod. Programlar EUR ile hesaplaşır; verilmezse programın para birimi kullanılır |
eventType | hayır | SALE (varsayılan), LEAD veya SIGNUP |
customerType | hayır | Yeni müşteri komisyon kuralları için NEW veya RETURNING |
matchKey | hayır | Ürün anahtarı içeren kurallar için ürün veya kategori anahtarı. commissionGroup da kabul edilir |
occurredAt | hayır | Satışın saat dilimli ISO 8601 zamanı, ör. 2026-09-28T14:05:00Z |
test | hayır | true, para hareketi yaratmayan bir test dönüşümü kaydeder |
Bilinmesi gereken ayrıntılar
- amount bir dize veya sayı olabilir. Ondalık ayırıcı olarak nokta kullan (
"149.99").149,99ve1.234,56değerlerini de okuruz.1.234gibi belirsiz değerleri, negatif değerleri ve makul olmayan büyüklükteki sepetleri reddederiz.LEADveSIGNUPiçin tutar isteğe bağlıdır. - EUR dışındaki bir currency kaydedilir ama incelemeye bekletilir, çünkü programlar yalnızca EUR ile hesaplaşır.
- Başka bir değere sahip customerType yok sayılır.
RETURNINGolarak değerlendirilmez, bu yüzden bir yazım hatası yayıncının yeni müşteri komisyonunu düşüremez. - occurredAt, geç bildirdiğinde önemlidir, örneğin ödeme netleştikten sonra. Çerez süresi isteğin geldiği ana göre değil, bu zamana göre kontrol edilir. Tıklamadan önce veya gelecekte olamaz. Beş dakikalık saat farkı tolere edilir.
- test,
1veya"true"değil, JSON boolean değeritrueolmalıdır.
İdempotentlik
Her sipariş bir kez sayılır. Aynı orderId aynı eventType için tekrar gelirse yeni bir şey oluşturulmaz. Yanıt, "duplicate": true ve zaten kayıtlı olan dönüşümle birlikte 200 olur. Bu yüzden zaman aşımından sonra güvenle yeniden deneyebilir veya bildirimi iki yerden gönderebilirsin.
Bir potansiyel müşteri (lead) ve bir satış aynı sipariş numarasını paylaşabilir, örneğin şimdi kayıt, sonra satın alma. Bunlar eventType başına ayrı ayrı sayılır.
Örnekler
cURL
curl -X POST https://cli.gs/api/v1/track/conversion \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ref": "01J9Z4K6V0QX8M2N3P5R7S9T1WABCD",
"orderId": "100234",
"amount": "149.99",
"currency": "EUR",
"customerType": "NEW"
}'Node.js (fetch)
// Node 18+. Call this from your order-paid handler.
async function reportConversion(order) {
const res = await fetch("https://cli.gs/api/v1/track/conversion", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLIGS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
ref: order.cligsRef, // saved with the order at checkout
orderId: String(order.id),
amount: order.netSubtotal.toFixed(2),
currency: "EUR",
customerType: order.isFirstOrder ? "NEW" : "RETURNING",
occurredAt: order.createdAt.toISOString(),
}),
signal: AbortSignal.timeout(5000),
});
if (res.ok) return res.json(); // 200 or 201
if (res.status >= 500 || res.status === 429) throw new Error("retry later");
const err = await res.json().catch(() => ({}));
console.error("cli.gs refused the conversion", res.status, err.error); // do not retry unchanged
}PHP (curl)
<?php
function cligs_report_conversion(array $data): array {
$ch = curl_init('https://cli.gs/api/v1/track/conversion');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CLIGS_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($data),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
return ['status' => $status, 'body' => json_decode((string) $body, true)];
}
$result = cligs_report_conversion([
'ref' => $order['cligs_ref'],
'orderId' => (string) $order['id'],
'amount' => number_format($order['net_subtotal'], 2, '.', ''),
'currency' => 'EUR',
]);WooCommerce
Bu örnek, ödeme adımında ref kodunu siparişe kaydeder. Sipariş İşleniyor durumuna geçtiğinde, yani ödendiğinde satışı bildirir. ref kodunu yakala sayfasındaki cligs_ref çerezini varsayar.
<?php
// 1. At checkout: copy the ref code from the cookie onto the order.
function cligs_save_ref_on_order($order) {
$ref = $_COOKIE['cligs_ref'] ?? '';
if ($ref !== '' && preg_match('/^[0-9A-Za-z]{10,64}$/', $ref)) {
$order->update_meta_data('_cligs_ref', $ref);
}
}
add_action('woocommerce_checkout_create_order', 'cligs_save_ref_on_order'); // classic checkout
add_action('woocommerce_store_api_checkout_update_order_from_request', function ($order) { // block checkout
cligs_save_ref_on_order($order);
$order->save();
});
// 2. When the order is paid: report it. Runs server-side, also for background payment callbacks.
add_action('woocommerce_order_status_processing', function ($order_id) {
$order = wc_get_order($order_id);
$ref = $order ? $order->get_meta('_cligs_ref') : '';
if (!$ref || $order->get_meta('_cligs_reported')) {
return;
}
// Net subtotal after discount, excluding tax and shipping.
$amount = (float) $order->get_subtotal() - (float) $order->get_discount_total();
$response = wp_remote_post('https://cli.gs/api/v1/track/conversion', [
'headers' => [
'Authorization' => 'Bearer ' . CLIGS_API_KEY, // define in wp-config.php
'Content-Type' => 'application/json',
],
'body' => wp_json_encode([
'ref' => $ref,
'orderId' => (string) $order->get_id(),
'amount' => number_format(max(0, $amount), 2, '.', ''),
'currency' => $order->get_currency(),
'occurredAt' => $order->get_date_created()->format(DATE_ATOM),
]),
'timeout' => 5,
]);
$code = wp_remote_retrieve_response_code($response);
if ($code === 200 || $code === 201) {
$order->update_meta_data('_cligs_reported', 1);
$order->save();
}
});_cligs_reported işareti yalnızca bir isteği tasarruf eder; bildirimin kendisi idempotenttir. Bir istek başarısız olursa siparişi daha sonra yeniden bildirebilirsin. _cligs_ref olan ama _cligs_reported olmayan ödenmiş siparişleri arayan zamanlanmış bir görev bunu iyi yapar.
Yanıtlar
Başarılı bir bildirim, dönüşümü kaydettiğimiz haliyle döndürür:
{
"ok": true,
"conversionId": "cmg3x1q2w0001abcd9876efgh",
"status": "PENDING",
"commission": 12,
"duplicate": false,
"confirmed": false,
"test": false
}Alanların anlamı
status, komisyon kaydedilip onay süresini beklerkenPENDINGolur. Dönüşüm senin karar vermen için bekletiliyorsaNEEDS_REVIEWolur; örneğin EUR dışı para birimi, eşleşen komisyon kuralı olmaması, yetersiz bakiye veya dolandırıcılık sinyalleri nedeniyle. Bir test için veya artık aktif olmayan bir yayıncı içinREJECTEDolur.commission, program para birimindeki yayıncı komisyonudur.duplicate: true, bu siparişin zaten kayıtlı olduğu anlamına gelir. Hiçbir şey değişmedi.confirmed: true, bu bildirimin takip pikselinin aynı sipariş için zaten bildirdiği bir dönüşümü onayladığı anlamına gelir.
HTTP durum kodları
| HTTP | Gövde | Ne yapmalı |
|---|---|---|
| 201 | ok: true | Kaydedildi. Tamam |
| 200 | ok: true, duplicate veya confirmed | Zaten kayıtlı ya da piksel dönüşümü onaylandı. Tamam |
| 400 | issues ile error: "invalid payload" veya "invalid json body" | İsteği düzelt (eksik orderId, yanlış eventType, boolean olmayan test, ...) |
| 401 | ör. "invalid api key", "invalid signature" | Anahtarı ve imzayı kontrol et |
| 403 | error: "REF_PROGRAM_MISMATCH" | Ref kodu başka bir programa ait; o programın anahtarını kullan |
| 422 | error: "<CODE>" | Bildirim anlaşıldı ama kabul edilmedi. Değiştirmeden yeniden denemek işe yaramaz |
| 429 | "rate limit exceeded" | Bu anahtar için dakikada 600'den fazla istek. Daha sonra yeniden dene |
| 5xx | Bizim tarafımızda geçici bir sorun. Daha sonra yeniden dene |
422 kodları (REF_UNKNOWN, REF_EXPIRED, INVALID_BASKET ve diğerleri) çözümleriyle birlikte Test ve tanılama sayfasında açıklanıyor.
Sonraki adımlar
İsteği bir imzayla koru, ardından iadeleri ve iptalleri ele al.