[{"data":1,"prerenderedAt":600},["ShallowReactive",2],{"navigation-en":3,"en:\u002Fdeposits\u002Fcashier":208,"en:\u002Fdeposits\u002Fcashier:surround":595},[4,20,30,61,92,110,125,148,173,187],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fgetting-started","1.getting-started",[10,15],{"title":11,"path":12,"stem":13,"icon":14},"Portal Preparation","\u002Fgetting-started\u002Fportal-setup","1.getting-started\u002F1.portal-setup","i-lucide-rocket",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart","i-lucide-zap",{"title":21,"icon":22,"path":23,"stem":24,"children":25,"page":6},"Service & Terms","i-lucide-scale","\u002Fterms","10.terms",[26],{"title":27,"path":28,"stem":29,"icon":22},"Settlement & Service Terms","\u002Fterms\u002Fsettlement-and-terms","10.terms\u002F1.settlement-and-terms",{"title":31,"icon":32,"path":33,"stem":34,"children":35,"page":6},"Core Concepts","i-lucide-key-round","\u002Fconcepts","2.concepts",[36,41,46,51,56],{"title":37,"path":38,"stem":39,"icon":40},"Authentication","\u002Fconcepts\u002Fauthentication","2.concepts\u002F1.authentication","i-lucide-fingerprint",{"title":42,"path":43,"stem":44,"icon":45},"IP Allowlist","\u002Fconcepts\u002Fip-allowlist","2.concepts\u002F2.ip-allowlist","i-lucide-shield-check",{"title":47,"path":48,"stem":49,"icon":50},"Money Format","\u002Fconcepts\u002Fmoney","2.concepts\u002F3.money","i-lucide-banknote",{"title":52,"path":53,"stem":54,"icon":55},"Idempotency","\u002Fconcepts\u002Fidempotency","2.concepts\u002F4.idempotency","i-lucide-repeat",{"title":57,"path":58,"stem":59,"icon":60},"Error envelope & codes","\u002Fconcepts\u002Ferrors","2.concepts\u002F5.errors","i-lucide-octagon-alert",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":6},"Deposits","i-lucide-arrow-down-to-line","\u002Fdeposits","3.deposits",[67,72,77,82,87],{"title":68,"path":69,"stem":70,"icon":71},"Deposit Overview & State Machine","\u002Fdeposits\u002Foverview","3.deposits\u002F1.overview","i-lucide-info",{"title":73,"path":74,"stem":75,"icon":76},"Create a Deposit","\u002Fdeposits\u002Fcreate","3.deposits\u002F2.create","i-lucide-plus",{"title":78,"path":79,"stem":80,"icon":81},"Get a Deposit","\u002Fdeposits\u002Fretrieve","3.deposits\u002F3.retrieve","i-lucide-search",{"title":83,"path":84,"stem":85,"icon":86},"Cancel a Deposit","\u002Fdeposits\u002Fcancel","3.deposits\u002F4.cancel","i-lucide-x",{"title":88,"path":89,"stem":90,"icon":91},"Hosted Cashier Page","\u002Fdeposits\u002Fcashier","3.deposits\u002F5.cashier","i-lucide-external-link",{"title":93,"icon":94,"path":95,"stem":96,"children":97,"page":6},"Withdrawals","i-lucide-arrow-up-from-line","\u002Fwithdrawals","4.withdrawals",[98,102,106],{"title":99,"path":100,"stem":101,"icon":71},"Withdrawal Overview","\u002Fwithdrawals\u002Foverview","4.withdrawals\u002F1.overview",{"title":103,"path":104,"stem":105,"icon":76},"Create a Withdrawal","\u002Fwithdrawals\u002Fcreate","4.withdrawals\u002F2.create",{"title":107,"path":108,"stem":109,"icon":81},"Get & List Withdrawals","\u002Fwithdrawals\u002Fretrieve","4.withdrawals\u002F3.retrieve",{"title":111,"icon":112,"path":113,"stem":114,"children":115,"page":6},"Balance & Banks","i-lucide-wallet","\u002Fbalance","5.balance",[116,120],{"title":117,"path":118,"stem":119,"icon":112},"Get Balance","\u002Fbalance\u002Fget-balance","5.balance\u002F1.get-balance",{"title":121,"path":122,"stem":123,"icon":124},"Bank List","\u002Fbalance\u002Fbanks","5.balance\u002F2.banks","i-lucide-landmark",{"title":126,"icon":127,"path":128,"stem":129,"children":130,"page":6},"Webhooks","i-lucide-webhook","\u002Fwebhooks","6.webhooks",[131,135,140,144],{"title":132,"path":133,"stem":134,"icon":71},"Webhook Overview","\u002Fwebhooks\u002Foverview","6.webhooks\u002F1.overview",{"title":136,"path":137,"stem":138,"icon":139},"Event Catalog & Payloads","\u002Fwebhooks\u002Fevents","6.webhooks\u002F2.events","i-lucide-list",{"title":141,"path":142,"stem":143,"icon":45},"Signature Verification","\u002Fwebhooks\u002Fsignature-verification","6.webhooks\u002F3.signature-verification",{"title":145,"path":146,"stem":147,"icon":55},"Endpoint Requirements, Retries & SSRF","\u002Fwebhooks\u002Fdelivery-and-retries","6.webhooks\u002F4.delivery-and-retries",{"title":149,"icon":150,"path":151,"stem":152,"children":153,"page":6},"Sandbox","i-lucide-flask-conical","\u002Fsandbox","7.sandbox",[154,158,163,168],{"title":155,"path":156,"stem":157,"icon":71},"Test Mode Overview","\u002Fsandbox\u002Foverview","7.sandbox\u002F1.overview",{"title":159,"path":160,"stem":161,"icon":162},"Simulate Transfer","\u002Fsandbox\u002Fsimulate-transfer","7.sandbox\u002F2.simulate-transfer","i-lucide-banknote-arrow-down",{"title":164,"path":165,"stem":166,"icon":167},"Top-up & Reset","\u002Fsandbox\u002Ftop-up-and-reset","7.sandbox\u002F3.top-up-and-reset","i-lucide-rotate-ccw",{"title":169,"path":170,"stem":171,"icon":172},"End-to-End Test Flow","\u002Fsandbox\u002Fe2e-test-flow","7.sandbox\u002F4.e2e-test-flow","i-lucide-list-checks",{"title":174,"icon":14,"path":175,"stem":176,"children":177,"page":6},"Go-live","\u002Fgo-live","8.go-live",[178,182],{"title":179,"path":180,"stem":181,"icon":172},"Go-live Checklist","\u002Fgo-live\u002Fchecklist","8.go-live\u002F1.checklist",{"title":183,"path":184,"stem":185,"icon":186},"Contact & Support","\u002Fgo-live\u002Fsupport","8.go-live\u002F2.support","i-lucide-life-buoy",{"title":188,"icon":189,"path":190,"stem":191,"children":192,"page":6},"Reference","i-lucide-book-marked","\u002Freference","9.reference",[193,198,203],{"title":194,"path":195,"stem":196,"icon":197},"Endpoint Catalog","\u002Freference\u002Fendpoints","9.reference\u002F1.endpoints","i-lucide-table",{"title":199,"path":200,"stem":201,"icon":202},"Code Samples (Node.js & PHP)","\u002Freference\u002Fcode-samples","9.reference\u002F2.code-samples","i-lucide-code",{"title":204,"path":205,"stem":206,"icon":207},"Status Values & Glossary","\u002Freference\u002Fglossary-states","9.reference\u002F3.glossary-states","i-lucide-book-a",{"id":209,"title":88,"badge":210,"body":211,"description":589,"extension":590,"links":210,"meta":591,"method":210,"navigation":592,"path":89,"seo":593,"stem":90,"__hash__":594},"docs_en\u002F3.deposits\u002F5.cashier.md",null,{"type":212,"value":213,"toc":578},"minimark",[214,222,235,256,261,271,285,294,308,315,370,381,387,404,427,431,469,473,519,523,530,536,546,550],[215,216,217,221],"p",{},[218,219,220],"code",{},"cashier_url"," — optional field on the deposit response",[215,223,224,225,230,231,234],{},"A deposit response can carry a ",[226,227,228],"strong",{},[218,229,220],{},": a payment page we host for that one deposit. It shows the PromptPay QR or the destination account number, the exact ",[218,232,233],{},"expected_amount",", a countdown, and refreshes the status by itself. Instead of building a payment screen, you can simply send the customer there.",[236,237,238],"note",{},[215,239,240,243,244,247,248,251,252,255],{},[226,241,242],{},"Entirely optional."," If you already render your own payment page from ",[218,245,246],{},"pay_to"," \u002F ",[218,249,250],{},"qr_payload",", ignore the field — nothing else changes, and the same ",[218,253,254],{},"deposit.success"," webhook still decides the outcome.",[257,258,260],"h2",{"id":259},"two-ways-to-show-the-payment-instructions","Two ways to show the payment instructions",[262,263,269],"pre",{"className":264,"code":266,"language":267,"meta":268},[265],"language-text","merchant creates the deposit  (POST \u002Fv1\u002Fdeposits)\n   |-- (a) merchant renders its own page from pay_to \u002F qr_payload   \u003C- unchanged\n   \\-- (b) merchant redirects the customer to cashier_url           \u003C- optional, nothing to build\n                    |\n                    v\n        wait for the deposit.success webhook  (identical either way)\n","text","",[218,270,266],{"__ignoreMap":268},[215,272,273,276,277,247,279,281,282,284],{},[226,274,275],{},"(a)"," is the classic S2S integration: take ",[218,278,246],{},[218,280,250],{}," + ",[218,283,233],{}," from the response and draw your own payment screen.",[215,286,287,290,291,293],{},[226,288,289],{},"(b)"," uses ",[218,292,220],{}," — redirect the customer to that URL and build nothing.",[215,295,296,297,247,299,302,303,307],{},"Both branches end the same way: the authoritative result arrives on the ",[218,298,254],{},[218,300,301],{},"deposit.expired"," webhook. See ",[304,305,306],"a",{"href":137},"Webhook Events",".",[257,309,311,312,314],{"id":310},"where-cashier_url-comes-from","Where ",[218,313,220],{}," comes from",[316,317,318,334],"table",{},[319,320,321],"thead",{},[322,323,324,328],"tr",{},[325,326,327],"th",{},"Endpoint",[325,329,330,331,333],{},"Returns ",[218,332,220],{},"?",[335,336,337,350],"tbody",{},[322,338,339,347],{},[340,341,342],"td",{},[304,343,344],{"href":74},[218,345,346],{},"POST \u002Fv1\u002Fdeposits",[340,348,349],{},"On creation, when the hosted page is available for your account.",[322,351,352,359],{},[340,353,354],{},[304,355,356],{"href":79},[218,357,358],{},"GET \u002Fv1\u002Fdeposits\u002F:id",[340,360,361,362,365,366,369],{},"Only while ",[218,363,364],{},"status"," is ",[218,367,368],{},"PENDING",", and it is exactly the same link creation returned — use it to recover the page for a customer who closed the tab.",[215,371,372,373,376,377,380],{},"The link has the shape ",[218,374,375],{},"\u003Ccashier-origin>\u002Fc\u002F\u003Cdeposit_id>\u002F\u003Ccashier_token>",", where ",[218,378,379],{},"cashier_token"," is a random 128-bit value (32 hex characters) minted per deposit:",[262,382,385],{"className":383,"code":384,"language":267,"meta":268},[265],"https:\u002F\u002Fpay.example.com\u002Fc\u002F8f2b1c4e-7a90-4d2f-9b3a-1c2d3e4f5a6b\u002F9f2c1d4e7a3b5c8d0e1f2a3b4c5d6e7f\n",[218,386,384],{"__ignoreMap":268},[215,388,389,390,393,394,397,398],{},"The host above is only an example. The cashier origin is a ",[226,391,392],{},"separate domain from the API"," — never assume it shares ",[218,395,396],{},"api.unkpay.co",", its cookies, or its CORS policy — and it is configured server-side and may change. ",[226,399,400,401,403],{},"Always redirect to the ",[218,402,220],{}," value exactly as returned; never hardcode the host or rebuild the URL yourself.",[405,406,407],"caution",{},[215,408,409,365,411,414,415,418,419,247,421,423,424,426],{},[218,410,220],{},[226,412,413],{},"optional and may be absent entirely"," (the key is omitted, not ",[218,416,417],{},"null",") — for example when the hosted page is not available for your account, when the deposit is already terminal, or on deposits created before this feature shipped. Always code for its absence: if it is missing, render your own page from ",[218,420,246],{},[218,422,250],{}," as before. Never treat a missing ",[218,425,220],{}," as an error.",[257,428,430],{"id":429},"treat-the-link-as-a-per-customer-secret","Treat the link as a per-customer secret",[405,432,433,440],{},[215,434,435,436,439],{},"The link is a ",[226,437,438],{},"bearer capability",": anyone holding the full URL can open that customer's payment page — no login, no signature, no API key.",[441,442,443,457,460,463],"ul",{},[444,445,446,447,453,454,456],"li",{},"The token is deliberately ",[226,448,449,450],{},"separate from ",[218,451,452],{},"deposit_id",", because ",[218,455,452],{}," travels widely (webhooks, your back office, logs, support tickets) and leaking it must never open a customer's payment page.",[444,458,459],{},"Give the link only to the customer who owns the order (redirect \u002F their SMS \u002F their email).",[444,461,462],{},"Never write it to shared logs, analytics events, APM or error trackers, or a group chat.",[444,464,465,468],{},[226,466,467],{},"It does not expire on its own"," — it lives as long as the deposit and cannot be revoked.",[257,470,472],{"id":471},"what-the-page-shows-in-each-state","What the page shows in each state",[441,474,475,484,499,506],{},[444,476,477,478,480,481,483],{},"While ",[218,479,368],{},": the QR \u002F destination account number, the exact ",[218,482,233],{},", and a countdown. The page refreshes the status by polling on its own — there is no push channel, so do not build latency guarantees on it.",[444,485,486,487,490,491,494,495,498],{},"Once the deposit is ",[218,488,489],{},"CREDITED",", ",[218,492,493],{},"EXPIRED"," or ",[218,496,497],{},"CANCELLED",": the page still opens, but shows only the result — no QR, no account number, nothing payable.",[444,500,501,502,505],{},"Cancelling a deposit does ",[226,503,504],{},"not"," revoke the link. It keeps opening and simply reports the cancellation, so stop showing or sending it after you cancel.",[444,507,508,509,511,512,515,516,518],{},"A deposit can still read ",[218,510,368],{}," for a short moment after ",[218,513,514],{},"match_window_until"," has passed (expiry is swept asynchronously). Do not redirect a customer when ",[218,517,514],{}," is already in the past — create a new deposit instead.",[257,520,522],{"id":521},"the-customer-slip-upload-box","The customer slip-upload box",[215,524,525,526,529],{},"Some deposits are allocated to a destination account that accepts transfer slips. On those, the cashier page adds a box where the ",[226,527,528],{},"customer"," uploads their transfer slip; the system verifies it with the bank and credits the deposit.",[215,531,532,533,535],{},"You do nothing extra: no field in the deposit response tells you which deposits get the box, you cannot request or disable it, and you still wait for the same ",[218,534,254],{}," webhook with the same payload.",[405,537,538],{},[215,539,540,541,494,543,545],{},"A late upload cannot revive a deposit. Once it is ",[218,542,493],{},[218,544,497],{}," the page refuses the upload — create a new deposit instead.",[257,547,549],{"id":548},"test-mode-sandbox","Test mode (sandbox)",[215,551,552,553,556,557,559,560,562,563,565,566,568,569,571,572,574,575,577],{},"Deposits created with a ",[218,554,555],{},"unk_test_..."," key do ",[226,558,504],{}," carry ",[218,561,220],{}," — neither from ",[218,564,346],{}," nor from ",[218,567,358],{},". The sandbox rehearses create → ",[304,570,159],{"href":160}," → ",[218,573,254],{},", which is the flow your server code depends on. Since the field is optional anyway, the correct sandbox behavior is the same as the live fallback: when ",[218,576,220],{}," is missing, render your own page.",{"title":268,"searchDepth":579,"depth":580,"links":581},1,2,[582,583,585,586,587,588],{"id":259,"depth":580,"text":260},{"id":310,"depth":580,"text":584},"Where cashier_url comes from",{"id":429,"depth":580,"text":430},{"id":471,"depth":580,"text":472},{"id":521,"depth":580,"text":522},{"id":548,"depth":580,"text":549},"cashier_url — an optional payment page UnknownPay hosts for a single deposit, so you can redirect the customer instead of building your own payment screen","md",{},{"icon":91},{"title":88,"description":589},"wDWoog6okWpCzJD1p4GUtzP5MIZO3wPOX2WTtSM5H0o",[596,598],{"title":83,"path":84,"stem":85,"description":597,"icon":86,"children":-1},"POST \u002Fv1\u002Fdeposits\u002F:id\u002Fcancel — cancel a still-PENDING deposit and release the amount slot; own + same-mode only",{"title":99,"path":100,"stem":101,"description":599,"icon":71,"children":-1},"How payouts work — gross debited immediately at create, manual approval, and the PENDING→SUCCESS\u002FFAILED\u002FREJECTED state machine",1786869825162]