Dit document is voorlopig alleen in het Turks beschikbaar.
Uygulama geliştirme
Başka mağazaların kurabileceği bir uygulama yaz: OAuth ile yetki al, Admin API'yi kullan, panele kendi düğmeni ekle. Akış, anahtar alma, kapsamlar ve aksiyon imzasının doğrulanması.
Nasıl çalışır
- Mağazam → Geliştirici → Uygulama geliştir sayfasında uygulamanı oluştur. Herhangi bir Piyodo hesabı oluşturabilir, hesap başına en çok 10 uygulama olur.
client_id,client_secretve imza anahtarı bir kez gösterilir, sakla. Kaybedersen aynı sayfadan yenilersin. Yenileme eskilerini hemen geçersiz kılar, kurulu mağazaların anahtarına dokunmaz.- Kendi mağazanda dene. Onaysız uygulamayı yalnız geliştiricisi, sahibi olduğu mağazaya kurabilir.
- İncelemeye gönder. Sonuç e-postayla gelir. Onaylanınca uygulamalar sayfasında ve mağazaların panelinde listelenir.
Bu sürümde uygulamalar ücretsizdir. Onaylı uygulamanın başka mağazalardaki anahtarı için mağazanın API'li planda olması gerekmez, aboneliğinin geçerli olması yeterlidir. Bir kez onaylanmış uygulama yeniden incelemeye düşse de kurulu mağazalarda çalışmaya devam eder; yeni kurulum onaya kadar kapalıdır. Reddedilen uygulamanın anahtarları 403 döner.
Kendi mağazandaki deneme anahtarı normal plan kuralına tabidir, uygulaman onaylı olsa da. Deneme süresinde tüm özellikler açık olduğu için bu sürede test edebilirsin; süre bitince mağazanın API'li planda olması gerekir. Webhook'lar plandan bağımsız çalışır.
Yetkilendirme
Standart OAuth 2.0 authorization code akışı. Mağaza sahibini ya da yöneticisini onay ekranına yönlendir:
https://piyodo.com/oauth/authorize?client_id=pa_...&redirect_uri=https%3A%2F%2Fornek.com%2Fpiyodo%2Fdonus&scope=orders.read%20products.read&state=rastgele-deger| Parametre | Zorunlu | Açıklama |
|---|---|---|
client_id |
Evet | Uygulamanın kimliği |
redirect_uri |
Evet | Kayıtlı dönüş adreslerinden biriyle birebir aynı, https |
scope |
Evet | Boşlukla ayrılmış kapsamlar. Uygulamanın beyan ettiklerinin alt kümesi olmalı |
state |
Evet | Rastgele değer, olduğu gibi geri döner. Dönüşte kendi kaydınla karşılaştır |
response_type |
Hayır | Verilirse code olmalı |
Kullanıcı giriş yapar, mağazasını seçer ve kapsamları onaylar. Onay ekranını yalnız mağaza sahibi ve yöneticiler görür, kapalı mağazaya kurulum yapılmaz.
Onaylanırsa dönüş adresine code ve state eklenir:
https://ornek.com/piyodo/donus?code=...&state=rastgele-degerKod 10 dakika geçerlidir ve tek kullanımlıktır. client_id ya da redirect_uri geçersizse hiçbir yere yönlendirilmez, kullanıcı hata sayfası görür. Uygulama onaylı değilse de geliştiricisi dışında kimse dönüş adresine yönlendirilmez, ret dahil. Bundan sonraki hatalar dönüş adresine error ve state ile gelir:
error |
Neden |
|---|---|
access_denied |
Kullanıcı vazgeçti |
invalid_scope |
Kapsam boş ya da uygulamanın beyan ettikleri dışında |
invalid_request |
state yok |
unsupported_response_type |
response_type code değil |
Kurulum adresi
Mağaza panelde Kur düğmesine bastığında iki yol vardır:
- Uygulamada kurulum adresi tanımlıysa kullanıcı oraya gider, sen kendi
statedeğerinle yetkilendirmeyi başlatırsın.statedoğrulamak istiyorsan bu yolu kullan. - Tanımlı değilse doğrudan onay ekranı açılır: tüm beyan edilen kapsamlar, ilk dönüş adresi ve Piyodo'nun ürettiği bir
stateile. Bu durumdastatesenin kaydında olmaz.
Anahtar alma
Kodu sunucu tarafında anahtara çevir. client_secret tarayıcıya hiç gitmemelidir.
POST /api/store/oauth/token
curl -X POST "https://piyodo.com/api/store/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"client_id": "pa_...",
"client_secret": "pas_...",
"code": "...",
"redirect_uri": "https://ornek.com/piyodo/donus"
}'{
"access_token": "psk_...",
"token_type": "Bearer",
"scope": "orders.read products.read",
"store": {
"id": "01J...",
"name": "Ayşe Butik",
"slug": "ayse",
"url": "https://ayse.example.com/"
}
}redirect_uri yetkilendirmedekiyle aynı olmalıdır. Hata yanıtları:
| Durum | error |
Neden |
|---|---|---|
400 |
invalid_request |
Alan eksik |
400 |
unsupported_grant_type |
grant_type authorization_code değil |
401 |
invalid_client |
client_id ya da client_secret yanlış |
400 |
invalid_grant |
Kod yanlış, süresi dolmuş, daha önce kullanılmış ya da adres uyuşmuyor. Mağaza kapalıysa, onay veren kişinin yetkisi kalktıysa ya da uygulama artık kurulamıyorsa da döner |
Dakikada en çok 20 istek kabul edilir.
Anahtarı kullanma
access_token normal bir Admin API anahtarıdır. Tüm uçlar, kapsamlar ve hız sınırı Kimlik doğrulama sayfasındaki gibidir, MCP de aynı anahtarla çalışır.
curl "https://piyodo.com/api/store/v1/orders" \
-H "Authorization: Bearer psk_..."Her mağaza için ayrı anahtar saklarsın; anahtar mağazayı belirler. Süresi dolmaz, yenileme anahtarı (refresh token) yoktur.
| Durum | Sonuç |
|---|---|
| Mağaza uygulamayı kaldırdı | Anahtar iptal, 401. Uygulamanın webhook abonelikleri silinir |
| Yeniden kurulum | Yeni kodla yeni anahtar alınır, eski anahtar iptal olur |
| Mağaza kapandı ya da abonelik bitti | 403, abonelik gelince yeniden çalışır |
| Yönetim uygulamayı yayından kaldırdı | 403, webhook gönderilmez. Geliştiricinin kendi mağazası hariç |
Kapsamı genişletmek için beyan ettiğin kapsamları güncelle, onaylandıktan sonra mağazayı yetkilendirmeden yeniden geçir.
İnceleme
Onaylı uygulamada site, kurulum adresi, dönüş adresi, kapsam ya da aksiyon değişirse uygulama yeniden incelemeye düşer. Bu sürede kurulu mağazaların anahtarı çalışır, yeni kurulum yapılamaz, aksiyon düğmeleri onaya kadar başka mağazalarda görünmez. Ad ve açıklama değişikliği incelemeye düşürmez.
Panel aksiyonları
Uygulama sipariş, ürün ve müşteri ekranlarına düğme ekleyebilir. En çok 10 aksiyon olur.
[
{
"id": "kargo-etiketi",
"label": "Kargo etiketi",
"target": "order",
"url": "https://panel.ornek.com/piyodo/etiket"
}
]| Alan | Kural |
|---|---|
id |
Küçük harf, rakam, - ve _. Uygulama içinde benzersiz |
label |
Düğmede görünen ad, en çok 40 karakter |
target |
order, product ya da customer |
url |
https, uygulamanın sitesiyle aynı ana alan adında |
Düğmeye basılınca adresin panelde iframe içinde açılır. Çerçeve kısıtlıdır: sandbox="allow-scripts allow-forms allow-same-origin allow-popups" ve referrerpolicy="no-referrer". Sayfan çerçevelenmeye izin vermelidir: X-Frame-Options gönderme, Content-Security-Policy kullanıyorsan frame-ancestors https://piyodo.com ver.
Adrese şu parametreler eklenir:
| Parametre | Açıklama |
|---|---|
store |
Mağaza kimliği, token yanıtındaki store.id |
resource_id |
Sipariş, ürün ya da müşteri kimliği, API'deki id |
action |
Aksiyonun id değeri |
ts |
Unix zamanı, saniye |
sig |
İmza |
Düğmeyi yalnız o kaydı görme yetkisi olan ekip üyesi kullanabilir, kapalı mağazada düğme görünmez.
Aksiyon imzasını doğrulama
Parametreler adres çubuğundan gelir, herkes değiştirebilir. Sayfanı göstermeden önce imzayı doğrula:
sig = HMAC-SHA256(imza anahtarı, store + "\n" + resource_id + "\n" + action + "\n" + ts)Sonuç küçük harf hex'tir. Bayat bağlantı kabul etme: ts en çok 5 dakika eski olsun.
function piyodoActionIsValid(array $query, string $signingSecret): bool
{
foreach (['store', 'resource_id', 'action', 'ts', 'sig'] as $key) {
if (! is_string($query[$key] ?? null)) {
return false;
}
}
if (abs(time() - (int) $query['ts']) > 300) {
return false;
}
$text = implode("\n", [$query['store'], $query['resource_id'], $query['action'], $query['ts']]);
return hash_equals(hash_hmac('sha256', $text, $signingSecret), $query['sig']);
}import { createHmac, timingSafeEqual } from 'node:crypto';
export function piyodoActionIsValid(query, signingSecret) {
const { store, resource_id, action, ts, sig } = query;
if (![store, resource_id, action, ts, sig].every((v) => typeof v === 'string')) return false;
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = createHmac('sha256', signingSecret).update([store, resource_id, action, ts].join('\n')).digest('hex');
return sig.length === expected.length && timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}İmza yalnız isteğin Piyodo panelinden geldiğini kanıtlar; kullanıcının kim olduğunu söylemez. Veriyi store için sakladığın anahtarla, sunucundan Admin API'ye sorarak al.