一. 创建应用(我这里创建了 商家后台应用)
https://open.pinduoduo.com/#/application/type
二.授权登录
1.拼接拼多多授权登录Url
https://mms.pinduoduo.com/open.html?response_type=code&client_id={0}&redirect_uri={1}&state=1212
注意这里的client_id 需要改成你当前应用的client_id ,
redirect_uri 需要修改成登录成功之后跳转的地址 这里的redirect_uri地址需要和你在应用设置里面填入的回调地址一致
如下图所示:
商家账号登录成功之后跳转到回调地址,在地址后面返回 code 和 state。
通过code 可以请求获取到 Token ,state则是验证与之前传入的state 是否相同
2.通过 Code 请求Token
/// <summary>
/// 拼多多Token刷新方法
/// </summary>
/// <param name="code"></param>
public void ResreshAccessByPDD(string code)
{
dynamic parameter = new
{
client_id = "应用client_id",
code = code,
grant_type = "authorization_code",
client_secret = "应用client_secret "
};
string json = Newtonsoft.Json.JsonConvert.SerializeObject(parameter);
string url = "http://open-api.pinduoduo.com/oauth/token";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json";
using (Stream s = request.GetRequestStream())
{
byte[] bytes = Encoding.UTF8.GetBytes(json);
s.Write(bytes, 0, bytes.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream s = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string data = sr.ReadToEnd();
}
}
}
二、通过 获取到的Token 获取 订单信息
#region PDD解决方案
private string pdd_url = "https://gw-api.pinduoduo.com/api/router";
private string pdd_client_id = "pdd_client_id";
private string pdd_client_secret = "pdd_client_secret";
/// <summary>
/// 拼多多根据时间获取订单
/// <remarks>
/// 拼多多接口查询时间间隔不支持大于24小时
/// 即:根据时间查询时需要根据时间翻页
/// 查询每页返回条数最高100条
/// 即:当前时间内查询的条数大于100条时,
/// 需要根据条数翻页。
/// </remarks>
/// </summary>
/// <param name="openid"></param>
/// <param name="access_token"></param>
/// <param name="StartTime"></param>
/// <param name="EndTime"></param>
/// <param name="status"></param>
/// <param name="action"></param>
/// <param name="Page"></param>
public void GetPinduoduoOrders(string openid, string access_token, string StartTime, string EndTime, string status, Action<Boolean, Object, Int32, Int32> action, int Page = 1)
{
try
{
status = PDDStatus.Where(w => w.Value.Equals(status)).FirstOrDefault().Key;
//查询开始时间与截止时间的间隔天数;
var SDate = Convert.ToDateTime(StartTime);
var EDate = Convert.ToDateTime(EndTime);
var ts = (EDate - SDate);
var Days = ts.Days + (ts.Hours > 0 ? 1 : 0);
for (int i = 1; i <= Days; i++)
{
string url = ChangedParameter(access_token, SDate.AddDays(i - 1), SDate.AddDays(i), status, 1);
RequestByPDD(url, openid, access_token, SDate, SDate.AddDays(i), status, action, Page);
}
}
catch (Exception ex)
{
action(false, ex.Message, 0, 0);
}
}
/// <summary>
/// 根据id 查询 拼多多订单
/// </summary>
public void GetPinduoduoOrderByID(string openid, string id, string access_token, Action<bool, object> action)
{
var parameter = GetParameterByPDD("pdd.order.information.get");
parameter.Add("access_token", access_token);
parameter.Add("order_sn", id);//订单ID;
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(url);
Request.Method = "POST";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
using (Stream s = Response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string json = sr.ReadToEnd();
Newtonsoft.Json.Linq.JObject job = JObject.Parse(json);
if (job.Property("error_response") == null)
{
trade t = SerializeData(job["order_info_get_response"]["order_info"]);
t.seller_openid = openid;
t.receiver_country = "CN";
action(true, t);
}
else
{
action(false, job["error_response"].Value<string>("error_msg"));
}
}
}
}
/// <summary>
/// 拼多多在线发货
/// </summary>
public string PDDOnLineSendOrders(string billNo, string Token, string billID, string logistics_id, string tracking_number)
{
try
{
var parameter = GetParameterByPDD("pdd.logistics.online.send");
parameter.Add("access_token", Token);
parameter.Add("order_sn", billID);
parameter.Add("logistics_id", logistics_id);
parameter.Add("tracking_number", tracking_number);
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
HttpWebResponse Response = (HttpWebResponse)request.GetResponse();
using (Stream s = Response.GetResponseStream())
{
StreamReader sr = new StreamReader(s);
string json = sr.ReadToEnd();
JObject job = JObject.Parse(json);
if (job.Property("error_response") == null)
{
if (job["logistics_online_send_response"].Value<bool>("is_success"))
{
return "回传成功";
}
else
{
return "回传失败";
}
}
else
{
return job["error_response"].Value<string>("error_msg");
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}
//查询拼多多支持物流公司列表
public List<logistics_company> GetPDDLogisticsCompany()
{
try
{
var parameter = GetParameterByPDD("pdd.logistics.companies.get");
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream s = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string json = sr.ReadToEnd();
JObject job = JObject.Parse(json);
if (job.Property("error_response") == null)
{
List<logistics_company> dl = new List<logistics_company>();
foreach (var item in job["logistics_companies_get_response"]["logistics_companies"])
{
if (item.Value<int>("available").Equals(1))
dl.Add(new logistics_company
{
id = item.Value<int>("id"),
code = item.Value<string>("code"),
Identifier = item.Value<int>("id").ToString(),
name = item.Value<string>("logistics_company")
});
}
return dl;
}
}
}
return null;
}
catch
{
return null;
}
}
//根据物流公司Code查询所支持模板
public List<dynamic> GetStdtemplatesByPDD(string code)
{
var parameter = GetParameterByPDD("pdd.cloudprint.stdtemplates.get");
parameter.Add("wp_code", code);
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream s = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string data = sr.ReadToEnd();
Newtonsoft.Json.Linq.JObject job = JObject.Parse(data);
var templates = job["pdd_cloudprint_stdtemplates_get_response"]["result"]["datas"][0]["standard_templates"];
List<dynamic> list = new List<dynamic>();
foreach (var item in templates)
{
list.Add(new
{
cp_code = code,
standard_template_id = item["standard_waybill_type"].Value<string>(),
standard_template_name = item["standard_template_name"].Value<string>(),
standard_template_url = item["standard_template_url"].Value<string>()
});
}
return list;
}
}
}
//根据物流公司Code查询已开通物流公司网点和可用单号数量
public List<branchAddress> PDDGetWaybillByLogistics(string code, string token)
{
try
{
List<branchAddress> list = new List<branchAddress>();
var parameter = GetParameterByPDD("pdd.waybill.search");
parameter.Add("wp_code", code);
parameter.Add("access_token", token);
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream s = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string json = sr.ReadToEnd();
var data = Newtonsoft.Json.Linq.JObject.Parse(json);
branchAddress address;
var waybill_address = data["pdd_waybill_search_response"]["waybill_apply_subscription_cols"][0]["branch_account_cols"];
foreach (var item in waybill_address)
{
address = new branchAddress();
address.branch_code = item.Value<string>("branch_code");
address.quantity = item.Value<Int32>("quantity");
address.province = item["shipp_address_cols"][0].Value<string>("province");
address.city = item["shipp_address_cols"][0].Value<string>("city");
address.area = item["shipp_address_cols"][0].Value<string>("district");
address.address_detail = item["shipp_address_cols"][0].Value<string>("detail");
list.Add(address);
}
return list;
}
}
}
catch (Exception ex)
{
return null;
}
}
public List<string> PDDGetWaybill(string context, string Token)
{
try
{
var parameter = GetParameterByPDD("pdd.waybill.get");
parameter.Add("access_token", Token);
parameter.Add("param_waybill_cloud_print_apply_new_request", context);
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(url);
Request.Method = "POST";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
using (Stream s = Response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string json = sr.ReadToEnd();
Newtonsoft.Json.Linq.JObject job = JObject.Parse(json);
if (job.Property("error_response") != null)
{
return new List<string>()
{
"0",
job["error_response"].Value<string>("error_msg")
};
}
var data = job["pdd_waybill_get_response"]["modules"][0];
return new List<string>()
{
"1",
data["waybill_code"].Value<string>(),
data["print_data"].Value<string>()
};
}
}
}
catch (Exception ex)
{
return new List<string>() {
"0",
ex.Message
};
}
}
public List<string> PDDQueryWaybillCode(string object_id, string waybill_code, string wp_code, string Token)
{
try
{
var parameter = GetParameterByPDD("pdd.waybill.query.by.waybillcode");
parameter.Add("access_token", Token);
var param = new[]
{
new{
object_id = object_id,
waybill_code = waybill_code,
wp_code = wp_code
}
};
parameter.Add("param_list", Newtonsoft.Json.JsonConvert.SerializeObject(param));
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(url);
Request.Method = "POST";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
using (Stream s = Response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string json = sr.ReadToEnd();
Newtonsoft.Json.Linq.JObject job = JObject.Parse(json);
var data = job["pdd_waybill_query_by_waybillcode_response"]["modules"][0]["waybill_cloud_print_response"];
return new List<string>()
{
"1",
data["waybill_code"].Value<string>(),
data["print_data"].Value<string>()
};
}
}
}
catch (Exception ex)
{
return new List<string>() {
"0",
ex.Message
};
}
}
/// <summary>
/// 拼多多撤回物流单号
/// </summary>
/// <param name="waybill_code"></param>
/// <param name="wp_code"></param>
/// <param name="token"></param>
/// <returns></returns>
public bool PddWaybillCancel(string waybill_code, string wp_code, string token)
{
try
{
var parameter = GetParameterByPDD("pdd.waybill.cancel");
parameter.Add("waybill_code", waybill_code);
parameter.Add("wp_code", wp_code);
parameter.Add("access_token", token);
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(url);
Request.Method = "POST";
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
using (Stream s = Response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string json = sr.ReadToEnd();
Newtonsoft.Json.Linq.JObject job = JObject.Parse(json);
return job["pdd_waybill_cancel_response"].Value<bool>("cancel_result");
}
}
}
catch (Exception ex)
{
return false;
}
}
private void RequestByPDD(string url, string openid, string access_token, DateTime StartTime, DateTime EndTime, string status, Action<Boolean, Object, Int32, Int32> action, int page)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (Stream s = response.GetResponseStream())
{
using (StreamReader sr = new StreamReader(s))
{
string data = sr.ReadToEnd();
JObject job = JObject.Parse(data);
if (job.Property("error_response") != null)
{
action(false, job["error_response"].Value<string>("error_msg"), 0, 0);
}
else
{
int count = job["order_list_get_response"].Value<int>("total_count");//当前时间内查询到的总数据条数
if (count > 0)
{
var trades = new List<trade>();
foreach (var item in job["order_list_get_response"]["order_list"])
{
trades.Add(SerializeData(item));//初始化参数
}
trades.ForEach(w => { w.seller_openid = openid; w.receiver_country = "CN"; });
action(true, trades, trades.Count(), count);
if (count > 100 && page / 100 < count)
{
url = ChangedParameter(access_token, StartTime, EndTime, status, page + 1);
RequestByPDD(url, openid, access_token, StartTime, EndTime, status, action, page + 1);
}
}
}
}
}
}
private trade SerializeData(JToken data)
{
trade t = new trade();
t.tid = data.Value<string>("order_sn");
//通过售后状态判断 当前订单 是否退货;
string refund_status = data.Value<string>("refund_status");
if (refund_status.Equals("1"))//无售后
{
t.status = PDDStatus.Where(w => w.Key.Equals(data.Value<string>("order_status"))).FirstOrDefault().Value;
}
else if (refund_status.Equals("2") || refund_status.Equals("3"))
{
t.status = "LOCKED";
}
else if (refund_status.Equals("4"))
{
t.status = "TRADE_CLOSED";
}
t.seller_memo = data.Value<string>("remark");
t.receiver_state = data.Value<string>("province");
t.receiver_provinceId = data.Value<string>("province_id");
t.receiver_name = data.Value<string>("receiver_name");
t.receiver_mobile = data.Value<string>("receiver_phone");
t.receiver_district = data.Value<string>("town");
t.receiver_countyId = data.Value<string>("town_id");
t.receiver_country = data.Value<string>("country");
t.receiver_cityId = data.Value<string>("city_id");
t.receiver_city = data.Value<string>("city");
t.receiver_address = data.Value<string>("receiver_address");
t.post_fee = data.Value<decimal>("postage");
t.pay_time = data.Value<string>("confirm_time");
t.over_time_left = data.Value<string>("last_ship_time");
//t.invoice_no = data.Value<string>("tracking_number");
t.end_time = data.Value<string>("receive_time");
t.created = data.Value<string>("created_time");
t.couponPrice = data.Value<decimal>("discount_amount");
t.buyer_nick = data.Value<string>("receiver_name");
t.buyer_message = data.Value<string>("buyer_memo");
List<orders> os = new List<orders>();
orders o;
foreach (var item in data["item_list"])
{
o = new orders();
o.invoice_no = data.Value<string>("tracking_number");
o.item_meal_name = item.Value<string>("goods_name");
o.num = item.Value<int>("goods_count");
o.outer_iid = item.Value<string>("outer_goods_id");
o.outer_sku_id = item.Value<string>("outer_id");
o.payment = item.Value<decimal>("goods_price");
o.pic_path = item.Value<string>("goods_img");
//商品价格-团长拼团优惠价格-商家优惠价格
o.price = item.Value<decimal>("goods_price") - data.Value<decimal>("capital_free_discount") - data.Value<decimal>("seller_discount");
o.refund_status = data.Value<string>("refund_status");
o.sku_properties_name = item.Value<string>("goods_spec");
o.tid = t.tid;
o.title = item.Value<string>("goods_name");
os.Add(o);
}
t.orders = new Porder(os);
return t;
}
/// <summary>
/// 返回请求url并拼接参数
/// </summary>
/// <param name="access_token"></param>
/// <param name="StartTime"></param>
/// <param name="EndTime"></param>
/// <param name="status"></param>
/// <param name="Page"></param>
/// <returns></returns>
private string ChangedParameter(string access_token, DateTime StartTime, DateTime EndTime, string status, int Page)
{
var parameter = GetParameterByPDD("pdd.order.list.get");
parameter.Add("access_token", access_token);
parameter.Add("order_status", status);
parameter.Add("refund_status", "5");
parameter.Add("start_confirm_at", DateTimeToStamp(Convert.ToDateTime(StartTime)).ToString());//时间时间间隔不能大于
parameter.Add("end_confirm_at", DateTimeToStamp(Convert.ToDateTime(EndTime)).ToString());
parameter.Add("page", Page.ToString());
parameter.Add("page_size", "100");
parameter.Add("sign", GetPDDSign(parameter));
string url = pdd_url + "?" + string.Join("&", parameter.Select(w => w.Key + "=" + w.Value));
return url;
}
public Dictionary<string, string> GetParameterByPDD(string type)
{
Dictionary<string, string> list = new Dictionary<string, string>();
list.Add("type", type);
list.Add("data_type", "JSON");
list.Add("timestamp", DateTimeToStamp(DateTime.Now).ToString());
list.Add("client_id", pdd_client_id);
return list;
}
/// <summary>
/// 获取拼多多签名
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public string GetPDDSign(Dictionary<string, string> parameter)
{
string value = pdd_client_secret + string.Join("", parameter.OrderBy(w => w.Key).Select(w => w.Key + w.Value)) + pdd_client_secret;
return GETMD5(value);
}
private string GETMD5(string value)
{
MD5 md5 = MD5.Create();
byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(value));
// 第四步:把二进制转化为大写的十六进制
StringBuilder result = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
result.Append(bytes[i].ToString("X2"));
}
return result.ToString();
}
// DateTime时间格式转换为Unix时间戳格式
private long DateTimeToStamp(System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return (int)(time - startTime).TotalSeconds;
}
#endregion
...年纪大了懒得一个一个方法解释了,全发出来自己看吧。重点说下第三部分。物流单打印
三。物流单打印
2.拼多多打印机组件下载:和菜鸟打印组件一样 https://api.pinduoduo.com/api/app/v1/latest/com.xunmeng.pddprint/windows
3.设置设置打印模板:
这一步很重要,每个物流供应商都有多个模板,所以我们要设置每个物流每个模板对应的打印机
/// <summary>
/// 获取本地打印机列表
/// </summary>
public class LocalPrinter
{
private static PrintDocument fPrintDocument = new PrintDocument();
///
/// 获取本机默认打印机名称
///
public static String DefaultPrinter
{
get { return fPrintDocument.PrinterSettings.PrinterName; }
}
///
/// 获取本机的打印机列表。列表中的第一项就是默认打印机。
///
public static List<LookUpList.LookUpEditList> GetLocalPrinters()
{
List<LookUpList.LookUpEditList> fPrinters = new List<LookUpList.LookUpEditList>();
fPrinters.Add(new LookUpList.LookUpEditList() { lookname = DefaultPrinter, lookvalue = DefaultPrinter, istrue = false });//第一个为默认打印机
foreach (String fPrinterName in PrinterSettings.InstalledPrinters)
{
if (!fPrinters.Select(w => w.lookname.Equals(fPrinterName)).FirstOrDefault())
fPrinters.Add(new LookUpList.LookUpEditList() { lookname = fPrinterName, lookvalue = fPrinterName, istrue = false });
}
return fPrinters;
}
}
//连接PDD打印组件
private void PrintSetting()
{
WebSocket ws = new WebSocket("ws://127.0.0.1:13528");
ws.MessageReceived += ws_MessageReceived;
ws.Error += ws_Error;
ws.Open();
}
/// <summary>
/// 打印机回调参数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ws_MessageReceived(object sender, MessageReceivedEventArgs e)
{
//获取回调函数
Newtonsoft.Json.Linq.JObject job = Newtonsoft.Json.Linq.JObject.Parse(e.Message);
if (job.Property("msg")!=null)
{
if (job.Value<string>("msg").Equals("成功"))
{
Conlose.log("打印成功");
}
else
{
Conlose.log("打印失败");
}
}
else if (job.Property("status")!=null)
{
if (job.Value<string>("status").Equals("success"))
{
Conlose.log("打印成功");
}
else
{
Conlose.log("打印失败");
}
}
}
/// <summary>
/// 回传打印机错误消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ws_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
{
if (e.Exception.Message.Equals("由于目标计算机积极拒绝,无法连接。"))
{
Conlose.log(e.Exception.Message + "\r\n请确认本地安装了拼多多打印组件,并启动");
}
}
else if (e.Exception.Message.Equals("由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。"))
{
}
else
{
Conlose.log(e.Exception.Message);
}
}
来源:CSDN
作者:dy_Model
链接:https://blog.csdn.net/dy_Model/article/details/103528531