İçeriğe geç
Dokümantasyon
GeliştiricilerEntegrasyon kılavuzu

Kişiler, firmalar ve dış kimlik

Kendi sisteminizdeki kullanıcı ve firma numaralarını dış kimlik olarak eşleyin; kişiyi dış kimlikle oluşturun veya güncelleyin, firmayı bağlayın, kullanım ve gelir sinyali gönderin.

Dış kimlik: kişi ve şirket

Kendi sisteminizdeki numaralar ClickFix'te dış kimlik (external_id) olarak tutulur. Kişi ve şirket dış kimlikleri ayrı alanlardır, birbirinden bağımsızdır ve organizasyon içinde tekildir:

KayıtAPI alanıWidget identify karşılığıSistem bağlamada
Kişiexternal_iduser_id{external_id}
Şirketexternal_idcompany.id{company_external_id}

PUT /v1/public-api/contacts/by-external-id kişiyi dış kimliğiyle oluşturur ya da günceller (201 oluşturuldu, 200 güncellendi). Eşleşme yalnız dış kimlikle yapılır; e-posta ya da telefon üzerinden başka bir kişi devralınmaz. Başka kişide olan bir kimlik 409 EXTERNAL_ID_EXISTS döner. Kişiyi önce API ile açıp sonra kullanıcı identify ile gelirse yeni kişi açılmaz, aynı kişiye bağlanır; temsilcinin müşteri siteye girmeden açtığı konuşma (contact_external_id ile) kullanıcı oturum açınca widget'ta görünür.

// Adım 2: kişi ve şirket için ayrı dış kimlik. user_id kişinin, company.id şirketin.
// @ts-check
ClickFix("identify", {
  user_id: "1001", // API: contacts.external_id
  user_hash: "SUNUCUDA_HESAPLANAN", // user_id + "\n" + company.id üzerinden imzalı
  company: { id: "F-77", name: "Acme A.Ş.", domain: "acme.com.tr" }, // API: companies.external_id
});
ClickFix("on", "identify", ({ verified, company_verified }) =>
  console.log("doğrulandı:", verified, "firma:", company_verified),
);
// Adım 2: kişiyi dış kimliğiyle oluştur/güncelle, şirketi dış kimliğiyle bul.
import { createClient } from "@getclickfix/node";

const client = createClient({
  baseURL: process.env.CLICKFIX_BASE_URL!, // https://api.getclickfix.com
  apiKey: process.env.CLICKFIX_API_KEY!, // contacts:read, contacts:write, companies:read
});

// Aynı dış kimlikle ikinci çağrı yeni kişi açmaz, günceller (200); ilki 201 döner.
const contact = await client.request(
  "/v1/public-api/contacts/by-external-id",
  "put",
  { external_id: "1001", name: "Ayşe Yılmaz", email: "ayse@example.com" },
  { idempotencyKey: `user-1001-${Date.now()}` },
);

// Şirketin dış kimliği kişininkinden ayrıdır (widget: company.id).
const companies = await client.request(
  "/v1/public-api/companies",
  "get",
  undefined,
  { query: { external_id: "F-77" } },
);

console.log(
  JSON.stringify({ contact: contact.data, companies: companies.data }),
);
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"time"

	clickfix "github.com/ClickSolveMainTR/clickfix-sdks/go"
)

// Adım 2: kişiyi dış kimliğiyle oluştur/güncelle, şirketi dış kimliğiyle bul.
func externalID(ctx context.Context) error {
	client, err := clickfix.New(os.Getenv("CLICKFIX_BASE_URL"), os.Getenv("CLICKFIX_API_KEY"))
	if err != nil {
		return err
	}
	name, email := "Ayşe Yılmaz", "ayse@example.com"
	key := fmt.Sprintf("user-1001-%d", time.Now().UnixNano())
	res, err := client.PutV1PublicApiContactByExternalIdWithResponse(ctx,
		&clickfix.PutV1PublicApiContactByExternalIdParams{IdempotencyKey: key},
		clickfix.PutV1PublicApiContactByExternalIdJSONRequestBody{ExternalId: "1001", Name: &name, Email: &email})
	if err != nil {
		return err
	}
	if res.StatusCode() != 200 && res.StatusCode() != 201 { // 200 güncellendi, 201 oluşturuldu
		return fmt.Errorf("clickfix: HTTP %d", res.StatusCode())
	}
	ext := "F-77" // şirketin dış kimliği (widget identify: company.id)
	companies, err := client.GetV1PublicApiCompaniesWithResponse(ctx, &clickfix.GetV1PublicApiCompaniesParams{ExternalId: &ext})
	if err != nil {
		return err
	}
	return json.NewEncoder(os.Stdout).Encode(map[string]any{"contact": res.StatusCode(), "companies": companies.StatusCode()})
}
<?php
// Adım 2: kişiyi dış kimliğiyle oluştur/güncelle, şirketi dış kimliğiyle bul.
require __DIR__.'/vendor/autoload.php'; // composer require clickfix/sdk guzzlehttp/guzzle

use ClickFix\Client;

$client = new Client(
    getenv('CLICKFIX_BASE_URL'), // https://api.getclickfix.com
    getenv('CLICKFIX_API_KEY'),  // contacts:read, contacts:write, companies:read
);

// Aynı dış kimlikle ikinci çağrı yeni kişi açmaz, günceller (200); ilki 201 döner.
$contact = $client->contacts()->upsertByExternalId(
    '1001',
    ['name' => 'Ayşe Yılmaz', 'email' => 'ayse@example.com'],
    idempotencyKey: 'user-1001-'.(int) (microtime(true) * 1000),
);

// Şirketin dış kimliği kişininkinden ayrıdır (widget: company.id).
$company = $client->companies()->findByExternalId('F-77');

echo json_encode(['contact' => $contact, 'company' => $company]), PHP_EOL;
# Adım 2: kişiyi dış kimliğiyle oluştur/güncelle (201 oluşturuldu, 200 güncellendi).
curl -sS --fail-with-body -X PUT "$CLICKFIX_BASE_URL/v1/public-api/contacts/by-external-id" \
  -H "Authorization: Bearer $CLICKFIX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: user-1001-$(date +%s)" \
  -d '{ "external_id": "1001", "name": "Ayşe Yılmaz", "email": "ayse@example.com" }'

# Şirketi kendi dış kimliğiyle bul (kişi dış kimliğinden ayrıdır).
curl -sS --fail-with-body "$CLICKFIX_BASE_URL/v1/public-api/companies?external_id=F-77" \
  -H "Authorization: Bearer $CLICKFIX_API_KEY"

Konuşma ve kişi yanıtlarındaki identity_state alanı verified, anonymous ya da self_named değerini alır; webhook olayları contact_external_id, contact_verified, company_uuid ve company_external_id taşır, böylece kendi kaydınızı ek istek atmadan eşleştirirsiniz.

Şirket

Şirket, widget identify çağrısındaki company ile oluşur ya da eşleşir: birinci anahtar company.id (şirketin dış kimliği; yalnız user_hash onu da imzalıyorsa kullanılır, bkz. kimlik doğrulama), ikinci anahtar domain. İmzalı kimlikle bağlanan şirket panelde Doğrulanmış rozeti taşır. API'de şirket GET /v1/public-api/companies?external_id= ile bulunur; şirket kaydı üzerinde müşteri sağlığı için üç sinyal gönderilir: kullanım (PUT /company-usage, 0–100), gelir (PUT /company-revenue) ve ürün olayları (POST /company-events, bir sonraki bölüm). Şirket her üçünde company_uuid, external_id ya da domain ile seçilir.

// Adım 4: şirket identify ile oluşur ya da dış kimliğiyle eşleşir (ikinci anahtar: domain).
// company.id yalnız user_hash onu da imzalıyorsa bağlanır (user_id + "\n" + company.id).
// @ts-check
ClickFix("boot", {
  widgetId: "WIDGET_ID",
  user: {
    user_id: "1001",
    user_hash: "SUNUCUDA_HESAPLANAN", // user_id + "\n" + "F-77" üzerinden
    company: { id: "F-77", name: "Acme A.Ş.", domain: "acme.com.tr" },
  },
});
// Adım 4: şirket. Şirket widget identify (company.id) ile oluşur; API ile
// bulunur ve müşteri sağlığı sinyalleri (kullanım, gelir, olay) gönderilir.
import { createClient } from "@getclickfix/node";

const client = createClient({
  baseURL: process.env.CLICKFIX_BASE_URL!,
  apiKey: process.env.CLICKFIX_API_KEY!, // companies:read, health:write
});

const found = await client.request(
  "/v1/public-api/companies",
  "get",
  undefined,
  {
    query: { external_id: "F-77" },
  },
);

// 0-100 arası kullanım sinyali; 30 gün boyunca sağlık puanına katılır.
const usage = await client.request(
  "/v1/public-api/company-usage",
  "put",
  { external_id: "F-77", score: 82 },
  // İşlemi tanımlayan sabit değer: kendi ölçüm kaydınızın kimliği (örnekte zaman damgası)
  { idempotencyKey: `usage-F-77-${Date.now()}` },
);

console.log(JSON.stringify({ found: found.data, usage: usage.data }));
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"time"

	clickfix "github.com/ClickSolveMainTR/clickfix-sdks/go"
)

// Adım 4: şirketi bul ve kullanım sinyali gönder (health:write).
func company(ctx context.Context) error {
	client, err := clickfix.New(os.Getenv("CLICKFIX_BASE_URL"), os.Getenv("CLICKFIX_API_KEY"))
	if err != nil {
		return err
	}
	ext := "F-77"
	found, err := client.GetV1PublicApiCompaniesWithResponse(ctx, &clickfix.GetV1PublicApiCompaniesParams{ExternalId: &ext})
	if err != nil {
		return err
	}
	usage, err := client.PutV1PublicApiCompanyUsageWithResponse(ctx,
		// İşlemi tanımlayan sabit değer: kendi ölçüm kaydınızın kimliği (örnekte zaman damgası)
		&clickfix.PutV1PublicApiCompanyUsageParams{IdempotencyKey: fmt.Sprintf("usage-F-77-%d", time.Now().UnixNano())},
		clickfix.PutV1PublicApiCompanyUsageJSONRequestBody{ExternalId: &ext, Score: 82})
	if err != nil {
		return err
	}
	if usage.StatusCode() != 200 {
		return fmt.Errorf("clickfix: HTTP %d", usage.StatusCode())
	}
	return json.NewEncoder(os.Stdout).Encode(map[string]int{"found": found.StatusCode(), "usage": usage.StatusCode()})
}
<?php
// Adım 4: şirket. Şirket widget identify (company.id) ile oluşur; API ile
// bulunur ve müşteri sağlığı sinyalleri (kullanım, gelir, olay) gönderilir.
require __DIR__.'/vendor/autoload.php';

use ClickFix\Client;

$client = new Client(
    getenv('CLICKFIX_BASE_URL'),
    getenv('CLICKFIX_API_KEY'), // companies:read, health:write
);

$found = $client->companies()->findByExternalId('F-77');

// 0-100 arası kullanım sinyali; 30 gün boyunca sağlık puanına katılır.
$usage = $client->companies()->setUsage(
    ['external_id' => 'F-77', 'score' => 82],
    // İşlemi tanımlayan sabit değer: kendi ölçüm kaydınızın kimliği (örnekte zaman damgası)
    idempotencyKey: 'usage-F-77-'.(int) (microtime(true) * 1000),
);

echo json_encode(['found' => $found, 'usage' => $usage]), PHP_EOL;
# Adım 4: şirket kullanım sinyali (0-100, health:write); şirket external_id ile bulunur.
curl -sS --fail-with-body -X PUT "$CLICKFIX_BASE_URL/v1/public-api/company-usage" \
  -H "Authorization: Bearer $CLICKFIX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: usage-F-77-$(date +%s%N)" \
  -d '{ "external_id": "F-77", "score": 82 }'

Son güncelleme