Ana içeriğe geç

Partner İmzası (sunucu-sunucu)

Partner imzası, sizin sunucunuzun kimliğidir — mükellefin değil. Kayıtlı bir partner olduğunuzu, ortada henüz bir mükellef hesabı yokken kanıtlar.

API anahtarı ve OAuth mükellefin verisine erişmek içindir. Partner imzası onların yerini almaz, yanlarında durur:

API Anahtarı / OAuthPartner İmzası
Kimi temsil edermükellefisizi (partner uygulamasını)
Nerede kullanılırsatış, fatura, durum uçlarıPOST /v1/partner-applications
Kapsamtek mükellef firmasıfirma kapsamı yok
Anahtarı kim üretirmükellef / partner kaydıFinans Fatura, talebiniz üzerine

Bugün imza tek bir ucu korur: henüz hesabı olmayan bir mağaza sahibinin başvurusunu kendi uygulamanızdan iletmek. Yeni sunucu-sunucu uçları eklendiğinde aynı imzayı kullanacaklar.

Kimlik bilgileri​

Üç parça alırsınız:

AlanNe işe yararNerede durur
appNameuygulamanızın adı; imzalanan metne girer ve kaydınızı buluristekte açık gider
developerKeyimzalanan metne girersunucunuzda, gizli
saltKeyHMAC anahtarısunucunuzda, gizli

developerKey ve saltKey yalnızca üretildikleri anda size iletilir; sonrasında panelde developerKey'in ilk 8 karakteri görünür. Kaybederseniz yeniden üretilir — yeniden üretim eskisini anında geçersiz kılar, tek bir çift saklanır.

Sandbox ve üretim ayrı sistemlerdir; her ortam için ayrı çift alırsınız. Talep için [email protected].

saltKey istemciye hiç inmemeli

İmza sunucunuzda hesaplanır. saltKey tarayıcıya, mobil uygulamaya veya mağaza temasına bundle edilirse imzayı herkes üretebilir — kimlik hükümsüz kalır.

Başlıklar​

Her istekte üç başlık gider:

BaşlıkDeğer
X-FF-App-NameappName
X-FF-Rndher istekte yeniden üretilen nonce (en fazla 128 karakter)
X-FF-Signatureaşağıdaki HMAC, küçük harf hex (64 karakter)

İmza kuralı​

hashString = developerKey + "|" + appName + "|" + randomKey
signature = hex( HMAC_SHA256( saltKey, hashString ) )

Üç kural:

  • randomKey imzaya girer. Her istek için yeni üretin (randomBytes(16) gibi); aynı nonce'u yeniden kullanmak imzayı geçersiz kılmaz ama nonce'u imzadan çıkarmak kılar.
  • appName kaydınızı büyük/küçük harf duyarsız bulur, ama hash'e gönderdiğiniz hâli girer. Başlıkta ne yazdıysanız imzada da o olmalı.
  • İmza küçük harf hextir. Base64 ya da büyük harf gönderilirse 401 döner.

Doğrulama vektörü​

Kendi kodunuzu bağlamadan önce bu değeri üretebildiğinizi doğrulayın:

GirdiDeğer
saltKeySALT_KEY
developerKeyDEVELOPER_KEY
appNameAPP_NAME
randomKey0.3521896431818765
hashString = DEVELOPER_KEY|APP_NAME|0.3521896431818765
signature = a0b4d662d839d1cf80aa40b31acf98347e8258704fe520c595e0d1dbaebe8fa7

Örnekler​

Node.js
import { createHmac, randomBytes } from "node:crypto";

function partnerHeaders({ appName, developerKey, saltKey }) {
const randomKey = randomBytes(16).toString("hex");
const signature = createHmac("sha256", saltKey)
.update(`${developerKey}|${appName}|${randomKey}`)
.digest("hex");

return {
"X-FF-App-Name": appName,
"X-FF-Rnd": randomKey,
"X-FF-Signature": signature,
};
}
Python
import hashlib, hmac, secrets

def partner_headers(app_name: str, developer_key: str, salt_key: str) -> dict:
random_key = secrets.token_hex(16)
signature = hmac.new(
salt_key.encode(),
f"{developer_key}|{app_name}|{random_key}".encode(),
hashlib.sha256,
).hexdigest()

return {
"X-FF-App-Name": app_name,
"X-FF-Rnd": random_key,
"X-FF-Signature": signature,
}
PHP
function partnerHeaders(string $appName, string $developerKey, string $saltKey): array
{
$randomKey = bin2hex(random_bytes(16));
$signature = hash_hmac('sha256', "{$developerKey}|{$appName}|{$randomKey}", $saltKey);

return [
'X-FF-App-Name: ' . $appName,
'X-FF-Rnd: ' . $randomKey,
'X-FF-Signature: ' . $signature,
];
}

Uç: mükellef başvurusu​

POST /v1/partner-applications

Mağaza sahibinin Finans Fatura hesabı yoksa, uygulamanızdaki formu doldurup başvurusunu buradan iletirsiniz. Hesap açılır, sizin partner kaydınıza bağlanır ve başvurana "şifreni belirle" e-postası gider.

Şifre sormayın

Gövdede şifre alanı yoktur. Başvuran şifresini e-postadaki bağlantıdan kendisi koyar; böylece müşterinin şifresi sizin uygulamanızdan hiç geçmez.

curl -X POST https://sandbox-api.finansfatura.com/v1/partner-applications \
-H "X-FF-App-Name: ornek-app" \
-H "X-FF-Rnd: 9f2c1d8b4a7e6053" \
-H "X-FF-Signature: 3b1c…" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"name": "Ayşe",
"surname": "Yılmaz",
"phone": "5551112233",
"company_title": "Örnek Ticaret A.Ş."
}'
AlanZorunluNot
emailevethesabın kimliği; şifre belirleme postası buraya gider (aşağıdaki normalleştirmeye dikkat)
nameevet
surnamehayır
phonehayır
company_titlehayırşirket unvanı olarak yazılır
201 Created
{
"company_id": 4821,
"user_id": 9134,
"email": "[email protected]",
"status": "PENDING_VERIFICATION"
}

PENDING_VERIFICATION: hesap açıldı, kullanıcı e-postasındaki bağlantıdan şifresini belirleyip giriş yapacak. Başvuru bir bağlantı değildir — veri akması için mükellefin ayrıca size API anahtarı vermesi ya da OAuth onayından geçmesi gerekir.

E-posta normalleştirilir​

Adres kaydedilmeden önce sadeleştirilir: küçük harfe iner, +etiket kısmı atılır, gmail.com / googlemail.com adreslerinde noktalar silinir.

Görünürde farklı iki adres bu yüzden aynı hesap sayılabilir ve ikincisi ERROR_EMAIL_ALREADY_REGISTERED alır. Test hesabı açarken +etiket işinize yaramaz; gerçekten farklı bir adres kullanın.

Mükellef–partner bağı yalnız burada kurulur​

Bir şirketin hangi partnerden geldiği yalnızca bu uçta yazılır; hakediş buna bakar. Bu yüzden e-posta zaten kayıtlıysa uç 400 döner: var olan bir hesabı sonradan partnere bağlamak, getirmediğiniz müşteriden komisyon almak olurdu. Kullanıcıyı "hesabım var" yoluna — OAuth bağlantısına — yönlendirin.

Hatalar​

DurummessageSebep
401ERROR_PARTNER_SIGNATURE_MISSINGüç başlıktan biri boş, ya da X-FF-Rnd / X-FF-Signature 128 karakterden uzun
401ERROR_PARTNER_SIGNATURE_INVALIDimza tutmuyor, partner pasif, ya da anahtar üretilmemiş/silinmiş
400ERROR_EMAIL_REQUIREDemail boş
400ERROR_NAME_REQUIREDname boş
400ERROR_EMAIL_ALREADY_REGISTEREDhesap zaten var — OAuth yoluna yönlendirin

401 iki sebebi bilerek ayırmaz: dışarıya "bu appName kayıtlı ama imza yanlış" demek, kayıtlı partner adlarını sızdırmak olurdu. İmzayı yukarıdaki vektörle yerel olarak doğrulayın.

Anahtar yönetimi​

  • Yeniden üretim, eski çifti anında geçersiz kılar. Değişimi planlayın: yeni çifti yapılandırmaya yazın, sonra üretimi isteyin.
  • appName değişikliği imzayı bozar — yeni adla hesaplanmalı. Değiştirmek isterseniz önceden haber verin, birlikte yapalım.
  • Sızıntı şüphesinde anahtarı sildirin: partner erişiminiz o anda durur, mükelleflerin kendi API anahtarları ve OAuth bağlantıları etkilenmez.
  • Tekrar oynatma (replay) takibi yoktur. Trafik TLS altındadır ve uç mükerrer e-postayı zaten reddeder. Kendi tarafınızda aynı başvuruyu iki kez göndermemek için form gönderimini tekilleştirin.