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ı / OAuth | Partner İmzası | |
|---|---|---|
| Kimi temsil eder | mükellefi | sizi (partner uygulamasını) |
| Nerede kullanılır | satış, fatura, durum uçları | POST /v1/partner-applications |
| Kapsam | tek mükellef firması | firma kapsamı yok |
| Anahtarı kim üretir | mü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:
| Alan | Ne işe yarar | Nerede durur |
|---|---|---|
appName | uygulamanızın adı; imzalanan metne girer ve kaydınızı bulur | istekte açık gider |
developerKey | imzalanan metne girer | sunucunuzda, gizli |
saltKey | HMAC 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].
İ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ık | Değer |
|---|---|
X-FF-App-Name | appName |
X-FF-Rnd | her istekte yeniden üretilen nonce (en fazla 128 karakter) |
X-FF-Signature | aşağıdaki HMAC, küçük harf hex (64 karakter) |
İmza kuralı
hashString = developerKey + "|" + appName + "|" + randomKey
signature = hex( HMAC_SHA256( saltKey, hashString ) )
Üç kural:
randomKeyimzaya 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.appNamekaydı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
401döner.
Doğrulama vektörü
Kendi kodunuzu bağlamadan önce bu değeri üretebildiğinizi doğrulayın:
| Girdi | Değer |
|---|---|
saltKey | SALT_KEY |
developerKey | DEVELOPER_KEY |
appName | APP_NAME |
randomKey | 0.3521896431818765 |
hashString = DEVELOPER_KEY|APP_NAME|0.3521896431818765
signature = a0b4d662d839d1cf80aa40b31acf98347e8258704fe520c595e0d1dbaebe8fa7
Örnekler
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,
};
}
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,
}
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.
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.Ş."
}'
| Alan | Zorunlu | Not |
|---|---|---|
email | evet | hesabın kimliği; şifre belirleme postası buraya gider (aşağıdaki normalleştirmeye dikkat) |
name | evet | |
surname | hayır | |
phone | hayır | |
company_title | hayır | şirket unvanı olarak yazılır |
{
"company_id": 4821,
"user_id": 9134,
"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
| Durum | message | Sebep |
|---|---|---|
401 | ERROR_PARTNER_SIGNATURE_MISSING | üç başlıktan biri boş, ya da X-FF-Rnd / X-FF-Signature 128 karakterden uzun |
401 | ERROR_PARTNER_SIGNATURE_INVALID | imza tutmuyor, partner pasif, ya da anahtar üretilmemiş/silinmiş |
400 | ERROR_EMAIL_REQUIRED | email boş |
400 | ERROR_NAME_REQUIRED | name boş |
400 | ERROR_EMAIL_ALREADY_REGISTERED | hesap 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.
appNamedeğ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.