function operationReceipt(outcome,receipt){ const original=typeof receipt==='string'?JSON.parse(receipt):receipt; if(!original||!outcome?.source||!['locationId','workflowId','recordId','revision','phone','country','profile'].every(k=>outcome.source[k]===original[k])||!/^\+[1-9][0-9]{6,14}$/.test(outcome.source.e164||'')||!/^[a-f0-9]{8}-[a-f0-9]{4}-[1-8][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i.test(outcome.operationId||''))throw Error('Retain the original request and response for review; no replacement purchase.'); return {operationId:outcome.operationId,receipt:JSON.stringify({...original,e164:outcome.source.e164,operationId:outcome.operationId})}; } function retainDecision(outcome,receipt){ if(outcome?.state==='preview'&&outcome.operationId===null&&outcome.readyToWrite===false)return {retain:false,reason:'preview_only',operationId:'',receipt:''}; const bound=operationReceipt(outcome,receipt); return {retain:true,reason:null,...bound}; } function nativeObject(value,name){ let parsed=value; if(typeof value==='string'){ try{parsed=JSON.parse(value);}catch(error){ // Native workflow interpolation HTML-encodes the JSON string. Decode // exactly one layer only when the opening JSON key is visibly encoded. if(!/^\s*\{(?:"|"|")/i.test(value))throw error; const entities={'quot':'"','amp':'&','apos':"'",'lt':'<','gt':'>'}; const decoded=value.replace(/&(#x[0-9a-f]+|#[0-9]+|quot|amp|apos|lt|gt);/gi,(entity,key)=>{ if(key[0]!=='#')return entities[key.toLowerCase()]??entity; const point=key[1].toLowerCase()==='x'?parseInt(key.slice(2),16):parseInt(key.slice(1),10); return point>0&&point<=0x10ffff?String.fromCodePoint(point):entity; }); parsed=JSON.parse(decoded); } } if(!parsed||typeof parsed!=='object'||Array.isArray(parsed))throw Error(name+' must be a JSON object.'); return parsed; } return retainDecision(nativeObject(inputData.outcome,'outcome'), nativeObject(inputData.receipt,'receipt'));