企业应用和平台应用的区别:
(1)企业应用提交应用审核后即可上线,平台应用需上线后再完成上架审核才可在平台服务市场展示供商家订购;
(2)企业应用获取商家授权即可,平台应用需要商家在服务市场中完成订购并完成授权;
(3)由于企业应用提供大型商户整体的解决方案,平台应用承载的是中小型商户的痛点需求,平台应用会以商品的形式面向全量商户出现在应用市场中,企业应用仅对授权商户展示;
(4)目前,平台应用仅面向1万家以上商户服务规模的ISV开放申请。
一、前期开发准备
第一步:注册开发者账号
第二部:资质审核
第三部:创建企业应用
二、沙箱环境进行开发测试
代码链接:https://coding.net/u/napos_openapi/p/eleme-openapi-java-sdk/git
流程链接:https://open.shop.ele.me/openapi/documents/isvoauth
应用权限授权:需要对调用的服务进行授权,只用经过授权服务商才能进行调用
1)生成商户绑定URL
//获取商户饿了么授权URL
@Override
public ResponseInfo getAuthUrl(HttpServletRequest request) {
ResponseInfo response = new ResponseInfo();
String token = request.getHeader(PublicHeaders.KEY_TOKEN);
QingShopDto qingShopDto = getShopInfo(token, request);
logger.info("shopId:"+qingShopDto.getId()+" Get the store eleme authorization URL");
String state = String.valueOf(qingShopDto.getId());
// 实例化一个配置类
Config config = new Config(isSandbox, appKey, appSecret);
// 使用config对象,实例化一个授权类
OAuthClient client = new OAuthClient(config);
// 根据OAuth2.0中的对应state,scope和callback_url,获取授权URL
String authUrl = client.getAuthUrl( callback_url, scope, state);
response.setCode(ResponseEnum.SUCCESS.getCode());
response.setMsg(ResponseEnum.SUCCESS.getMsg());
response.setData(authUrl);
return response;
}
2)获取沙箱环境的测试店铺下单地址和用户名密码
3)设置饿了么回调地址(https)
/**
* 商户授权回调地址
* @param code
* @param state 服务商后台商户ID
* @return
*/
@RequestMapping("/callback")
public Object callback(String code, String state, HttpServletRequest request){
return elemeService.callback(code, state, request);
}
//商户授权回调逻辑处理
@Override
public ResponseInfo callback(String code, String state, HttpServletRequest request) {
logger.info("shopId:"+state+" Enter eleme store to authorize the callback of address and code ="+code);
ResponseInfo response = new ResponseInfo();
// 通过授权得到的code,以及正确的callback_url,获取token
try {
// 实例化一个配置类
Config config = new Config(isSandbox, appKey, appSecret);
// 使用config对象,实例化一个授权类
OAuthClient client = new OAuthClient(config);
Token token = client.getTokenByCode(code, callback_url);
logger.info("shopId:"+state+" get token ="+token);
//授权码换取访问令牌成功
if(token!=null && token.getAccessToken()!=null){
//进行商户饿了么绑定
QingShop qingShop = qingShopDao.getById(Integer.valueOf(state));
if(qingShop != null){
Map<String, Object> params = new HashMap<>();
params.put("type", 2);
params.put("shopId", Integer.valueOf(state));
QingAuthorization qingAuthorization = bindInfoDao.select(params);
if(qingAuthorization != null){
response.setCode(ResponseEnum.ELEME_REPETITION_AUTHORIZATION.getCode());
response.setMsg(ResponseEnum.ELEME_REPETITION_AUTHORIZATION.getMsg());
logger.info("shopId:"+state+" repetition to authorization of eleme store");
}else{
logger.info("shopId:"+state+" redis save token ="+token);
qingAuthorization = new QingAuthorization(2, new Date(), "饿了么", Integer.valueOf(state),token.getAccessToken(), token.getRefreshToken());
Integer binding = bindInfoDao.AuthorizationBinding(qingAuthorization);
if(binding>0){
//缓存商户ID和访问令牌
redisObjectTemplate.opsForValue().set("shopId"+state, JSON.toJSONString(token));
//创建延时消息进行token刷新
try {
ScheduledDto scheduledDto = new ScheduledDto();
long delay = 25*24*60*60*1000;//29天
scheduledDto.setDelay(delay);
pushMessage.sendTextMessage(destination, state, scheduledDto);
} catch (Exception e) {
logger.info("shopId:"+state+" Failed to create refresh token message");
e.printStackTrace();
}
response.setCode(ResponseEnum.SUCCESS.getCode());
response.setMsg(ResponseEnum.SUCCESS.getMsg());
response.setData(token);
}else{
response.setCode(ResponseEnum.ELEME_AUTHORIZATION_FAILURE.getCode());
response.setMsg(ResponseEnum.ELEME_AUTHORIZATION_FAILURE.getMsg());
logger.info("shopId:"+state+" Failed to authorization of eleme store");
}
}
}else{
response.setCode(ResponseEnum.SHOP_NOT_USER.getCode());
response.setMsg(ResponseEnum.SHOP_NOT_USER.getMsg());
logger.info("shopId:"+state+" store does not exist");
}
}else{
response.setCode(ResponseEnum.ELEME_AUTHORIZATION_FAILURE.getCode());
response.setMsg(ResponseEnum.ELEME_AUTHORIZATION_FAILURE.getMsg());
logger.info("shopId:"+state+" Failed to get eleme authorization token");
}
} catch (Exception e) {
response.setCode(ResponseEnum.ELEME_AUTHORIZATION_FAILURE.getCode());
response.setMsg(ResponseEnum.ELEME_AUTHORIZATION_FAILURE.getMsg());
logger.info("shopId:"+state+" Failed to authorization of eleme store");
e.printStackTrace();
}
return response;
}
4)通过商户信息查找对应的店铺ID
// 实例化一个配置类
Config config = new Config(isSandbox, appKey, appSecret);
Token access_token = new Token();
access_token.setAccessToken(qingAuthorization.getAccessToken());
UserService userService = new UserService(config, access_token);
//查找商户信息
OUser user;
try {
user = userService.getUser();
} catch (Exception e) { //鉴权令牌失效
e.printStackTrace();
logger.error("shopId:"+id+" eleme authentication token is invalid");
response.setCode(ResponseEnum.ELEME_AUTHENTICATION_TOKEN_INVALID.getCode());
response.setMsg(ResponseEnum.ELEME_AUTHENTICATION_TOKEN_INVALID.getMsg());
return response;
}
//查找商户的店铺信息
List<OAuthorizedShop> authorizedShops = user.getAuthorizedShops();
List<OShop> shops = new ArrayList<OShop>();
for (OAuthorizedShop oAuthorizedShop : authorizedShops) {
//查找店铺信息
ShopService shopService = new ShopService(config, access_token);
OShop shop = shopService.getShop(oAuthorizedShop.getId());
shops.add(shop);
if(shops!=null && shops.size()>1){ //为总店铺授权
//商户解除授权绑定
bindInfoDao.cancelAuthorization(qingAuthorization.getId());
//解除店铺授权
//redisObjectTemplate.delete("shopId"+id);
logger.info("shopId:"+id+" Release the authorization of the general store");
response.setCode(ResponseEnum.ELEME_GENERAL_STORE_AUTHORIZATION.getCode());
response.setMsg(ResponseEnum.ELEME_GENERAL_STORE_AUTHORIZATION.getMsg());
return response;
}
}