During the work period, the customer specifies to use this. During the actual work time, the other party has no demo, has an md5 signature that is also 1.0, and can't find the case through online search. The official website doesn't provide any related content of the document. Everything should be written according to the document provided by the docking personnel, but the good thing is that I have written it. Here I directly provide the code
config.php
<?php return [ 'merId'=>'Merchant id', 'key'=>'Private key of a single line', 'public_key'=>'Single line public key', 'frontUrl'=>'Sync return address', 'backUrl'=>'Asynchronous notification address', 'ChinagUrl'=>'Request address', //No need for customs declaration 'ChinagCustomsReportNotifyUrl'=>'Customs declaration asynchronous request address', 'ChinagReportCustomsCode'=>'Customs code', 'intype'=>'Type of import business,Although the document says it can be left blank, it doesn't work' ];
Place an order in advance
<?php include 'ChinaG.php'; $OrderNumber = date('YmdHis') . str_pad(mt_rand(0, 99999), 6, '0'); $Config = include 'config.php'; $Amount = 0.01; $ChinaG = new \ChinaG\ChinaG($Config); $Data = $ChinaG->preOrder($OrderNumber, $Amount); //This is usually implemented with templates, but in order to demonstrate it, you need to directly set php? > //Initiating payment request < form action = "<? = $data ['url ']? > method =" post "> <?php foreach ($Data['params'] as $Key => $Value): ?> <input type="hidden" name="<?=$Key?>" value="<?=$Value?>"> <?php endforeach; ?> </form> <script>document.forms[0].submit();</script>
Prompt payment asynchronous notification
<?php include 'ChinaG.php'; $Config = include 'config.php'; $ChinaG = new \ChinaG\ChinaG($Config); if($ChinaG->Notify($_POST)){ //Successful payment processing here file_put_contents('log.txt',var_export($_POST,true),FILE_APPEND); //Output SUCCESS if successful echo 'SUCCESS'; }
ChinaG.php
<?php /** * Class ChinaG * @author gcud * @version 20200427 */ namespace ChinaG; class ChinaG { private $config; private $UrlPrefix; public function __construct($Config) { $this->config = $Config; $this->UrlPrefix=$this->config['ChinagUrl']; } /** * Pre order * @param $OrderSerialNumber * @param $Amount * @return array */ public function preOrder($OrderSerialNumber, $Amount) { $Url = 'frontPay/preOrder.do'; $Parameters['signMethod'] = 'RSA'; $Parameters['version'] = '2.0.0'; $Parameters['merId'] = $this->config['merId']; $Parameters['merOrderId'] = $OrderSerialNumber; $Parameters['traceNo'] = date('YmdHis' . str_pad(mt_rand(0, 99999), 5, '0')); $Parameters['bizType'] = '010002'; $Parameters['txnAmt'] =$Amount * 100; $Parameters['currency'] = 'CNY'; $Parameters['backUrl'] = $this->config['backUrl']; $Parameters['frontUrl'] = $this->config['frontUrl']; $Parameters['txnTime'] = date('YmdHms'); $Parameters['subject'] = 'Order payment'; $Parameters['body'] = ''; //Combining signature strings $SignContent = $this->buildSignContent($Parameters); $Parameters['signature'] = $this->Sign($SignContent, $this->config['key']); return ['params' => $Parameters, 'url' => $this->UrlPrefix . $Url]; } private function buildSignContent($Data) { ksort($Data); $DataString = ''; foreach ($Data as $Key => $Value) $DataString .= $Key . '=' . $Value . '&'; $DataString = substr($DataString, 0, -1); return $DataString; } /** * Signature, the method copied from Alipay. * @param $data * @param $priKey * @return string */ private function Sign($data, $priKey) { $res = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($priKey, 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----"; ($res) or die('The format of the private key you are using is wrong. Please check RSA Private key configuration'); openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); $sign = base64_encode($sign); return $sign; } public function Notify($Data) { if ($this->CheckSign($Data, $this->config['public_key'])) { return true; } else { return false; } } private function CheckSign($Data, $PublicKey) { $res = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($PublicKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; $Sign = $Data['signature']; unset($Data['signature']); $SignContent = $this->buildSignContent($Data); return openssl_verify($SignContent, base64_decode($Sign), $res, OPENSSL_ALGO_SHA256); } /** * Customs declaration, only one commodity can be declared at a time * @param $OrderNumber * @param $OrderSerialNumber * @param $GoodsNumber * @param $GoodsName * @param $ReceiverName * @param $ReceiverIdCard * @param $ReceiverPhone * @return bool|string */ public function customsReport($OrderNumber,$OrderSerialNumber,$GoodsNumber,$GoodsName,$ReceiverName,$ReceiverIdCard,$ReceiverPhone) { $Url = 'declare/reportDeclare.do'; //Special parameters $TimeString=date('YmdHis'); $Data['merOrderId']=$OrderNumber; $Data['txnTime']=$TimeString; $Data['backUrl']=$this->config['ChinagCustomsReportNotifyUrl']; $Data['customCode']=$this->config['ChinagReportCustomsCode']; $Data['oriMerOrderId']=$OrderSerialNumber; $Data['orderNo']=$OrderNumber; $Data['subject']=$GoodsNumber; $Data['body']=$GoodsName; $Data['customerNm']=$ReceiverName; $Data['certifyId']=$ReceiverIdCard; $Data['phoneNo']=$ReceiverPhone; $Data['intype']=$this->config['intype']; //Sort Dictionaries ksort($Data); //Common parameters $Parameters['version']='2.0.0'; $Parameters['merId']=$this->config['merId']; $Parameters['traceNo']= date('YmdHis' . str_pad(mt_rand(0, 99999), 5, '0')); $Parameters['signMethod']='RSA'; $Parameters['data']=$Data; //Sort Dictionaries ksort($Parameters); //Construct signature string without escaping url separator and Chinese $SignContent=json_encode($Parameters,320); //Sign $Parameters['signature']=$this->Sign($SignContent,$this->config['key']); //request $DataString=json_encode($Parameters); $curl=curl_init($this->config['ChinagUrl'].$Url); curl_setopt($curl,CURLOPT_POSTFIELDS,$DataString); curl_setopt($curl,CURLOPT_RETURNTRANSFER,true); curl_setopt($curl,CURLOPT_HTTPHEADER,['Content-Type: application/json','Content-Length: ' . strlen($DataString)]); $Result=curl_exec($curl); curl_close($curl); return $Result; } }
I didn't write the demo in the declaration part, but I also wrote the direct call of parameters. I did the coordination process of declaration myself for the first time, which is also not clear
< protection content