[{"data":1,"prerenderedAt":1917},["ShallowReactive",2],{"navigation":3,"external-navigation":214,"external_core:\u002Fcore\u002Fprocessors\u002Fgo-gift-v2":443},[4,8,201],{"title":5,"path":6,"stem":7},"Documentation","\u002F","README",{"title":9,"path":10,"stem":11,"children":12},"EOS","\u002Feos","eos\u002FREADME",[13,44,121,181],{"title":14,"collapsed":15,"path":16,"stem":17,"children":18,"page":43},"Adrs",true,"\u002Feos\u002Fadrs","eos\u002Fadrs",[19,23,27,31,35,39],{"title":20,"path":21,"stem":22},"Use Turborepo for the EOS monorepo","\u002Feos\u002Fadrs\u002F0001-use-turborepo-for-eos","eos\u002Fadrs\u002F0001-use-turborepo-for-eos",{"title":24,"path":25,"stem":26},"Use Oxc for linting and formatting","\u002Feos\u002Fadrs\u002F0003-use-oxc-for-linting-and-formatting","eos\u002Fadrs\u002F0003-use-oxc-for-linting-and-formatting",{"title":28,"path":29,"stem":30},"Lint Markdown and validate links in CI","\u002Feos\u002Fadrs\u002F0004-lint-markdown-in-ci","eos\u002Fadrs\u002F0004-lint-markdown-in-ci",{"title":32,"path":33,"stem":34},"Use Lefthook for repository-managed Git hooks","\u002Feos\u002Fadrs\u002F0005-use-lefthook-for-repository-git-hooks","eos\u002Fadrs\u002F0005-use-lefthook-for-repository-git-hooks",{"title":36,"path":37,"stem":38},"Use Commitlint's conventional configuration","\u002Feos\u002Fadrs\u002F0006-use-commitlint-conventional-configuration","eos\u002Fadrs\u002F0006-use-commitlint-conventional-configuration",{"title":40,"path":41,"stem":42},"Use Nx for EOS task execution","\u002Feos\u002Fadrs\u002F0007-use-nx-for-eos","eos\u002Fadrs\u002F0007-use-nx-for-eos",false,{"title":45,"path":46,"stem":47,"children":48},"Harbourmaster","\u002Feos\u002Fharbourmaster","eos\u002Fharbourmaster\u002FREADME",[49,58,71,96],{"title":50,"path":51,"stem":52,"children":53,"page":43},"Decisions","\u002Feos\u002Fharbourmaster\u002Fdecisions","eos\u002Fharbourmaster\u002Fdecisions",[54],{"title":55,"path":56,"stem":57},"AI-50: GitHub auth and fork pull request policy","\u002Feos\u002Fharbourmaster\u002Fdecisions\u002Fai-50-auth-and-fork-policy","eos\u002Fharbourmaster\u002Fdecisions\u002Fai-50-auth-and-fork-policy",{"title":59,"path":60,"stem":61,"children":62,"page":43},"Explanation","\u002Feos\u002Fharbourmaster\u002Fexplanation","eos\u002Fharbourmaster\u002Fexplanation",[63,67],{"title":64,"path":65,"stem":66},"The Harbourmaster review pipeline","\u002Feos\u002Fharbourmaster\u002Fexplanation\u002Freview-pipeline","eos\u002Fharbourmaster\u002Fexplanation\u002Freview-pipeline",{"title":68,"path":69,"stem":70},"The Harbourmaster shared-action trust boundary","\u002Feos\u002Fharbourmaster\u002Fexplanation\u002Fshared-action-trust-boundary","eos\u002Fharbourmaster\u002Fexplanation\u002Fshared-action-trust-boundary",{"title":72,"path":73,"stem":74,"children":75,"page":43},"How To","\u002Feos\u002Fharbourmaster\u002Fhow-to","eos\u002Fharbourmaster\u002Fhow-to",[76,80,84,88,92],{"title":77,"path":78,"stem":79},"How to add Harbourmaster reviews to a repository","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Fadd-harbourmaster-to-a-repository","eos\u002Fharbourmaster\u002Fhow-to\u002Fadd-harbourmaster-to-a-repository",{"title":81,"path":82,"stem":83},"How to build a pilot dashboard","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Fbuild-pilot-dashboard","eos\u002Fharbourmaster\u002Fhow-to\u002Fbuild-pilot-dashboard",{"title":85,"path":86,"stem":87},"How to configure model routing","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Fconfigure-model-routing","eos\u002Fharbourmaster\u002Fhow-to\u002Fconfigure-model-routing",{"title":89,"path":90,"stem":91},"How to request a Harbourmaster review","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Frequest-a-review","eos\u002Fharbourmaster\u002Fhow-to\u002Frequest-a-review",{"title":93,"path":94,"stem":95},"How to diagnose a Harbourmaster review failure","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Ftroubleshoot-a-review","eos\u002Fharbourmaster\u002Fhow-to\u002Ftroubleshoot-a-review",{"title":97,"path":98,"stem":99,"children":100,"page":43},"Reference","\u002Feos\u002Fharbourmaster\u002Freference","eos\u002Fharbourmaster\u002Freference",[101,105,109,113,117],{"title":102,"path":103,"stem":104},"Harbourmaster command-line interface","\u002Feos\u002Fharbourmaster\u002Freference\u002Fcli","eos\u002Fharbourmaster\u002Freference\u002Fcli",{"title":106,"path":107,"stem":108},"Harbourmaster configuration","\u002Feos\u002Fharbourmaster\u002Freference\u002Fconfiguration","eos\u002Fharbourmaster\u002Freference\u002Fconfiguration",{"title":110,"path":111,"stem":112},"Harbourmaster GitHub Action","\u002Feos\u002Fharbourmaster\u002Freference\u002Fgithub-action","eos\u002Fharbourmaster\u002Freference\u002Fgithub-action",{"title":114,"path":115,"stem":116},"Harbourmaster review behavior","\u002Feos\u002Fharbourmaster\u002Freference\u002Freview-behavior","eos\u002Fharbourmaster\u002Freference\u002Freview-behavior",{"title":118,"path":119,"stem":120},"Harbourmaster telemetry","\u002Feos\u002Fharbourmaster\u002Freference\u002Ftelemetry","eos\u002Fharbourmaster\u002Freference\u002Ftelemetry",{"title":72,"path":122,"stem":123,"children":124,"page":43},"\u002Feos\u002Fhow-to","eos\u002Fhow-to",[125,129,133,137,141,145,149,153,157,161,165,169,173,177],{"title":126,"path":127,"stem":128},"How to add an external documentation source","\u002Feos\u002Fhow-to\u002Fadd-external-documentation-source","eos\u002Fhow-to\u002Fadd-external-documentation-source",{"title":130,"path":131,"stem":132},"How to connect SDLC integrations","\u002Feos\u002Fhow-to\u002Fconnect-sdlc-integrations","eos\u002Fhow-to\u002Fconnect-sdlc-integrations",{"title":134,"path":135,"stem":136},"How to consume the EOS plugin marketplace","\u002Feos\u002Fhow-to\u002Fconsume-eos-marketplace","eos\u002Fhow-to\u002Fconsume-eos-marketplace",{"title":138,"path":139,"stem":140},"How to create a spike ticket","\u002Feos\u002Fhow-to\u002Fcreate-spike-ticket","eos\u002Fhow-to\u002Fcreate-spike-ticket",{"title":142,"path":143,"stem":144},"How to finalise a repository change","\u002Feos\u002Fhow-to\u002Ffinalise-change","eos\u002Fhow-to\u002Ffinalise-change",{"title":146,"path":147,"stem":148},"How to install the EOS Docs MCP server","\u002Feos\u002Fhow-to\u002Finstall-eos-docs-mcp","eos\u002Fhow-to\u002Finstall-eos-docs-mcp",{"title":150,"path":151,"stem":152},"How to resolve a spike ticket","\u002Feos\u002Fhow-to\u002Fresolve-spike-ticket","eos\u002Fhow-to\u002Fresolve-spike-ticket",{"title":154,"path":155,"stem":156},"How to run Git hook checks","\u002Feos\u002Fhow-to\u002Frun-git-hook-checks","eos\u002Fhow-to\u002Frun-git-hook-checks",{"title":158,"path":159,"stem":160},"How to use the AI-enabled SDLC","\u002Feos\u002Fhow-to\u002Fuse-ai-enabled-sdlc","eos\u002Fhow-to\u002Fuse-ai-enabled-sdlc",{"title":162,"path":163,"stem":164},"Use the Aikido plugin","\u002Feos\u002Fhow-to\u002Fuse-aikido-plugin","eos\u002Fhow-to\u002Fuse-aikido-plugin",{"title":166,"path":167,"stem":168},"How to use Compass","\u002Feos\u002Fhow-to\u002Fuse-compass","eos\u002Fhow-to\u002Fuse-compass",{"title":170,"path":171,"stem":172},"How to use Fallow","\u002Feos\u002Fhow-to\u002Fuse-fallow","eos\u002Fhow-to\u002Fuse-fallow",{"title":174,"path":175,"stem":176},"How to use incremental mutation tests","\u002Feos\u002Fhow-to\u002Fuse-incremental-mutation-tests","eos\u002Fhow-to\u002Fuse-incremental-mutation-tests",{"title":178,"path":179,"stem":180},"How to use Scout","\u002Feos\u002Fhow-to\u002Fuse-scout","eos\u002Fhow-to\u002Fuse-scout",{"title":97,"path":182,"stem":183,"children":184,"page":43},"\u002Feos\u002Freference","eos\u002Freference",[185,189,193,197],{"title":186,"path":187,"stem":188},"Compass CLI","\u002Feos\u002Freference\u002Fcompass-cli","eos\u002Freference\u002Fcompass-cli",{"title":190,"path":191,"stem":192},"EOS marketplace skills","\u002Feos\u002Freference\u002Fmarketplace-skills","eos\u002Freference\u002Fmarketplace-skills",{"title":194,"path":195,"stem":196},"Nx task execution and cache","\u002Feos\u002Freference\u002Fnx-task-execution","eos\u002Freference\u002Fnx-task-execution",{"title":198,"path":199,"stem":200},"Scout CLI","\u002Feos\u002Freference\u002Fscout-cli","eos\u002Freference\u002Fscout-cli",{"title":202,"path":203,"stem":204,"children":205},"Product engineering","\u002Fproduct-engineering","product-engineering\u002FREADME",[206],{"title":14,"collapsed":15,"path":207,"stem":208,"children":209,"page":43},"\u002Fproduct-engineering\u002Fadrs","product-engineering\u002Fadrs",[210],{"title":211,"path":212,"stem":213},"Codify Engineering Standards as Skills","\u002Fproduct-engineering\u002Fadrs\u002F0002-codify-engineering-standards-as-skills","product-engineering\u002Fadrs\u002F0002-codify-engineering-standards-as-skills",[215,268],{"nav":216,"source":265},[217],{"title":218,"path":219,"stem":220,"children":221},"Ember","\u002Fember","ember",[222,225,257,261],{"title":223,"path":219,"stem":224},"StoreFront Documentation","ember\u002Findex",{"title":14,"path":226,"stem":227,"children":228,"page":43},"\u002Fember\u002Fadrs","ember\u002Fadrs",[229,233,237,241,245,249,253],{"title":230,"path":231,"stem":232},"Add Infection as a non-blocking mutation testing tool for Ember","\u002Fember\u002Fadrs\u002F0001-infection-mutation-testing","ember\u002Fadrs\u002F0001-infection-mutation-testing",{"title":234,"path":235,"stem":236},"Process DELETE scheduled changes before CREATE_UPDATE at the same instant","\u002Fember\u002Fadrs\u002F0002-scheduled-change-processing-order","ember\u002Fadrs\u002F0002-scheduled-change-processing-order",{"title":238,"path":239,"stem":240},"Standard rate scheduling is permanent until overridden","\u002Fember\u002Fadrs\u002F0003-standard-rate-scheduling-is-permanent","ember\u002Fadrs\u002F0003-standard-rate-scheduling-is-permanent",{"title":242,"path":243,"stem":244},"Promotions require an existing standard rate","\u002Fember\u002Fadrs\u002F0004-promotions-require-existing-standard-rate","ember\u002Fadrs\u002F0004-promotions-require-existing-standard-rate",{"title":246,"path":247,"stem":248},"UTC datetime contract between Storefront and Hub","\u002Fember\u002Fadrs\u002F0005-utc-datetime-contract-between-storefront-and-hub","ember\u002Fadrs\u002F0005-utc-datetime-contract-between-storefront-and-hub",{"title":250,"path":251,"stem":252},"Elapsed unprocessed scheduled changes do not block rate changes","\u002Fember\u002Fadrs\u002F0006-stale-scheduler-rows-do-not-block-rate-changes","ember\u002Fadrs\u002F0006-stale-scheduler-rows-do-not-block-rate-changes",{"title":254,"path":255,"stem":256},"ADR-0007: Delete ConfigureTenantAuth routing command once OIDC setup migrates to Hub","\u002Fember\u002Fadrs\u002F0007-delete-configure-tenant-auth-routing-command","ember\u002Fadrs\u002F0007-delete-configure-tenant-auth-routing-command",{"title":258,"path":259,"stem":260},"Domain Overview","\u002Fember\u002Fdomain_overview","ember\u002Fdomain_overview",{"title":262,"path":263,"stem":264},"Main Flows","\u002Fember\u002Fkey_flows","ember\u002Fkey_flows",{"collectionName":266,"label":267,"prefix":220},"external_ember","StoreFront (Ember)",{"nav":269,"source":441},[270],{"title":271,"path":272,"stem":273,"children":274},"Core","\u002Fcore","core",[275,278,306,310,332,336,346,363,420,424],{"title":276,"path":272,"stem":277},"Documentation Index","core\u002Findex",{"title":14,"path":279,"stem":280,"children":281,"page":43},"\u002Fcore\u002Fadrs","core\u002Fadrs",[282,286,290,294,298,302],{"title":283,"path":284,"stem":285},"ADR-XXXX: Short, descriptive title","\u002Fcore\u002Fadrs\u002F0000-template","core\u002Fadrs\u002F0000-template",{"title":287,"path":288,"stem":289},"ADR-1: Promotions endpoint","\u002Fcore\u002Fadrs\u002F0001-add-promotions-endpoint","core\u002Fadrs\u002F0001-add-promotions-endpoint",{"title":291,"path":292,"stem":293},"ADR-2: EOM partner report job dispatch","\u002Fcore\u002Fadrs\u002F0002-eom-report-job-dispatch","core\u002Fadrs\u002F0002-eom-report-job-dispatch",{"title":295,"path":296,"stem":297},"ADR-3: Replace PB fee waive flag with a Zero scheme override","\u002Fcore\u002Fadrs\u002F0003-replace-pb-fee-waive-with-zero-scheme","core\u002Fadrs\u002F0003-replace-pb-fee-waive-with-zero-scheme",{"title":299,"path":300,"stem":301},"ADR-4: No processor Digital Top-up capability gate in Reloadable Commercials","\u002Fcore\u002Fadrs\u002F0004-no-processor-top-up-capability-gate","core\u002Fadrs\u002F0004-no-processor-top-up-capability-gate",{"title":303,"path":304,"stem":305},"ADR-5: Sparse polymorphic sale fee override reason stamp","\u002Fcore\u002Fadrs\u002F0005-sale-fee-override-reason-stamp","core\u002Fadrs\u002F0005-sale-fee-override-reason-stamp",{"title":307,"path":308,"stem":309},"Agent Workflow","\u002Fcore\u002Fai-workflow","core\u002Fai-workflow",{"title":311,"path":312,"stem":313,"children":314},"Backend Guide","\u002Fcore\u002Fbackend","core\u002Fbackend\u002Findex",[315,316,320,324,328],{"title":311,"path":312,"stem":313},{"title":317,"path":318,"stem":319},"Backend AI Tooling","\u002Fcore\u002Fbackend\u002Fai-tooling","core\u002Fbackend\u002Fai-tooling",{"title":321,"path":322,"stem":323},"Backend Linting and Formatting","\u002Fcore\u002Fbackend\u002Flinting-and-formatting","core\u002Fbackend\u002Flinting-and-formatting",{"title":325,"path":326,"stem":327},"Backend Setup","\u002Fcore\u002Fbackend\u002Fsetup","core\u002Fbackend\u002Fsetup",{"title":329,"path":330,"stem":331},"Backend Testing","\u002Fcore\u002Fbackend\u002Ftesting","core\u002Fbackend\u002Ftesting",{"title":333,"path":334,"stem":335},"Documentation Health","\u002Fcore\u002Fdoc-health","core\u002Fdoc-health",{"title":337,"path":338,"stem":339,"children":340},"Frontend Guide","\u002Fcore\u002Ffrontend","core\u002Ffrontend\u002Findex",[341,342],{"title":337,"path":338,"stem":339},{"title":343,"path":344,"stem":345},"Frontend Development","\u002Fcore\u002Ffrontend\u002Fdevelopment","core\u002Ffrontend\u002Fdevelopment",{"title":347,"path":348,"stem":349,"children":350,"page":43},"Modules","\u002Fcore\u002Fmodules","core\u002Fmodules",[351,355],{"title":352,"path":353,"stem":354},"Connect API","\u002Fcore\u002Fmodules\u002Fconnect-api","core\u002Fmodules\u002Fconnect-api",{"title":356,"path":357,"stem":358,"children":359,"page":43},"Secure Links","\u002Fcore\u002Fmodules\u002Fsecure-links","core\u002Fmodules\u002Fsecure-links",[360],{"title":356,"path":361,"stem":362},"\u002Fcore\u002Fmodules\u002Fsecure-links\u002Fsecure-links","core\u002Fmodules\u002Fsecure-links\u002Fsecure-links",{"title":364,"path":365,"stem":366,"children":367,"page":43},"Processors","\u002Fcore\u002Fprocessors","core\u002Fprocessors",[368,372,376,380,384,388,392,396,400,404,408,412,416],{"title":369,"path":370,"stem":371},"Amazon Processor and API","\u002Fcore\u002Fprocessors\u002Famazon","core\u002Fprocessors\u002Famazon",{"title":373,"path":374,"stem":375},"Amilon Processor and API","\u002Fcore\u002Fprocessors\u002Familon","core\u002Fprocessors\u002Familon",{"title":377,"path":378,"stem":379},"Cadooz Processor and API","\u002Fcore\u002Fprocessors\u002Fcadooz","core\u002Fprocessors\u002Fcadooz",{"title":381,"path":382,"stem":383},"Choice Digital Processor and API","\u002Fcore\u002Fprocessors\u002Fchoice-digital","core\u002Fprocessors\u002Fchoice-digital",{"title":385,"path":386,"stem":387},"Diggecard processor reference","\u002Fcore\u002Fprocessors\u002Fdiggecard","core\u002Fprocessors\u002Fdiggecard",{"title":389,"path":390,"stem":391},"ePay Processor and API","\u002Fcore\u002Fprocessors\u002Fepay","core\u002Fprocessors\u002Fepay",{"title":393,"path":394,"stem":395},"GoGift v2 Processor and API","\u002Fcore\u002Fprocessors\u002Fgo-gift-v2","core\u002Fprocessors\u002Fgo-gift-v2",{"title":397,"path":398,"stem":399},"InComm Processor and API","\u002Fcore\u002Fprocessors\u002Fincomm","core\u002Fprocessors\u002Fincomm",{"title":401,"path":402,"stem":403},"Ogloba Processor and API","\u002Fcore\u002Fprocessors\u002Fogloba","core\u002Fprocessors\u002Fogloba",{"title":405,"path":406,"stem":407},"SVSECard Processor and API","\u002Fcore\u002Fprocessors\u002Fsvs-ecard","core\u002Fprocessors\u002Fsvs-ecard",{"title":409,"path":410,"stem":411},"Vananam Processor and API","\u002Fcore\u002Fprocessors\u002Fvananam","core\u002Fprocessors\u002Fvananam",{"title":413,"path":414,"stem":415},"Vouchers Depot processor reference","\u002Fcore\u002Fprocessors\u002Fvouchers-depot","core\u002Fprocessors\u002Fvouchers-depot",{"title":417,"path":418,"stem":419},"You Got a Gift Processor and API","\u002Fcore\u002Fprocessors\u002Fyou-got-a-gift","core\u002Fprocessors\u002Fyou-got-a-gift",{"title":421,"path":422,"stem":423},"Development Quickstart","\u002Fcore\u002Fsetup","core\u002Fsetup",{"title":425,"path":426,"stem":427,"children":428,"page":43},"Workflows","\u002Fcore\u002Fworkflows","core\u002Fworkflows",[429,433,437],{"title":430,"path":431,"stem":432},"Hub Endpoint Workflow","\u002Fcore\u002Fworkflows\u002Fhub-endpoints","core\u002Fworkflows\u002Fhub-endpoints",{"title":434,"path":435,"stem":436},"OpenAPI Tooling","\u002Fcore\u002Fworkflows\u002Fopenapi-tooling","core\u002Fworkflows\u002Fopenapi-tooling",{"title":438,"path":439,"stem":440},"Processor Integration Workflow","\u002Fcore\u002Fworkflows\u002Fprocessors","core\u002Fworkflows\u002Fprocessors",{"collectionName":442,"label":271,"prefix":273},"external_core",{"page":444,"surround":1914},{"id":445,"title":393,"body":446,"config":1909,"description":452,"extension":1910,"meta":1911,"navigation":15,"path":394,"seo":1912,"stem":395,"__hash__":1913},"external_core\u002Fcore\u002Fprocessors\u002Fgo-gift-v2.md",{"type":447,"value":448,"toc":1890},"minimark",[449,453,458,461,548,552,603,607,610,615,622,652,655,675,685,963,973,1007,1010,1029,1033,1053,1133,1140,1186,1189,1193,1311,1318,1322,1447,1454,1458,1461,1503,1506,1510,1514,1520,1604,1611,1615,1621,1625,1761,1765,1774,1780,1783,1787,1790,1794,1886],[450,451,452],"p",{},"This reference is for operations and customer-service teams. It describes the GoGift v2 basket and webhook lifecycle, the fields required before a sale can complete, and the evidence to collect before retrying or escalating.",[454,455,457],"h2",{"id":456},"what-gogift-v2-does","What GoGift v2 does",[450,459,460],{},"GoGift v2 is an asynchronous basket processor with catalogue support and webhook delivery. The application creates a basket, adds one product, finalises the basket, and stores the resulting order ID. GoGift v2 then sends fulfilment data to the configured webhook; retrieval reads that locally stored response.",[462,463,464,477],"table",{},[465,466,467],"thead",{},[468,469,470,474],"tr",{},[471,472,473],"th",{},"Property",[471,475,476],{},"Behaviour",[478,479,480,489,497,505,513,520,528],"tbody",{},[468,481,482,486],{},[483,484,485],"td",{},"Processor type",[483,487,488],{},"SKU per denomination with a brand-level product ID",[468,490,491,494],{},[483,492,493],{},"Processing",[483,495,496],{},"Asynchronous basket update and finalisation, followed by webhook-backed retrieval",[468,498,499,502],{},[483,500,501],{},"Delivery",[483,503,504],{},"Digital gift-card URL with a PIN appended during mapping",[468,506,507,510],{},[483,508,509],{},"Balance lookup",[483,511,512],{},"Unsupported",[468,514,515,518],{},[483,516,517],{},"Cancellation",[483,519,512],{},[468,521,522,525],{},[483,523,524],{},"Catalogue",[483,526,527],{},"Supported through product list and product-by-ID operations",[468,529,530,533],{},[483,531,532],{},"Provider completion evidence",[483,534,535,536,540,541,544,545],{},"A valid webhook payload containing ",[537,538,539],"code",{},"orderId",", ",[537,542,543],{},"giftcardUri",", and ",[537,546,547],{},"pin",[454,549,551],{"id":550},"order-lifecycle","Order lifecycle",[553,554,555,559,566,577,584,593,600],"ol",{},[556,557,558],"li",{},"The sale supplies the brand, face value, currency, transaction reference, and delivery method.",[556,560,561,562,565],{},"The interaction reads the brand ",[537,563,564],{},"product_id"," attribute and the denomination SKU for the requested face value.",[556,567,568,569,572,573,576],{},"A basket is created with sales channel ID ",[537,570,571],{},"109",". The returned ",[537,574,575],{},"id"," is required and is cached against the transaction reference for seven days.",[556,578,579,580,583],{},"The basket is updated with the B2B department, product ID, SKU, currency, integer gift-card value, transaction reference, and the application confirmation webhook URL. The update clears existing basket products and adds one product with delivery method ",[537,581,582],{},"Webhook",".",[556,585,586,587,572,590,592],{},"The basket is finalised with payment method ",[537,588,589],{},"InvoiceByFinance",[537,591,539],{}," becomes the processor reference.",[556,594,595,596,599],{},"GoGift v2 sends a signed webhook. The handler validates the request headers and signature, validates the first ",[537,597,598],{},"content"," item, finds the sale by processor reference, stores the encrypted payload, writes a response audit record, and dispatches asynchronous code retrieval.",[556,601,602],{},"Retrieval validates the stored payload and maps its URL and PIN. After a successful sale response is produced, a cleanup job is delayed by 30 seconds before deleting the stored webhook response.",[454,604,606],{"id":605},"example-api-order-flow","Example API order flow",[450,608,609],{},"The following examples use illustrative values. API keys, bearer tokens, webhook signatures, PINs, and live gift-card URLs are intentionally omitted.",[611,612,614],"h3",{"id":613},"create-update-and-finalise-a-basket","Create, update, and finalise a basket",[450,616,617,618,621],{},"The API uses bearer authentication. Create sends ",[537,619,620],{},"POST baskets\u002F",":",[623,624,629],"pre",{"className":625,"code":626,"language":627,"meta":628,"style":628},"language-json shiki shiki-themes github-dark github-light","{ \"salesChannelId\": 109 }\n","json","",[537,630,631],{"__ignoreMap":628},[632,633,636,640,644,647,649],"span",{"class":634,"line":635},"line",1,[632,637,639],{"class":638},"sQ3_J","{ ",[632,641,643],{"class":642},"s0DvM","\"salesChannelId\"",[632,645,646],{"class":638},": ",[632,648,571],{"class":642},[632,650,651],{"class":638}," }\n",[450,653,654],{},"The response must contain a basket ID:",[623,656,658],{"className":625,"code":657,"language":627,"meta":628,"style":628},"{ \"id\": \"\u003Cbasket-id>\" }\n",[537,659,660],{"__ignoreMap":628},[632,661,662,664,667,669,673],{"class":634,"line":635},[632,663,639],{"class":638},[632,665,666],{"class":642},"\"id\"",[632,668,646],{"class":638},[632,670,672],{"class":671},"sg6BJ","\"\u003Cbasket-id>\"",[632,674,651],{"class":638},[450,676,677,678,681,682,621],{},"Update sends ",[537,679,680],{},"PUT baskets\u002F"," with an idempotency key of ",[537,683,684],{},"\u003Cbasket-id>-update",[623,686,688],{"className":625,"code":687,"language":627,"meta":628,"style":628},"{\n  \"id\": \"\u003Cbasket-id>\",\n  \"buyer\": {\n    \"accountId\": \"\u003Cb2b-department-id>\",\n    \"accountType\": \"B2BDepartment\",\n    \"name\": \"Tillo\",\n    \"email\": \"noreply@tillo.io\",\n    \"phone\": \"[REDACTED]\",\n    \"address\": { \"countryCode\": \"GB\" }\n  },\n  \"addProducts\": {\n    \"deliveryMethod\": \"Webhook\",\n    \"recipientName\": \"Tillo\",\n    \"recipientWebhookUrl\": \"https:\u002F\u002F\u003Capplication-host>\u002Fwebhook\u002F\u003Cprocessor>\u002Fconfirmation\",\n    \"stockKeepingUnit\": \"\u003Cdenomination-sku>\",\n    \"productId\": \"\u003Cproduct-id>\",\n    \"quantity\": 1,\n    \"valueCurrency\": \"GBP\",\n    \"giftCardValue\": 10,\n    \"productReference\": \"\u003Ctransaction-reference>\"\n  },\n  \"doClearProducts\": true,\n  \"reference\": \"\u003Ctransaction-reference>\"\n}\n",[537,689,690,695,708,717,730,743,756,769,782,801,807,815,828,840,853,866,879,892,905,918,929,934,947,957],{"__ignoreMap":628},[632,691,692],{"class":634,"line":635},[632,693,694],{"class":638},"{\n",[632,696,698,701,703,705],{"class":634,"line":697},2,[632,699,700],{"class":642},"  \"id\"",[632,702,646],{"class":638},[632,704,672],{"class":671},[632,706,707],{"class":638},",\n",[632,709,711,714],{"class":634,"line":710},3,[632,712,713],{"class":642},"  \"buyer\"",[632,715,716],{"class":638},": {\n",[632,718,720,723,725,728],{"class":634,"line":719},4,[632,721,722],{"class":642},"    \"accountId\"",[632,724,646],{"class":638},[632,726,727],{"class":671},"\"\u003Cb2b-department-id>\"",[632,729,707],{"class":638},[632,731,733,736,738,741],{"class":634,"line":732},5,[632,734,735],{"class":642},"    \"accountType\"",[632,737,646],{"class":638},[632,739,740],{"class":671},"\"B2BDepartment\"",[632,742,707],{"class":638},[632,744,746,749,751,754],{"class":634,"line":745},6,[632,747,748],{"class":642},"    \"name\"",[632,750,646],{"class":638},[632,752,753],{"class":671},"\"Tillo\"",[632,755,707],{"class":638},[632,757,759,762,764,767],{"class":634,"line":758},7,[632,760,761],{"class":642},"    \"email\"",[632,763,646],{"class":638},[632,765,766],{"class":671},"\"noreply@tillo.io\"",[632,768,707],{"class":638},[632,770,772,775,777,780],{"class":634,"line":771},8,[632,773,774],{"class":642},"    \"phone\"",[632,776,646],{"class":638},[632,778,779],{"class":671},"\"[REDACTED]\"",[632,781,707],{"class":638},[632,783,785,788,791,794,796,799],{"class":634,"line":784},9,[632,786,787],{"class":642},"    \"address\"",[632,789,790],{"class":638},": { ",[632,792,793],{"class":642},"\"countryCode\"",[632,795,646],{"class":638},[632,797,798],{"class":671},"\"GB\"",[632,800,651],{"class":638},[632,802,804],{"class":634,"line":803},10,[632,805,806],{"class":638},"  },\n",[632,808,810,813],{"class":634,"line":809},11,[632,811,812],{"class":642},"  \"addProducts\"",[632,814,716],{"class":638},[632,816,818,821,823,826],{"class":634,"line":817},12,[632,819,820],{"class":642},"    \"deliveryMethod\"",[632,822,646],{"class":638},[632,824,825],{"class":671},"\"Webhook\"",[632,827,707],{"class":638},[632,829,831,834,836,838],{"class":634,"line":830},13,[632,832,833],{"class":642},"    \"recipientName\"",[632,835,646],{"class":638},[632,837,753],{"class":671},[632,839,707],{"class":638},[632,841,843,846,848,851],{"class":634,"line":842},14,[632,844,845],{"class":642},"    \"recipientWebhookUrl\"",[632,847,646],{"class":638},[632,849,850],{"class":671},"\"https:\u002F\u002F\u003Capplication-host>\u002Fwebhook\u002F\u003Cprocessor>\u002Fconfirmation\"",[632,852,707],{"class":638},[632,854,856,859,861,864],{"class":634,"line":855},15,[632,857,858],{"class":642},"    \"stockKeepingUnit\"",[632,860,646],{"class":638},[632,862,863],{"class":671},"\"\u003Cdenomination-sku>\"",[632,865,707],{"class":638},[632,867,869,872,874,877],{"class":634,"line":868},16,[632,870,871],{"class":642},"    \"productId\"",[632,873,646],{"class":638},[632,875,876],{"class":671},"\"\u003Cproduct-id>\"",[632,878,707],{"class":638},[632,880,882,885,887,890],{"class":634,"line":881},17,[632,883,884],{"class":642},"    \"quantity\"",[632,886,646],{"class":638},[632,888,889],{"class":642},"1",[632,891,707],{"class":638},[632,893,895,898,900,903],{"class":634,"line":894},18,[632,896,897],{"class":642},"    \"valueCurrency\"",[632,899,646],{"class":638},[632,901,902],{"class":671},"\"GBP\"",[632,904,707],{"class":638},[632,906,908,911,913,916],{"class":634,"line":907},19,[632,909,910],{"class":642},"    \"giftCardValue\"",[632,912,646],{"class":638},[632,914,915],{"class":642},"10",[632,917,707],{"class":638},[632,919,921,924,926],{"class":634,"line":920},20,[632,922,923],{"class":642},"    \"productReference\"",[632,925,646],{"class":638},[632,927,928],{"class":671},"\"\u003Ctransaction-reference>\"\n",[632,930,932],{"class":634,"line":931},21,[632,933,806],{"class":638},[632,935,937,940,942,945],{"class":634,"line":936},22,[632,938,939],{"class":642},"  \"doClearProducts\"",[632,941,646],{"class":638},[632,943,944],{"class":642},"true",[632,946,707],{"class":638},[632,948,950,953,955],{"class":634,"line":949},23,[632,951,952],{"class":642},"  \"reference\"",[632,954,646],{"class":638},[632,956,928],{"class":671},[632,958,960],{"class":634,"line":959},24,[632,961,962],{"class":638},"}\n",[450,964,965,966,969,970,621],{},"Finalise sends ",[537,967,968],{},"POST baskets\u002Ffinalize\u002F"," with idempotency key ",[537,971,972],{},"\u003Cbasket-id>-finalize",[623,974,976],{"className":625,"code":975,"language":627,"meta":628,"style":628},"{\n  \"basketId\": \"\u003Cbasket-id>\",\n  \"paymentMethod\": \"InvoiceByFinance\"\n}\n",[537,977,978,982,993,1003],{"__ignoreMap":628},[632,979,980],{"class":634,"line":635},[632,981,694],{"class":638},[632,983,984,987,989,991],{"class":634,"line":697},[632,985,986],{"class":642},"  \"basketId\"",[632,988,646],{"class":638},[632,990,672],{"class":671},[632,992,707],{"class":638},[632,994,995,998,1000],{"class":634,"line":710},[632,996,997],{"class":642},"  \"paymentMethod\"",[632,999,646],{"class":638},[632,1001,1002],{"class":671},"\"InvoiceByFinance\"\n",[632,1004,1005],{"class":634,"line":719},[632,1006,962],{"class":638},[450,1008,1009],{},"The finalisation response must contain the provider order ID:",[623,1011,1013],{"className":625,"code":1012,"language":627,"meta":628,"style":628},"{ \"orderId\": \"\u003Cgogift-order-id>\" }\n",[537,1014,1015],{"__ignoreMap":628},[632,1016,1017,1019,1022,1024,1027],{"class":634,"line":635},[632,1018,639],{"class":638},[632,1020,1021],{"class":642},"\"orderId\"",[632,1023,646],{"class":638},[632,1025,1026],{"class":671},"\"\u003Cgogift-order-id>\"",[632,1028,651],{"class":638},[611,1030,1032],{"id":1031},"webhook-and-retrieval","Webhook and retrieval",[450,1034,1035,1036,540,1039,540,1042,544,1045,1048,1049,1052],{},"The webhook request must contain ",[537,1037,1038],{},"Signature",[537,1040,1041],{},"X-Request-Datetime",[537,1043,1044],{},"X-Client-ID",[537,1046,1047],{},"X-Request-ID",". The signature header has a ",[537,1050,1051],{},"signature=\"...\""," value; the application verifies it using the request method, those headers, a SHA-256 body digest, and the configured webhook secret. A redacted body example is:",[623,1054,1056],{"className":625,"code":1055,"language":627,"meta":628,"style":628},"{\n  \"content\": [\n    {\n      \"orderId\": \"\u003Cgogift-order-id>\",\n      \"giftcardUri\": \"https:\u002F\u002F\u003Cprovider-host>\u002Fgiftcard\u002F\u003Credacted>\",\n      \"pin\": \"[REDACTED]\",\n      \"expiresAt\": \"\u003Cprovider-expiry-or-omitted>\"\n    }\n  ]\n}\n",[537,1057,1058,1062,1070,1075,1086,1098,1109,1119,1124,1129],{"__ignoreMap":628},[632,1059,1060],{"class":634,"line":635},[632,1061,694],{"class":638},[632,1063,1064,1067],{"class":634,"line":697},[632,1065,1066],{"class":642},"  \"content\"",[632,1068,1069],{"class":638},": [\n",[632,1071,1072],{"class":634,"line":710},[632,1073,1074],{"class":638},"    {\n",[632,1076,1077,1080,1082,1084],{"class":634,"line":719},[632,1078,1079],{"class":642},"      \"orderId\"",[632,1081,646],{"class":638},[632,1083,1026],{"class":671},[632,1085,707],{"class":638},[632,1087,1088,1091,1093,1096],{"class":634,"line":732},[632,1089,1090],{"class":642},"      \"giftcardUri\"",[632,1092,646],{"class":638},[632,1094,1095],{"class":671},"\"https:\u002F\u002F\u003Cprovider-host>\u002Fgiftcard\u002F\u003Credacted>\"",[632,1097,707],{"class":638},[632,1099,1100,1103,1105,1107],{"class":634,"line":745},[632,1101,1102],{"class":642},"      \"pin\"",[632,1104,646],{"class":638},[632,1106,779],{"class":671},[632,1108,707],{"class":638},[632,1110,1111,1114,1116],{"class":634,"line":758},[632,1112,1113],{"class":642},"      \"expiresAt\"",[632,1115,646],{"class":638},[632,1117,1118],{"class":671},"\"\u003Cprovider-expiry-or-omitted>\"\n",[632,1120,1121],{"class":634,"line":771},[632,1122,1123],{"class":638},"    }\n",[632,1125,1126],{"class":634,"line":784},[632,1127,1128],{"class":638},"  ]\n",[632,1130,1131],{"class":634,"line":803},[632,1132,962],{"class":638},[450,1134,1135,1136,1139],{},"The handler returns HTTP ",[537,1137,1138],{},"200"," after validation and processing. Retrieval then maps the stored payload to:",[623,1141,1143],{"className":625,"code":1142,"language":627,"meta":628,"style":628},"{\n  \"processor_reference\": \"\u003Cgogift-order-id>\",\n  \"url\": \"https:\u002F\u002F\u003Cprovider-host>\u002Fgiftcard\u002F\u003Credacted>\u002F[REDACTED]\",\n  \"expiration_date\": \"\u003CISO-8601-or-null>\"\n}\n",[537,1144,1145,1149,1160,1172,1182],{"__ignoreMap":628},[632,1146,1147],{"class":634,"line":635},[632,1148,694],{"class":638},[632,1150,1151,1154,1156,1158],{"class":634,"line":697},[632,1152,1153],{"class":642},"  \"processor_reference\"",[632,1155,646],{"class":638},[632,1157,1026],{"class":671},[632,1159,707],{"class":638},[632,1161,1162,1165,1167,1170],{"class":634,"line":710},[632,1163,1164],{"class":642},"  \"url\"",[632,1166,646],{"class":638},[632,1168,1169],{"class":671},"\"https:\u002F\u002F\u003Cprovider-host>\u002Fgiftcard\u002F\u003Credacted>\u002F[REDACTED]\"",[632,1171,707],{"class":638},[632,1173,1174,1177,1179],{"class":634,"line":719},[632,1175,1176],{"class":642},"  \"expiration_date\"",[632,1178,646],{"class":638},[632,1180,1181],{"class":671},"\"\u003CISO-8601-or-null>\"\n",[632,1183,1184],{"class":634,"line":732},[632,1185,962],{"class":638},[450,1187,1188],{},"The URL above is illustrative only. Do not place a real provider URL or PIN in an incident record.",[454,1190,1192],{"id":1191},"response-mapping-and-validation","Response mapping and validation",[462,1194,1195,1205],{},[465,1196,1197],{},[468,1198,1199,1202],{},[471,1200,1201],{},"Provider response or record",[471,1203,1204],{},"Application result",[478,1206,1207,1224,1239,1253,1273,1282,1295],{},[468,1208,1209,1214],{},[483,1210,1211,1212],{},"Create basket ",[537,1213,575],{},[483,1215,1216,1217,1220,1221,1223],{},"Cached as ",[537,1218,1219],{},"go-gift-v2-basket-id-\u003Ctransaction-reference>","; missing ",[537,1222,575],{}," prevents issuance",[468,1225,1226,1231],{},[483,1227,1228,1229],{},"Finalise response ",[537,1230,539],{},[483,1232,1233,1234,1220,1237,1223],{},"Returned as ",[537,1235,1236],{},"processor_reference",[537,1238,539],{},[468,1240,1241,1247],{},[483,1242,1243,1244],{},"Webhook ",[537,1245,1246],{},"content.0.orderId",[483,1248,1249,1250,1252],{},"Used to locate the sale and returned as ",[537,1251,1236],{},"; required",[468,1254,1255,1260],{},[483,1256,1243,1257],{},[537,1258,1259],{},"content.0.giftcardUri",[483,1261,1262,1263,1265,1266,1269,1270],{},"Must be a URL; concatenated with ",[537,1264,6],{}," and ",[537,1267,1268],{},"content.0.pin"," to form the returned ",[537,1271,1272],{},"url",[468,1274,1275,1279],{},[483,1276,1243,1277],{},[537,1278,1268],{},[483,1280,1281],{},"Required and appended to the provider URI; never copy it into support notes",[468,1283,1284,1289],{},[483,1285,1243,1286],{},[537,1287,1288],{},"content.0.expiresAt",[483,1290,1291,1292],{},"Optional; when present it is converted to an ISO-8601 ",[537,1293,1294],{},"expiration_date",[468,1296,1297,1300],{},[483,1298,1299],{},"Webhook payload",[483,1301,1302,1303,1306,1307,1310],{},"Stored against ",[537,1304,1305],{},"sale_uuid"," in ",[537,1308,1309],{},"go_gift_v2_webhook_responses"," and encrypted by the model cast",[450,1312,1313,1314,1317],{},"Only the first item, ",[537,1315,1316],{},"content.0",", is validated and mapped. Update-basket response content is not parsed for completion; finalisation and the later webhook provide the required evidence. A missing or invalid webhook field raises webhook handling or response validation failure rather than producing a partial voucher response.",[454,1319,1321],{"id":1320},"provider-states-and-retry-behaviour","Provider states and retry behaviour",[462,1323,1324,1337],{},[465,1325,1326],{},[468,1327,1328,1331,1334],{},[471,1329,1330],{},"Condition",[471,1332,1333],{},"Integration behaviour",[471,1335,1336],{},"Operational consequence",[478,1338,1339,1357,1370,1383,1395,1409,1434],{},[468,1340,1341,1348,1354],{},[483,1342,1343,1344,1347],{},"Network failure, HTTP ",[537,1345,1346],{},"429",", or unexpected server-side failure during create, update, or finalise",[483,1349,1350,1351],{},"Raises ",[537,1352,1353],{},"RetryableRequestException",[483,1355,1356],{},"Retry the same operation only after checking the existing basket and audit trail",[468,1358,1359,1362,1367],{},[483,1360,1361],{},"Other HTTP client failures, such as authentication, malformed request, not found, or resource conflict",[483,1363,1350,1364],{},[537,1365,1366],{},"ProcessorInteractionException",[483,1368,1369],{},"Correct configuration or data, or escalate; do not blindly repeat the sale",[468,1371,1372,1377,1380],{},[483,1373,1374,1375],{},"Create response missing ",[537,1376,575],{},[483,1378,1379],{},"Response validation failure",[483,1381,1382],{},"No basket ID is available to continue; inspect the raw response",[468,1384,1385,1390,1392],{},[483,1386,1387,1388],{},"Finalise response missing ",[537,1389,539],{},[483,1391,1379],{},[483,1393,1394],{},"The basket outcome is uncertain; check the basket and provider audit before any new order",[468,1396,1397,1400,1406],{},[483,1398,1399],{},"Valid webhook for a processing sale",[483,1401,1402,1403],{},"Stores or updates the response, audits it, and dispatches ",[537,1404,1405],{},"AsyncFetchCode",[483,1407,1408],{},"Retrieval can process the voucher payload",[468,1410,1411,1425,1431],{},[483,1412,1413,1414,540,1417,1420,1421,1424],{},"Webhook for ",[537,1415,1416],{},"SUCCESS",[537,1418,1419],{},"ERROR",", or ",[537,1422,1423],{},"CANCELLED"," sale",[483,1426,1427,1428,1430],{},"Returns HTTP ",[537,1429,1138],{}," without storing a new payload",[483,1432,1433],{},"A duplicate or late callback is acknowledged and ignored",[468,1435,1436,1439,1444],{},[483,1437,1438],{},"No stored webhook response during retrieval",[483,1440,1350,1441],{},[537,1442,1443],{},"WebhookResponseNotFoundException",[483,1445,1446],{},"Treat fulfilment as unresolved; there is no API status fallback in this interaction",[450,1448,1449,1450,1453],{},"The basket ID cache lasts ",[537,1451,1452],{},"604800"," seconds (one week). Update and finalise use idempotency keys derived from that basket ID, so a retry with the same cached basket can be correlated to the original provider actions. A manual re-order or a retry after the cache has expired can create a new basket and duplicate fulfilment; resolve the original basket and order first.",[454,1455,1457],{"id":1456},"audit-comparison-fields","Audit comparison fields",[450,1459,1460],{},"Compare the following values across application and provider records:",[553,1462,1463,1473,1479,1487,1495,1500],{},[556,1464,1465,1466,540,1469,1472],{},"Internal sale UUID and transaction reference against ",[537,1467,1468],{},"productReference",[537,1470,1471],{},"reference",", and the cache key used for the basket.",[556,1474,1475,1476,1478],{},"Brand ",[537,1477,564],{},", denomination SKU, currency, integer gift-card value, and basket ID against the update payload.",[556,1480,1481,1482,1265,1484,1486],{},"Update and finalise idempotency keys against the basket ID and operation (",[537,1483,684],{},[537,1485,972],{},").",[556,1488,1489,1490,1492,1493,583],{},"Finalise ",[537,1491,539],{}," against the stored processor reference and webhook ",[537,1494,1246],{},[556,1496,1243,1497,1499],{},[537,1498,1047],{},", request timestamp, sale UUID, webhook-response record ID, and the response-audit timestamp.",[556,1501,1502],{},"Sale status and the presence of a stored payload before retrying retrieval. Inspect voucher-field presence without copying the URL or PIN into a ticket.",[450,1504,1505],{},"The webhook handler writes the received body to the processor interaction response audit. Treat that audit and the encrypted database payload as sensitive evidence; record field names, identifiers, states, and timestamps rather than voucher values.",[454,1507,1509],{"id":1508},"settings","Settings",[611,1511,1513],{"id":1512},"processor-settings","Processor settings",[450,1515,1516,1519],{},[537,1517,1518],{},"config\u002Fgo-gift-v2.php"," reads these environment-backed settings:",[462,1521,1522,1532],{},[465,1523,1524],{},[468,1525,1526,1529],{},[471,1527,1528],{},"Setting",[471,1530,1531],{},"Environment variable",[478,1533,1534,1544,1554,1564,1574,1584,1594],{},[468,1535,1536,1539],{},[483,1537,1538],{},"API base URI",[483,1540,1541],{},[537,1542,1543],{},"GO_GIFT_V2_API_URI",[468,1545,1546,1549],{},[483,1547,1548],{},"OAuth\u002Ftoken base URI",[483,1550,1551],{},[537,1552,1553],{},"GO_GIFT_V2_AUTH_URI",[468,1555,1556,1559],{},[483,1557,1558],{},"API secret",[483,1560,1561],{},[537,1562,1563],{},"GO_GIFT_V2_API_SECRET",[468,1565,1566,1569],{},[483,1567,1568],{},"OAuth client ID",[483,1570,1571],{},[537,1572,1573],{},"GO_GIFT_V2_CLIENT_ID",[468,1575,1576,1579],{},[483,1577,1578],{},"B2B department\u002Fclient ID",[483,1580,1581],{},[537,1582,1583],{},"GO_GIFT_V2_B2B_DEPARTMENT_ID",[468,1585,1586,1589],{},[483,1587,1588],{},"HTTP timeout",[483,1590,1591],{},[537,1592,1593],{},"GO_GIFT_V2_TIMEOUT",[468,1595,1596,1599],{},[483,1597,1598],{},"Webhook signature secret",[483,1600,1601],{},[537,1602,1603],{},"GO_GIFT_V2_WEBHOOK_SIGNATURE",[450,1605,1606,1607,1610],{},"The API client obtains an OAuth client-credentials token from ",[537,1608,1609],{},"\u003Cauth-base-uri>\u002Fconnect\u002Ftoken",", caches the access token, and sends it as a bearer token. Never expose the token, API secret, client ID, or webhook secret in an audit or escalation.",[611,1612,1614],{"id":1613},"brand-settings","Brand settings",[450,1616,1617,1618,1620],{},"Each enabled brand requires the GoGift v2 ",[537,1619,564],{}," brand attribute and a denomination-level SKU mapping. The processor type migration changed the fixed type to SKU per denomination. Check both values for the requested face value; a valid product ID with a missing or incorrect SKU can produce a basket that does not represent the requested product.",[454,1622,1624],{"id":1623},"api-operations","API operations",[462,1626,1627,1643],{},[465,1628,1629],{},[468,1630,1631,1634,1637,1640],{},[471,1632,1633],{},"Client operation",[471,1635,1636],{},"Provider path",[471,1638,1639],{},"Method",[471,1641,1642],{},"Purpose",[478,1644,1645,1667,1686,1705,1724,1744],{},[468,1646,1647,1652,1657,1662],{},[483,1648,1649],{},[537,1650,1651],{},"createBasket",[483,1653,1654],{},[537,1655,1656],{},"baskets\u002F",[483,1658,1659],{},[537,1660,1661],{},"POST",[483,1663,1664,1665],{},"Create a basket with sales channel ID ",[537,1666,571],{},[468,1668,1669,1674,1678,1683],{},[483,1670,1671],{},[537,1672,1673],{},"updateBasket",[483,1675,1676],{},[537,1677,1656],{},[483,1679,1680],{},[537,1681,1682],{},"PUT",[483,1684,1685],{},"Replace basket products with one webhook-delivered item",[468,1687,1688,1693,1698,1702],{},[483,1689,1690],{},[537,1691,1692],{},"finalizeBasket",[483,1694,1695],{},[537,1696,1697],{},"baskets\u002Ffinalize\u002F",[483,1699,1700],{},[537,1701,1661],{},[483,1703,1704],{},"Finalise the basket using invoice finance",[468,1706,1707,1712,1717,1721],{},[483,1708,1709],{},[537,1710,1711],{},"listAllProducts",[483,1713,1714],{},[537,1715,1716],{},"products\u002Ffilter\u002F",[483,1718,1719],{},[537,1720,1661],{},[483,1722,1723],{},"Catalogue product listing",[468,1725,1726,1731,1736,1741],{},[483,1727,1728],{},[537,1729,1730],{},"getProductById",[483,1732,1733],{},[537,1734,1735],{},"products\u002F\u003Cproduct-id>\u002F",[483,1737,1738],{},[537,1739,1740],{},"GET",[483,1742,1743],{},"Retrieve one catalogue product",[468,1745,1746,1749,1754,1758],{},[483,1747,1748],{},"Webhook confirmation",[483,1750,1751],{},[537,1752,1753],{},"\u002Fwebhook\u002F\u003Cprocessor>\u002Fconfirmation",[483,1755,1756],{},[537,1757,1661],{},[483,1759,1760],{},"Receive signed fulfilment data; the application stores it locally",[454,1762,1764],{"id":1763},"customer-service-investigation","Customer-service investigation",[450,1766,1767,1768,1770,1771,1773],{},"For a delayed or failed sale, collect the internal sale UUID, transaction reference, brand ",[537,1769,564],{},", requested denomination and SKU, currency, basket ID, processor reference\u002Forder ID, sale status, and timestamps. Review the ordered create, update, finalise, webhook, and retrieval evidence. For webhook failures, also check the four required headers, client-ID match, signature verification result, and ",[537,1772,1047],{}," without recording their secret values.",[450,1775,1776,1777,1779],{},"Before retrying, determine whether create returned a basket ID, whether update and finalise used the expected idempotency keys, and whether finalise may already have returned or created an order. Check the webhook-response record and its ",[537,1778,1305],{}," before dispatching another retrieval. Do not start a new order until the original basket and provider order have been reconciled.",[450,1781,1782],{},"If the webhook is absent, check provider delivery evidence and the local sale status; retrieval cannot query GoGift v2 for the voucher as a fallback. If the webhook exists but validation fails, compare only the required field names, order ID, URL validity, expiration presence, and audit timestamps. Keep the URI and PIN redacted.",[454,1784,1786],{"id":1785},"limitations","Limitations",[450,1788,1789],{},"Escalations should include the internal sale UUID, transaction reference, basket ID, provider order ID, idempotency keys, webhook request ID and timestamp, sale status, and redacted audit evidence. Do not include bearer tokens, API secrets, webhook signatures, gift-card URLs, or PINs.",[454,1791,1793],{"id":1792},"related-code","Related code",[1795,1796,1797,1803,1809,1815,1821,1827,1833,1839,1845,1851,1856,1862,1868,1874,1880],"ul",{},[556,1798,1799,1802],{},[537,1800,1801],{},"app\u002FProcessors\u002FGoGiftV2\u002FGoGiftV2Processor.php"," — asynchronous processor and webhook capability.",[556,1804,1805,1808],{},[537,1806,1807],{},"app\u002FProcessors\u002FInteraction\u002FIntegrations\u002FGoGiftV2\u002FGoGiftV2ProcessorInteraction.php"," — basket issue flow, cache, idempotency keys, webhook retrieval, validation, and cleanup dispatch.",[556,1810,1811,1814],{},[537,1812,1813],{},"app\u002FProcessors\u002FGoGiftV2\u002FGoGiftV2WebhookHandler.php"," — webhook authentication, sale lookup, storage, auditing, and retrieval dispatch.",[556,1816,1817,1820],{},[537,1818,1819],{},"app\u002FHttp\u002FClients\u002FGoGiftV2\u002FGoGiftV2Api.php"," — OAuth token handling, transport, headers, and provider operations.",[556,1822,1823,1826],{},[537,1824,1825],{},"app\u002FHttp\u002FClients\u002FGoGiftV2\u002FRequests\u002FCreateBasketRequestData.php"," — create payload.",[556,1828,1829,1832],{},[537,1830,1831],{},"app\u002FHttp\u002FClients\u002FGoGiftV2\u002FRequests\u002FUpdateBasketRequestData.php"," — basket update payload.",[556,1834,1835,1838],{},[537,1836,1837],{},"app\u002FHttp\u002FClients\u002FGoGiftV2\u002FRequests\u002FFinalizeBasketRequestData.php"," — finalisation payload.",[556,1840,1841,1844],{},[537,1842,1843],{},"app\u002FHttp\u002FClients\u002FGoGiftV2\u002FRequests\u002FListAllProductsRequestData.php"," — catalogue listing request.",[556,1846,1847,1850],{},[537,1848,1849],{},"app\u002FHttp\u002FClients\u002FGoGiftV2\u002FRequests\u002FGetProductByIdRequestData.php"," — catalogue product request.",[556,1852,1853,1855],{},[537,1854,1518],{}," — API, OAuth, B2B, timeout, and webhook settings.",[556,1857,1858,1861],{},[537,1859,1860],{},"database\u002Fmigrations\u002F2024_11_11_205846_create_go_gift_v2_processor.php"," — processor capabilities and technical contact.",[556,1863,1864,1867],{},[537,1865,1866],{},"database\u002Fmigrations\u002F2024_11_13_095635_rcc-15266_create_go_gift_v2_webhook_responses_table.php"," — webhook-response storage schema.",[556,1869,1870,1873],{},[537,1871,1872],{},"database\u002Fmigrations\u002F2025_02_13_141933_modify_go_gift_v2_fixed_processor_type_column.php"," — denomination SKU processor type.",[556,1875,1876,1879],{},[537,1877,1878],{},"tests\u002FUnit\u002FProcessors\u002FInteraction\u002FIntegrations\u002FGoGiftV2\u002FGoGiftV2ProcessorInteractionTest.php"," — basket, retrieval, validation, and retry scenarios.",[556,1881,1882,1885],{},[537,1883,1884],{},"tests\u002FUnit\u002FProcessors\u002FGoGiftV2\u002FGoGiftV2WebhookHandlerTest.php"," — webhook header, signature, payload, sale-state, storage, and dispatch scenarios.",[1887,1888,1889],"style",{},"html pre.shiki code .sQ3_J, html code.shiki .sQ3_J{--shiki-dark:#E1E4E8;--shiki-default:#24292E}html pre.shiki code .s0DvM, html code.shiki .s0DvM{--shiki-dark:#79B8FF;--shiki-default:#005CC5}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);}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 pre.shiki code .sg6BJ, html code.shiki .sg6BJ{--shiki-dark:#9ECBFF;--shiki-default:#032F62}",{"title":628,"searchDepth":710,"depth":710,"links":1891},[1892,1893,1894,1898,1899,1900,1901,1905,1906,1907,1908],{"id":456,"depth":697,"text":457},{"id":550,"depth":697,"text":551},{"id":605,"depth":697,"text":606,"children":1895},[1896,1897],{"id":613,"depth":710,"text":614},{"id":1031,"depth":710,"text":1032},{"id":1191,"depth":697,"text":1192},{"id":1320,"depth":697,"text":1321},{"id":1456,"depth":697,"text":1457},{"id":1508,"depth":697,"text":1509,"children":1902},[1903,1904],{"id":1512,"depth":710,"text":1513},{"id":1613,"depth":710,"text":1614},{"id":1623,"depth":697,"text":1624},{"id":1763,"depth":697,"text":1764},{"id":1785,"depth":697,"text":1786},{"id":1792,"depth":697,"text":1793},{},"md",{},{"title":393,"description":452},"LBNBMm7hJz0pei7hmg_kkTpmITL4GnCVJxug2CCg-6c",[1915,1916],{"title":389,"path":390,"stem":391,"children":-1},{"title":397,"path":398,"stem":399,"children":-1},1789777549029]