Қысқаша
Қайтару сұрауы refund_unknown (502) немесе refund_pending_unknown (409) қайтарса, бұл «қайтару өтпеді» дегенді білдірмейді — бұл нәтижесі әлі белгісіз дегенді білдіреді. Сол сәтте қайталап жіберсеңіз, бірінші қайтару шын мәнінде өтіп кеткен болса, клиентке ақша екі рет барады. Дұрыс әрекет біреу: қайталамаңыз, GET /api/v1/invoices/{id} арқылы счёттың күйін оқып, нәтижені содан біліңіз.
Неге «белгісіз» деген жауап болады
Қайтару — бірнеше жүйеден өтетін әрекет. Сұрау Kaspi-ге жетіп, ол әрекетті орындап та қойып, бірақ жауабы бізге жетпей қалуы мүмкін. Сол кезде біз сізге адал жауап береміз: нәтижесі белгісіз.
| Код | HTTP | Мағынасы |
|---|---|---|
refund_unknown | 502 | Kaspi жауап бермеді, қайтару өтті ме, жоқ па — белгісіз |
refund_pending_unknown | 409 | Алдыңғы қайтарудың нәтижесі әлі белгісіз, жаңасын қабылдамаймыз |
refund_failed | 502 | Kaspi қайтаруды орындамады. Бұл — нақты «өтпеді» |
refund_state_conflict | 409 | Қайтару күйі күткеннен басқа, күйді қайта оқу керек |
refund_failed пен refund_unknown арасындағы айырмашылық осы мақаланың негізі. Біріншісі — нақты сәтсіздік, оны түзетіп қайталауға болады. Екіншісі — белгісіздік, оны қайталауға болмайды.
refund_pending_unknown — бұл біздің қорғанысымыз: алдыңғы қайтарудың тағдыры шешілмей тұрып, жаңасын өткізбейміз. Оны көрсеңіз, жүйе сізді дәл қазір қателіктен сақтап тұр деп біліңіз.
Дұрыс әрекет реті
- Қайталамаңыз. Автоматты қайталау логикаңыз болса, қайтару сұрауын одан алып тастаңыз.
- Біраз күтіңіз — бірнеше секунд.
GET /api/v1/invoices/{id}жіберіңіз. Жауапта счёттың күйі және оның қайтарулары болады.- Күйге қарап шешіңіз:
| Счёттың күйі | Нені білдіреді | Не істеу керек |
|---|---|---|
refunded | Толық қайтарылған | Бітті. Қайталамаңыз |
partially_refunded | Бір бөлігі қайтарылған | Қайтарылған соманы есептеп, жеткіліксіз болса ғана айырмасын жіберіңіз |
paid | Қайтару өтпеген | Енді ғана қайталауға болады |
- Нәтижені өз журналыңызға жазыңыз — келесі жолы қайта сұрамау үшін.
Егер бірнеше рет сұрағанда да күй анық болмай тұрса, күте тұрыңыз және қолдауға жазыңыз. Бұл жағдайда «бір рет қана қайталап көрейін» деген қауіпті.
Webhook арқылы да біле аласыз
Қайтару әрекетінің нәтижесі оқиға түрінде де келеді: refund.done, refund.failed, refund.unknown, ал счёттың күйі өзгергенде invoice.refunded немесе invoice.partially_refunded.
Яғни refund_unknown алған соң екі жол бар: күйді өзіңіз сұрау немесе оқиғаны күту. Ең сенімдісі — екеуін қатар жүргізу, бірақ екеуінің де нәтижесін бір орында, идемпотентті түрде өңдеу.
Идемпоттылық
Екі рет қайтарудан қорғайтын басты нәрсе — қайталанбайтындықты өз жағыңызда қамтамасыз ету.
- Бір счётқа бір ғана «қайтару тапсырмасы» болсын. Оны өз базаңызда жазба етіп сақтаңыз:
счёт id,сома,күйі(жіберілді / расталды / белгісіз / өтпеді). - Жазбаны құлыптаңыз. Сол счёт бойынша екінші қайтару тапсырмасы қосылмасын. Қатар жүретін екі процесс бір счётқа бір уақытта қайтару жібермеуі керек.
- Кезектегі тапсырманы автоматты қайталайтын болсаңыз, «белгісіз» күйді қайталауға жарамсыз деп белгілеңіз. Ондай тапсырма қайталауға емес, тексеруге кетуі керек.
- Webhook өңдеуі де идемпотентті болсын.
(счёт id, күй)жұбы бұрын өңделген болса, ештеңе істемеңіз. Webhook 2xx емес жауап алса 11 рет қайталанады, сондықтан бір оқиға сізге бірнеше рет келуі әбден мүмкін. - Қолмен қайтару да журналға түссін. Кабинеттен қолмен қайтарып, сосын жүйеңіз тағы бір қайтару жіберсе, нәтиже сол екі есе болады.
Ішінара қайтару есебі
Ішінара қайтару кезінде санақ адасу оңай. Ереже қарапайым: қайтарылған сомалардың қосындысы төленген сомадан аспауы керек. Артық жіберсеңіз invalid_refund_amount (422) аласыз — бұл жақсы, бірақ оған сүйенбеңіз, өзіңіз есептеңіз.
Мысалы: 10 000 ₸ төленген счёт. 3 000 ₸ қайтардыңыз — счёт partially_refunded болады, қалғаны 7 000 ₸. Екінші рет 3 000 ₸ жіберсеңіз, ол бірінші қайтаруды қайталау емес, жаңа қайтару: барлығы 6 000 ₸ болады. Сондықтан «қайталап жіберейін» деген ой ішінара қайтаруда ең қауіпті.
Есепті әрқашан GET /api/v1/invoices/{id} жауабындағы қайтарулар тізімінен жүргізіңіз, өз болжамыңызбен емес.
Журнал нені жазуы керек
Даулы жағдайда сізді осы құтқарады.
- Қайтару сұрауын жіберген уақыт, счёт id, сома
- Жауаптың HTTP күйі және
errorкоды - Одан кейінгі
GET /invoices/{id}жауабы: күйі мен қайтарулары - Келген webhook оқиғалары,
X-Webhook-Deliveryтақырыбымен - Қайтаруды кім бастады: жүйе ме, әлде адам қолмен бе
Кілттің өзін журналға жазбаңыз. Тақырыптарды тіркегенде X-API-Key мәнін сүзіп тастаңыз.
Жиі қойылатын сұрақтар
refund_unknown алдым, күйі paid болып тұр. Қайталауға бола ма? Иә. Күй paid болса, қайтару өтпеген, қайталауға болады.
refund_pending_unknown қанша тұрады? Алдыңғы қайтарудың тағдыры анықталғанша. Бірнеше секунд күтіп, счёттың күйін қайта оқыңыз.
Екі рет қайтарып жіберсем, кері қайтаруға бола ма? Жоқ, қайтаруды «болдырмау» деген әрекет жоқ. Клиентпен тікелей сөйлесіп, артық сомадан жаңа счёт шығару керек болады.
Қайтарудың идемпоттылық кілті бар ма? Счёт жасауда Idempotency-Key тақырыбы бар. Қайтаруда қорғаныс басқаша жұмыс істейді: алдыңғы қайтарудың нәтижесі белгісіз болса, жаңасы қабылданбайды (refund_pending_unknown). Өз жағыңыздағы журнал мен құлып — бәрібір міндетті.
Қайтару ақшасы қайдан алынады? Kaspi шотыңыздан. Ақша бізде тұрмайды: Ақша қашан және қайда түседі.