中国海关CEB311电子订单XML报文
第一步:办理 IC卡,法人卡,读卡器,UKEY
黄色的是法人卡,蓝色的是IC卡,U盘是UKEY 黑色的是读卡器也称为ukey
第二步:填写申请表,发邮件
发送到邮箱:services@gzeport.com
第三步:开发联调报文,截图,填表,发邮件
发送到邮箱:services@gzeport.com
安装UKEY,用于获取加签:
要先安装JAVA环境,具体请百度,然后去海关群里的群文件去下载ukey驱动程序包,然后在群文件中也有说明,请按流程说明走即可
ukey除了是加签的功能,还有一个就是会在D盘生成一个GZEportExchange文件夹,将xml放进去,可以随时检测上传到海关的后台,然后还需要人工进入http://www.singlewindow.gz.cn/后台对这个订单点击提交,也是有一层人工审核的保障
另外广州海关那边咨询后得知:电商只需要推CEB311订单,不需要加签,只有清单才需要加签,也没有撤消订单可以推,暂时广州海关是不支持的,退货的广州海关也没有,所以对接海关的技术们,只需要拼一个CEB311的xml报文就可以了
报文校验网址:http://www.singlewindow.gz.cn/testcbes/gzValidateXml.jsp
PHP Code复制内容到剪贴板
- {
- "func":"ChineseCustomsDeclaration",
- "batchNumbers":"商品批次号选填",
- "buyerRegNo":"11",
- "items":[{"itemUnitName":"瓶","skuId":"3207","skuBarcode":"1951480546","skuPrice":"102.29","madeIn":"中国","itemFullName":"390粒胶原蛋白片含18种氨基酸美容护肤Youtheory Collagen","salePrice":"150.00","itemDescribe":"我是商品的详细描述信息","qty":"5"}],
- "freight":"64.00",
- "taxTotal":"52.62",
- "buyerName":"周京",
- "buyerMobile":"15011111111",
- "buyerIdNumber":"510701198107078395",
- "buyerAddress":"汉中路27号友谊广场20楼",
- "buyerCityName":"常州市",
- "orderNo":"TB123456",
- "goodsValue":"300",
- "acturalPaid":"300"
- }
PHP Code复制内容到剪贴板
- //==================================================================
- //功能: 中国海关申报生成XML报文 CEB311
- //输入参数: (必选)
- //==================================================================
- /*
- //必填项
- batchNumbers //商品批次号(选填)
- buyerRegNo //订购人的交易平台注册号(选填)
- buyerName //订购人的真实姓名,必须与电子运单的收货人姓名一致
- buyerMobile //订购人手机号,必须与电子运单的收货人电话一致
- buyerIdNumber //订购人身份证号
- buyerCityName //订购人城市名称
- buyerAddress //订购人详细地址,必须与电子运单的收货地址一致
- orderNo //交易平台的订单编号(订单编号应唯一(长度不能超过60))
- goodsValue //商品实际成交价,含非现金抵扣金额
- acturalPaid //商品价格+运杂费+代扣税款-非现金抵扣金额,必须与支付凭证的支付金额一致
- items //商品信息列表(数组)
- */
- function ChineseCustomsDeclaration($post){
- //转换参数形式
- foreach ($post as $kp=>$p) {
- $$kp = $p;
- };
- $guid = $this->getGuidOnlyValue();
- $guid1 = $this->GetRandStr(3).$guid;
- $guid2 = $this->GetRandStr(3).$guid;
- //011g02支付宝 011g01财富通 011g03银联
- $customsConfig = [
- 'customsCode' => '1105910159',
- 'customsName' => '东方物通科技(北京)有限公司'
- ];
- $addTime = date("YmdHis");
- $OrderList = [];
- $i = 0;
- foreach($items as $k1 => $v1){
- $i++;
- //查询海关的国别代码
- $res1 = $this->empire->fetch1("select outside_code from `outside_code_map` where type=1 and source_type=1 and del_flag=0 and name='$v1[madeIn]' ");
- $countryCode = $res1['outside_code'];
- //查询海关的计量代码
- $res2 = $this->empire->fetch1("select outside_code from `outside_code_map` where type=3 and source_type=1 and del_flag=0 and name='$v1[itemUnitName]' ");
- $unitCode = $res2['outside_code'];
- $OrderList[]['ceb:OrderList'] = [
- "ceb:gnum" => $i,
- "ceb:itemNo" => $v1['skuId'], //企业商品货号,电商企业自定义的商品货号(SKU)(可为空)
- "ceb:itemName" => $v1['itemFullName'], //交易平台销售商品的中文名称
- "ceb:itemDescribe" => $v1['itemDescribe'], //交易平台销售商品的描述信息(可为空)
- "ceb:barCode" => $v1['skuBarcode'], //国际通用的商品条形码(可为空)
- "ceb:unit" => $unitCode, //计量单位,填写海关标准的参数代码
- "ceb:qty" => $v1['qty'], //商品实际数量
- "ceb:price" => $v1['salePrice'],
- "ceb:totalPrice" => $v1['salePrice'] * $v1['qty'],
- "ceb:currency" => "142",
- "ceb:country" => $countryCode,
- "ceb:note" => ''
- ];
- }
- //查询海关的城市代码
- $res = $this->empire->fetch1("select province_index from `outside_district_zipcode` where del_flag=0 and city='$buyerCityName' ");
- $buyerCityId = $res['province_index'];
- $order = [
- 'ceb:OrderHead'=>[
- 'ceb:guid' => $guid2,
- 'ceb:appType' => '1', //企业报送类型。1-新增 2-变更 3-删除。默认为1
- 'ceb:appTime' => $addTime, //企业报送时间
- 'ceb:appStatus' => '2', //业务状态:1-暂存,2-申报,默认为1。填写2时,Signature节点必须填写
- 'ceb:orderType' => 'I', //电子订单类型:I进口
- 'ceb:orderNo' => $orderNo, //交易平台的订单编号,同一交易平台的订单编号应唯一。长度不能超过60
- 'ceb:ebpCode' => $customsConfig['customsCode'], //电商平台的海关注册登记编号
- 'ceb:ebpName' => $customsConfig['customsName'],
- 'ceb:ebcCode' => $customsConfig['customsCode'],
- 'ceb:ebcName' => $customsConfig['customsName'],
- 'ceb:goodsValue' => $goodsValue, //商品实际成交价,含非现金抵扣金额
- 'ceb:freight' => $freight, //不包含在商品价格中的运杂费,无则填写"0"。
- 'ceb:discount' => '0', //使用积分、虚拟货币、代金券等非现金支付金额,无则填写"0"
- 'ceb:taxTotal' => $taxTotal, //企业预先代扣的税款金额,无则填写“0”
- 'ceb:acturalPaid' => $acturalPaid, //商品价格+运杂费+代扣税款-非现金抵扣金额,与支付凭证的支付金额一致。
- 'ceb:currency' => '142', //限定为人民币,填写“142”
- 'ceb:buyerRegNo' => $buyerRegNo, //订购人的交易平台注册号(可以传自家平台的ID,也可以随便传,不校验)
- 'ceb:buyerName' => $buyerName, //订购人的真实姓名
- 'ceb:buyerIdType' => '1', //订购人证件类型,1-身份证,2-其它。限定为身份证,填写“1”
- 'ceb:buyerIdNumber' => $buyerIdNumber, //订购人身份证号
- 'ceb:payCode' => '', //支付企业代码 支付企业需在JC2006注册备案
- 'ceb:payName' => '', //支付企业名称
- 'ceb:payTransactionId' => '', //支付交易流水号
- 'ceb:batchNumbers' => $batchNumbers, //商品批次号(选填)
- 'ceb:consignee' => $buyerName, //收货人姓名,必须与电子运单的收货人姓名一致。(收货人同订购人信息一致)
- 'ceb:consigneeTelephone'=> $buyerMobile, //收货人联系电话,必须与电子运单的收货人电话一致。
- 'ceb:consigneeAddress' => $buyerAddress, //收货地址,必须与电子运单的收货地址一致。
- 'ceb:consigneeDistrict' => $buyerCityId, //收货地址行政区划代码,参照国家统计局公布的国家行政区划标准填制。
- 'ceb:note' => 'test',
- ]
- ];
- $order = array_merge($order,$OrderList);
- $res = [];
- $res['ceb:CEB311Message'] = [
- 'guid' => $guid1,
- 'version' => '1.0',
- 'xmlns:ceb' => 'http://www.chinaport.gov.cn/ceb',
- 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
- 'ceb:Order' => $order,
- 'ceb:BaseTransfer' => [
- 'ceb:copCode' => $customsConfig['customsCode'],
- 'ceb:copName' => $customsConfig['customsName'],
- 'ceb:dxpMode' => 'DXP',
- 'ceb:dxpId' => 'DXPENTTEST510001',
- 'ceb:note' => 'test'
- ]
- ];
- $xml = new ArrayToXML;
- $res = $xml->toXml($res);
- // return Message(400,'error','调试断点11',$res);
- $xmlName = $this->GetRandStr(5).'.xml';
- $filePath = ECMS_PATH.'/d/file/uploads/'.date("Ymd").'/';
- $finalFileName = $filePath.'haimilt_CEB311_'.date('YmdHis').'_'.$xmlName; //这个是根目录下的runtime文件夹
- $filePath = '/d/file/uploads/'.date("Ymd").'/haimilt_CEB311_'.date('YmdHis').'_'.$xmlName; //返回的文件路径
- $xml->saveFile($finalFileName,$res);
- // exit;
- return Message(200,'success','',$filePath);
- }
- //海关生成唯一guid值
- function getGuidOnlyValue(){
- $a4 = uniqid().rand(10,99);
- $a4 = $this->insertToStr($a4,4,'-'); //这里是后面两组的唯一值 如5770-A529AD987M
- $a4 = $a4.$this->GetRandStr(1);
- $a1 = $this->GetRandStr(5);
- $a2 = $this->GetRandStr(4);
- $a3 = $this->GetRandStr(4);
- $val = $a1.'-'.$a2.'-'.$a3.'-'.$a4;
- return strtoupper($val);
- }
- /**
- * 指定位置插入字符串
- * @param $str 原字符串
- * @param $i 插入位置
- * @param $substr 插入字符串
- * @return string 处理后的字符串
- */
- function insertToStr($str, $i, $substr){
- $startstr="";
- for($j=0; $j<$i; $j++){
- $startstr .= $str[$j];
- }
- //指定插入位置后的字符串
- $laststr="";
- for ($j=$i; $j<strlen($str); $j++){
- $laststr .= $str[$j];
- }
- //将插入位置前,要插入的,插入位置后三个字符串拼接起来
- $str = $startstr . $substr . $laststr;
- //返回结果
- return $str;
- }
- /**
- * 获得指定位数随机数
- * @param $length 指定位数
- * @return string 处理后的字符串
- */
- function GetRandStr($length){
- $str='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- $len=strlen($str)-1;
- $randstr='';
- for($i=0;$i<$length;$i++){
- $num=mt_rand(0,$len);
- $randstr .= $str[$num];
- }
- return $randstr;
- }
- //获取地区的国家
- function getChineseCustomsCountry($post){
- global $dbtbpre;
- $country = [];
- //查询多条数据
- $sql = $this->empire->query("select area_name,area_id from `outside_area` where area_type = 'country' and del_flag = 0 group by area_name order by area_id asc");
- while($res = $this->empire->fetch($sql)){
- $country[] = [
- 'countryName' => $res['area_name'],
- 'provinceId' => $res['area_id']
- ];
- }
- return Message(200,'success','',$country);
- }
- //获取地区的省份
- function getChineseCustomsProvince($post){
- global $dbtbpre;
- $province = [];
- //查询多条数据
- $sql = $this->empire->query("select area_name,area_id from `outside_area` where area_type = 'province' and del_flag = 0 group by area_name order by area_id asc");
- while($res = $this->empire->fetch($sql)){
- $province[] = [
- 'provinceName' => $res['area_name'],
- 'provinceId' => $res['area_id']
- ];
- }
- return Message(200,'success','',$province);
- }
- //获取地区的城市
- function getChineseCustomsCity($post){
- global $dbtbpre;
- //转换参数形式
- foreach ($post as $kp=>$p) {
- $$kp = $p;
- };
- $city = [];
- if($provinceId){
- $sql = $this->empire->query("select area_name,area_id from `outside_area` where area_type = 'city' and del_flag = 0 and parent_area_id = '$provinceId' group by area_name order by area_id desc");
- }else{
- //查询多条数据
- $sql = $this->empire->query("select area_name,area_id from `outside_area` where area_type = 'city' and del_flag = 0 and parent_area_id = '110000' group by area_name order by area_id desc");
- }
- while($res = $this->empire->fetch($sql)){
- $city[] = [
- 'cityName' => $res['area_name'],
- 'cityId' => $res['area_id']
- ];
- }
- return Message(200,'success','',$city);
- }
- function getChineseCustomsItemUnitName(){
- global $dbtbpre;
- $itemUnitName = [];
- //查询多条数据
- $sql = $this->empire->query("select outside_code,name from `outside_code_map` where type=3 and source_type=1 and del_flag=0");
- while($res = $this->empire->fetch($sql)){
- $itemUnitName[] = [
- 'itemUnitName' => $res['name'],
- 'itemUnitCode' => $res['outside_code']
- ];
- }
- return Message(200,'success','',$itemUnitName);
- }
海关申报的时候,需要拼接XML文件,将数组转为XML,单独写的一段转换:
XML报文:
XML/HTML Code复制内容到剪贴板
- <?xml version="1.0" encoding="UTF-8" ?>
- - <ceb:CEB311Message guid="556E1CFD-EDED-46B1-946C-B8022E42FC94" version="1.0" xmlns:ceb="http://www.chinaport.gov.cn/ceb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- - <ceb:Order>
- - <ceb:OrderHead>
- <ceb:guid>4CDE1CFD-EDED-46B1-946C-B8022E42FC94</ceb:guid>
- <ceb:appType>1</ceb:appType>
- <ceb:appTime>20160308112701</ceb:appTime>
- <ceb:appStatus>2</ceb:appStatus>
- <ceb:orderType>I</ceb:orderType>
- <ceb:orderNo>order20160321116421002</ceb:orderNo>
- <ceb:ebpCode>1105910159</ceb:ebpCode>
- <ceb:ebpName>东方物通科技(北京)有限公司</ceb:ebpName>
- <ceb:ebcCode>1105910159</ceb:ebcCode>
- <ceb:ebcName>东方物通科技(北京)有限公司</ceb:ebcName>
- <ceb:goodsValue>14000</ceb:goodsValue>
- <ceb:freight>5000</ceb:freight>
- <ceb:discount>0</ceb:discount>
- <ceb:taxTotal>50</ceb:taxTotal>
- <ceb:acturalPaid>19050</ceb:acturalPaid>
- <ceb:currency>142</ceb:currency>
- <ceb:buyerRegNo>ID20160001</ceb:buyerRegNo>
- <ceb:buyerName>aa</ceb:buyerName>
- <ceb:buyerIdType>1</ceb:buyerIdType>
- <ceb:buyerIdNumber>130681136250023332</ceb:buyerIdNumber>
- <ceb:payCode>1105910159</ceb:payCode>
- <ceb:payName>东方物通科技(北京)有限公司</ceb:payName>
- <ceb:payTransactionId>20160001634226001</ceb:payTransactionId>
- <ceb:batchNumbers>20160317</ceb:batchNumbers>
- <ceb:consignee>焦洪宇</ceb:consignee>
- <ceb:consigneeTelephone>13522652231</ceb:consigneeTelephone>
- <ceb:consigneeAddress>北京市海淀区</ceb:consigneeAddress>
- <ceb:consigneeDistrict>072750</ceb:consigneeDistrict>
- <ceb:note>test</ceb:note>
- </ceb:OrderHead>
- - <ceb:OrderList>
- <ceb:gnum>1</ceb:gnum>
- <ceb:itemNo>AF001-001</ceb:itemNo>
- <ceb:itemName>b</ceb:itemName>
- <ceb:itemDescribe>v</ceb:itemDescribe>
- <ceb:barCode>2345123</ceb:barCode>
- <ceb:unit>007</ceb:unit>
- <ceb:qty>100</ceb:qty>
- <ceb:price>20</ceb:price>
- <ceb:totalPrice>2000</ceb:totalPrice>
- <ceb:currency>142</ceb:currency>
- <ceb:country>116</ceb:country>
- <ceb:note />
- </ceb:OrderList>
- - <ceb:OrderList>
- <ceb:gnum>2</ceb:gnum>
- <ceb:itemNo>AF001-002</ceb:itemNo>
- <ceb:itemName>v</ceb:itemName>
- <ceb:itemDescribe>v</ceb:itemDescribe>
- <ceb:barCode>2345123</ceb:barCode>
- <ceb:unit>007</ceb:unit>
- <ceb:qty>200</ceb:qty>
- <ceb:price>10</ceb:price>
- <ceb:totalPrice>12000</ceb:totalPrice>
- <ceb:currency>142</ceb:currency>
- <ceb:country>116</ceb:country>
- <ceb:note />
- </ceb:OrderList>
- </ceb:Order>
- - <ceb:BaseTransfer>
- <ceb:copCode>1101180326</ceb:copCode>
- <ceb:copName>物流企业</ceb:copName>
- <ceb:dxpMode>DXP</ceb:dxpMode>
- <ceb:dxpId>EXP2016522002580001</ceb:dxpId>
- <ceb:note>test</ceb:note>
- </ceb:BaseTransfer>
- </ceb:CEB311Message>
PHP类转换:
PHP Code复制内容到剪贴板
- <?php
- header("Content-type: application/xml");
- class ArrayToXML
- {
- function arrForeach($arr) {
- if (!is_array ($arr)) {
- return false;
- }
- $xml='';
- foreach($arr as $key => $value){
- $xml .= is_numeric($key)?"":"<{$key}>";
- $xml .= is_array($value)? self::arrForeach($value):$value;
- $xml .= is_numeric($key)?"":"</{$key}>\n";
- }
- return $xml;
- }
- function toXml($post){
- foreach ($post as $key => $value) {
- $attribute = '';
- $str = '';
- foreach ($value as $k1 => $v1) {
- if(is_array($v1)){ //如果含有数组
- $str .= is_numeric($k1)?"":"<{$k1}>";
- $str .= $this->arrForeach($v1);
- $str .= is_numeric($k1)?"":"</{$k1}>";
- }else{
- $attribute .= $k1.'="'.$v1.'" ';
- }
- }
- $strHead = '<?xml version="1.0" encoding="UTF-8"?>';
- $strHead .= '<'.$key.' '.$attribute.'>'; //key为第一行标签名称 + 第一行的属性
- $strFot .= '</'.$key.'>';
- }
- $string = $strHead.$str.$strFot;
- return $string;
- }
- function to_xml2(SimpleXMLElement $object, array $data, $level)
- {
- foreach ($data as $key => $value) {
- if (is_array($value)) {
- if (is_numeric($key)) { //是数字用上级$object做父元素
- $tnum = $level + 1;
- $this->to_xml2($object, $value, $tnum);
- } else { //不是数字直接创建元素$new_object做父元素
- $new_object = $object->addChild($key);
- $newLevel = $level + 1;
- $this->to_xml2($new_object, $value, $newLevel);
- }
- } else {
- if ($level == 1) { //第一层级
- $object->addAttribute($key, $value);
- } else {
- $object->addChild($key, $value);
- }
- }
- }
- }
- /**
- * 保存文件
- *
- * @param string $fileName 文件名(含相对路径)
- * @param string $text 文件内容
- * @return boolean
- */
- function saveFile($fileName, $text) {
- if (!$fileName || !$text)
- return '失败1';
- if(!file_exists(dirname($fileName)))
- {
- mkdir(dirname($fileName));
- }
- if ($fp = fopen($fileName, "w")) {
- if (@fwrite($fp, $text)) {
- fclose($fp);
- return '成功';
- } else {
- fclose($fp);
- return '失败2';
- }
- }
- return '失败';
- }
- }
订单,不用加签,清单需要ukey加签,另外撤消订单的功能,目前广州海关还没有开放,退货接口的目前也没开放,虽然有XML报文格式,客服那边回复说暂时广州海关是还没有开通的
该接口,仅针对广州海关