一. 创建应用(我这里创建了 商家后台应用)
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
///
/// 拼多多Token刷新方法
///
///
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";
///
/// 拼多多根据时间获取订单
///
/// 拼多多接口查询时间间隔不支持大于24小时
/// 即:根据时间查询时需要根据时间翻页
/// 查询每页返回条数最高100条
/// 即:当前时间内查询的条数大于100条时,
/// 需要根据条数翻页。
///
///
///
///
///
///
///
///
///
public void GetPinduoduoOrders(string openid, string access_token, string StartTime, string EndTime, string status, Action 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);
}
}
///
/// 根据id 查询 拼多多订单
///
public void GetPinduoduoOrderByID(string openid, string id, string access_token, Action 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("error_msg"));
}
}
}
}
///
/// 拼多多在线发货
///
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("is_success"))
{
return "回传成功";
}
else
{
return "回传失败";
}
}
else
{
return job["error_response"].Value("error_msg");
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}
//查询拼多多支持物流公司列表
public List 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 dl = new List();
foreach (var item in job["logistics_companies_get_response"]["logistics_companies"])
{
if (item.Value("available").Equals(1))
dl.Add(new logistics_company
{
id = item.Value("id"),
code = item.Value("code"),
Identifier = item.Value("id").ToString(),
name = item.Value("logistics_company")
});
}
return dl;
}
}
}
return null;
}
catch
{
return null;
}
}
//根据物流公司Code查询所支持模板
public List 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 list = new List();
foreach (var item in templates)
{
list.Add(new
{
cp_code = code,
standard_template_id = item["standard_waybill_type"].Value(),
standard_template_name = item["standard_template_name"].Value(),
standard_template_url = item["standard_template_url"].Value()
});
}
return list;
}
}
}
//根据物流公司Code查询已开通物流公司网点和可用单号数量
public List PDDGetWaybillByLogistics(string code, string token)
{
try
{
List list = new List();
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("branch_code");
address.quantity = item.Value("quantity");
address.province = item["shipp_address_cols"][0].Value("province");
address.city = item["shipp_address_cols"][0].Value("city");
address.area = item["shipp_address_cols"][0].Value("district");
address.address_detail = item["shipp_address_cols"][0].Value("detail");
list.Add(address);
}
return list;
}
}
}
catch (Exception ex)
{
return null;
}
}
public List 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()
{
"0",
job["error_response"].Value("error_msg")
};
}
var data = job["pdd_waybill_get_response"]["modules"][0];
return new List()
{
"1",
data["waybill_code"].Value(),
data["print_data"].Value()
};
}
}
}
catch (Exception ex)
{
return new List() {
"0",
ex.Message
};
}
}
public List 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()
{
"1",
data["waybill_code"].Value(),
data["print_data"].Value()
};
}
}
}
catch (Exception ex)
{
return new List() {
"0",
ex.Message
};
}
}
///
/// 拼多多撤回物流单号
///
///
///
///
///
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("cancel_result");
}
}
}
catch (Exception ex)
{
return false;
}
}
private void RequestByPDD(string url, string openid, string access_token, DateTime StartTime, DateTime EndTime, string status, Action 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("error_msg"), 0, 0);
}
else
{
int count = job["order_list_get_response"].Value("total_count");//当前时间内查询到的总数据条数
if (count > 0)
{
var trades = new List();
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("order_sn");
//通过售后状态判断 当前订单 是否退货;
string refund_status = data.Value("refund_status");
if (refund_status.Equals("1"))//无售后
{
t.status = PDDStatus.Where(w => w.Key.Equals(data.Value("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("remark");
t.receiver_state = data.Value("province");
t.receiver_provinceId = data.Value("province_id");
t.receiver_name = data.Value("receiver_name");
t.receiver_mobile = data.Value("receiver_phone");
t.receiver_district = data.Value("town");
t.receiver_countyId = data.Value("town_id");
t.receiver_country = data.Value("country");
t.receiver_cityId = data.Value("city_id");
t.receiver_city = data.Value("city");
t.receiver_address = data.Value("receiver_address");
t.post_fee = data.Value("postage");
t.pay_time = data.Value("confirm_time");
t.over_time_left = data.Value("last_ship_time");
//t.invoice_no = data.Value("tracking_number");
t.end_time = data.Value("receive_time");
t.created = data.Value("created_time");
t.couponPrice = data.Value("discount_amount");
t.buyer_nick = data.Value("receiver_name");
t.buyer_message = data.Value("buyer_memo");
List os = new List();
orders o;
foreach (var item in data["item_list"])
{
o = new orders();
o.invoice_no = data.Value("tracking_number");
o.item_meal_name = item.Value("goods_name");
o.num = item.Value("goods_count");
o.outer_iid = item.Value("outer_goods_id");
o.outer_sku_id = item.Value("outer_id");
o.payment = item.Value("goods_price");
o.pic_path = item.Value("goods_img");
//商品价格-团长拼团优惠价格-商家优惠价格
o.price = item.Value("goods_price") - data.Value("capital_free_discount") - data.Value("seller_discount");
o.refund_status = data.Value("refund_status");
o.sku_properties_name = item.Value("goods_spec");
o.tid = t.tid;
o.title = item.Value("goods_name");
os.Add(o);
}
t.orders = new Porder(os);
return t;
}
///
/// 返回请求url并拼接参数
///
///
///
///
///
///
///
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 GetParameterByPDD(string type)
{
Dictionary list = new Dictionary();
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;
}
///
/// 获取拼多多签名
///
///
///
public string GetPDDSign(Dictionary 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
...年纪大了懒得一个一个方法解释了,全发出来自己看吧。重点说下第三部分。物流单打印
三。物流单打印
1.官方文档:https://open.pinduoduo.com/#/document?url=https%253A%252F%252Fmstatic.pinduoduo.com%252Fautopage%252F213_static_10%252Findex.html
2.拼多多打印机组件下载:和菜鸟打印组件一样 https://api.pinduoduo.com/api/app/v1/latest/com.xunmeng.pddprint/windows
3.设置设置打印模板:
这一步很重要,每个物流供应商都有多个模板,所以我们要设置每个物流每个模板对应的打印机
///
/// 获取本地打印机列表
///
public class LocalPrinter
{
private static PrintDocument fPrintDocument = new PrintDocument();
///
/// 获取本机默认打印机名称
///
public static String DefaultPrinter
{
get { return fPrintDocument.PrinterSettings.PrinterName; }
}
///
/// 获取本机的打印机列表。列表中的第一项就是默认打印机。
///
public static List GetLocalPrinters()
{
List fPrinters = new List();
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();
}
///
/// 打印机回调参数
///
///
///
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("msg").Equals("成功"))
{
Conlose.log("打印成功");
}
else
{
Conlose.log("打印失败");
}
}
else if (job.Property("status")!=null)
{
if (job.Value("status").Equals("success"))
{
Conlose.log("打印成功");
}
else
{
Conlose.log("打印失败");
}
}
}
///
/// 回传打印机错误消息
///
///
///
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);
}
}