海关179号通知对接C#完整源码

电子口岸抓取实时始数据流程

流程一:

  1. 电子口岸调用电商企业接口,通知其上传实时数据,接口参数含有订单ID和SessionID
  2. 电商企业响应请求,返回码为1000,告知电子口岸可以上传数据

流程二:

  1. 电商企业根据流程一的订单ID和SessionID生成上报数据
  2. 将数据通过websocket发送给ukey服务器,ukey服务器返回签名
  3. 将数据和签名url编码
  4. 上传给电子口岸

参考1

参考2

C#源码

namespace Admin.Controllers
{
    public class PushController : Controller
    {
        /// <summary>
        /// 等待海关请求的接口
        /// </summary>
        [HttpPost]
        public JsonResult OpenRealTimeUpload(string openReq)
        {
            openReq = HttpUtility.UrlDecode(openReq, Encoding.UTF8);
            var reqModel = JsonConvert.DeserializeObject<ServiceStack.Text.JsonObject>(openReq);
            var pushPayInfoRecord = new
            {
                orderNo = reqModel.GetValueOrDefault("orderNo"),
                sessionID = reqModel.GetValueOrDefault("sessionID"),
                serviceTime = reqModel.GetValueOrDefault("serviceTime"),
            };

            GetPayInfo(pushPayInfoRecord);

            return new JsonResult()
            {
                Data = new
                {
                    code = 10000,
                    message = "",
                    serviceTime = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds
                },
            };
        }

        /// <summary>
        /// 组装需要上传的数据
        /// </summary>
        private PushPayInfoModel GetPayInfo(PushPayInfoRecord pushPayInfoRecord)
        {
            
            var pushPayInfoModel = new PushPayInfoModel();
            pushPayInfoModel.sessionID = pushPayInfoRecord.sessionID;
            pushPayInfoModel.serviceTime = ((long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds).ToString();
            pushPayInfoModel.certNo = pushSetting.certNo;

            var payExchangeInfoHead = new PayExchangeInfoHead();
            payExchangeInfoHead.guid = Guid.NewGuid().ToString();
            payExchangeInfoHead.initalRequest = "test";
            payExchangeInfoHead.initalResponse = "test";
            payExchangeInfoHead.ebpCode = pushSetting.ebpCode;
            payExchangeInfoHead.payCode = pushSetting.payCode;
            payExchangeInfoHead.payTransactionId = "test";
            payExchangeInfoHead.totalAmount = 1.0;
            payExchangeInfoHead.currency = "142";
            payExchangeInfoHead.verDept = pushSetting.verDept;
            payExchangeInfoHead.payType = "3";
            payExchangeInfoHead.tradingTime = DateTime.Now.ToString("yyyyMMddHHmmss");
            payExchangeInfoHead.note = "test";
            pushPayInfoModel.payExchangeInfoHead = payExchangeInfoHead;

            var payExchangeInfoList = new List<PayExchangeInfoList>();
            var orderItems = _orderService.GetOrderItemsByOrderId(long.Parse(pushPayInfoRecord.orderNo));
            payExchangeInfoList.Add(new PayExchangeInfoList
            {
                orderNo = pushPayInfoRecord.orderNo,
                recpAccount = pushSetting.recpAccount,
                recpCode = pushSetting.recpCode,
                recpName = pushSetting.recpName,
                goodsInfo = orderItems.Select(item => new GoodsInfo
                {
                    gname = item.ProductName,
                    itemLink = item.Link
                }).ToList()
            });
            pushPayInfoModel.payExchangeInfoLists = payExchangeInfoList;

            SignAndUpload(pushPayInfoModel, pushPayInfoRecord);
            return pushPayInfoModel;
        }

        /// <summary>
        /// 签名
        /// </summary>
        private void SignAndUpload(PushPayInfoModel pushPayInfoModel, PushPayInfoRecord pushPayInfoRecord)
        {
            string pushPayInfoStr = JsonConvert.SerializeObject(pushPayInfoModel);
            // 移除第一个{号
            pushPayInfoStr = pushPayInfoStr.Remove(0, 1);
            // 移除签名节点
            pushPayInfoStr = Regex.Replace(pushPayInfoStr, @",""certNo.+$", "");
            // 插入||分隔符
            pushPayInfoStr = Regex.Replace(pushPayInfoStr, @",(""payExchangeInfoHead"":)", "||$1\"");
            pushPayInfoStr = Regex.Replace(pushPayInfoStr, @",(""payExchangeInfoLists"":)", "\"||$1\"");
            pushPayInfoStr = Regex.Replace(pushPayInfoStr, @",(""serviceTime"":)", "\"||$1");

            var websocket = new WebSocket("ws://127.0.0.1:61232");
            websocket.Error += new EventHandler<SuperSocket.ClientEngine.ErrorEventArgs>((sender, e) =>
            {
                websocket.Close();
                pushPayInfoRecord.signError = e.Exception.Message.Trim();
            });
            websocket.MessageReceived += new EventHandler<MessageReceivedEventArgs>((sender, e) =>
            {
                var message = e.Message.Trim();
                var errorMessage = Regex.Match(message, @"Error"":\[(\S+)\]").Groups[1].Value;
                if (message.Contains("握手成功"))
                {
                    string strSendData = "{\"_method\":\"cus-sec_SpcSignDataAsPEM\",\"_id\":1,\"args\":{\"inData\":\"" + pushPayInfoStr.Replace("\"", "\\\"") + "\",\"passwd\":\"12345678\"}}";
                    websocket.Send(strSendData);
                }
                else if (errorMessage.Length > 0)
                {
                    // 加签错误
                    websocket.Close();
                    pushPayInfoRecord.signError = errorMessage;
                }
                else
                {
                    // 加签正确
                    websocket.Close();
                    pushPayInfoModel.signValue = Regex.Match(message, @"Data"":\[""(\S+?)""").Groups[1].Value;
                    UploadRealTimeData(pushPayInfoModel, pushPayInfoRecord);
                }
            });
            websocket.Open();
        }

        /// <summary>
        /// 上传实时数据
        /// </summary>
        public void UploadRealTimeData(PushPayInfoModel pushPayInfoModel, PushPayInfoRecord pushPayInfoRecord)
        {
            var dataJson = JsonConvert.SerializeObject(pushPayInfoModel);
            var dataInfo = HttpUtility.UrlEncode(dataJson, Encoding.UTF8);
            // 需要使用payExInfoStr=UrlEncodeDate的键值组成报文内容
            var content = new StringContent("payExInfoStr=" + dataInfo, Encoding.UTF8, "application/x-www-form-urlencoded");
            
            var client = new HttpClient();
            var url = "https://customs.chinaport.gov.cn/ceb2grab/grab/realTimeDataUpload";
            var response = client.PostAsync(url, content).GetAwaiter().GetResult();

            pushPayInfoRecord.uploadRealTimeData = dataJson;
            pushPayInfoRecord.uploadResponse = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            pushPayInfoRecord.uploadTime = DateTime.Now;
        }
    }
}
posted @ 2021-01-01 10:10  woncode  阅读(1099)  评论(0编辑  收藏  举报