针对聚顺可以直接用的代码
- 发货接收的Controller
- 下单退单的实现
- 实现方法
- 实现方法的工具类
- 抽取公共模块
- 简略计算签名
- 将Object对象里面的属性和值转化成Map对象
- 工具类
- 签名方法
- MD5加密
- HTTPUtil
- 实体类
- AskFromJuShun
- Content
- Detail
- Invoice
- JuShunResult
- OrderPickedUpParam
- Promotion
- ReturnGoods
- SendContent
- Tender
调用的是聚顺的下单、退单、发货接口。需要注意的是有的参数和类型名对不上,需要好好看看
发货接收的Controller
聚顺发过来的json:需要注意的是发过来的content是字符串形式,所以无法直接转化为对象使用
{"msgid": "617be1223d28a4140c17fb7a","fn": "ecp.scm.b2corder.send","timestamp": "2021-10-29 11:55:14","content": "{\"tid\":\"21102911485808699209\",\"issplit\":\"0\",\"expressno\":\"SF11111\",\"invoiceurl\":\"\",\"expressname\":\"顺丰速运\",\"expresscode\":\"SF\"}","tenantid": "6109217bb84c590a5842a309"
}
处理方法:
//借口是指定的
@PostMapping(value = "/ecp.scm.b2corder.send")public JSONObject ship(@RequestBody AskFromJuShun askFromJuShun) {//这里需要处理一下content参数为一个对象JuShunResult ship = juShunService.ship(JSONUtil.toBean(askFromJuShun.getContent(), SendContent.class));//剩下就是你自己的具体逻辑了return JSONUtil.parseObj(ship);}
下单退单的实现
实现方法
/*** @description: 通知聚顺网站创建订单* @param:* @return:** @param content*/@Overridepublic String sendDomestic(Content content) {Map<String, Object> map = extract(content);map.put("_functionname", "ecp.scm.salesorder.create");String result = HttpRequest.post(url).header("content-type", "application/json").body(JSONUtil.parseObj(map)).execute().body();return "聚顺创建订单结果:{}" + result;}/*** @description: 通知聚顺网站退单* @param:* @return:**/@Overridepublic String chargeback(ReturnGoods returnGoods) {Map<String, Object> map = extract(returnGoods);map.put("_functionname", "ecp.scm.salesorder.refund");String result = HttpRequest.post(url).header("content-type", "application/json").body(JSONUtil.parseObj(map)).execute().body();log.info("聚顺退单结果:{}" + result);return "聚顺退单结果:{}" + result;}
实现方法的工具类
抽取公共模块
public Map<String,Object> extract(Object object) {JSONObject jsonObject = JSONUtil.parseObj(object);String contentJson = jsonObject.toStringPretty();Map<String,Object> map = new HashMap<>();map.put("content", contentJson);map.put("_appkey", appkey);map.put("_async", true);map.put("_sessionkey", sessionKey);map.put("_timestamp", System.currentTimeMillis()/1000 + "");map.put("_version", "1.0");try {String sign = jushunSign(map);map.put("_sign", sign);} catch (Exception e) {log.info("聚顺签名异常");}return map;}
简略计算签名
/*** @description: 计算签名* @param:* @return:**/private String jushunSign(Object object) throws IllegalAccessException {Map<String, String> map = objectToMap(object);return JushunSignUtil.formatUrlMap(map);}
将Object对象里面的属性和值转化成Map对象
private Map<String, String> objectToMap(Object obj) throws IllegalAccessException {Map<String, String> map = new HashMap();Class<?> clazz = obj.getClass();for (Field field : clazz.getDeclaredFields()) {field.setAccessible(true);String fieldName = field.getName();if (field.get(obj) != null) {String value = JSONUtil.toJsonStr(field.get(obj));map.put(fieldName, value);}}return map;}
工具类
签名方法
/*** @description: 对所有传入参数按照字段名ASCII 码从小到大排序(字典序)后,按key1value1key2value2…的形式拼接成字符串* 在排序后的字符串前后拼接secretkey* 对拼接后的字符串进行md5 运算,再将得到的字符串所有字符转换为小写* @param: paraMap 需要改变的map* @return: 加密后的签名**/public static String formatUrlMap(Map<String, String> paraMap){String buff = "";Map<String, String> tmpMap = paraMap;try{List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(tmpMap.entrySet());// 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {@Overridepublic int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2){return (o1.getKey()).toString().compareTo(o2.getKey());}});// 构造URL 键值对的格式StringBuilder buf = new StringBuilder();for (Map.Entry<String, String> item : infoIds) {if (StringUtils.isNotBlank(item.getKey())) {String key = item.getKey();String val = item.getValue();buf.append(key + val);}}buff = buf.toString();if (buff.isEmpty() == false) {buff = buff.substring(0, buff.length() - 1);}} catch (Exception e) {return "签名失败";}buff = buff + secretkey;return stringToMD5(buff);}
MD5加密
/*** @description: 进行md5加密,并且全部转化为小写* @param: plainText 需要加密的字符串* @return: 加密后的字符串**/public static String stringToMD5(String plainText) {byte[] secretBytes = null;try {secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());} catch (NoSuchAlgorithmException e) {throw new RuntimeException("没有这个md5算法!");}String md5code = new BigInteger(1, secretBytes).toString(16);for (int i = 0; i < 32 - md5code.length(); i++) {md5code = "0" + md5code;}md5code.toLowerCase();return md5code;}
HTTPUtil
@Component
@Slf4j
public class HttpUtil {@Autowiredprivate CloseableHttpClient httpClient;public String doGet(String url, Map<String, Object> map) throws Exception {URIBuilder builder = new URIBuilder(url);if (map != null) {for (Map.Entry<String, Object> entry : map.entrySet()) {builder.setParameter(entry.getKey(), entry.getValue().toString());}}URI uri = builder.build();HttpGet httpGet = new HttpGet(uri);httpGet.setHeader("Accept", "application/json");CloseableHttpResponse response = httpClient.execute(httpGet);return commonResult(response);}public String doPost(String url, String param) throws Exception {HttpPost httpPost = new HttpPost(url);StringEntity entity = new StringEntity(param, StandardCharsets.UTF_8);entity.setContentType("application/json");httpPost.setEntity(entity);httpPost.setHeader("Accept", "application/json;charset=UTF-8");httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");CloseableHttpResponse response = httpClient.execute(httpPost);return commonResult(response);}private String commonResult(CloseableHttpResponse response) throws Exception {try {int statusCode = response.getStatusLine().getStatusCode();if (statusCode==200 && response.getEntity() != null) {return EntityUtils.toString(response.getEntity(), "utf-8");} else {String errMsg = EntityUtils.toString(Objects.requireNonNull(response.getEntity()));System.out.println(errMsg);throw new IOException(errMsg);}} finally {response.close();}}}
实体类
AskFromJuShun
/*** @Author: 王木风* @DateTime: 2021/10/29 4:14 下午* @description:聚顺请求接收实体类**/
@Data
public class AskFromJuShun {private String msgid;private String fn;private String timestamp;private String content;private String tenantid;AskFromJuShun(){}
}
Content
/*** @Author: 王木风* @DateTime: 2021/10/25 3:56 下午* @description:聚顺所需参数**/
@Data
public class Content {@ApiModelProperty("店铺代码 必填")private String storecode;@ApiModelProperty("小程序订单号 必填")private String tid;@ApiModelProperty("拍单时间 必填")private String created;@ApiModelProperty("付款时间 必填")private String pay_time;@ApiModelProperty("最后修改时间 必填")private String modified;@ApiModelProperty("订单平台状态 必填")private String topstatus;@ApiModelProperty("支付总金额 必填")private String payment;@ApiModelProperty("会员昵称 必填")private String buyer_nick;@ApiModelProperty("收货人 必填")private String receiver_name;@ApiModelProperty("收货人手机 必填")private String receiver_mobile;@ApiModelProperty("收获省 必填")private String receiver_state;@ApiModelProperty("收货市 必填")private String receiver_city;@ApiModelProperty("收货区/县 必填")private String receiver_district;@ApiModelProperty("收货地址 必填")private String receiver_address;@ApiModelProperty("收获邮编 必填")private String receiver_zip;@ApiModelProperty("会员卡号")private String cardno;@ApiModelProperty("聚顺会员id")private String vip_id;@ApiModelProperty("聚顺会员卡id")private String vipcard_id;@ApiModelProperty("来源会员id")private String source_vip_id;@ApiModelProperty("来源会员卡id")private String source_vipcard_id;@ApiModelProperty("货到付款 0非货到付款 1货到付款 默认0")private int iscod;@ApiModelProperty("买家支付运费")private String post_fee;@ApiModelProperty("积分支付")private String point_fee;@ApiModelProperty("配送方式 0仓库快递配送 1自提 2门店配送")private String deliverytype;@ApiModelProperty("自提或配送门店代码、仓库代码")private String deliverystorecode;@ApiModelProperty("自提或配送门店名称、仓库名称")private String deliverystorename;@ApiModelProperty("收货人电话")private String receiver_phone;@ApiModelProperty("收货人邮件")private String buyer_email;@ApiModelProperty("买家备注")private String buyer_memo;@ApiModelProperty("卖家昵称")private String seller_nick;@ApiModelProperty("卖家名称")private String seller_name;@ApiModelProperty("卖家手机")private String seller_mobile;@ApiModelProperty("卖家邮件地址")private String seller_email;@ApiModelProperty("旗帜")private String seller_flag;@ApiModelProperty("卖家备注")private String seller_memo;@ApiModelProperty("交易内部来源 WAP(手机);PC;")private String trade_from;@ApiModelProperty("订单商品明细")private ArrayList<Detail> detail;@ApiModelProperty("发票信息")private ArrayList<Invoice> invoice;@ApiModelProperty("付款信息")private ArrayList<Tender> tender;@ApiModelProperty("促销和优惠信息")private ArrayList<Promotion> promotion;
}
Detail
/*** @Author: 王木风* @DateTime: 2021/10/25 4:21 下午* @description:订单商品明细**/
@Data
public class Detail {@ApiModelProperty("明细 id 必填")private String oid;@ApiModelProperty("商品 id 必填")private String num_iid;@ApiModelProperty("商品 skuid 必填")private String sku_id;@ApiModelProperty("商品外部商家编码 必填")private String outer_id;@ApiModelProperty("商品sku外部商家编码 必填")private String outer_sku_id;@ApiModelProperty("数量 必填")private String num;@ApiModelProperty("实际单价 必填")private String price;@ApiModelProperty("实际金额 必填")private String payment;@ApiModelProperty("标准单价")private String unitprice;@ApiModelProperty("明细状态")private String topstatus;@ApiModelProperty("退款状态")private String toprefund_status;@ApiModelProperty("sku描述")private String sku_name;@ApiModelProperty("商品链接描述")private String title;@ApiModelProperty("图片url")private String pic_path;@ApiModelProperty("1——赠品")private String isgift;@ApiModelProperty("退货交易时,第三方的原销售订单id")private String returnordersourcekey;@ApiModelProperty("退货交易时,第三方的原销售订单明细id")private String returnsourcekey;@ApiModelProperty("退货交易时,原销售订单id")private String returnorder_id;@ApiModelProperty("退货交易时,原销售订单明细id")private String returnorderdetail_id;@ApiModelProperty("营业员")private String salesman;@ApiModelProperty("营业员id")private String salesmanid;@ApiModelProperty("pos营业员id")private String source_salesmanid;}
Invoice
/*** @Author: 王木风* @DateTime: 2021/10/25 4:33 下午* @description:发票信息**/
@Data
public class Invoice {@ApiModelProperty("开票类型0—纸质发票 1—电子发票")private String invoicekind;@ApiModelProperty("发票类型,与ESCM中发票类型代码匹配")private String invoicetype;@ApiModelProperty("发票抬头")private String invoicetitle;@ApiModelProperty("发票内容")private String invoicecontent;@ApiModelProperty("纳税人识别号")private String taxpayerid;@ApiModelProperty("开户行和账号")private String invoicebank;@ApiModelProperty("注册电话")private String invoicetel;@ApiModelProperty("注册地址")private String invoiceaddress;
}
JuShunResult
/*** @Author: 王木风* @DateStringime: 2021/10/26 12:06 下午* @description:属于聚顺的返回参数**/
@Data
public class JuShunResult {private String success;private String desc;public JuShunResult(String success, String desc) {this.success = success;this.desc = desc;}
}
OrderPickedUpParam
/*** @description: OrderPickedUpParam* @author: cuijin* @create: 2020-06-16 15:39*/
@Getter
@Setter
public class OrderPickedUpParam {@NotBlankprivate String orderId;@NotNullprivate Date pickUpTime;
}
Promotion
/*** @Author: 王木风* @DateTime: 2021/10/25 4:40 下午* @description:促销和优惠信息**/@Data
public class Promotion {@ApiModelProperty("优惠类型 0-整单优惠 1-明细优惠")private String promotiontype;@ApiModelProperty("促销代码")private String promotion_code;@ApiModelProperty("促销名称")private String promotion_name;@ApiModelProperty("明细id")private String oid;@ApiModelProperty("赠送优惠卷id")private String gift_item_id;@ApiModelProperty("赠送优惠卷名称")private String gift_item_name;@ApiModelProperty("赠送优惠卷数量")private String gift_item_num;@ApiModelProperty("明细优惠金额")private String discount_fee;
}
ReturnGoods
/*** @Author: 王木风* @DateTime: 2021/10/26 12:41 下午* @description:聚顺退货实体类**/
@Data
public class ReturnGoods {@ApiModelProperty("小程序退款单号")private String refund_id;@ApiModelProperty(" 小程序订单号")private String tid;@ApiModelProperty("平台售后状态")private String status;@ApiModelProperty(" 售后申请时间")private String created;@ApiModelProperty(" 售后更新时间")private String modified;@ApiModelProperty("是否有实物退回,fales——退款 true——退货退款")private String has_good_return;@ApiModelProperty("订单原支付流水号")private String payno;@ApiModelProperty("退货金额")private String amount;@ApiModelProperty("退货原因")private String reason;@ApiModelProperty("退货备注")private String remark;@ApiModelProperty("退回物流单号")private String expressno;@ApiModelProperty("退回物流公司")private String expressname;@ApiModelProperty("退货商品明细")private Detail detail;}
SendContent
/*** @Author: 王木风* @DateTime: 2021/10/29 4:44 下午* @description:**/
@Data
public class SendContent {private String tid;private String issplit;private String expressno;private String invoiceurl;private String expressname;private String expresscode;SendContent() {}
}
Tender
/*** @Author: 王木风* @DateTime: 2021/10/25 4:37 下午* @description:付款实体**/@Data
public class Tender {@ApiModelProperty("付款方式代码")private String tendercode;@ApiModelProperty("付款方式名称")private String tendername;@ApiModelProperty("0-现金 1-积分 2-礼卷 必填")private int tendertype;@ApiModelProperty("付款账号")private String cardno;@ApiModelProperty("金额 必填")private String amount;
}