İçeriğe geç
İçeriğe geç

Kasa API rehberi

Shoppern müşterisinin sepeti kasanıza iki yoldan gelir: telefon barkodları kasiyere gösterir ya da Shoppern sepeti kasanızın https adresine gönderir. Bu sayfa ikincisini kuracak mağaza ve POS firmaları içindir.

Hangi tür?

Kasiyere göster: hiçbir kurulum gerekmez. Müşterinin telefonu sepeti tek tek barkod olarak gösterir; kasiyer kasanın kendi okuyucusuyla okutur. Her kasa ilk gün bununla başlayabilir ve her açık kasa gerektiğinde buna döner.

Kasa API'si: kasanızın ya da POS firmanızın bulutunun internette bir https adresi vardır. Müşteri “Sepeti kasaya aktar”a dokununca Shoppern'in sunucusu bu adrese sepeti, kasanın kendi biçiminde gönderir.

Örnek sepet

Shoppern kasanızın biçimini, herkes için aynı olan bu üç satırlık örnek sepetin sizin kasanızdaki yazılışından öğrenir. Barkodlar GS1'in tanıtım için ayırdığı 952 önekindendir; gerçek bir ürüne ait değildir.

AdetBarkod
79521111111115
49522222222226
139523333333337

Adetler her basamakta farklıdır; satır sayısı (3), adetlerin toplamı (24) ve tek tek yazılmış kayıt sayısı (24) böylece birbirine karışmaz.

Örnek nasıl verilir

Örnek, kasanızın bu sepeti nasıl almak istediğidir. Shoppern onu adresinizden alır ya da panelde yapıştırırsınız. Üç türü vardır:

  • Düz metin (text/plain): her ürün bir kayıt; barkod ve adet aynı düzende, aralarında aynı ayraç.
  • JSON (application/json): içinde shoppern_till anahtarı olmayan her JSON; kayıtlar tek bir dizinin öğeleridir.
  • Zarf: { "shoppern_till": 1, "send": "all" | "each", "content_type": …, "example": … }. each için example, çağrı başına bir gövdeden oluşan listedir.

Adet yerine barkodu adet kadar tekrar yazan bir kasa da olur (7 kez A, 4 kez B, 13 kez C): Shoppern bunu da öğrenir.

Barkodlar 14 haneye (başına 0) ve adetler sabit genişliğe (07) doldurulabilir; satır sayısı ve toplam adet kayıtların çevresinde durabilir. Shoppern bunları her sepet için yeniden yazar.

Örnekler ve Shoppern'in öğrendiği

örnek · text/plain · all
7,9521111111115
4,9522222222226
13,9523333333337

Düz metin, sepetin tamamı tek çağrıda; adet önce, sonra barkod, aralarında virgül; her ürün ayrı satırda. 3 × A ve 1 × B şöyle gönderilir:

Shoppern'in göndereceği
3,9521111111115
1,9522222222226
örnek · application/json · all
{"lines":3,"total":24,"items":[{"barcode":"9521111111115","qty":7},{"barcode":"9522222222226","qty":4},{"barcode":"9523333333337","qty":13}]}

JSON, tek çağrıda; her üründe önce barkod, sonra adet; satır sayısı (3) ve toplam adet (24) her sepet için yeniden yazılır:

Shoppern'in göndereceği
{"lines":2,"total":4,"items":[{"barcode":"9521111111115","qty":3},{"barcode":"9522222222226","qty":1}]}
örnek · zarf · each
{"shoppern_till":1,"send":"each","content_type":"text/plain","example":["09521111111115;07","09522222222226;04","09523333333337;13"]}

Düz metin, her ürün ayrı çağrıda; barkod önce (14 haneli), sonra adet (2 haneli), aralarında noktalı virgül. İki çağrı yapılır:

Shoppern'in göndereceği
09521111111115;03
--- ayrı çağrı ---
09522222222226;01

Shoppern ne gönderir

Müşteri “Sepeti kasaya aktar”a dokununca Shoppern adresinize bir POST yapar: all için sepetin tamamıyla bir çağrı, each için kayıt başına, sırayla birer çağrı. Her çağrı şu başlıkları taşır:

BaşlıkAnlamı
Content-TypeÖğrenilen içerik türü (text/plain ya da application/json).
Kasanın kendi başlıklarıPanelde girdiğiniz en fazla 5 başlık (API anahtarı gibi).
X-Shoppern-CheckoutBu aktarımın kimliği (chk_…).
X-Shoppern-TimestampÇağrının zamanı, Unix saniyesi.
Idempotency-Key<kasa>-<sepetin özeti>[-<n>]: aynı sepet için hep aynıdır; each'te n kaydın sırasıdır.
X-Shoppern-Signaturesha256=<hex>: aşağıdaki HMAC-SHA256 imzası.

İmzayı ve zamanı doğrulama

İmza, panelde bir kez gösterilen 64 karakterlik imza anahtarıyla atılır. Anahtar, metnin kendisi olarak (64 ASCII baytı) kullanılır; onaltılık çözülmez.

imza = hex(HMAC-SHA256(anahtar, zaman + "." + Idempotency-Key + "." + gövde))

  1. X-Shoppern-Timestamp ile kendi saatiniz arasındaki fark 5 dakikadan fazlaysa çağrıyı reddedin.
  2. İmzayı aynı formülle kendiniz hesaplayın ve X-Shoppern-Signature ile sabit zamanlı karşılaştırın; tutmazsa reddedin.
  3. Idempotency-Key'leri saklayın: daha önce aldığınız bir anahtar yeniden gelirse sepeti ikinci kez okutmayın, ilk yanıtınızı yineleyin. Shoppern “Tekrar gönder”de aynı anahtarları kullanır.
  4. Yeni bir imza anahtarı panelde oluşturulur; eskisi o andan sonra imza atmaz.
Doğrulama örneği (Node.js)
const crypto = require("node:crypto");

function dogrula(istek, govde, anahtar) {
  const zaman = istek.headers["x-shoppern-timestamp"];
  const key = istek.headers["idempotency-key"];
  const gelen = istek.headers["x-shoppern-signature"] ?? "";
  if (Math.abs(Date.now() / 1000 - Number(zaman)) > 300) return false;
  const beklenen =
    "sha256=" +
    crypto.createHmac("sha256", Buffer.from(anahtar, "ascii"))
      .update(zaman + "." + key + "." + govde)
      .digest("hex");
  const a = Buffer.from(gelen);
  const b = Buffer.from(beklenen);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Yanıtlar ne anlama gelir

Yanıtın yalnızca durumu ve (JSON ise, en fazla 4 KiB) üç alanı okunur; geri kalanı ve müşteriye hiçbir şey gösterilmez.

YanıtAnlamı
2xxAlındı.
{"ok": false}2xx olsa da alınmadı.
{"accepted": n}n satır alındı; geri kalanı alınmadı.
{"unknown": ["barkod", …]}Bu barkodları tanımadınız; müşteriye “Kasada tanınmadı” denir.
409 ya da 429Kasa meşgul; müşteriye biraz sonra denemesi söylenir. Kasanın hatası sayılmaz.
404 ya da 422 (each, tek kayıt)O satır reddedildi; aktarım kalanlarla sürer.
400 ya da 415Biçim yanlış: kasa bir sonraki kullanımdan önce yeniden öğretilmelidir.
Zaman aşımı, kopan bağlantıBilinmiyor: kasa sepeti almış olabilir. Müşteri kasiyere sorar.
Diğer her şeyBaşarısız; each'te kaç kaydın alındığı ve hangi satırda durduğu tutulur.

Adres doğrulama ve örnek

Adresi doğrula: Shoppern adresinize bir GET yapar ve X-Shoppern-Challenge başlığında bir değer gönderir. Yanıtınız aynı başlığı aynı değerle geri göndermelidir. Adres değişince doğrulama yenilenir; doğrulanmamış bir adrese sepet gönderilmez.

Örneği adresten al: Shoppern adresinize X-Shoppern-Till: example ve Accept: application/json, text/plain başlıklarıyla bir GET yapar. Yanıtınız örnek sepetin kendi yazılışınız olmalıdır (en fazla 64 KiB). Örneği panelde yapıştırmak da olur.

Deneme gönder: örnek sepet gerçekten gönderilir ve X-Shoppern-Test: 1 ile işaretlenir. Bu işareti gören kasa okutmamalıdır.

Shoppern'in asla göndermedikleri

Kasaya yalnızca barkodlar ve adetler gider. Şunlar asla gönderilmez:

  • Ürün adı ya da açıklaması
  • Fiyat, tutar ya da vergi — parayı kasa hesaplar
  • Müşterinin adı, telefonu ya da herhangi bir bilgisi
  • Müşterinin geçmiş alışverişleri

Sınırlar

  • Adres https olmalı, 443 numaralı kapıda, herkese açık bir DNS adıyla (IP adresi değil); en fazla 400 bayt.
  • Bağlantı 3 saniyede kurulmalı, bir çağrı 6 saniyede bitmeli.
  • Bir yanıtın en fazla 4 KiB'ı okunur; örnek en fazla 64 KiB olabilir.
  • Bir sepet en fazla 200 satırdır; adetler 1 ile 99 arasındadır.
  • Bir aktarım en fazla 60 çağrı (each) ve 2000 kayıttır (tekrar yazımda); daha büyük sepet için müşteri “Kasiyere göster”i kullanır.
  • Kasanın günlük sepet sınırı paneldedir (en fazla 5000; doğrulanmamış hesapta 100).
  • Yönlendirmeler izlenmez.

Çağrıların geldiği adres

Shoppern'in çağrıları aşağıdaki adreslerden gelir. POS bulutunuz bir izin listesi tutuyorsa bunları ekleyin.

179.198.202.51

Kasanızı panelde Kasalar sayfasından ekleyin.

Örneğinizi deneyin

Kasanızın örnek sepeti nasıl yazdığını yapıştırın; Shoppern'in ne öğreneceğini görün. Hiçbir şey kaydedilmez.