工作期间客户指定要用这个,实际做的时间对方没有demo,有也是1.0的md5签名,网上搜也找不到案例,官网不提供文档任何相关内容,一切都要按照对接人员提供的文档自己写,不过好的是我写出来了,这里直接提供代码
config.php
return [
'merId'=>'商户id',
'key'=>'单行的私钥',
'public_key'=>'单行的公钥',
'frontUrl'=>'同步返回地址',
'backUrl'=>'异步通知地址',
'ChinagUrl'=>'请求地址',
//没有报关需求的下面都可以不要
'ChinagCustomsReportNotifyUrl'=>'报关异步请求地址',
'ChinagReportCustomsCode'=>'海关编码',
'intype'=>'进口业务类型,虽然文档说可以不填但通不过'
];
预下单 demo_create_order.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);
//这里一般是用模板实现,但为了演示就直接套php了?>
正在发起支付请求
<?php foreach ($Data['params'] as $Key => $Value): ?>
快捷支付异步通知
include 'ChinaG.php';
$Config = include 'config.php';
$ChinaG = new \ChinaG\ChinaG($Config);
if($ChinaG->Notify($_POST)){
//在这里做支付成功处理
file_put_contents('log.txt',var_export($_POST,true),FILE_APPEND);
//成功的话要输出SUCCESS
echo 'SUCCESS';
}
ChinaG.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'];
}
/**
* 预下单
* @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'] = '订单支付';
$Parameters['body'] = '';
//组合签名字符串
$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;
}
/**
* 签名,从支付宝抄来的方法
* @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('您使用的私钥格式错误,请检查RSA私钥配置');
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);
}
/**
* 海关报关,一次只能报一种商品
* @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';
//专用参数
$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'];
//进行字典排序
ksort($Data);
//公共参数
$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;
//进行字典排序
ksort($Parameters);
//构造签名字符串,同时不转义url分隔符和中文
$SignContent=json_encode($Parameters,320);
//进行签名
$Parameters['signature']=$this->Sign($SignContent,$this->config['key']);
//请求
$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;
}
}
报关部分没写demo,不过也就写参数直接调用的事,报关的协调流程我自己第一次做,同样不怎么清楚