baseUrl=rtrim($baseUrl,'/'); } public static function signature(array $data,string $key): string { unset($data['sign']);ksort($data); foreach($data as $name=>$value) if($value==='') unset($data[$name]); return hash_hmac('sha256',http_build_query($data,'','&',PHP_QUERY_RFC1738),$key); } public function call(string $path,array $parameters=[]): array { if(!preg_match('~^/(?:shared/[a-zA-Z/]+|api/[a-zA-Z_-]+)$~D',$path)) throw new InvalidArgumentException('Invalid API path'); $data=$parameters; $data['app_id']=$this->appId;$data['sign_type']='HMAC-SHA256';$data['timestamp']=(string)time();$data['nonce']=bin2hex(random_bytes(16)); $data['sign']=self::signature($data,$this->appKey); $response='';$curl=curl_init($this->baseUrl.$path); curl_setopt_array($curl,[CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>http_build_query($data,'','&',PHP_QUERY_RFC1738), CURLOPT_HTTPHEADER=>['Content-Type: application/x-www-form-urlencoded','Accept: application/json'], CURLOPT_RETURNTRANSFER=>false,CURLOPT_FOLLOWLOCATION=>false,CURLOPT_CONNECTTIMEOUT=>8,CURLOPT_TIMEOUT=>45, CURLOPT_SSL_VERIFYPEER=>true,CURLOPT_SSL_VERIFYHOST=>2, CURLOPT_WRITEFUNCTION=>static function($handle,string $chunk) use(&$response): int { if(strlen($response)+strlen($chunk)>8388608) return 0;$response.=$chunk;return strlen($chunk); }]); $ok=curl_exec($curl);$status=(int)curl_getinfo($curl,CURLINFO_HTTP_CODE);curl_close($curl); if($ok===false || $status>=500) throw new RuntimeException('Result unknown: query the original request_no/tradeNo; do not create a new purchase'); $result=json_decode($response,true,64,JSON_THROW_ON_ERROR); if(!is_array($result)) throw new RuntimeException('Unexpected response; query the original order'); return $result; } }