[{"data":1,"prerenderedAt":787},["ShallowReactive",2],{"navigation-en":3,"en:\u002Fconcepts\u002Ferrors":193,"en:\u002Fconcepts\u002Ferrors:surround":782},[4,20,51,77,95,110,133,158,172],{"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},"Core Concepts","i-lucide-key-round","\u002Fconcepts","2.concepts",[26,31,36,41,46],{"title":27,"path":28,"stem":29,"icon":30},"Authentication","\u002Fconcepts\u002Fauthentication","2.concepts\u002F1.authentication","i-lucide-fingerprint",{"title":32,"path":33,"stem":34,"icon":35},"IP Allowlist","\u002Fconcepts\u002Fip-allowlist","2.concepts\u002F2.ip-allowlist","i-lucide-shield-check",{"title":37,"path":38,"stem":39,"icon":40},"Money Format","\u002Fconcepts\u002Fmoney","2.concepts\u002F3.money","i-lucide-banknote",{"title":42,"path":43,"stem":44,"icon":45},"Idempotency","\u002Fconcepts\u002Fidempotency","2.concepts\u002F4.idempotency","i-lucide-repeat",{"title":47,"path":48,"stem":49,"icon":50},"Error envelope & codes","\u002Fconcepts\u002Ferrors","2.concepts\u002F5.errors","i-lucide-octagon-alert",{"title":52,"icon":53,"path":54,"stem":55,"children":56,"page":6},"Deposits","i-lucide-arrow-down-to-line","\u002Fdeposits","3.deposits",[57,62,67,72],{"title":58,"path":59,"stem":60,"icon":61},"Deposit Overview & State Machine","\u002Fdeposits\u002Foverview","3.deposits\u002F1.overview","i-lucide-info",{"title":63,"path":64,"stem":65,"icon":66},"Create a Deposit","\u002Fdeposits\u002Fcreate","3.deposits\u002F2.create","i-lucide-plus",{"title":68,"path":69,"stem":70,"icon":71},"Get a Deposit","\u002Fdeposits\u002Fretrieve","3.deposits\u002F3.retrieve","i-lucide-search",{"title":73,"path":74,"stem":75,"icon":76},"Cancel a Deposit","\u002Fdeposits\u002Fcancel","3.deposits\u002F4.cancel","i-lucide-x",{"title":78,"icon":79,"path":80,"stem":81,"children":82,"page":6},"Withdrawals","i-lucide-arrow-up-from-line","\u002Fwithdrawals","4.withdrawals",[83,87,91],{"title":84,"path":85,"stem":86,"icon":61},"Withdrawal Overview","\u002Fwithdrawals\u002Foverview","4.withdrawals\u002F1.overview",{"title":88,"path":89,"stem":90,"icon":66},"Create a Withdrawal","\u002Fwithdrawals\u002Fcreate","4.withdrawals\u002F2.create",{"title":92,"path":93,"stem":94,"icon":71},"Get & List Withdrawals","\u002Fwithdrawals\u002Fretrieve","4.withdrawals\u002F3.retrieve",{"title":96,"icon":97,"path":98,"stem":99,"children":100,"page":6},"Balance & Banks","i-lucide-wallet","\u002Fbalance","5.balance",[101,105],{"title":102,"path":103,"stem":104,"icon":97},"Get Balance","\u002Fbalance\u002Fget-balance","5.balance\u002F1.get-balance",{"title":106,"path":107,"stem":108,"icon":109},"Bank List","\u002Fbalance\u002Fbanks","5.balance\u002F2.banks","i-lucide-landmark",{"title":111,"icon":112,"path":113,"stem":114,"children":115,"page":6},"Webhooks","i-lucide-webhook","\u002Fwebhooks","6.webhooks",[116,120,125,129],{"title":117,"path":118,"stem":119,"icon":61},"Webhook Overview","\u002Fwebhooks\u002Foverview","6.webhooks\u002F1.overview",{"title":121,"path":122,"stem":123,"icon":124},"Event Catalog & Payloads","\u002Fwebhooks\u002Fevents","6.webhooks\u002F2.events","i-lucide-list",{"title":126,"path":127,"stem":128,"icon":35},"Signature Verification","\u002Fwebhooks\u002Fsignature-verification","6.webhooks\u002F3.signature-verification",{"title":130,"path":131,"stem":132,"icon":45},"Endpoint Requirements, Retries & SSRF","\u002Fwebhooks\u002Fdelivery-and-retries","6.webhooks\u002F4.delivery-and-retries",{"title":134,"icon":135,"path":136,"stem":137,"children":138,"page":6},"Sandbox","i-lucide-flask-conical","\u002Fsandbox","7.sandbox",[139,143,148,153],{"title":140,"path":141,"stem":142,"icon":61},"Test Mode Overview","\u002Fsandbox\u002Foverview","7.sandbox\u002F1.overview",{"title":144,"path":145,"stem":146,"icon":147},"Simulate Transfer","\u002Fsandbox\u002Fsimulate-transfer","7.sandbox\u002F2.simulate-transfer","i-lucide-banknote-arrow-down",{"title":149,"path":150,"stem":151,"icon":152},"Top-up & Reset","\u002Fsandbox\u002Ftop-up-and-reset","7.sandbox\u002F3.top-up-and-reset","i-lucide-rotate-ccw",{"title":154,"path":155,"stem":156,"icon":157},"End-to-End Test Flow","\u002Fsandbox\u002Fe2e-test-flow","7.sandbox\u002F4.e2e-test-flow","i-lucide-list-checks",{"title":159,"icon":14,"path":160,"stem":161,"children":162,"page":6},"Go-live","\u002Fgo-live","8.go-live",[163,167],{"title":164,"path":165,"stem":166,"icon":157},"Go-live Checklist","\u002Fgo-live\u002Fchecklist","8.go-live\u002F1.checklist",{"title":168,"path":169,"stem":170,"icon":171},"Contact & Support","\u002Fgo-live\u002Fsupport","8.go-live\u002F2.support","i-lucide-life-buoy",{"title":173,"icon":174,"path":175,"stem":176,"children":177,"page":6},"Reference","i-lucide-book-marked","\u002Freference","9.reference",[178,183,188],{"title":179,"path":180,"stem":181,"icon":182},"Endpoint Catalog","\u002Freference\u002Fendpoints","9.reference\u002F1.endpoints","i-lucide-table",{"title":184,"path":185,"stem":186,"icon":187},"Code Samples (Node.js & PHP)","\u002Freference\u002Fcode-samples","9.reference\u002F2.code-samples","i-lucide-code",{"title":189,"path":190,"stem":191,"icon":192},"Status Values & Glossary","\u002Freference\u002Fglossary-states","9.reference\u002F3.glossary-states","i-lucide-book-a",{"id":194,"title":47,"badge":195,"body":196,"description":776,"extension":777,"links":195,"meta":778,"method":195,"navigation":779,"path":48,"seo":780,"stem":49,"__hash__":781},"docs_en\u002F2.concepts\u002F5.errors.md",null,{"type":197,"value":198,"toc":771},"minimark",[199,213,218,333,336,408,428,432,695,699,711,715,760,763,767],[200,201,202,203,207,208,212],"p",{},"Every error the system returns uses the ",[204,205,206],"strong",{},"same JSON structure"," — a merchant can branch logic on the ",[209,210,211],"code",{},"error.code"," field (machine-readable, stable), with no need to parse the message text.",[214,215,217],"h2",{"id":216},"_1-json-structure","1. JSON structure",[219,220,225],"pre",{"className":221,"code":222,"language":223,"meta":224,"style":224},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"error\": {\n    \"code\": \"INVALID_AMOUNT\",\n    \"message\": \"amount must have at most 2 decimal places\",\n    \"request_id\": \"0H1K2L3M4N5P6Q7R8S9T\"\n  }\n}\n","json","",[209,226,227,236,255,280,301,321,327],{"__ignoreMap":224},[228,229,232],"span",{"class":230,"line":231},"line",1,[228,233,235],{"class":234},"sMK4o","{\n",[228,237,239,242,246,249,252],{"class":230,"line":238},2,[228,240,241],{"class":234},"  \"",[228,243,245],{"class":244},"spNyl","error",[228,247,248],{"class":234},"\"",[228,250,251],{"class":234},":",[228,253,254],{"class":234}," {\n",[228,256,258,261,264,266,268,271,275,277],{"class":230,"line":257},3,[228,259,260],{"class":234},"    \"",[228,262,209],{"class":263},"sBMFI",[228,265,248],{"class":234},[228,267,251],{"class":234},[228,269,270],{"class":234}," \"",[228,272,274],{"class":273},"sfazB","INVALID_AMOUNT",[228,276,248],{"class":234},[228,278,279],{"class":234},",\n",[228,281,283,285,288,290,292,294,297,299],{"class":230,"line":282},4,[228,284,260],{"class":234},[228,286,287],{"class":263},"message",[228,289,248],{"class":234},[228,291,251],{"class":234},[228,293,270],{"class":234},[228,295,296],{"class":273},"amount must have at most 2 decimal places",[228,298,248],{"class":234},[228,300,279],{"class":234},[228,302,304,306,309,311,313,315,318],{"class":230,"line":303},5,[228,305,260],{"class":234},[228,307,308],{"class":263},"request_id",[228,310,248],{"class":234},[228,312,251],{"class":234},[228,314,270],{"class":234},[228,316,317],{"class":273},"0H1K2L3M4N5P6Q7R8S9T",[228,319,320],{"class":234},"\"\n",[228,322,324],{"class":230,"line":323},6,[228,325,326],{"class":234},"  }\n",[228,328,330],{"class":230,"line":329},7,[228,331,332],{"class":234},"}\n",[200,334,335],{},"Fields in the envelope:",[337,338,339,355],"table",{},[340,341,342],"thead",{},[343,344,345,349,352],"tr",{},[346,347,348],"th",{},"field",[346,350,351],{},"type",[346,353,354],{},"description",[356,357,358,371,383,395],"tbody",{},[343,359,360,365,368],{},[361,362,363],"td",{},[209,364,211],{},[361,366,367],{},"string",[361,369,370],{},"A stable error code for branch logic",[343,372,373,378,380],{},[361,374,375],{},[209,376,377],{},"error.message",[361,379,367],{},[361,381,382],{},"A safe human-readable message (no internal\u002Fsecret data)",[343,384,385,390,392],{},[361,386,387],{},[209,388,389],{},"error.request_id",[361,391,367],{},[361,393,394],{},"A request id to quote when reporting an issue to the team",[343,396,397,402,405],{},[361,398,399],{},[209,400,401],{},"error.details",[361,403,404],{},"object",[361,406,407],{},"(present in some cases) extra safe key-value data — dropped if absent",[409,410,411],"note",{},[200,412,413,414,417,418,420,421,424,425,427],{},"For server-level errors (HTTP 5xx) the system will ",[204,415,416],{},"not reveal internal detail"," — ",[209,419,287],{}," will be a generic string (e.g. ",[209,422,423],{},"\"internal error\"",") while the real cause is logged on the system side. Use the ",[209,426,308],{}," so the team can trace it.",[214,429,431],{"id":430},"_2-http-status-error-code-table-the-merchant-must-handle","2. HTTP status + error code table the merchant must handle",[337,433,434,449],{},[340,435,436],{},[343,437,438,441,443,446],{},[346,439,440],{},"HTTP",[346,442,209],{},[346,444,445],{},"Occurs when",[346,447,448],{},"What the merchant should do",[356,450,451,472,489,507,525,543,561,579,597,617,638,654,674],{},[343,452,453,458,463,469],{},[361,454,455],{},[209,456,457],{},"400",[361,459,460],{},[209,461,462],{},"IDEMPOTENCY_KEY_REQUIRED",[361,464,465,466],{},"A money POST is called without an ",[209,467,468],{},"Idempotency-Key",[361,470,471],{},"Add the header and resend",[343,473,474,478,483,486],{},[361,475,476],{},[209,477,457],{},[361,479,480],{},[209,481,482],{},"BAD_REQUEST",[361,484,485],{},"A generally malformed request",[361,487,488],{},"Fix the request",[343,490,491,496,501,504],{},[361,492,493],{},[209,494,495],{},"401",[361,497,498],{},[209,499,500],{},"UNAUTHORIZED",[361,502,503],{},"Credential invalid\u002Fexpired\u002Fbad signature",[361,505,506],{},"Check the API key + signing",[343,508,509,514,519,522],{},[361,510,511],{},[209,512,513],{},"403",[361,515,516],{},[209,517,518],{},"FORBIDDEN",[361,520,521],{},"No permission \u002F out of allowed scope (e.g. IP not in the allowlist)",[361,523,524],{},"Check permission\u002Fallowlist",[343,526,527,532,537,540],{},[361,528,529],{},[209,530,531],{},"404",[361,533,534],{},[209,535,536],{},"NOT_FOUND",[361,538,539],{},"Resource not found, or not the caller's (existence not revealed)",[361,541,542],{},"Check the referenced id",[343,544,545,550,555,558],{},[361,546,547],{},[209,548,549],{},"405",[361,551,552],{},[209,553,554],{},"METHOD_NOT_ALLOWED",[361,556,557],{},"Wrong HTTP method for the path",[361,559,560],{},"Check the method",[343,562,563,568,573,576],{},[361,564,565],{},[209,566,567],{},"409",[361,569,570],{},[209,571,572],{},"IDEMPOTENCY_IN_PROGRESS",[361,574,575],{},"A record with the same key is currently processing",[361,577,578],{},"Wait and retry",[343,580,581,586,591,594],{},[361,582,583],{},[209,584,585],{},"413",[361,587,588],{},[209,589,590],{},"PAYLOAD_TOO_LARGE",[361,592,593],{},"Body exceeds the limit",[361,595,596],{},"Reduce the body size",[343,598,599,604,608,611],{},[361,600,601],{},[209,602,603],{},"422",[361,605,606],{},[209,607,274],{},[361,609,610],{},"Malformed money field (negative\u002F>2dp\u002Fscientific\u002Fout-of-range\u002Fempty)",[361,612,613,614],{},"Fix the amount per the rules in ",[615,616,37],"a",{"href":38},[343,618,619,623,628,631],{},[361,620,621],{},[209,622,603],{},[361,624,625],{},[209,626,627],{},"INVALID_CURRENCY",[361,629,630],{},"Currency is not THB",[361,632,633,634,637],{},"Send ",[209,635,636],{},"\"THB\""," only",[343,639,640,644,649,652],{},[361,641,642],{},[209,643,603],{},[361,645,646],{},[209,647,648],{},"VALIDATION",[361,650,651],{},"Request fails general validation (e.g. body is not valid JSON)",[361,653,488],{},[343,655,656,660,665,671],{},[361,657,658],{},[209,659,603],{},[361,661,662],{},[209,663,664],{},"IDEMPOTENCY_KEY_MISMATCH",[361,666,667,668,670],{},"Reused the same ",[209,669,468],{}," with a different body",[361,672,673],{},"Use a new key, or send the same body",[343,675,676,681,686,689],{},[361,677,678],{},[209,679,680],{},"500",[361,682,683],{},[209,684,685],{},"INTERNAL",[361,687,688],{},"A system-side error",[361,690,691,692,694],{},"Retry later + keep the ",[209,693,308],{}," to report to the team",[696,697],"placeholder-note",{"value":698},"domain-level error codes (e.g. pool\u002Flimit\u002Fstate) exist per endpoint — collect the deposit\u002Fwithdrawal-specific codes into each endpoint's docs; this table only covers cross-cutting codes (foundation + money + idempotency + HTTP mapping) confirmed from the code",[700,701,702],"caution",{},[200,703,704,705,707,708,710],{},"Business-specific codes (e.g. pool out of funds, over a limit, a state that does not allow cancel) are additional codes defined per endpoint — a merchant should branch on ",[209,706,211],{}," in a default-safe way: treat any unknown code as an error and log the ",[209,709,308],{},".",[214,712,714],{"id":713},"_3-http-content-type-conventions","3. HTTP & Content-Type conventions",[716,717,718,731,740,757],"ul",{},[719,720,721,724,725,728,729,710],"li",{},[204,722,723],{},"Content-Type:"," a request with a body must be ",[209,726,727],{},"application\u002Fjson",", and every response (including errors and idempotency replays) is ",[209,730,727],{},[719,732,733,736,737,739],{},[204,734,735],{},"Request ID:"," every error response has ",[209,738,389],{}," for referencing the issue (keep it every time you hit an error).",[719,741,742,745,746,749,750,753,754,756],{},[204,743,744],{},"2xx = success",", ",[204,747,748],{},"4xx = merchant-side request error"," (fix then resend), ",[204,751,752],{},"5xx = system-side"," (safe to retry if you use ",[209,755,468],{}," on a money POST).",[719,758,759],{},"Always use HTTPS.",[696,761],{"value":762},"confirm whether an X-Request-Id response header exists — from the code, request_id appears mainly in the error body; if we communicate an echo header, confirm the requestid middleware first",[764,765],"placeholder-image",{"subject":766},"sequence diagram showing the flow of retrying a money POST with the same Idempotency-Key → the system returns the original response with header Idempotent-Replay: true",[768,769,770],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":224,"searchDepth":231,"depth":238,"links":772},[773,774,775],{"id":216,"depth":238,"text":217},{"id":430,"depth":238,"text":431},{"id":713,"depth":238,"text":714},"Every error uses one JSON envelope — branch on error.code, never the message — plus the consolidated cross-cutting error reference","md",{},{"icon":50},{"title":47,"description":776},"vIGcxCJ-onUTnh6mlL6nb1uwvR1kzCIaGjmy3XpEkps",[783,785],{"title":42,"path":43,"stem":44,"description":784,"icon":45,"children":-1},"Every money-moving POST requires an Idempotency-Key header so a retry returns the original result instead of creating a duplicate",{"title":58,"path":59,"stem":60,"description":786,"icon":61,"children":-1},"How a merchant takes money in via UnknownPay S2S — from creating a deposit to exact-amount matching, crediting, and the PENDING → CREDITED \u002F EXPIRED \u002F CANCELLED state machine",1781891152608]