Қысқаша
Интеграцияның қауіпсіздігі екі нәрсеге келіп тіреледі: API кілт тек сіздің серверіңізде болуы және келген webhook шынымен бізден келгенін тексеруіңіз. Қалған тармақтар осы екеуін бекітеді.
Төмендегі 12 тармақты өткізіңіз. Әрқайсысының қасында «неге керек» деген бағаны бар — тармақты түсінбей орындағаннан, түсініп орындаған әлдеқайда пайдалы.
1. Кілт тек серверде
X-API-Key тақырыбындағы кілт тек өз серверіңіздің жадында немесе .env файлында болуы керек. Браузерде орындалатын JavaScript-ке, мобильді қосымшаның ішіне (APK/IPA), фронтенд бандліне салмаңыз.
Неге: кілт — счёт жасауға, күйін оқуға, қайтару жасауға берілген толық құқық. Браузерге шыққан кілтті кез келген адам DevTools-тан көреді. APK-ны декомпиляциялау бірнеше минут.
Мобильді қосымша жағдайында реті: қосымша → өз серверіңіз → Qut Pay → Kaspi. Қосымша бізге ешқашан тікелей жүгінбейді.
2. Кілтті репозиторийге салмау
.env файлын .gitignore-ға қосыңыз. Кілтті кодтың ішіне жазбаңыз, тестке де, мысалға да.
Неге: git тарихынан кілт жойылмайды — файлды өшірсеңіз де ескі коммитте қалады. Репозиторийді кейін ашық қылсаңыз немесе біреуге берсеңіз, кілт сонымен бірге кетеді.
Кілт коммитке түсіп кетсе: файлды тазалау жеткіліксіз, кілттің өзін кабинеттен жойып, жаңасын жасаңыз.
3. Әр интеграцияға бөлек кілт
Сайт, мобильді қосымша, CRM, ішкі скрипт — әрқайсысына өз кілті. Кабинетте кілттің атын түсінікті қойыңыз («Сайт», «1С», «Тестілеу»).
Неге: бір жер бұзылса, тек сол кілтті жоясыз. Бір ортақ кілт болса, бәрін бірден тоқтатуға мәжбүр боласыз.
4. Ең аз scope
Кілтке тек қажет құқықты беріңіз. Алты scope бар: invoices:read, invoices:write, refunds:write, subscriptions:manage, webhooks:manage, partner:manage.
| Не істейді | Қандай scope жеткілікті |
|---|---|
| Сайтта счёт жасау | invoices:write |
| Есеп беретін панель | invoices:read |
| Қолдау қызметінің құралы | invoices:read, refunds:write |
| Жазылым сервисі | subscriptions:manage, invoices:read |
Неге: refunds:write жоқ кілт сырттан ақша қайтара алмайды. Кілт шықса да, зияны шектеулі болады. Толығы: Құқықтар (scopes).
5. Кілтті кассирге байлау
Бірнеше кассир немесе бірнеше нүкте болса, кілтті нақты кассирге байлаңыз. Байланған кілттің live счёттары тек сол кассир арқылы жүреді, басқа кассирдің счёттарын көрмейді (404).
Неге: нүкте бойынша бөлу де, қауіпсіздік те. Толығы: API кілтті кассирге байлау.
6. Webhook қолтаңбасын RAW BODY бойынша тексеру
X-Webhook-Signature тақырыбы: sha256= префиксі + HMAC-SHA256(secret, timestamp + "." + rawBody), hex.
rawBody — келген дененің өзгертілмеген байттары. JSON-ға айналдырғанға дейін алыңыз. JSON.parse жасап, сосын қайта JSON.stringify жасасаңыз — бос орындар мен өрістердің реті өзгеріп, қолтаңба ешқашан сәйкес келмейді.
Неге: қолтаңба — webhook-тың шынымен бізден келгенінің жалғыз дәлелі. Адресіңіз ашық тұр (авторизациясыз болуы керек), сондықтан оны кез келген адам таба алса, сізге жалған «төленді» жіберуі мүмкін. Қолтаңба тексерілмесе, төленбеген тапсырысты жөнелтіп жіберуіңіз мүмкін.
Толығы және мысал код: Webhook қауіпсіздігі.
7. Timestamp 5 минут
X-Webhook-Timestamp мәнін өз сағатыңызбен салыстырыңыз. 5 минуттан ескі сұрауды қабылдамаңыз.
Неге: қолтаңба дұрыс болса да, ескі сұрауды ұстап алып, кейін қайта жіберуге болады (replay). Timestamp тексеруі осы терезені жабады. Серверіңіздің сағаты NTP арқылы дұрыс жүруі керек — әйтпесе барлық webhook «ескі» болып шығады.
8. HTTPS, тек нақты домен
Webhook адресі продакшенде міндетті түрде https және нақты домен болуы керек. IP-мекенжай да, уақытша туннель адресі де (ngrok, localtunnel сияқты) қабылданбайды — webhook_url_requires_https, webhook_url_requires_domain, webhook_url_tunnel_forbidden қателерін аласыз.
Неге: HTTP арқылы келген webhook-ты жолда оқуға да, өзгертуге де болады. Туннель адрестері уақытша: ертең ол адрес басқа адамға тиеді.
9. Webhook адресін болжауға келмейтін ету
/webhook емес, /hooks/qutpay/8f3c1a9e2b7d4f60 сияқты кездейсоқ бөлігі бар адрес жасаңыз.
Неге: бұл қолтаңбаның орнын баспайды, бірақ адресіңізді жаппай іздейтін скрипттер таппайды. Екі қабат қорғаныс бірден.
Ескерту: адрес авторизациясыз ашық болуы керек — Basic Auth немесе IP-сүзгі қойсаңыз, webhook жетпейді.
10. Журнал жүргізу — бірақ кілтсіз
Әр счёт жасауды, әр келген webhook-ты журналға жазыңыз: уақыты, invoice.id, externalOrderId, күйі, HTTP коды, X-Webhook-Delivery мәні.
Журналға ешқашан жазбаңыз: API кілттің өзін, webhook құпиясын, Authorization немесе X-API-Key тақырыптарының толық мәнін. Кілттің соңғы төрт таңбасын ғана жазыңыз.
Неге: журналсыз ешқандай мәселені шеше алмайсыз — «webhook келді ме, келмеді ме» деген сұраққа жауап беретін жалғыз орын сол. Бірақ журнал файлдары жиі басқа жүйелерге көшіріледі, сол арқылы кілт таралып кетеді.
11. Кілт сыртқы шықса — бірден жою
Кілт репозиторийге, скриншотқа, чатқа, журнал файлына түсіп кетті деп күдіктенсеңіз:
- Кабинет → Интеграциялар → сол кілтті жойыңыз. Жойылған кілт сол сәттен бастап 401 қайтарады
- Жаңа кілт жасаңыз, серверде ауыстырыңыз
- Соңғы күндердің счёттарын қарап шығыңыз: бөтен счёттар, күтпеген қайтарулар бар ма
- Кілт қалай шығып кеткенін тауып, сол жолды жабыңыз
Неге: «кейін ауыстырамын» деген жоспар жұмыс істемейді. Кілт жарамды тұрғанда, оны тапқан адам сіздің атыңыздан счёт жасай алады. Қадамдап: API кілт сыртқа шығып кетті.
12. Мерзімді ауыстыру
Кілтті жылына бір рет, сондай-ақ мына жағдайларда ауыстырыңыз: әзірлеуші жұмыстан кетті, мердігермен шарт бітті, сервер басқа жерге көшті.
Ауыстыру реті үзіліссіз болады: жаңа кілт жасаңыз → серверде ауыстырыңыз → жұмыс істеп тұрғанын тексеріңіз → ескісін жойыңыз. Екі кілт қатар жұмыс істей алады.
Неге: кілттің қанша адамның қолында болғанын уақыт өте есіңізден шығарасыз. Мерзімді ауыстыру осы белгісіздікті нөлге түсіреді.
Бонус: кассир нөмірін қорғау
Бұл техникалық емес, ұйымдастыру тармағы, бірақ іс жүзінде жиі бұзылады.
Kaspi бір кассирге бір ғана белсенді құрылғыға рұқсат береді. Кассир нөмірімен біреу Kaspi Pay қосымшасына кірсе, біздің сессия үзіледі (Kaspi коды -101001) және счёт жасау тоқтайды.
Сондықтан: кассир SIM-картасын сейфте немесе жауапты адамда ұстаңыз, ол нөмірмен қосымшаға кірмеңіз, қызметкерлерге «бұл нөмір бос жатыр» деп бермеңіз.
Жиі қойылатын сұрақтар
Webhook орнына күйді сұрап отырсам, қолтаңба керек пе? Жоқ — сіз өзіңіз сұрағанда жауап бізден келгені анық. Бірақ webhook-ты да қатар қосып қойған дұрыс: Webhook пен күйді сұрау.
Кілтті қай жерде сақтаған дұрыс? .env файлы немесе хостингіңіздің құпия айнымалылар қоймасы. Дерекқорда ашық мәтінмен сақтамаңыз.
Тест кілтін де осылай қорғау керек пе? qp_test_… кілтімен нақты ақша жүрмейді, сондықтан тәуекел аз. Бірақ әдетті бұзбаңыз — кодта тест кілті жазулы тұрса, біреу оны live кілтке ауыстырып, солай қалдырады.
Webhook құпиясын жоғалтып алдым. Ол бір рет қана көрсетіледі. Кабинет → Интеграциялар бөлімінен webhook адресін қайта жасаңыз, жаңа құпия аласыз.
Барлығын бір рет тексеріп шығатын тізім бар ма? Иә: Продакшенге шығу чек-парағы.