<?php
declare(strict_types=1);
define('RFJ_CONTEXT_ONLY',true);require __DIR__.'/preflight.php';
$state=json_decode((string)file_get_contents(__DIR__.'/private-state.json'),true);if(($state['phase']??'')!=='qualified-ready')throw new RuntimeException('Never replay an existing financial state');
$report=['lane'=>$lane,'marker'=>$state['marker'],'cases'=>[],'retention_policy'=>'Keep complete marked successful financial chain; no CAS and no financial DELETE','new_interface_keys'=>0];$stage='boundary';
$check=static function(bool $ok,string $why):void{if(!$ok)throw new RuntimeException($why);};$money=static function($value):string{return bcadd((string)$value,'0',2);};
$hash=static function($v):string{return hash('sha256',json_encode($v,JSON_UNESCAPED_UNICODE|JSON_INVALID_UTF8_SUBSTITUTE|JSON_PRESERVE_ZERO_FRACTION));};
$shape=static function($v)use(&$shape){if(is_object($v)){$x=[];foreach(get_object_vars($v) as $k=>$s)$x[$k]=$shape($s);ksort($x);return ['object'=>$x];}return is_array($v)?['array'=>array_map($shape,$v)]:(is_int($v)||is_float($v)?'number':gettype($v));};
$save=static function()use(&$state):void{file_put_contents(__DIR__.'/private-state.json',json_encode($state,JSON_PRETTY_PRINT));chmod(__DIR__.'/private-state.json',0600);};
$snapshot=static function()use($q,$store,$ai,$s,$a,$chosen):array{$data=['store_user'=>$q($store,'SELECT ID,UUID,STAFF_UUID,AI_USER_ID,NAME,PAY_MONEY FROM '.$s.'user WHERE ID=?',[(int)$chosen['store_user']['id']])];foreach(['user','recharge_order','user_balance_log','user_gift_log','user_subsidy','user_subsidy_log','user_subsidy_used','account_settlement'] as $t){$rows=$q($ai,'SELECT * FROM '.$a.$t.' WHERE USER_ID=?',[(int)$chosen['ai_user']['user_id']]);foreach($rows as &$row)ksort($row);unset($row);usort($rows,static function($x,$y){return strcmp(serialize($x),serialize($y));});$data['ai_'.$t]=$rows;}return $data;};
$sourceSummary=static function(array $data)use($hash):array{$r=[];foreach($data as $k=>$rows)$r[$k]=['rows'=>count($rows),'sha256'=>$hash($rows)];return $r;};
$clear=static function(string $key):void{$file=__DIR__.'/cache/CENT10_/'.md5($key).'.php';if(!is_file($file)||is_link($file)||!unlink($file))throw new RuntimeException('Exact private cache key absent or not removed');};
$actor=$q($store,'SELECT ID,UUID FROM '.$s.'user WHERE ID=(SELECT MIN(ID) FROM '.$s.'user WHERE TYPE=0 AND IS_DELETE=0)')[0];require_once $root.'/application/base/Security.php';$token=\app\base\Security::encrypt(implode("\t",[(string)$actor['id'],(string)$actor['uuid'],'CDXCENTADMIN','0','','','CDXCENTADMIN']));$auth=json_decode((string)file_get_contents(__DIR__.'/private-auth.json'),true);
$request=static function(string $label,string $path,array $params,?string $number=null,bool $device=false)use($lane,$token,$auth,$hash,$shape,&$report):array{$header="Content-Type: application/x-www-form-urlencoded\r\n";if($device)$header.='account: '.$auth['account']."\r\npwd: ".$auth['pwd']."\r\nkey: ".$auth['key']."\r\n";else $header.='token: '.$token."\r\n";
 if($number!==null){$nonce=bin2hex(random_bytes(16));file_put_contents(__DIR__.'/private-request-order-no.json',json_encode(['nonce'=>$nonce,'path'=>$path,'order_no'=>$number]));chmod(__DIR__.'/private-request-order-no.json',0600);$header.='X-RFJ-Fixture-Nonce: '.$nonce."\r\n";}
 $raw=@file_get_contents('http://127.0.0.1:'.($lane==='B'?18301:18302).$path,false,stream_context_create(['http'=>['method'=>'POST','header'=>$header,'content'=>http_build_query($params),'ignore_errors'=>true,'timeout'=>30]]));preg_match('#^HTTP/\S+\s+(\d+)#',$http_response_header[0]??'',$m);$body=json_decode((string)$raw,true);$wire=json_decode((string)$raw);file_put_contents(__DIR__.'/private-response-'.$label.'.json',(string)$raw);chmod(__DIR__.'/private-response-'.$label.'.json',0600);
 $entry=['scenario'=>$label,'method'=>'POST','path'=>$path,'http_status'=>(int)($m[1]??0),'json_valid'=>is_array($body),'code'=>$body['code']??null,'wire_shape'=>$shape($wire),'raw_wire_sha256'=>hash('sha256',(string)$raw)];if(is_array($body)&&isset($body['message']))$entry['message_sha256']=hash('sha256',(string)$body['message']);$report['cases'][]=$entry;if(!is_array($body)||(int)($m[1]??0)!==200)throw new RuntimeException('No valid HTTP response '.$label);return $body;};
$phase=static function(string $value)use(&$state,$save):void{$state['phase']=$value;$save();};
$before=null;
try{
 $boundary=json_decode((string)file_get_contents('http://127.0.0.1:'.($lane==='B'?18301:18302).'/__poc_boundary'),true);$check(is_array($boundary)&&$boundary['private_file_cache']&&$boundary['redis_disabled']&&$boundary['external_stubs_configured']&&!$boundary['real_queue']&&$boundary['real_settlement_source']&&$boundary['original_debug']===false,'Safe real-wallet boundary');$report['boundary']=$boundary;
 $before=$snapshot();$report['source_before']=$sourceSummary($before);file_put_contents(__DIR__.'/private-before.json',json_encode($before,JSON_PRESERVE_ZERO_FRACTION|JSON_UNESCAPED_UNICODE));chmod(__DIR__.'/private-before.json',0600);$cashBefore=$money($before['ai_user'][0]['balance']);$giftBefore=$money($before['ai_user'][0]['gift_balance']);$payMoneyBefore=$money($before['store_user'][0]['pay_money']);
 $stage='cash-recharge';$phase('cash-request-sent');$rechargeForm=['department_uuid'=>'','staff_uuids'=>$chosen['staff']['uuid'],'money'=>'0.01','pay_method'=>'cash','note'=>$state['marker']];$body=$request('cash_recharge','/p/rechargeOrder/add',$rechargeForm,$state['marker'].'C');$check($body['code']===0,'Cash recharge success');
 $recharges=$q($ai,'SELECT * FROM '.$a.'recharge_order WHERE ORDER_NO=? AND USER_ID=? AND NOTE=?',[$state['cash_no'],(int)$chosen['ai_user']['user_id'],$state['marker']]);$check(count($recharges)===1,'Own recharge identity');$rc=$recharges[0];$state['recharge_order_id']=(int)$rc['order_id'];$save();$check((int)$rc['pay_status']===20&&$money($rc['pay_price'])==='0.01'&&$money($rc['gift_money'])==='0.00'&&$money($rc['actual_money'])==='0.01','Actual cash/gift/source amount');$funded=$snapshot();$check($money($funded['ai_user'][0]['balance'])===bcadd($cashBefore,'0.01',2)&&$money($funded['ai_user'][0]['gift_balance'])===$giftBefore,'Real cash wallet credited only one cent');$report['cash_source']=['paid_recharge_rows'=>1,'cash_credit'=>'0.01','gift_credit'=>'0.00','wallet_delta_verified'=>true];$phase('cash-confirmed');
 $stage='cash-repeat-cache';$body=$request('cash_repeat_cache','/p/rechargeOrder/add',$rechargeForm,$state['marker'].'C');$check($body['code']===1&&$body['message']==='充值中，请勿重复提交'&&$snapshot()===$funded,'Cash File repeat no additional credit');
 $stage='cash-repeat-business-key';$key='recharge_order_add_'.sha1(implode('|',[$chosen['staff']['uuid'],'0.01','cash']));$clear($key);$body=$request('cash_repeat_same_forced_number','/p/rechargeOrder/add',$rechargeForm,$state['marker'].'C');$check($body['code']===0&&$snapshot()===$funded,'Existing paid recharge key no additional credit');
 $stage='internal-pay';$phase('pay-request-sent');$payForm=['staff_uuid'=>$chosen['staff']['uuid'],'equipment_code'=>$state['equipment_code'],'paycode'=>'','card_id'=>'','money'=>'0.01','dishes'=>[['uuid'=>'custom_dish','number'=>1,'money'=>'0.01']],'create_time'=>date('Y-m-d H:i:s'),'msgid'=>$state['msgid'],'order_type'=>1];$state['pay_form']=$payForm;$save();$body=$request('internal_pay','/api/consume/orderPay',$payForm,$state['marker'].'R',true);$check($body['code']===0,'Internal payment HTTP success');$orders=$q($store,'SELECT * FROM '.$s.'meal_order WHERE ORDER_NO=? AND MSGID=? AND USER_ID=?',[$state['pay_no'],$state['msgid'],(int)$chosen['store_user']['id']]);$check(count($orders)===1,'Own actual paid order');$order=$orders[0];$state['order_id']=(int)$order['id'];$save();$check((int)$order['order_status']===30&&(int)$order['pay_status']===20&&(int)$order['pay_type']===40&&(int)$order['trade_id']===0&&$money($order['pay_price'])==='0.01','Actual local face-balance paid order');$check($q($store,'SELECT ID FROM '.$s.'one_card_trade_order WHERE LOCAL_ORDER_NO=?',[$state['pay_no']])===[],'No external card trade');
 $check($body['data']['order_no']===$state['pay_no']&&$body['data']['staff_uuid']===$chosen['staff']['uuid']&&$body['data']['staff_name']===$before['store_user'][0]['name'],'Owned payment response identity');foreach(['total_price'=>'0.01','pay_price'=>'0.01','management_fee'=>'0.00','discount_amount'=>'0.00'] as $field=>$expected)$check(($body['data'][$field]??null)===$expected,'Exact MySQL monetary response contract '.$field);
 $goods=$q($store,'SELECT * FROM '.$s.'initial_menu WHERE MEAL_ORDER_ID=?',[$state['order_id']]);$check(count($goods)===1&&$goods[0]['dishes_uuid']==='custom_dish'&&$money($goods[0]['total_price'])==='0.01'&&(int)$goods[0]['pay_status']===20,'Real virtual dish initial menu');$settlements=$q($ai,'SELECT * FROM '.$a.'account_settlement WHERE BIZ_ORDER_NO=? AND BIZ_TYPE=?',[$state['pay_no'],'consume']);$check(count($settlements)===1&&(int)$order['account_settlement_id']>0,'Real consume settlement');$paid=$snapshot();$cashUsed=$money($order['cash']);$giftUsed=$money($order['gift']);$subsidyUsed=$money($order['subsidy']);$check(bcadd(bcadd($cashUsed,$giftUsed,2),$subsidyUsed,2)==='0.01','Exact split sums one cent');$check($money($paid['ai_user'][0]['balance'])===bcsub(bcadd($cashBefore,'0.01',2),$cashUsed,2)&&$money($paid['ai_user'][0]['gift_balance'])===bcsub($giftBefore,$giftUsed,2)&&$money($paid['store_user'][0]['pay_money'])===bcadd($payMoneyBefore,'0.01',2),'Actual two-database wallet/cumulative debit');$report['payment_source']=['paid_order_rows'=>1,'initial_menu_rows'=>1,'consume_settlement_rows'=>1,'cash'=>$cashUsed,'gift'=>$giftUsed,'subsidy'=>$subsidyUsed,'whole_split_and_wallet_verified'=>true,'response_money_text_verified'=>true];$phase('pay-confirmed');
 $stage='pay-repeat-cache';$body=$request('pay_repeat_cache','/api/consume/orderPay',$payForm,$state['marker'].'R',true);$check($body['code']===1&&$snapshot()===$paid,'Pay immediate File guard no debit');
 $stage='pay-repeat-database';$clear('consume_orderpay_'.$state['msgid']);$body=$request('pay_repeat_same_msgid_database','/api/consume/orderPay',$payForm,$state['marker'].'R',true);$check($body['code']===0&&$body['data']['order_no']===$state['pay_no']&&$snapshot()===$paid&&count($q($store,'SELECT ID FROM '.$s.'meal_order WHERE MSGID=?',[$state['msgid']]))===1,'Real paid order and settlement idempotence');
 $stage='refund-apply';$phase('refund-apply-request-sent');$body=$request('refund_apply','/p/mealOrder/refund',['order_id'=>$state['order_id'],'refund_amount'=>'0.01','apply_desc'=>$state['marker']],$state['marker'].'F');$check($body['code']===0&&is_string($body['data']['refund_id']),'Original refund ID text contract');$refunds=$q($store,'SELECT * FROM '.$s.'meal_order_refund WHERE MEAL_ORDER_ID=? AND ORDER_NO=? AND APPLY_DESC=?',[$state['order_id'],$state['refund_no'],$state['marker']]);$check(count($refunds)===1&&(string)$refunds[0]['id']===$body['data']['refund_id']&&(int)$refunds[0]['refund_status']===1,'Owned pending refund source');$state['refund_id']=(int)$refunds[0]['id'];$save();$check($snapshot()===$paid,'Refund request alone moves no money');
 $stage='internal-refund';$phase('refund-agree-request-sent');$body=$request('internal_refund_agree','/p/mealOrder/refundAgree',['refund_id'=>$state['refund_id']]);$check($body['code']===0,'Internal refund HTTP success');$order=$q($store,'SELECT * FROM '.$s.'meal_order WHERE ID=? AND ORDER_NO=?',[$state['order_id'],$state['pay_no']])[0];$refund=$q($store,'SELECT * FROM '.$s.'meal_order_refund WHERE ID=? AND MEAL_ORDER_ID=?',[$state['refund_id'],$state['order_id']])[0];$check((int)$order['refund_status']===3&&$money($order['refund_amount'])==='0.01'&&(int)$refund['refund_status']===2&&$money($refund['refund_amount'])==='0.01','Real completed refund source');foreach(['cash'=>$cashUsed,'gift'=>$giftUsed,'subsidy'=>$subsidyUsed] as $field=>$amount)$check($money($order[$field.'_refund_amount'])===$amount&&$money($refund[$field.'_refund_amount'])===$amount,'Refund original split restoration');$refundSettlements=$q($ai,'SELECT * FROM '.$a.'account_settlement WHERE BIZ_ORDER_NO=? AND BIZ_TYPE=? AND REFUND_NO=?',[$state['pay_no'],'refund',$state['refund_no']]);$check(count($refundSettlements)===1&&(int)$refund['account_settlement_id']>0,'Real refund settlement');$refunded=$snapshot();$check($money($refunded['ai_user'][0]['balance'])===bcadd($cashBefore,'0.01',2)&&$money($refunded['ai_user'][0]['gift_balance'])===$giftBefore&&$money($refunded['store_user'][0]['pay_money'])===bcadd($payMoneyBefore,'0.01',2),'Net retained principal and original cumulative logic');$report['refund_source']=['approved_refund_rows'=>1,'refund_settlement_rows'=>1,'original_splits_restored'=>true,'cash_principal_net'=>'0.01','gift_net'=>'0.00','store_pay_money_net'=>'0.01'];$phase('refund-confirmed');
 $stage='refund-repeat-cache';$body=$request('refund_repeat_cache','/p/mealOrder/refundAgree',['refund_id'=>$state['refund_id']]);$check($body['code']===1&&$snapshot()===$refunded,'Refund File repeat no double credit');
 $stage='refund-repeat-business';$clear('meal_order_refund_audit_'.$state['refund_id']);$body=$request('refund_repeat_approved_state','/p/mealOrder/refundAgree',['refund_id'=>$state['refund_id']]);$check($body['code']==='2'&&$body['message']==='当前状态不可重复操作'&&$snapshot()===$refunded,'Refund business approved-state no double credit');
 $stage='ledger-final';$after=$snapshot();$report['source_after']=$sourceSummary($after);$cashLogs=array_values(array_filter($after['ai_user_balance_log'],static function($row)use($before){foreach($before['ai_user_balance_log'] as $old)if((string)$row['log_id']===(string)$old['log_id'])return false;return true;}));$giftLogs=array_values(array_filter($after['ai_user_gift_log'],static function($row)use($before){foreach($before['ai_user_gift_log'] as $old)if((string)$row['log_id']===(string)$old['log_id'])return false;return true;}));
 $sum='0.00';foreach($cashLogs as $row)$sum=bcadd($sum,(string)$row['money'],2);$check($sum==='0.01','Actual cash ledger net one cent');$giftSum='0.00';foreach($giftLogs as $row)$giftSum=bcadd($giftSum,(string)$row['money'],2);$check($giftSum==='0.00','Actual gift ledger net zero');$check(count($cashLogs)===(1+($cashUsed!=='0.00'?2:0))&&count($giftLogs)===($giftUsed!=='0.00'?2:0),'Exact cash/gift ledger row count');$report['ledger_source']=['new_cash_log_rows'=>count($cashLogs),'new_gift_log_rows'=>count($giftLogs),'cash_log_net'=>'0.01','gift_log_net'=>'0.00','exact_row_counts_verified'=>true];$phase('complete-retained');$report['failure']=null;
}catch(Throwable $e){$report['failure']=['stage'=>$stage,'class'=>get_class($e),'message_sha256'=>hash('sha256',$e->getMessage())];$state['last_failure_stage']=$stage;$save();file_put_contents(__DIR__.'/private-error.json',json_encode(['stage'=>$stage,'message'=>$e->getMessage()]));chmod(__DIR__.'/private-error.json',0600);}
finally{
 $report['retained_records']=['marker'=>$state['marker'],'restaurant_id'=>$state['restaurant_id'],'equipment_id'=>$state['equipment_id'],'recharge_order_id'=>$state['recharge_order_id'],'order_id'=>$state['order_id'],'refund_id'=>$state['refund_id'],'cash_no'=>$state['cash_no'],'order_no'=>$state['pay_no'],'refund_no'=>$state['refund_no'],'phase'=>$state['phase']];
 try{$references=$q($store,'SELECT ID FROM '.$s.'meal_order WHERE API_ACCOUNT=?',[$auth['account']]);if($references){$stmt=$store->prepare('UPDATE '.$s.'api_auth SET STATUS=0,END_TIME=? WHERE ID=? AND ACCOUNT=?');$stmt->execute([date('Y-m-d H:i:s',time()-1),$state['auth_id'],$auth['account']]);$report['credential_cleanup']=['historical_references'=>count($references),'retained_disabled'=>true,'exact_deleted'=>false];}else{$stmt=$store->prepare('DELETE FROM '.$s.'api_auth WHERE ID=? AND ACCOUNT=? AND PWD=?');$stmt->execute([$state['auth_id'],$auth['account'],$auth['pwd']]);$check($stmt->rowCount()===1,'Exact temporary credential revoke');$report['credential_cleanup']=['historical_references'=>0,'retained_disabled'=>false,'exact_deleted'=>true];}$check($q($store,'SELECT ID FROM '.$s.'api_auth WHERE ID=? AND STATUS=1',[$state['auth_id']])===[],'No active temporary API credential');}catch(Throwable $e){$report['credential_cleanup_error']=['class'=>get_class($e),'message_sha256'=>hash('sha256',$e->getMessage())];}
}
file_put_contents(__DIR__.'/result-private.json',json_encode($report,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));chmod(__DIR__.'/result-private.json',0600);echo json_encode($report,JSON_UNESCAPED_UNICODE|JSON_INVALID_UTF8_SUBSTITUTE),"\n";exit($report['failure']!==null||isset($report['credential_cleanup_error'])?2:0);
