调用顺丰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 具体设计与实现 说明:在实际的业务中,难免会跟第三方系统进行数据的交互与传递,那么如何保证数据在传输过程中的安全呢(防窃 ...
随机推荐
- python: 关于解决'\u'开头的字符串转中文的方法
爬虫爬到的内容是这样的: 如果直接打印出来是这样的: python3的解决办法:字符串.encode('utf-8').decode('unicode_escape') python2:字符串.dec ...
- uboot的仓库在哪里?
答: https://gitlab.denx.de/u-boot/u-boot# 1. 获取源码 git clone git@gitlab.denx.de:u-boot/u-boot.git Or g ...
- Angular 执行 css3 简单的动画
<div class="content"> 内容区域 <button (click)="showAside()">弹出侧边栏</b ...
- 几种主流浏览器内置http抓包工具软件使用方
对于学习网站的人或者相关编程人员,经常需要用到http抓包工具来跟踪网页,但主流抓包软件如httpwatch.httpanalyzerstdv都是收费的,破解版往往也不稳定.实际上现在很多浏览器都内置 ...
- Java 5-11新特性的整理(转)
Java 5-11新特性的整理(转) 作者:拔剑少年 简书地址:https://www.jianshu.com/u/dad4d9675892博客地址:https://it18monkey.github ...
- spark中的cache和persist的区别
在使用中一直知其然不知其所以然的地使用RDD.cache(),系统的学习之后发现还有一个与cache功能类似看起来冗余的persist 点进去一探究竟之后发现cache()是persist()的特例, ...
- JEECG新建用户不用系统用户表的实现
首先新增组织机构 和 角色: -- 新增 组织机构 INSERT INTO `t_s_depart` VALUES ('dept001', '你所在的机构', '你所在的机构的描述', null, ' ...
- 【ARTS】01_35_左耳听风-201900708~201900714
ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...
- iOS-登录加密也许用到,反转字符串
- (NSString *)stringByReversed{// NSMutableString *s = [NSMutableString string];// for (NSUInt ...
- 2019年11月27日 Linux所学知识 总结
查看网络信息和网络状态 nmcli connection show 使用con-name参数指定公司使用的网络会话名称company,然后依次用ifname参数指定本机的网卡名称. 用autoconn ...