cli.gs
Sign in

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/conversion gönder.
  • Her zaman ref, orderId ve net amount gönder. Mümkün olduğunda currency ve customerType ekle.
  • Bildirimler idempotenttir: aynı orderId bir kez sayılır, bu yüzden yeniden denemek güvenlidir.
  • 201 kaydedildi, 200 zaten kayıtlı demektir. 429 ve 5xx durumunda yeniden dene; 400, 401 ve 422 durumunda isteği düzelt.

İstek

text
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.

Entegrasyon sayfasındaki parametreler ve kod örnekleri
Programın için hazır kod içeren Parametreler bölümü

Alanlar

AlanZorunluAnlamı
refevetAçılış sayfasındaki ?ref= parametresinden gelen kod
orderIdevetSipariş numaran, en fazla 190 karakter. Tekrarlanan bildirimleri zararsız kılar
amountSALE 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
eventTypehayırSALE (varsayılan), LEAD veya SIGNUP
customerTypehayırYeni müşteri komisyon kuralları için NEW veya RETURNING
matchKeyhayırÜrün anahtarı içeren kurallar için ürün veya kategori anahtarı. commissionGroup da kabul edilir
occurredAthayırSatışın saat dilimli ISO 8601 zamanı, ör. 2026-09-28T14:05:00Z
testhayırtrue, 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,99 ve 1.234,56 değerlerini de okuruz. 1.234 gibi belirsiz değerleri, negatif değerleri ve makul olmayan büyüklükteki sepetleri reddederiz. LEAD ve SIGNUP iç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. RETURNING olarak 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, 1 veya "true" değil, JSON boolean değeri true olmalı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

bash
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)

js
// 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
<?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
<?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:

json
{
  "ok": true,
  "conversionId": "cmg3x1q2w0001abcd9876efgh",
  "status": "PENDING",
  "commission": 12,
  "duplicate": false,
  "confirmed": false,
  "test": false
}

Alanların anlamı

  • status, komisyon kaydedilip onay süresini beklerken PENDING olur. Dönüşüm senin karar vermen için bekletiliyorsa NEEDS_REVIEW olur; ö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çin REJECTED olur.
  • 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ı

HTTPGövdeNe yapmalı
201ok: trueKaydedildi. Tamam
200ok: true, duplicate veya confirmedZaten kayıtlı ya da piksel dönüşümü onaylandı. Tamam
400issues 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
403error: "REF_PROGRAM_MISMATCH"Ref kodu başka bir programa ait; o programın anahtarını kullan
422error: "<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
5xxBizim 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.