In-Store integracija

In-Store API vgradi Leanpay neposredno v programsko opremo, ki jo prodajalci že uporabljajo — POS, ERP ali lasten blagajniški sistem. Ko kupec na blagajni izbere Leanpay, blagajnik ne zapusti svojega vmesnika: sistem prevzame kupčeve podatke (iz ERP ali pa jih blagajnik vnese), jih pošlje Leanpayu, spremlja status in ga prikaže na isti blagajniški strani.

Celoten postopek temelji na majhnem naboru endpointov — happy path obsega osem klicev. Integracija je primerna za trgovce z lastno razvojno ekipo, POS ponudnikom ali sistemskim integratorjem.

V praksi to pomeni manj ročnega vnosa (znani podatki o kupcu se prenesejo iz CRM oz. ERP), manj napak (ni prepisovanja med sistemi) in enotno izkušnjo za kupca — račun, številka naročila in poprodajni postopek se ujemajo z obstoječim sistemom trgovca.

Potek integracije

Blagajnik vzame telefonsko številko, pri Leanpayu preveri, kaj je o kupcu že znano, nato ustvari ali posodobi zapis kupca, odpre ponudbo in počaka, da kupec na svojem telefonu podpiše pogodbo. Ko Leanpay vrne SUCCESS, blagajnik izroči blago in potrdi dostavo.

In-Store glavni potek
Glavni potek — od telefonske številke do potrditve dostave.
Klikni za povečavo
1
Priprava na blagajni
Kupec je na blagajni z izbranim blagom in želi plačati z Leanpayem. Blagajnik najprej vpraša za telefonsko številko. Ta je Leanpayev univerzalni identifikator kupca — en kupec je ena telefonska številka, enotno po vseh Leanpayevih sistemih. Kupec ne more imeti dveh zapisov pod različnima številkama.
2
Preverjanje statusa kupca
GET/v1/customers/{customerPhoneNumber}/status
S telefonsko številko se izvede prvi klic. Odgovor pove, kako nadaljevati: ali kupca ustvariti na novo, osvežiti obstoječe podatke, ustaviti postopek (kupec je blokiran) ali takoj odpreti ponudbo. Ker gre za GET, header Signature ni potreben.
Kaj pošljemo — samo headerji, brez telesa:
GET /v1/customers/38640123456/status HTTP/1.1
Host: api.leanpay.si
X-Api-Key: vk_live_abc123...
Accept: application/json

Odgovor je eden od petih izidov:

Pet izidov preverjanja statusa kupca
Statusa kupca
Klikni za povečavo
HTTP 404 — neznana številka
Leanpay te telefonske številke še ne pozna. Treba je ustvariti nov zapis kupca (korak 3a).
BLOCKED — blokiran kupec
Zapis obstaja in ima blocked: true. Kupec ne more izvesti transakcije. Postopek se ustavi, kupca se napoti na Leanpay podporo. Odločilni signal je blocked: true (ne glede na vrednost verified).
UNVERIFIED / EXPIRED — potrebna osvežitev
Zapis obstaja, kupec ni blokiran, a preverjanje identitete ni dokončano (verified: false) ali pa je poteklo. V obeh primerih se podatki osvežijo s klicem Update Customer (korak 3b).
VERIFIED — pripravljen kupec
Zapis obstaja, kupec ni blokiran in je veljavno preverjen (blocked: false, verified: true). Korak ustvarjanja/posodabljanja se preskoči, postopek gre naravnost na ustvarjanje ponudbe (korak 4).
3a
Create Customer (le ob HTTP 404)
POST/v1/customers
Če številka Leanpayu ni bila znana, blagajnik zbere osebne podatke kupca in jih pošlje kot nov zapis. Po uspešnem klicu postopek nadaljuje na korak 4.
Kaj pošljemo — headerji in JSON body:
POST /v1/customers HTTP/1.1
Host: api.leanpay.si
X-Api-Key: vk_live_abc123...
Signature: 8f9c...d23e        // SHA-256 (ENDPOINT_URL + SECRET_TOKEN + raw body)
Content-Type: application/json

{
  "phoneNumber": "38640123456",
  "firstName": "Janez",
  "lastName": "Novak",
  "email": "janez.novak@example.com",
  "createdBy": "blagajna@trgovec.si",
  "address": {
    "street": "Slovenska cesta",
    "houseNumber": "12",
    "zipcode": "1000",
    "place": "Ljubljana"
  },
  "identityCard": {
    "number": "AB1234567",
    "type": { "id": "PERSONAL_ID" },
    "dateOfExpire": "2030-06-12",
    "dateOfBirth": "1985-06-12",
    "issuer": { "id": 24 }
  }
}

Nabor polj se razlikuje glede na konfiguracijo države. Obvezni so telefonska številka, ime, priimek in objekt identityCard (s številko, tipom, datumom rojstva in datumom poteka); znotraj address so obvezni place, street in zipcode. Email se sprejme, a se ne validira. Vrednosti za izdajatelja dokumenta (issuer) prihajajo iz endpointa Country-info.

Odgovor vrne le, kar je shranjeno. Polja, ki jih pošlješ, a niso vrnjena (npr. createdBy), so vseeno shranjena. Ugnezdena objekta type in issuer vrneta le id; berljivo ime pride iz Country-info.
3b
Update Customer (le ob UNVERIFIED ali EXPIRED)
PUT/v1/customers/{customerPhoneNumber}
Če zapis že obstaja, a so podatki nepopolni ali pretekli, se osvežijo s trenutnimi podatki kupca. Telefonska številka v poti določa zapis, ki se posodablja. Telo ima enako obliko kot pri Create Customer, brez phoneNumber. Obvezni so firstName, lastName in identityCard.
PUT je popolna zamenjava (full replace). Vsako opcijsko polje, ki ga v telesu izpustiš (npr. address, email), se v Leanpay bazi pobriše — zato vedno pošlji celoten zapis, ne le spremenjenih polj.
4
Ustvarjanje ponudbe
POST/vendor/v1/offers
Kupec obstaja in lahko izvede transakcijo. Zdaj se Leanpayu pove, kaj kupec kupuje: znesek, opcijski finančni produkt in lastni transakcijski identifikator za kasnejše usklajevanje. Leanpay rezervira ponudbo, vrne offerId in samodejno pošlje kupcu SMS s povezavo za podpis.
Kaj pošljemo — headerji in JSON body:
POST /vendor/v1/offers HTTP/1.1
Host: api.leanpay.si
X-Api-Key: vk_live_abc123...
Signature: 9a1b...0c4d
Content-Type: application/json

{
  "customerPhoneNumber": "38640123456",
  "amount": 599.00,
  "financialProductId": "798212f1-7c77-466c-a2b0-0d17a04abdc2",
  "validityPeriodId": "1_HOUR",
  "vendorTransactionId": "POS-2026-05-21-00042",
  "createdBy": "blagajna@trgovec.si",
  "branchId": "BTC-01",
  "offerItems": [
    {
      "name": "Pralni stroj X200",
      "stockKeepingUnit": "SKU-PR-001",
      "price": 599.00,
      "quantity": 1
    }
  ]
}

Obvezni: customerPhoneNumber, amount, financialProductId, validityPeriodId, vendorTransactionId, createdBy. financialProductId je UUID produkta, konfiguriranega na računu trgovca; validityPeriodId je eden od 1_HOUR, 3_HOURS, 24_HOURS, 48_HOURS, 72_HOURS, 7_DAYS. Polji offerItems in branchId sta opcijski — offerItems se kupcu prikaže med podpisom.

Kaj Leanpay vrne — ponudbo z začetnim statusom PENDING:
{
  "offer": {
    "offerId": "52312",
    "amount": 599.00,
    "validityPeriodId": "1_HOUR",
    "validUntil": "2026-05-22T17:02:36.835Z",
    "status": "PENDING",
    "vendorTransactionId": "POS-2026-05-21-00042"
  }
}
offerId je identifikator za vse nadaljnje klice (Get Offer, Cancel, Delivery, Dispute). validUntil se izračuna iz validityPeriodId — za 1_HOUR je to trenutni čas + 1 ura. Kupec rok izbere na svojem telefonu med podpisom, iz nabora rokov finančnega produkta.
5
Kupec podpiše na svojem telefonu
Z vidika blagajnika je ta korak pasiven. Leanpay samodejno pošlje SMS kot posledico koraka 4; kupec odpre povezavo, dopolni morebitne manjkajoče korake preverjanja identitete (npr. fotografije dokumenta), prebere pogodbene pogoje in digitalno podpiše. Med tem oknom trgovcu ni treba klicati nobenega API-ja — blagajnik počaka in spremlja status (korak 6).
6
Spremljanje statusa ponudbe
GET/vendor/v1/offers/{offerId}
Medtem ko je kupec na telefonu, blagajnik kliče status ponudbe, dokler ta ne doseže končnega stanja. Običajen ritem je vsakih 3–5 sekund. Če je v Vendor profilu nastavljen URL za status ponudbe, Leanpay status samodejno pošlje (POST) na ta naslov — namesto spremljanja ali poleg njega.
Življenjski cikel ponudbe
Življenjski cikel ponudbe.
Klikni za povečavo
StatusPomen
PENDINGKupec je še na telefonu ali pa še ni začel s podpisom. Spremljaj naprej.
SUCCESSKupec je podpisal pogodbo. Leanpay se je zavezal k izplačilu — sledi izročitev blaga.
FAILEDKupec je bil zavrnjen ali je prekinil. Blago se ne izroči.
EXPIREDKupec ni dokončal podpisa v veljavnem oknu. Blago se ne izroči.
CANCELEDPonudba je bila preklicana (Cancel Offer) ali zaradi drugega razloga. Blago se ne izroči.
7
Izročitev blaga
Ko spremljanje vrne SUCCESS, je pogodba podpisana in Leanpay se je zavezal k izplačilu trgovcu. Blagajnik fizično izroči blago kupcu. Pri tem koraku ni API klica — gre za dejanje v resničnem svetu, ki da pomen naslednjemu koraku.
8
Potrditev dostave
POST/vendor/v1/offers/{offerId}/delivery
Takoj po izročitvi blaga blagajnik pošlje potrditev dostave. S tem trgovec sporoči, da je svoj del izpolnil, in transakcija se uvrsti v naslednji tedenski cikel izplačil. Status ponudbe ostane SUCCESS (ločenega statusa za dostavo ni), zato trgovec stanje dostave spremlja lokalno.
Kaj pošljemo — samo headerji, prazno telo za polno dostavo:
POST /vendor/v1/offers/52312/delivery HTTP/1.1
Host: api.leanpay.si
X-Api-Key: vk_live_abc123...
Signature: 5e6f...a8b3
Content-Type: application/json

{}

Leanpay odgovori s HTTP 200 in praznim telesom.

Dostava ni idempotentna: drugi klic dostave na isto ponudbo vrne 400 z error.business.INVALID_ARGUMENT in detajlom “Delivery was already made.” Pri logiki ponovnih poskusov je to napako treba obravnavati kot uspeh.
Delna dostava

Kadar dela košarice ni mogoče izročiti (artikel manjka, poškodovan kos, neujemanje količine), se dostava lahko potrdi za nižji znesek od podpisane ponudbe. Brez nove ponudbe in brez ponovnega podpisa — Leanpay samodejno prilagodi znesek kredita na obstoječi pogodbi. Isti endpoint z znižanim amount v telesu:

{
  "amount": 189.00
}

Dostavljeni znesek mora biti strogo nižji od prvotnega. Za polno dostavo se klic pošlje brez polja amount.

Dodatni API

POSTPreklic ponudbe — /vendor/v1/offers/{offerId}/cancel

Cancel Offer čisto zaključi PENDING ponudbo — na primer, če si kupec premisli, odide ali je blagajnik vnesel napačen znesek. Klic na ponudbo, ki je že v končnem stanju (FAILED, EXPIRED, CANCELED), se obravnava kot no-op, zato ga je varno klicati brez predhodnega preverjanja. Preklic je dovoljen na PENDING ponudbah in na podpisanih (SUCCESS) ponudbah, ki še niso dostavljene. Po dostavi se namesto preklica uporabi spor (dispute).

Telo je prazno ali nosi opcijsko polje reason. Odgovor potrdi nov status (CANCELED) in čas preklica.

POSTPredkvalifikacija — /vendor/v1/pre-qualify

Predkvalifikacija omogoča, da se kupcu pokaže okviren Leanpay kreditni limit, še preden se odpre ponudba — uporabno za pogovor “koliko lahko dobim?”, ko kupec še ni zavezan k nakupu. Klic se sproži s kupčevo telefonsko številko; Leanpay pošlje SMS s povezavo, ki jo kupec izpolni na svojem telefonu (lahkotno preverjanje, brez pogodbe). Po zaključku kupec na svojem zaslonu vidi razpoložljiv limit.

POST /vendor/v1/pre-qualify?customerPhoneNumber=38640123456

Brez telesa. Leanpay vrne kratkoživo povezavo na spletnem gostitelju za kupce, ki jo trgovec pošlje ali izroči kupcu:

{
  "url": "https://app.leanpay.si/vendor/pre-qualified?vendor=3er7jp"
}
Potek predkvalifikacije
Potek predkvalifikacije.
Klikni za povečavo

Ne ustvari se nobena ponudba in ne podpiše pogodba. Predkvalifikacija je zgolj informativna. Parameter vendor v povezavi je kratek javno-varen identifikator, ne API ključ.

GETInformativni izračun kredita — /v1/credit-calculation

Prikaže, kako bi za dani znesek izgledal obročni načrt, brez ustvarjanja ponudbe. Vrne število obrokov, mesečni znesek, skupni znesek z morebitnimi obrestmi in stroški ter EOM.

GET /v1/credit-calculation?amount=599.00&financialProductId=798212f1-... HTTP/1.1
Host: api.leanpay.si
X-Api-Key: vk_live_abc123...
Accept: application/json
Kaj Leanpay vrne — polje izračunov (eden na rok):
{
  "calculations": [
    {
      "numberOfInstallments": 12,
      "installmentAmount": 55.98,
      "firstInstallmentAmount": 57.97,
      "loanAmount": 599.00,
      "costOfReview": 23.96,
      "costOfRisk": 23.96,
      "clientInterestPercent": 7.00,
      "effectiveInterestRate": 22.61,
      "totalAmount": 673.68
    }
  ]
}
Informativni izračun kredita
Informativni izračun kredita.
Klikni za povečavo

effectiveInterestRate je EOM. Razlika med clientInterestPercent (7 %) in effectiveInterestRate (22,61 % v tem primeru) izhaja iz stroškov costOfReview in costOfRisk.

POSTSpori (po dostavi) — /vendor/v1/offers/{offerId}/disputes

Spor odpre trgovec, ko je treba kredit preklicati po dostavi blaga — tipično ob vračilu izdelka ali napačni košarici. Spor prekliče kredit, ko ga Leanpay odobri.

AkcijaMetodaEndpoint
Odpri sporPOST/vendor/v1/offers/{offerId}/disputes
Seznam sporov ponudbeGET/vendor/v1/offers/{offerId}/disputes
Posamezen sporGET/vendor/v1/offers/{offerId}/disputes/{disputeId}

Telo ob odprtju spora — obvezno je le message (prosto besedilo z razlogom):

{
  "message": "Kupec je vrnil izdelek"
}
Življenjski cikel spora
Življenjski cikel spora.
Klikni za povečavo
StatusPomen
NEWSpor je odprt in čaka na pregled.
IN_REVIEWLeanpay pregleduje spor.
APPROVEDSpor je potrjen, kredit preklican.
REJECTEDSpor je zavrnjen, kredit ostane aktiven.
CLOSEDSpor je rešen in zaprt.
Pomožni endpointi (country-info, configuration, seznam ponudb)
EndpointMetodaNamen
/v1/country-infoGETSeznam izdajateljev dokumentov in tipov dokumentov za državo (vrednosti za identityCard).
/vendor/in-store/v1/configurationGETKonfiguracija trgovca: razpoložljivi finančni produkti, najnižji/najvišji znesek, obdobja veljavnosti.
/vendor/v1/offersGETSeznam ponudb s filtri (datum, status). Brez {offerId} v poti.

Tehnične osnove

Predpogoji, okolja in avtentikacija

Predpogoji

  • Aktiven Leanpay vendor račun s konfiguriranim finančnim produktom
  • API Key in Secret Token (Vendor aplikacija, razdelek Podjetje > Development)
  • POS oz. ERP sistem, ki lahko izvaja strežniške API klice

Okolja

OkoljeHost
Stage (testno)https://stage-api.leanpay.si
Produkcijahttps://api.leanpay.si

Avtentikacija

Vsak klic nosi statični X-Api-Key header. Klici, ki spreminjajo stanje (POST, PUT), dodatno nosijo header Signature — SHA-256 podpis niza:

Signature = SHA-256( ENDPOINT_URL + SECRET_TOKEN + RAW_BODY_PAYLOAD )

GET klici (status kupca, status ponudbe, izračun) headerja Signature ne potrebujejo.

Identifikatorji in vrednosti

Telefonska številka je univerzalni identifikator kupca. offerId je numerični niz in se uporablja v vseh nadaljnjih klicih ponudbe. validityPeriodId določa rok veljavnosti ponudbe (1_HOUR7_DAYS). Za SI je država alpha-3 SVN, valuta 978 (EUR), tipa dokumenta PERSONAL_ID in PASSPORT.

×
Diagram v polni velikosti
Klikni sliko za povečavo · Esc za zapri