# Жалға беру бизнесіне

> Пауэрбанк станциясы, велосипед, самокат, құрал-жабдық, киім. Депозитті алу мен қайтару, мерзімдік төлем, QR арқылы автоматты беру және ішінара қайтару.

## Қысқаша

Жалға беруде екі бөлек ақша қозғалысы бар: **депозит** (кепілдік, көбіне толық қайтарылады) және **жалдау ақысы** (қайтарылмайды). Екеуін бір счётқа қоспаңыз — бөлек счёт жасаңыз, сонда қайтару таза шығады. Автомат немесе құлып арқылы беретін болсаңыз, схема біреу: клиент QR-ды сканерлейді → төлейді → бізден сіздің серверге `invoice.paid` webhook келеді → сіздің сервер құрылғыны ашады. Қай құрылғы екенін `metadata` өрісіне жазып қоясыз.

## Кімге жарайды

Пауэрбанк станциялары, велосипед пен самокат, аспап-құрал, құрылыс жабдығы, той киімі мен костюм, фотоаппарат, палатка — реті бәрінде бірдей.

## Жұмыс схемасы қадамдап

Автомат арқылы беретін нұсқасы:

| Қадам | Кім | Не болады |
|---|---|---|
| 1 | Клиент | Станциядағы QR-ды Kaspi қосымшасымен сканерлейді |
| 2 | Станция немесе сіздің сервер | `POST /api/v1/invoices` — счёт жасайды, `metadata`-ға слот пен құрылғы нөмірін салады |
| 3 | Клиент | Kaspi-де растайды |
| 4 | Qut Pay | `invoice.paid` оқиғасын сіздің адреске жібереді |
| 5 | Сіздің сервер | `metadata`-дан құрылғы нөмірін оқып, құлыпты ашады |
| 6 | Клиент | Заттың өзін алады |

Адам қабылдайтын нүктеде (прокат пункті, киім салоны) 5-қадам орнына қызметкер затты береді — қалғаны сол.

## Депозитті қалай алу керек

Екі счёт жасаңыз:

| Счёт | Сомасы | Сипаттамасы | Тағдыры |
|---|---|---|---|
| Жалдау ақысы | Мерзімге қарай | «Велосипед, 2 сағат» | Қалады |
| Депозит | Тұрақты сома | «Велосипед, кепілдік» | Қайтарылады |

Неге бөлек? Себебі қайтару счёт бойынша жүреді. Екеуін біріктірсеңіз, депозитті қайтару үшін ішінара қайтару жасауға тура келеді және есебіңіз шатасады.

**Депозит — нақты ақша, оны клиент шынымен төлейді.** Біз ақшаны бұғаттап ұстай алмаймыз: біздің жағымызда «ұсталған сома» деген нәрсе жоқ, ақша бірден сіздің Kaspi шотыңызға түседі. Сондықтан депозитті қайтару — бұл нақты қайтару операциясы, оны өзіңіз жасайсыз.

Клиентке мұны алдын ала түсіндіріңіз: «депозит қайтарылады, әдетте сол күні».

## Депозитті қайтару

Зат түскенде, тексеріп болған соң:

```
POST https://api.qut.kz/api/v1/invoices/{депозит счётының id}/refund
{ "reason": "зат бүтін күйінде қайтарылды" }
```

`amount` бермесеңіз толық сома қайтарылады.

## Ішінара қайтару

Зат зақымдалса немесе мерзімінен кеш қайтарылса, депозиттің бір бөлігін ұстап қаласыз:

```
POST https://api.qut.kz/api/v1/invoices/{id}/refund
{ "amount": 7000, "reason": "1 сағат кешіктірілді" }
```

Мұнда `amount` — **қайтаратын** сома, ұстап қалатын емес. 10 000 ₸ депозиттен 3 000 ₸ ұстағыңыз келсе, `7000` жазасыз. Счёт `partially_refunded` күйіне өтеді.

Қайтару жауабы белгісіз болып қалатын жағдай бар (`refund_unknown`) — бірден қайталамай, алдымен счёттың күйін оқыңыз. Толығы: [Қайтару API](/kb/refunds-api).

## Мерзімдік төлем

Ұзақ мерзімге беретін болсаңыз (айлық жабдық жалдау, ай сайынғы прокат), екі жол бар:

**1. Әр кезеңге қолмен счёт.** Кабинеттен немесе API-дан. Мерзім аяқталар алдында клиентке сілтеме жібересіз. Ең икемдісі: сома әр ай сайын өзгеруі мүмкін.

**2. Жазылым.** Кестеге сай счёт өздігінен шығады: `day`, `week`, `month` аралықтары бар. Бірақ маңызды: **ақша клиенттің шотынан өздігінен шешілмейді**, ол әр счётты Kaspi-де өзі растайды. Толығы: [Жазылымдық бизнеске](/kb/for-subscription-business).

Тәулік бойынша есептелетін жалдау (самокат, велосипед) үшін жазылым жарамайды — ол жерде әр жолы бөлек счёт дұрыс.

## Metadata: құрылғы нөмірін жазу

Бұл жалға беру бизнесіндегі ең маңызды техникалық тұсы. Счёт жасағанда:

```
{
  "amount": 500,
  "kind": "qr",
  "description": "Пауэрбанк, 2 сағат",
  "externalOrderId": "rent-90412",
  "metadata": {
    "station": "ALM-014",
    "slot": 7,
    "deviceId": "PB-33921",
    "type": "rent",
    "hours": 2
  }
}
```

`metadata` — кез келген JSON. Ол webhook-та **қайта келеді**, сондықтан `invoice.paid` алған кезде қай станцияның қай ұясын ашу керегін базадан іздеудің қажеті жоқ — оқиғаның өзінде тұрады.

`externalOrderId` — сіздің жалдау нөміріңіз, ол да webhook-та қайтады. Екеуін қатар қолданыңыз: [Metadata және тапсырыс нөмірі](/kb/metadata-and-orders).

Депозит счётында `"type": "deposit"` деп белгілеңіз — сонда webhook өңдеушіңіз екеуін шатастырмайды.

## Webhook жағында не істеу керек

- **Идемпотентті болсын.** Бір оқиға бірнеше рет келуі мүмкін. `(invoice.id, status)` жұбы бойынша тексеріңіз: егер осы счёт бойынша құлып бұрын ашылған болса, екінші рет ашпаңыз.
- **Қолтаңбаны тексеріңіз.** `X-Webhook-Signature` — `HMAC-SHA256(secret, timestamp + "." + rawBody)`. Денені өзгертілмеген байт күйінде тексеріңіз.
- **Жылдам жауап беріңіз.** 2xx емес жауап берсеңіз, 11 рет қайталанады. Құлыпты ашу ұзаққа созылса, оқиғаны кезекке салып, бірден 200 қайтарыңыз.
- **Адрес ашық болсын.** Продакшенде тек `https` және нақты домен, авторизациясыз.

Баптау: [Webhook баптау](/kb/webhook-setup).

## Ерекше ескертулер

- **QR-дың сканерлеу терезесі шамамен үш минут.** Станцияда тұрған клиент ойланып қалса, счёт `expired` болады. Экранда «QR-ды қайта жасау» батырмасы тұрсын.
- **Кеш келген төлем.** Счёт `expired` болғаннан кейін ақша келуі мүмкін — `invoice.paid` оқиғасы `late: true` белгісімен келеді. Ондайда клиент станцияның қасында тұрған шығар: затты беріңіз немесе ақшаны бірден қайтарыңыз. Схемаңызда бұл жағдай қарастырылсын.
- **Байланыс жоқ станция.** Станция интернетсіз қалса, счёт жасалмайды. Автомат схемасында бұл жағдай үшін бөлек мінез ойлаңыз.
- **Депозит сомасы шектен аспасын.** Тым үлкен депозит клиентті қорқытады, әрі қайтару операциясының көлемін өсіреді.
- **Ақша тіке сіздің Kaspi шотыңызға түседі**, бізде ұсталмайды.

## Жиі қойылатын сұрақтар

**Депозитті ұстап тұрып, кейін «босатуға» бола ма?** Жоқ. Ондай механизм жоқ. Депозит — толық төлем, оны қайтару үшін қайтару операциясын жасайсыз.

**Қайтаруға мерзім бар ма?** Иә, шектеу бар. Ұзақ мерзімді жалдауда депозитті бірнеше ай ұстамаңыз — мерзімі мен қателері: [Қайтару API](/kb/refunds-api).

**Автоматта экран жоқ, тек жапсырма QR қойсам бола ма?** Тұрақты (статикалық) сілтеме жасауға болады, бірақ ондайда счёт нақты құрылғыға байланбайды. Схемасы тұрақ пен шлагбаумға ұқсас: [Тұрақ пен шлагбаумға](/kb/for-parking) және [Вендинг автоматына](/kb/for-vending).

**Клиент затты қайтармаса ше?** Депозитті ұстап қаласыз, ол сіздің шотыңызда тұр — ешқандай әрекет керек емес. Қалғаны сіз бен клиенттің арасындағы мәселе.

**Бірнеше станциям бар, есепті бөлек көргім келеді.** Әр станцияға бөлек API кілт жасаңыз немесе `metadata.station` бойынша сүзіңіз: [Нүктелер бойынша бөлек есеп](/kb/multi-point-reporting).
