# API 403 қайтарады — құқық жетпей тұр

> 403 дегені кілтіңіз танылды, бірақ бұл әрекетке рұқсат жоқ. Бес түрлі себебі бар: scope жетпеуі, тариф, бөтен ұйым, кілт байланған кассир, sandbox әрекеті. Әрқайсысын қалай ажырату керек.

## Қысқаша

`403` келсе, кілтіңіз танылды — бұл жақсы жаңалық. Мәселе енді кілтте емес, **құқықта**. Жауаптағы `error` өрісін оқыңыз: ол бес түрлі мәннің бірі болады және әрқайсысының шешімі бөлек. `insufficient_scope` — кілтке құқық қосу керек. `tariff_inactive` — тарифті төлеу керек. `forbidden` — ресурс сіздің ұйымыңызға тиесілі емес. `not_sandbox` — бұл әрекет тек sandbox-та. `account_blocked` — қолдауға жазу керек.

Кодты ешқашан HTTP күйіне ғана қарап жазбаңыз. `403` — тым жалпы, шешім `error` өрісінде.

## Бес қате, бес шешім

| `error` | Не болды | Не істеу керек |
|---|---|---|
| `insufficient_scope` | Кілтте осы әрекетке құқық берілмеген | Кабинеттен кілтке керекті scope қосыңыз |
| `tariff_inactive` | Тариф белсенді емес немесе сынақ мерзімі бітті | Кабинет → Тариф |
| `forbidden` | Ресурс сіздің ұйымыңызға немесе кілтіңізге көрінбейді | Кілт пен счёт бір ұйымға тиесілі ме, тексеріңіз |
| `not_sandbox` | Әрекет тек sandbox режимінде істейді | Мысалы `simulate` live-та жұмыс істемейді |
| `account_blocked` | Аккаунт бөгелген | [Қолдауға](https://qut.kz/app) жазыңыз |

## Scope жетпей тұрса

Scope — кілттің не істей алатынын шектейтін құқық белгісі. Алтауы бар:

| Scope | Нені ашады |
|---|---|
| `invoices:read` | Счёттар тізімі мен біреуінің күйін оқу |
| `invoices:write` | Счёт жасау, болдырмау |
| `refunds:write` | Қайтару жасау |
| `subscriptions:manage` | Жазылымдарды басқару |
| `webhooks:manage` | Webhook адрестерін қосу және өзгерту |
| `partner:manage` | Серіктестік әдістері |

Ең жиі кездесетін жағдай: кілт тек оқуға берілген, ал код счёт жасамақ болады. Немесе қайтару жасағанда `refunds:write` жетпейді — бұл әдейі бөлек шығарылған, қайтару ең қауіпті әрекет.

Қосу жолы: [кабинет](https://qut.kz/app) → Интеграциялар → кілтті ашып, керекті құқықты белгілеңіз. Жаңа кілт жасаудың қажеті жоқ, ескісі сол күйі қала береді.

**Керегінен артық scope бермеңіз.** Дүкен сайтына `invoices:read` пен `invoices:write` жеткілікті. Кілт сыртқа шығып кетсе, зияны да сол құқықпен шектеледі.

## Тариф белсенді емес болса

`tariff_inactive` екі жағдайда келеді: сынақ мерзімі бітіп, тариф таңдалмаған немесе төленбеген. Сынақ **бірінші нақты счёттан** басталады, тіркелген күннен емес — сондықтан «мен кеше ғана тіркелдім» деген уәж мұнда жұмыс істемейді, есеп бірінші live счёттан жүреді.

Sandbox бұл қатеге ұшырамайды: `qp_test_` кілтпен жұмысыңыз тариф белсенді болмаса да жалғаса береді. Сондықтан sandbox-та бәрі істеп, live-та 403 келсе — бірінші тексеретін нәрсе осы.

## forbidden: ресурс сізге көрінбейді

`forbidden` дегені — сұраған счёт бар, бірақ ол сіздікі емес. Үш жағдайда болады.

**1. Кілт басқа ұйымдікі.** Бір аккаунтта бірнеше ұйым болса, әр ұйымның өз кілті бар. Бір ұйымның кілтімен екінші ұйымның счётын сұрасаңыз, дәл осы қате келеді. Кілт қай ұйымдікі екенін кабинеттен көресіз.

**2. Кілт нақты бір кассирге байланған.** Байланған кілттің live счёттары тек сол кассир арқылы жүреді. Басқа кассир жасаған счётты сұрасаңыз, ол кілтке көрінбейді. Көбіне мұндайда `invoice_not_found` (404) келеді, кейде `forbidden`. Бірнеше кассирмен жұмыс: [Бір ұйымға бірнеше кассир](/kb/two-cashiers).

**3. Идентификатор басқа ортадан алынған.** Sandbox-та жасалған счёттың `id`-ін live кілтпен сұрау — жиі кездесетін шатасу, әсіресе тестен көшкен соң.

Ажырату әдісі қарапайым: сол кілтпен `GET /api/v1/invoices` шақырыңыз. Тізім келсе, кілт жұмыс істейді, мәселе нақты счётта. Тізімде сіз іздеп жүрген счёт бар ма — соған қараңыз.

## not_sandbox

Кейбір әдістер тек sandbox-та бар. Ең жиі кездесетіні — төлемді симуляциялау:

```bash
# Тек sandbox-та істейді
curl -X POST https://api.qut.kz/api/v1/invoices/INV_ID/simulate \
  -H "X-API-Key: qp_test_СІЗДІҢ_КІЛТІҢІЗ" \
  -H "Content-Type: application/json" \
  -d '{"status":"paid"}'
```

Мұны live кілтпен жіберсеңіз, `not_sandbox` келеді. Бұл — қорғаныс: нақты ақша жүрмеген счётты «төленді» деп белгілеуге болмайды.

Автоматты тестеріңіз live кілтпен жүріп кетсе, дәл осы қатеге тіреледі. Тест ортасында `qp_test_` кілт тұрғанына көз жеткізіңіз.

## Ұйым сәйкессіздігі

Ең шатастыратын жағдай — кассир мүлде басқа Kaspi ұйымына тиесілі болуы. Ұйым бірінші байланыс кезінде бекітіледі: содан кейін басқа Kaspi ұйымының кассирін қосуға тырыссаңыз, счёттар не жасалмайды, не сізге көрінбейді.

Мұны былай тексересіз: кабинеттегі Kaspi бөлімінде байланыс картасында қай ұйым көрсетіліп тұр, сол ұйым Kaspi Pay қосымшасында көріп отырған ұйымыңызбен бір ме? Екеуі бөлек болса, дұрыс ұйымның кассирін қосу керек.

## Тексеру реті

1. Жауаптың `error` өрісін оқыңыз — HTTP кодына емес, соған қараңыз
2. `insufficient_scope` болса, кабинеттен кілтке құқық қосыңыз
3. `tariff_inactive` болса, Тариф бөлімін ашыңыз
4. `forbidden` болса, `GET /api/v1/invoices` тізімін сұрап, кілт қандай счёттарды көретінін қараңыз
5. Тізім бос болса, кілт басқа ұйымдікі немесе басқа кассирге байланған
6. Бәрі дұрыс көрінсе: [Мәселе менде ме, Kaspi-де ме](/kb/is-it-us-or-kaspi)

Кілттің өзі танылмай тұрса, 403 емес, 401 келеді: [API 401 қайтарады](/kb/api-401).

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

**Scope қосқан соң кілтті ауыстыру керек пе?** Жоқ. Құқық бірден күшіне енеді, ескі кілт жұмысын жалғастырады.

**403 келгенде қайталауға бола ма?** Жоқ. Құқық өзгермейінше нәтиже де өзгермейді.

**Кілтті кассирге байлауды кері қайтаруға бола ма?** Иә, кабинеттен байланысты алып тастауға болады. Бірақ бір кассирге байланған кілт бар кезде ол кассирді жоя алмайсыз — алдымен кілтті ажыратыңыз.

**Тарифті төлегеннен кейін бірден істей ме?** Иә, тариф белсенді болған сәттен бастап `tariff_inactive` жоғалады.

**`account_blocked` неге келеді?** Сирек кездеседі және оны өз бетіңізше шеше алмайсыз. WhatsApp +7 778 881 3333 немесе Telegram @qutpaybot арқылы қолдауға жазыңыз.
