1.需要的依赖和工具包
首先登录美团北极星的官网,看一下接口文档,可以先下载SDK并引入jar包和工具类,下面我列出基本的依赖和我使用到的工具类
1.需要的pom.xml文件
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.75.ALL</version>
</dependency>
2.需要的工具类
关于一些公共参数的工具类,比如字符集编码,加密方式等
AppContants类
public class AppConstants {
public final static String SIGN_METHOD_MD5 = "MD5";
public final static String SIGN_METHOD_HMAC = "HMAC";
public final static String CHARSET_UTF8 = "UTF-8";
public final static String APP_SECRET = "3b54c59ffa613793d0063e4b66cc2ab5720c9653";
public final static String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss";
public final static String DATE_PATTERN = "yyyy-MM-dd";
public final static String HOST = "https://openapi.dianping.com";
}
SignUtil类
package cn.superfw.biz.platform.common;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;
public class SignUtil {
public static String signTopRequest(Map<String, String> params,
String appSecret, String signMethod)
throws IOException, NoSuchAlgorithmException {
// 第一步:检查参数是否已经排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
if (StringUtils.isNotEmpty(appSecret)) {
query.append(appSecret);
}
for (String key : keys) {
String value = params.get(key);
if (StringUtil.areNotEmpty(key, value)) {
query.append(key).append(value);
}
}
// 第三步:使用MD5/HMAC加密
byte[] bytes;
if (AppConstants.SIGN_METHOD_HMAC.equals(signMethod)) {
bytes = encryptHMAC(query.toString(), appSecret);
} else {
query.append(appSecret);
bytes = encryptMD5(query.toString());
}
// 第四步:把二进制转化为小写的十六进制
return byte2hex(bytes);
}
public static byte[] encryptHMAC(String data, String secret) {
byte[] bytes;
try {
SecretKey secretKey = new SecretKeySpec(secret.getBytes(AppConstants.CHARSET_UTF8), "HmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
bytes = mac.doFinal(data.getBytes(AppConstants.CHARSET_UTF8));
} catch (Exception e) {
throw new RuntimeException("Encrypt HMAC error", e);
}
return bytes;
}
public static byte[] encryptMD5(String info) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] infoBytes = info.getBytes("UTF-8");
md5.update(infoBytes);
return md5.digest();
}
public static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toLowerCase());
}
return sign.toString();
}
}
RequestUtil类
package cn.superfw.biz.platform.common;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
public class RequestUtil {
/**
* Map转URL的参数串。
*
* @param params 请求参数
* @return param string
*/
public static String mapToGetParam(Map<String, String> params) throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8")).append("&");
}
return sb.toString();
}
}
2.部分接口
1.美团输码验券校验接口
一下代码包括了把美团返回的数据存到数据库中,使用的是jpa,可以自行写一下bean文件在此不介绍
@PostMapping("/prepare")
@Transactional
public Object Prepare(@RequestParam("receipt_code") String receiptCode) {
Map<String,String> requestParam = new HashMap<>();
requestParam.put("app_key","d8caff0aafc5cb23");
requestParam.put("timestamp", "2018-01-22 10:10:10");
requestParam.put("format", "json");
requestParam.put("v", "1");
requestParam.put("sign_method", "MD5");
requestParam.put("session", "b77aee186816e147e01a253466413c417f96e61c");
requestParam.put("open_shop_uuid", "43e0355ad911848f24809281c6e000aa");
requestParam.put("receipt_code", receiptCode);
//验证签名,详情见签名生成说明文档
try {
requestParam.put("sign", SignUtil.signTopRequest(requestParam, AppConstants.APP_SECRET, AppConstants.SIGN_METHOD_MD5));
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Form form = Form.form();
for(Map.Entry<String, String> entry : requestParam.entrySet()){
form.add(entry.getKey(), entry.getValue());
}
//发起post请求
try {
String str = Request.Post("https://openapi.dianping.com/router/tuangou/receipt/prepare")
.bodyForm(form.build())
.setHeader("Content-Type", ContentType.create("application/x-www-form-urlencoded","UTF-8").toString())
.execute().returnContent().asString();
PreparemtRecordResult preparemtRecordResult = new PreparemtRecordResult();
PreparemtRecord preparemtRecord = new PreparemtRecord();
JSONObject jsonStr = JSONObject.parseObject(str);
preparemtRecordResult = JSONObject.toJavaObject(jsonStr,PreparemtRecordResult.class);
preparemtRecordDsl.save(preparemtRecordResult.getData()).setType("美团");
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
2.美团验券接口
//美团验券接口
@PostMapping("/consume")
public Object Consume (
@RequestParam("requestid") String requestid,
@RequestParam("receipt_code") String receipt_code,
@RequestParam("count") String count,
@RequestParam("app_shop_account") String app_shop_account,
@RequestParam("app_shop_accountname") String app_shop_accountname){
Map<String, String> requestParam = new HashMap<>();
requestParam.put("app_key", "d8caff0aafc5cb23" );
requestParam.put("timestamp", "2018-01-22 10:10:10");
requestParam.put("format", "json");
requestParam.put("v", "1");
requestParam.put("sign_method", "MD5");
requestParam.put("session", "b77aee186816e147e01a253466413c417f96e61c");
requestParam.put("open_shop_uuid", "43e0355ad911848f24809281c6e000aa");
requestParam.put("receipt_code", receipt_code);
requestParam.put("requestid", requestid);
requestParam.put("count", count);
requestParam.put("app_shop_account", app_shop_account);
requestParam.put("app_shop_accountname", app_shop_accountname);
//验证签名,详情见签名生成说明文档
try {
requestParam.put("sign", SignUtil.signTopRequest(requestParam,AppConstants.APP_SECRET, AppConstants.SIGN_METHOD_MD5));
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//构造form
Form form = Form.form();
for(Map.Entry<String, String> entry : requestParam.entrySet()){
form.add(entry.getKey(), entry.getValue());
}
//发起post请求
try {
return Request.Post("https://openapi.dianping.com/router/tuangou/receipt/consume")
.bodyForm(form.build())
.setHeader("Content-Type", ContentType.create("application/x-www-form-urlencoded","UTF-8").toString())
.execute().returnContent().asString();
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
3.查询已验券信息
@GetMapping("/getconsumed")
public Object getConsumed(@RequestParam("receipt_code") String receipt_code,
@RequestParam("open_shop_uuid")String open_shop_uuid) throws IOException {
Map<String, String> requestParam = new HashMap<>();
requestParam.put("app_key", "d8caff0aafc5cb23" );
requestParam.put("timestamp", "2018-01-22 10:10:10");
requestParam.put("format", "json");
requestParam.put("v", "1");
requestParam.put("sign_method", "MD5");
requestParam.put("session", "b77aee186816e147e01a253466413c417f96e61c");
requestParam.put("open_shop_uuid", open_shop_uuid);
requestParam.put("receipt_code", receipt_code);
//验证签名,详情见签名生成说明文档
try {
requestParam.put("sign", SignUtil.signTopRequest(requestParam,AppConstants.APP_SECRET, AppConstants.SIGN_METHOD_MD5));
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//发起get请求
return Request.Get("https://openapi.dianping.com/router/tuangou/receipt/getconsumed"
+ "?"
+ RequestUtil.mapToGetParam(requestParam))
.execute().returnContent().asString();
}
4.团购验券ui组件
这是调用美团的ui组件 页面
@GetMapping("/uiyanjuan")
public Object ui(
@RequestParam("appKey") String appKey,
@RequestParam("appShopAccountName") String appShopAccountName,
@RequestParam("appShopAccount") String appShopAccount,
@RequestParam("secret") String secret,
@RequestParam("session") String session){
Map<String,String> requestParam = new HashMap<>();
requestParam.put("app_key",appKey);
requestParam.put("timestamp", "2018-01-22 10:10:10");
requestParam.put("format", "json");
requestParam.put("v", "1");
requestParam.put("sign_method", "MD5");
requestParam.put("appShopAccountName", appShopAccountName);
requestParam.put("appShopAccount", appShopAccount);
requestParam.put("secret", secret);
requestParam.put("open_shop_uuid", "43e0355ad911848f24809281c6e000aa");
requestParam.put("session", session);
try {
return Request.Get("https://openapi.dianping.com/uisdk/coupon/cancel")
.setHeader("Content-Type", ContentType.create("application/x-www-form-urlencoded","UTF-8").toString())
.execute().returnContent().asString();
} catch (IOException e) {
e.printStackTrace();
}
return 1 ;
}
5.同步创建pos订单
//同步创建POS订单
@PostMapping("/order/posordercreate")
public Object Posordercreate(
@RequestParam("open_shop_uuid") String open_shop_uuid,
@RequestParam("order_total_amount") String order_total_amount,
@RequestParam("third_party_order_id") String third_party_order_id,
@RequestParam("payment_channel") String payment_channel) throws IOException {
Map<String, String> requestParam = new HashMap<>();
requestParam.put("app_key", "d8caff0aafc5cb23" );
requestParam.put("session", "b77aee186816e147e01a253466413c417f96e61c");
requestParam.put("timestamp", "2018-01-22 10:10:10");
requestParam.put("format", "json");
requestParam.put("v", "1");
requestParam.put("sign_method", "MD5");
requestParam.put("order_total_amount", order_total_amount);
requestParam.put("open_shop_uuid", open_shop_uuid);
requestParam.put("third_party_order_id", third_party_order_id);
requestParam.put("payment_channel", payment_channel);
try {
requestParam.put("sign", SignUtil.signTopRequest(requestParam,AppConstants.APP_SECRET, AppConstants.SIGN_METHOD_MD5));
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//构造form
Form form = Form.form();
for(Map.Entry<String, String> entry : requestParam.entrySet()){
form.add(entry.getKey(), entry.getValue());
}
//发起post请求
try {
return Request.Post("https://openapi.dianping.com/router/order/posordercreate")
.bodyForm(form.build())
.setHeader("Content-Type", ContentType.create("application/x-www-form-urlencoded","UTF-8").toString())
.execute().returnContent().asString();
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
3.测试接口
需要在美团北极星官网创建应用,扫码进入店铺,下单测试券,根据券码使用postman调用接口传参即可,UI组件需要创建个页面进行测试,需要些ajax,下面是测试ui组件的文件
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>ueditor demo</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js"
></script>
<script src="esdk-obs-browserjs.3.22.3.min.js"></script>
</head>
<body>
<input type="text" id="message" disabled="disabled">
<br>
<a href="javascript:show();"> <font>弹出框</font>
</a>
<div id="myDiv" οnclick="cancle(this);"
style="position: absolute; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.2); z-index: 998">
<div id="popupDiv"
style="position: absolute; width: 80%; height: 80%; background-color: white; position: absolute; left: 50%; top: 50%; margin-left: -40%; margin-top: -20%;">
<iframe id="myFrame" frameborder="0"
style="position: absolute; width: 100%; height: 100%; border-radius: 3px;"></iframe>
</div>
</div>
</body>
<script type="text/javascript">
var myDiv = document.getElementById("myDiv");
function myfun() {
// 隐藏myDiv
myDiv.style.display = "none";
$.ajax({
url: 'http://192.168.1.14:18301/platform/router/tuangou/receipt/meituan/ui?organize_no=123456'
, type: 'GET'
, contentType: 'application/json; charset=utf-8'
, success: function (res) {
if (res.code == 0) {
alert(JSON.stringify(res.data));
const resp = res.data;
alert('https://openapi.dianping.com/uisdk/coupon/verify?appKey='+res.data.appKey+'&openShopUuid='+res.data.open_shop_uuid+'&appShopAccountName='+res.data.appShopAccountName+'&appShopAccount='+res.data.appShopAccount+'&secret='+res.data.secret+'&session='+res.data.session);
document.getElementById('myFrame').src = 'https://openapi.dianping.com/uisdk/coupon/verify?appKey='+res.data.appKey+'&openShopUuid='+res.data.open_shop_uuid+'&appShopAccountName='+res.data.appShopAccountName+'&appShopAccount='+res.data.appShopAccount+'&secret='+res.data.secret+'&session='+res.data.session;
}
}
});
}
function cancle(obj) {
obj.style.display = "none";
}
function show() {
myDiv.style.display = "block";
}
function get(data) {
var message = document.getElementById("message");
message.value = data;
myDiv.style.display = "none";
}
window.onload = myfun;
function sendMsgToParent () {
window.parent.postMessage('子页面向父页面发送消息','*');
}
//Request.Get("https://openapi.dianping.com/uisdk/coupon/verify?app_key=" + con.get(0).getAppKey() +
// "&appShopAccountName=" + con.get(0).getAppShopAccountName() + "&appShopAccount=" +
// con.get(0).getAppShopAccount() + "&secret=" + con.get(0).getSecret() + "&session=" + con.get(0).getSession() + "&open_shop_uuid=43e0355ad911848f24809281c6e000aa")
if (typeof window.addEventListener != 'undefined') { // for ie9+、chrome
window.addEventListener('message', dealMessage, false);
} else if (typeof window.attachEvent != 'undefined') { // for ie8-
window.attachEvent('onmessage', dealMessage);
}
function dealMessage(e){
console.log(e.data);
alert(JSON.stringify(e));
myDiv.style.display = "none";
}
</script>
</html>
大概这几个接口介绍完毕,一些细节问题需要自己注意