前言

网上文档整的花里胡哨的,于是笔者踩完坑之后决定将整套对接流程记录下来~

在申请美团开发者账号之前,一定要弄清楚需要申请的是品牌商,还是申请的服务商,品牌商的话是本公司自己的研发人员对接,而服务商的话是使用的第三方的人员来进行,这个一定要弄清,想当初笔者看服务商的文档看了一两天结果发现看错文档了┭┮﹏┭┮。

美团开发者账号申请

首先先附带上品牌商开发者账号地址:美团开发者账号申请
申请的材料也不像服务商那么多,基本只需要研发人员身份证照,在职证明以及公司的营业执照和法人身份证照就可以申请下来了,效率也是挺不错的,半天的样子就能验证通过了。
在这里插入图片描述

开发的前期工作

申请开通外卖业务

在这里插入图片描述

控制台

这里可以获取app secret,这个和向美团推送的数据有关,这里之后再提到。
回调接口的设置,可以设置美团的推送信息的接口等。
订阅字段值可以选择一些字段美团推送的时候有些不重要的字段是否携带,具体的在文档会详细的给出。
在这里插入图片描述

申请测试门店

当申请完毕后,会申请到一个测试门店。

美团餐饮开放平台目前仅提供一套开发环境。当您的应用创建成功后,系统会自动为该应用分配一个线上测试门店用于接口测试。测试门店的地址默认为南极洲,配送范围默认为西藏林芝墨脱县色金拉,在测试过程中,请您务必不要修改测试门店的配送范围,否则该测试门店很可能被美团品控审查后强制下线,无法恢复上线。

设置商品

这里我们需要使用我们的测试门店的商家账号添加商品,有网页版的和APP版的,哪个方便用哪个就是了,账号密码当测试门店注册完成后会以短信的方式反馈到我们的手机上。

开发

废话不多说,从这里开始上代码开始啃硬菜~
使用美团的商家平台给自己的测试门店设置商品,这里有一个很重要的点!

就是你开发的时候下单,是走的正式的生产环境的(只不过地址是在一个荒无人烟的地方),也就是说所有的操作都是可以进行扣钱的,所以呢读者下完单一定要及时的退款

这里就拿 APP方URL推送已支付订单(必接) 接口来作为讲解,美团官网链接如下:APP方URL推送已支付订单(必接),建议结合文档一起撸。

本代码是基于springboot的进行编写的,涉及敏感的代码会作模糊化处理

接收美团推送的请求

首先先新建好我们的controller层


/**
 *
 * 美团订单Controller
 *
 * @author Cocowwy
 * @create 2021-05-05-11:15
 *
 */
@RestController
@RequestMapping("/meituan")
@ResponseBody
@Slf4j
public class MeituanController {
    @Autowired
    MeiTuanPushService meiTuanPushService;
  
    /**
     *  用户成功支付订单
     *
     * @param request
     * @return
     */
    @MethodName("用户付款订单成功")
    @PostMapping("/push/paidOrder")
    public Map<String,Object> paidOrder(PaidOrderRequest request) {
        meiTuanPushService.paidOrder(request);
        return Result.OK;
    }
}

当然,美团是建议我们进行验签的,具体的验签方式瞅这里:美团开发文档
至于接收参数的request的属性的定义这我就同意贴在下面了,需要的话可以看下面,建议读者自己去文档上面复制粘贴即可。
笔者对于List的Object类型是使用的字符串的方式接收(比如文档里面的detail字段),需要使用的时候再使用Json的工具包对字符串与实体类进行转换即可。
当然,需要将Object映射成实体类的实体属性等会一起贴在下面。

当然,这里面也是有坑的!
在这里插入图片描述
看到这张图大家都知道啥坑了吧,对于含有中文的字段,我们需要进行转义,本人使用的是Hutool工具包的URLUtil.decode(request.getXxxxxx())方法进行解析的。
这样就能获取到中文了。

PaidOrderRequest字段


/**
 * 已支付订单接口入参
 * @author Cocowwy
 * @create 2021-05-05-10:30
 */
@Getter
@Setter
@ToString
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class PaidOrderRequest extends CommonRequest {
    /**
     * 订单ID(数据库中请用bigint(20)存储此字段)
     */
    private Long order_id;
    /**
     * 订单展示ID
     */
    private Long wm_order_id_view;
    /**
     * APP方商家ID
     */
    private String app_poi_code;
    /**
     * 美团商家名称
     */
    private String wm_poi_name;
    /**
     * 美团商家地址
     */
    private String wm_poi_address;
    /**
     * 美团商家电话
     */
    private String wm_poi_phone;
    /**
     * 收件人地址(此字段为用户填写的收货地址,可在开发者中心订阅是否根据经纬度反查地址,若订阅则会在此字段后追加反查结果,并用“@#”符号分隔,如:用户填写地址@#反查结果)
     */
    private String recipient_address;
    /**
     * 收件人电话(请兼容13812345678和13812345678_123456两种号码格式,以便对接隐私号订单,最多不超过20位)
     */
    private String recipient_phone;
    /**
     * 备用隐私号 ["13812345678_1236","13812345678_3456"]
     */
    private List<String> backup_recipient_phone;
    /**
     * 收件人姓名(若用户没有填写姓名,此字段默认为空。可在开发者中心订阅是否用“美团客人”填充此字段)
     */
    private String recipient_name;
    /**
     * 门店配送费
     */
    private Float shipping_fee;
    /**
     * 总价
     */
    private Double total;
    /**
     * 原价
     */
    private Double original_price;
    /**
     * 忌口或备注
     */
    private String caution;
    /**
     * 送餐员电话
     */
    private String shipper_phone;
    /**
     * 订单状态 2:新订单-用户支付完成,待商家接单 4:商家已接单 8:订单已完成 9:订单已取消
     */
    private String status;
    /**
     * 城市ID(目前暂时用不到此信息)
     */
    private Long city_id;
    /**
     * 是否开发票
     */
    private Integer has_invoiced;
    /**
     * 发票抬头
     */
    private String invoice_title;
    /**
     * 纳税人识别号,该信息默认不推送,如有需求可在开发者中心订阅
     */
    private String taxpayer_id;
    /**
     * 创建时间 (注:订单创建时间)
     */
    private Long ctime;
    /**
     * 更新时间
     */
    private Long utime;
    /**
     * 用户预计送达时间,“立即送达”时为0,非0 代表非即时单(包含到店自取,时间为用户到店取餐时间),预订单代表用户下单时填写的预计送达时间,单位是秒,10位时间戳
     */
    private Long delivery_time;
    /**
     * 	是否是第三方配送平台配送,0表否,1表是)
     */
    private Integer is_third_shipping;
    /**
     * 支付类型,1表货到付款,2表在线支付(非支付渠道)
     */
    private Integer pay_type;
    /**
     * 取餐类型(0:普通取餐;1:到店取餐),该信息默认不推送,如有需求可在开发者中心订阅
     */
    private Integer pick_type;
    /**
     * 实际送餐地址纬度
     */
    private Double latitude;
    /**
     * 实际送餐地址经度
     */
    private Double longitude;
    /**
     * 门店当天的推单流水号,该信息默认不推送,如有需求可在开发者中心订阅
     */
    private Integer day_seq;
    /**
     * 用户是否收藏此门店(true, false),该信息默认不推送,如有需求可在开发者中心订阅
     */
    private Boolean is_favorites;
    /**
     * 用户是否第一次在此门店点餐(true, false),该信息默认不推送,如有需求可在开发者中心订阅
     */
    private Boolean is_poi_first_order;
    /**
     * 用餐人数(0:用户没有选择用餐人数;1-10:用户选择的用餐人数;-10:10人以上用餐;88:用户需要餐具;99:用户不需要餐具),该信息默认不推送,如有需求可在开发者中心订阅
     */
    private String dinners_number;
    /**
     * 订单配送方式,该信息默认不推送,如有需求可在开发者中心订阅
     */
    private String logistics_code;
    /**
     * 商家对账信息的json数据,该信息默认不推送,如有需求可在开发者中心订阅
     */
    private String poi_receive_detail;
    /**
     * 订单商品详情,其值为由list<object>序列化得到的json字符串
     */
    private String detail;

    /**
     * 第一种:优惠信息,其值为由list<object>序列化得到的json字符串
     */
    private String extras;
    /**
     * 门店平均配送时长,单位为秒
     */
    private String avg_send_time;
    /**
     * 订单来源属性标识,该信息默认不推送,如有需求可在开发者中心订阅
     */
    private String channel;
    /**
     * 开发票方式,0,非自动开票订单,1美团发票合作商家,在线自动开具电子发票
     */
    private Integer invMakeType;
    /**
     * 订单数据状态标记。当订单中部分字段的数据因内部交互异常或网络等原因延迟生成(超时),导致开发者当前获取的订单数据不完整,此时平台对订单数据缺失情况进行标记。如不完整,建议尝试重新查询。注意,平台仅对部分模块的数据完整性进行监察标记(参考incmp_modules字段)。参考值: -1:有数据降级 0:无数据降级
     */
    private Integer incmp_code;
    /**
     *有降级的数据模块的集合,参考值: 0:订单商品详情 1:订单优惠信息 2:商品优惠详情 3:订单用户会员信息 4:订单维度的商家对账信息 5:订单维度的商家对账信息(元) 6:订单收货人地址 7:订单配送方式 8:开放平台用户id 9:部分退款商品信息 10:退货退款物流信息 11:部分订单基本信息(包括订单优惠信息、订单商品详情、门店信息等) 12:sku信息 13:spu信息 14:商品信息(可能是sku或spu等商品相关信息获取时降级) 15:替换折扣价为原价
     */
    private Set<Object> incmp_modules;
    /**
     * 其他费用,需要在mcc增加对应需要推送的app_id才推送,List<Object>的json string
     */
    private String extendsAmount;

}

detail字段

/**
 * 订单商品详情Json反序列化
 *
 * @author Cocowwy
 * @create 2021-05-05-15:58
 */
@Getter
@Setter
@ToString
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class OrderDetailDTO {
    /**
     * APP方菜品id,最大长度128,不同门店可以重复,同一门店内不能重复
     */
    private String app_food_code;
    /**
     * 菜品名称
     */
    private String food_name;
    /**
     * sku编码
     */
    private String sku_id;
    /**
     * 商品数量
     */
    private Float quantity;
    /**
     * 商品单价,不包含餐盒费,此字段默认为活动折扣后价格,可在开发者中心订阅是否替换为原价
     */
    private Float price;
    /**
     * 餐盒数量
     */
    private float box_num;
    /**
     *  餐盒价格
     */
    private float box_price;

    private Long mt_sku_id;

    private String detail_extra;

    private String unit;

    private Float weight;

    private String food_property;

    private Float food_discount;

}

如何外网调用本机接口呢?

在开发者中心点击回调接口设置

接着点击测试地址进行设置接口的回调地址
在这里插入图片描述
这样一来,如果我配置了推送订单URL的话,那么一旦用户在我的测试门店下单,那么就能够对我们的接口发起推送了。
问题来了,美团如何从外网调用我本机启动的接口呢?

使用内网穿透

笔者已经贴心的将内网穿透的工具奉上,包括使用方式,免费的哦,操作步骤很简单:内网穿透

如此一来,每当配置的行为触发之后,推送的接口就会向你的接口推送数据了。

如何向美团发送请求?

这里就拿order/riderPosition 自配订单同步配送信息来进行举例子,该接口的文档地址戳这里:自配订单同步配送信息
同时需要下载美团的SDK:美团SDK地址
如果嫌弃springboot引用本地jar包麻烦的话可以放上私服
需要引入的jar包是: …\waimai_open_java_sdk\集成SDK的测试工程(仅供参考)\TestCasesWithSDK\TestCasesWithSDK\src\lib
在这里插入图片描述
即这个,笔者是放到私服上了,直接通过maven的方式引入。
不知道是不是眼神不好的原因,反正笔者是没找到能直接调用这个接口的api
在这里插入图片描述
接下来就贴代码了,因为实在是没找到这个接口的api,于是就点进源码看了下一些常用的接口是怎么调用的,然后把它的代码扯了一点出来,接下来附上本人请求美团接口的代码。
我们的请求的接口,如下:

https://waimaiopen.meituan.com/api/v1/调用的方法名

在这里插入图片描述

这个是发送post请求的放法,使用的hutool工具包发送的

String body = HttpUtil.createPost(MeituanUtils.createPostURL(RIDER_POSITION, request, meiTuanEnvConfig)).execute().body();

createPostURL创建请求地址, ConvertUtil.convertSystemParamsToMap这个是美团的jar包里面的,就不贴代码了

    /**
     * 根据入参生成美团的接口访问地址
     *
     * @param methodName 方法名
     * @param request 方法参数
     * @param meiTuanEnvConfig
     * @return post地址
     * @throws ApiSysException
     */
    public static String createPostURL(String methodName, Object request, MeiTuanEnvConfig meiTuanEnvConfig) throws ApiSysException {
        Map<String, String> paramMap = new HashMap();
        Map<String, String> systemParamsMap = ConvertUtil.convertSystemParamsToMap(new SystemParam(meiTuanEnvConfig.getAppId(), meiTuanEnvConfig.getAppSecret()));
        paramMap.putAll(systemParamsMap);
        if (ConvertUtil.convertToMap(request) != null) {
            paramMap.putAll(ConvertUtil.convertToMap(request));
        }
        String urlForGenSig = meiTuanEnvConfig.getUrl() + "/" + methodName + "?" + concatParams(paramMap);
        String sig = SignGenerator.genSig(urlForGenSig + meiTuanEnvConfig.getAppSecret());
        urlForGenSig.replaceAll(meiTuanEnvConfig.getAppSecret(), "");
        return urlForGenSig + "&sig=" + sig;
    }

MeiTuanEnvConfig,这个是你的美团请求的环境参数配置,从你的yml文件里面取

/**
 * @author Cocowwy
 * @create 2021-05-05-18:06
 */
@ConfigurationProperties(prefix = "xxx.xxx")
@Getter
@Setter
@Configuration
public class MeiTuanEnvConfig {
    private String url;
    private String appId;
    private String appSecret;
}

美团参数配置

# 美团参数配置
xxx:
  xxx:
    url: https://waimaiopen.meituan.com/api/v1/order
    appId: xxx
    appSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxx  (还记得之前提过一嘴的appSecret吗,就是在那里获取的)

接下来,就能够发送请求了,之后自己对响应体进行逻辑上的解析吧。

美团接口的对接到此为止,如果还有其他想写的,会之后进行补充~

应用上线

应用上线

在这里插入图片描述
在这里申请上线后,悉心等待即可。

绑定门店

应用上线后还需要进行门店授权,
在这里插入图片描述
在这里绑定自家门店(连锁账号也行)的账号,然后绑定即可,注意,如果改门店绑定了其他的服务商的话,需要自行解绑,之后即可继续绑定到自己的开发者账号下面了。

上线的时候回调的坑

不过后续还有个小坑,在上线的回调接口中,发现数据并未正常推送,查看美团的订单回调发现出现如下异常:
在这里插入图片描述
通过翻看一些大佬的解答,说是服务调用方的JDK使用的版本为1.7的,说是因为JDK的版本问题导致会使用不同的TLS协议。
推送订单取消发生异常:Received fatal alert: protocol_version
解决方案:既然是配置美团的接口回调,自然不可能强制美团去升级JDK版本,所以解决方案就是将回调接口设置成HTTP请求即可。

如果有不理解的地方欢迎在下方留言!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐