调用顺丰API实现电商专递下单和获取面单功能
参考文章:https://www.cnblogs.com/zhangxiaoyong/p/8317229.html
顺丰需求文档:
链接:https://pan.baidu.com/s/16EEaphJu2MI9gEvR30pDwQ
提取码:ogry
我用的web API实现功能的
电商专递下单功能
static string xmlstr = "<Request service='OrderService' lang='zh-CN'><Head>erptest</Head><Body><Order orderid='M689082997131401_14' platform_order_id='ML28082997131401' platform_code='JUNXIN' erp_code='0000' express_type='9' j_company='JIELISI' j_contact='JIELISI' j_tel='12344' j_mobile='1234' j_province='GUANGDONG' j_city='FOSHAN' j_address=' GUANGDONG ,CHIAN' d_company='Brazil' d_contact='Leonel' d_tel='12345678' d_mobile='12345678' d_province='Minas Gerais' d_city='Sao Geraldo ' d_address='hubei ' parcel_quantity='1' pay_method='1' declared_value='1.00' declared_value_currency='USD' j_country='CN' j_post_code='528000' d_country='BR' d_post_code='36530000' cargo_total_weight='0.030' operate_flag='1' isBat='1'><Cargo name='Rubber Chin Fixing Band' count='1' unit='PCE' weight='0.030' amount='1.00' cargo_desc='ST-T475-BL' currency='USD' cname='橡胶' hscode='3926909090'/></Order></Body></Request>"; /// <summary>
/// 下单操作方法webService
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static string GetWebService(OrderService model)
{
//得到下单XML请求体
var xml = xmlstr; //Getxml(model);
//生成密匙
//var pass = Convert.ToBase64String(MD5(xml+Checkword));
string verifyCode = digest(xml + Checkword);//这是进一步封装好的
//下单请求 http post模式
// var str = GethttpBack(Posturl, "xml=" + xml + "&verifyCode=" + pass);
//下单请求web service模式
var str1 = SfKtsServiceAsync(xml, verifyCode).Result;
return str1;
} /// <summary>
/// 文档加密verifyCode的生成
/// </summary>
/// <param name="toVerifyText"></param>
/// <returns></returns>
static string digest(string toVerifyText)
{
// verifyCode的生成规则为:先把xml与checkword前后连接。把连接后的字符串做MD5编码。
//把MD5编码后的数据进行Base64编码,此时编码后的字符串即为verifyCode。
// MD5
byte[] md5 = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(toVerifyText));
// Base64
string base64 = Convert.ToBase64String(md5);
return base64;
} /// <summary>
/// 调用顺丰接口
/// </summary>
/// <param name="xml"></param>
/// <param name="verifyCode"></param>
/// <returns></returns>
public static async Task<string> SfKtsServiceAsync(string xml, string verifyCode)
{
var client = new SfKtsServiceClient();
string result = await client.sfKtsServiceAsync(xml, verifyCode);
//从XML文件中反序列化为对象
SfOrderResponse sfresponse;
if (Convert.ToString(GetNodeValue(result, "Head")) == "ERR")
{
result = XElement.Parse(result).Value;
ERROrderResponse ErrResonpse = new ERROrderResponse() { code = GetXmlNodeValue(result, "ERROR", "code") };
}
else
{
sfresponse = new SfOrderResponse()
{
//获取xml中orderid、mailno、destcode等节点值
orderid = GetXmlNodeValue(result, "OrderResponse", "orderid"),
mailno = GetXmlNodeValue(result, "OrderResponse", "mailno"),
agent_mailno = GetXmlNodeValue(result, "OrderResponse", "agent_mailno"),
direction_code = GetXmlNodeValue(result, "OrderResponse", "direction_code")
};
UsersInfoDal dal = new UsersInfoDal(); //如果不需要插入到数据库中可以注释掉
await dal.Add(sfresponse);//插入到数据库中
//测试面单获取
//string Url = "http://oms.uat.trackmeeasy.com/ruserver/api/getLabelUrl.action?mailno=" + sfresponse.mailno + "&orderid=" + sfresponse.orderid+ "&onepdf=false&jianhuodan=false&username=test&signature=BaZxxmrv6hJMwIt26m0wuw%3D%3D";
//var s = SfExpress.GetUrltoHtml(Url, "UTF8");
}
return result;
}
需要定义一个返回结果类 SfOrderResponse
/// <summary>
/// 因为下单成功会返回订单号和运单号 以及筛单结果,所以我们先定义一个返回的响应报文模型容器
/// </summary>
public class SfOrderResponse
{
/// <summary>
/// 订单号
/// </summary>
public string orderid { get; set; } /// <summary>
/// 运单号
/// </summary> public string mailno { get; set; } /// <summary>
/// 筛单结果 1 人工确认 2 可收派 3 不可以收派
/// </summary>
// public string filter_result { get; set; }
/// <summary>
/// 流向代码
/// </summary>
public string direction_code { get; set; }
/// <summary>
/// 代理运单号(仅限10:挂号件才会有) 不是必填项
/// </summary>
public string agent_mailno { get; set; }
}
/// <summary>
/// 失败响应
/// </summary>
public class ERROrderResponse
{
/// <summary>
/// 错误代码
/// </summary>
public string code { get; set; }
}
面单获取
#region 面单获取HTTPwebRequest ML28082997131401_14 21190111_115140" mailno="SF6042002242203
//string Url = "http://oms.uat.trackmeeasy.com/ruserver/api/getLabelUrl.action";
// string Url = "http://oms.uat.trackmeeasy.com/ruserver/api/getLabelUrl.action?mailno=SF6042002242203&orderid=21190111_115140&onepdf=false&jianhuodan=false&username=test&signature=BaZxxmrv6hJMwIt26m0wuw%3D%3D";
/// <summary>
/// 根据URL地址获取网页信息
/// </summary>
/// <param name="Url">地址</param>
/// <param name="type">编码格式</param>
/// <returns></returns>
public static string GetUrltoHtml(string Url, string type)
{
string result = "";
try
{
//对统一资源标识符(URL)发出请求这是abstract
System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);
// 获取响应实例
System.Net.WebResponse wResp = wReq.GetResponse();
//提供字节序列的一般视图
System.IO.Stream respStream = wResp.GetResponseStream();
// Dim reader As StreamReader = New StreamReader(respStream)
using (System.IO.StreamReader reader = new System.IO.StreamReader(respStream))//, Encoding.GetEncoding(type
{
result=reader.ReadToEnd();//返回的是json格式的result
JsonTos(result);//把json格式转成实体模型
return result;
}
}
catch (System.Exception ex)
{
//errorMsg = ex.Message;
}
return result;
}
///<summary>
///采用https协议访问网络
///</summary>
///<param name="URL">url地址</param>
///<param name="strPostdata">发送的数据</param>
///<returns></returns>
public static string OpenReadWithHttps(string URL, string strPostdata, string strEncoding)
{
Encoding encoding = Encoding.Default;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "post";
request.Accept = "text/html, application/xhtml+xml, */*";
request.ContentType = "application/x-www-form-urlencoded";
byte[] buffer = encoding.GetBytes(strPostdata);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, , buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding(strEncoding)))
{
return reader.ReadToEnd();
}
}
/// <summary>
/// 把JSON格式的字符串转换成实体对象
/// </summary>
public static string JsonTos(string jsonText)
{
//JsonSerializer js = new JsonSerializer();
//JsonReader reader = new JsonTextReader(new StringReader(jsonText));
//while (reader.Read())
//{
// Console.WriteLine(reader.TokenType + "\t\t" + reader.ValueType + "\t\t" + reader.Value);
//}
jsonText = jsonText.Replace("[", "");
jsonText = jsonText.Replace("]", "");
JObject jo = (JObject)JsonConvert.DeserializeObject(jsonText);
string Success = jo["success"].ToString();
string Mailno = jo["array"]["mailno"].ToString();
string Orderid = jo["array"]["orderid"].ToString();
string Url = jo["url"].ToString();//PDF文件
string ConfigId = jo["array"]["configId"].ToString();
string Version = jo["version"].ToString();
//创建一个实体对象
//expressSheet es = new expressSheet()
//{
// mailno=Mailno,
// orderid= Orderid
//};
//保存文件到本地
GetFileFromNetUrl(Url);
return Url;
}
/// <summary>
/// 下载文件并保存文件到本地
/// </summary>
/// <param name="url"></param>
private static void GetFileFromNetUrl(string url)
{
try
{
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
req.Method = "GET";
//获得用户名密码的Base64编码 添加Authorization到HTTP头 不需要的账号密码的可以注释下面两行代码
//string code = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "userName", "passWord")));
// req.Headers.Add("Authorization", "Basic " + code);
byte[] fileBytes;
using (WebResponse webRes = req.GetResponse())
{
int length = (int)webRes.ContentLength;
HttpWebResponse response = webRes as HttpWebResponse;
Stream stream = response.GetResponseStream(); //读取到内存
MemoryStream stmMemory = new MemoryStream();
byte[] buffer = new byte[length];
int i;
//将字节逐个放入到Byte中
while ((i = stream.Read(buffer, , buffer.Length)) > )
{
stmMemory.Write(buffer, , i);
}
fileBytes = stmMemory.ToArray();//文件流Byte,需要文件流可直接return,不需要下面的保存代码
stmMemory.Close(); MemoryStream m = new MemoryStream(fileBytes);
string file = string.Format("F:\\666666666666.pdf");//可根据文件类型自定义后缀
FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
m.WriteTo(fs);
m.Close();
fs.Close();
}
}
catch (System.Exception ex)
{
throw ex;
}
}
#endregion
获取XML节点信息的方法
/// <summary>
/// 读取XML资源中的指定节点内容
/// </summary>
/// <param name="source">XML资源</param>
/// <param name="nodeName">节点名称</param>
/// <returns>节点内容</returns>
public static object GetNodeValue(string source, string nodeName)
{
if (source == null || nodeName == null || source == "" || nodeName == "" ||
source.Length < nodeName.Length * ) return null; var start = source.IndexOf("<" + nodeName + ">") + nodeName.Length + ;
var end = source.IndexOf("</" + nodeName + ">");
if (start == - || end == -)
return null;
if (start >= end)
return null;
return source.Substring(start, end - start);
}
/// <summary>
/// 获取xml任意节点中某个属性值
/// </summary>
/// <param name="strXml">xml</param>
/// <param name="strNodeName">节点名称</param>
/// <param name="strValueName">属性名称</param>
/// <returns></returns>
public static string GetXmlNodeValue(string strXml, string strNodeName, string strValueName)
{
try
{
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(strXml);
var xNode = xmlDoc.SelectSingleNode("//" + strNodeName + "");
var strValue = xNode.Attributes[strValueName].Value;
return strValue;
}
catch (Exception ex)
{
return ex.Message;
}
}
调用顺丰API实现电商专递下单和获取面单功能的更多相关文章
- EF+MySQL乐观锁控制电商并发下单扣减库存,在高并发下的问题
下订单减库存的方式 现在,连农村的大姐都会用手机上淘宝购物了,相信电商对大家已经非常熟悉了,如果熟悉电商开发的同学,就知道在买家下单购买商品的时候,是需要扣减库存的,当然有2种扣减库存的方式, 一种是 ...
- 电商 APP 下单页(俗称车2) 业务流程概要设计
购物车是电商APP的一个关键功能点,一般购物车包含 3-4 个页面,分别是: 1.购物车的商品列表页 2.商品下单页 3.订单付款页面 4.订单付款成功页面 由于现有购物车逻辑相对混乱,这里重新整理一 ...
- 双十一临近,怎样让买家流畅地秒杀? ——腾讯WeTest独家开放电商产品压测服务
WeTest 导读 十一月临近,一年一度的电商大戏"双十一"又将隆重出场,目前各大商家已经开始各类优惠券的发放,各类大促的商品表单也已经提前流出,即将流入各个用户的购物车中. 作为 ...
- Java电商支付系统实战(一)- 简介
现如今,支付成为热点 对于电商业务,这都是不可或缺的 核心功能剖析 下单->支付 nginx 将用户请求反向代理到我们编写的电商系统 = 下单 之后,点击支付跳转到支付系统,最后对接 通过跳转将 ...
- SpringCloud Alibaba实战(2:电商系统业务分析)
选用了很常见的电商业务来进行SpringCloud Alibaba的实战. 当然,因为仅仅是为了学习SpringCloud Alibaba,所以对业务进行了大幅度简化,这里只取一个精简版的用户下单业务 ...
- 电商平台如何接入快递鸟电子面单API?
快递鸟是全球物流接口服务商,为电商 ERP.电商平台.仓储.清关公司提供物流跟踪.电子面单.智选物流.物流金融.在线下单等服务,解决电商的物流管理模块和金融模块.现就对快递鸟电子面单API做基本描述, ...
- Java生鲜电商平台-统一格式返回的API架构设计与实战
Java生鲜电商平台-统一格式返回的API架构设计与实战 说明:随着互联网各岗位精细化分工的普及,出现了很多的系统架构设计,比如常见的前后端分离架构,后端提供接口给前端,前端根据接口的数据进行渲染,大 ...
- Java生鲜电商平台-API请求性能调优与性能监控
Java生鲜电商平台-API请求性能调优与性能监控 背景 在做性能分析时,API的执行时间是一个显著的指标,这里使用SpringBoot AOP的方式,通过对接口添加简单注解的方式来打印API的执行时 ...
- Java生鲜电商平台-API接口设计之token、timestamp、sign 具体架构与实现(APP/小程序,传输安全)
Java生鲜电商平台-API接口设计之token.timestamp.sign 具体设计与实现 说明:在实际的业务中,难免会跟第三方系统进行数据的交互与传递,那么如何保证数据在传输过程中的安全呢(防窃 ...
随机推荐
- Mac 中使用phpstorm 修改文件提示"only read",只读权限
在终端中执行命令: 给max系统用户liutao赋予整个项目文件权限,即可成功 sudo chown -R liutao /Users/liutao/Desktop/vagrant/newprojec ...
- java.lang.ClassNotFoundException:org.apache.struts2.dispatcher.FilterDispatcher
老版本的Struts2升级,启动报的错. org.apache.struts2.dispatcher.FilterDispatcher 是web.xml中对struts2 2.2版本的接入点的类. ...
- 如何交叉编译curl?
1. 先准备一下openssl库 编译openssl库的方法在此 2. 获取curl源码 wget https://curl.haxx.se/download/curl-7.65.3.tar.gz 2 ...
- mybatis 的 <![CDATA[ ]]> 标签作用
有个细节一直没有注意到,今天mark一下: mybatis进行时间比较的时候我们会这么写,一直都是在复制粘贴所以没有注意,一个标签<![CDATA[ ]]> 今天在做另外一个有时间比较sq ...
- Java同步数据结构之ConcurrentHashMap
前言 这是Java并发包最后一个集合框架的数据结构,其复杂程度也较以往任何数据结构复杂的多,顾名思义ConcurrentHashMap是线程安全版本的HashMap,总所周知HashMap是非线程安全 ...
- SQL-W3School-函数:SQL MAX() 函数
ylbtech-SQL-W3School-函数:SQL MAX() 函数 1.返回顶部 1. MAX() 函数 MAX 函数返回一列中的最大值.NULL 值不包括在计算中. SQL MAX() 语法 ...
- 算法习题---3.11换抵挡装置(UVa1588)
一:题目 给你连个长度分别为n1,n2且每列高度只为1或2的长条,然后将他们拼在一起,高度不能超过3,问他们拼在一起的最短长度 二:实现思路 1.获取主动轮和从动轮的数据. 2.主动轮不动,从动轮从左 ...
- confluent kafka connect remote debugging
1. Deep inside of kafka-connect start up To begin with, let's take a look at how kafka connect start ...
- delphi 根据特殊符号字符获取字符串前或后的字符
function GetBefore(substr, str:string):string; {©Drkb v.3(2007): www.drkb.ru, ®Vit (Vitaly Nevzorov) ...
- 取数据超过内存限制的问题-解决方案(sample,takeSample,filter)
遇到的问题 在处理数据过程中,遇到需要取(n)个数的问题,而当样本量过大的时候,就不能简单的take(n),这类问题一般有两种情况: > - 有序取 TopN > - 无序取 N 先来讨论 ...