涉及接口 hotel.order.create、hotel.order.detail
demo语言: Java
开发环境:
前端 jQuery类库、layui、 bootstrap
后端 jdk1.7以上、 tomcat8以上、 springmvc + spring + mybatis
下单前rp相关数据校验之后创建订单,本地保存订单数据,之后调用订单详情接口回显订单数据
注意
1. 艺龙下单接口的超时时间为30s,建议代理也设置为30s,不然如果这边返回时间较长,代理接收为null
2. 代理不能通过接收结果为null或空字符串判断下单失败,应该根据返回码是否错误判断
3. 如果返回null,则应该隔30秒左右重新用相同参数下单,最多重试5次即可,如果之前下单成功,则返回之前的订单。
请求url
下单页面,选择rateplan和房间数量、填写联系人,手机号等参数
var createUrl = "/api/order/createOrder"; // 下单请求controller
var createReq = {
"userName": $('#inputUser').val(),
"arrivalDate": arrivalDate,
"departureDate": $("#inputDepartureDate").val(),
"hotelId": $("#inputHotelId").val(),
"roomTypeId": $("#inputRoomTypeId").val(),
"ratePlanId": $("#inputRatePlanId").val(),
"earliestArrivalTime": (nextHour.substring(0,1) == "0"
? arrivalNextDate: arrivalDate) + " " + nextHour + ":00",
"latestArrivalTime": ($('#btnArrivalTime').attr("value").substring(0,1) == "0"
? arrivalNextDate: arrivalDate) + " " + $('#btnArrivalTime').attr("value"),
"paymentType": $('#inputPaymentType').val(),
"numberOfRooms": $("#btnRoomNum").attr("value"),
"currencyCode": $('#inputTotalRate').attr("currencyCode"),
"totalPrice": parseFloat($('#inputTotalRate').val()),
"needInvoice": needInvoice,
"invoice": invoice,
"customerType": $('#inputCustomerType').val(),
"customers": customerString,
"contactName": $('#inputContactName').val(),
"contactPhone": $('#inputContactPhone').val()
};js请求后端
提交后端后返回下单结果,如果下单成功,调整到订单详情页面,如果显示失败原因
// 请求下单参数
var createResult = ajaxCommonForJson(createUrl, "POST", createReq);
// 处理下单结果
if (createResult != null) {
if (createResult.success) {
window.location.href = '/view/order/detail?user=' + $('#inputUser').val() + '&orderId=' + createResult.orderId;
} else {
alert(createResult.errorMessage);
}
}创建订单
后端通过http协议调用艺龙的hotel.order.create接口
public class HotelOrderCreateApi {
private static double version = 1.50;
private static EnumLocal locale = EnumLocal.zh_CN;
private static boolean isHttps = true; // 测试环境换为false
...
...
/**
* 通过http工具类调用艺龙接口,将前端参数拼接为URL
*/
public OrderCreateResult createOrder(CreateOrderCondition condition,
String userName, String appKey, String secretKey) {
OrderCreateResult result = new OrderCreateResult();
String url = "";
String responseData = "";
try{
//产生签名
Long epoch = System.currentTimeMillis()/1000;
if (condition.getCreditCard() != null) {
condition.getCreditCard().setNumber(CipherUtil.desEncrypt(epoch.toString()
+"#"+condition.getCreditCard().getNumber(),
appKey.substring(appKey.length()-8)));
}
BaseRequest<CreateOrderCondition> req = new BaseRequest<CreateOrderCondition>();
req.Version = version;
req.Local = locale;
req.Request = condition;
//请求参数转换为Json字符串
String str = JsonUtil.entity2Json(req);
String sig = Tool.md5(epoch + Tool.md5(str + appKey) + secretKey);
//产生请求链接
url = "http"+(this.isHttps ? "s": "")+ "://"
+ serverHost + "/rest?format=json&method=hotel.order.create";
url += "&user="+ userName +"×tamp=";
url += epoch;
url += "&signature=";
url += sig;
url += "&data=" + Tool.encodeUri(str);
log.info(url);
//发送请求
responseData = HttpUtil.Send("GET", url, "", "application/json");
//返回值处理
result = JsonUtil.jsonToObject(responseData, OrderCreateResult.class);
} catch (Exception e) {
log.info("[HotelOrderCreateApi] 异常: " + e);
log.info("发送的url: " + url);
log.info("返回值: " + responseData);
}
return result;
}
...
...
}保存订单信息
下单成功后,将订单保存到数据库中, 数据库表见sdk
// 创建数据库插入对象
OrderDo orderDo = new OrderDo();
orderDo.setOrderId(createResult.getResult().getOrderId());
orderDo.setAffiliateConfirmationId(affiliateConfirmationId);
orderDo.setUserId(request.getUserName());
orderDo.setBookingTime(new Date());
orderDo.setHotelId(request.getHotelId());
orderDo.setRoomTypeId(request.getRoomTypeId());
orderDo.setRatePlanId(request.getRatePlanId());
...
...
// 需要请求订单详情才能得知的信息
// 获取订单详情
OrderIdCondition orderIdCondition = new OrderIdCondition();
orderIdCondition.setOrderId(createResult.getResult().getOrderId());
try {
OrderInfoResult orderInfoResult = hotelOrderDetailApi.Invoke(orderIdCondition);
if (orderInfoResult != null) {
if (orderInfoResult.getCode().equals("0")) {
OrderDetailResult orderDetail = orderInfoResult.getResult();
orderDo.setStatus(orderDetail.getStatus());
orderDo.setShowStatus(orderDetail.getShowStatus());
orderDo.setHotelName(orderDetail.getHotelName());
orderDo.setRoomName(orderDetail.getRoomTypeName());
orderDo.setRatePlanName(orderDetail.getRatePlanName());
orderDo.setCancelTime(orderDetail.getCancelTime());
} else {
logger.error(orderInfoResult.getCode());
}
} else {
logger.error("请求订单详情超时或网络错误");
}
} catch (Exception e) {
// 捕获异常,以免影响正常的数据库操作
logger.error(e);
}
...
...
// 调用dao对象将数据存入数据库
try {
if (orderDao.addOrder(orderDo) < 1) {
logger.error("【数据库操作失败,订单信息:】" + JsonUtil.entity2Json(orderDo));
}
} catch (Exception e) {
// 捕获异常,以免影响正常的返回操作
logger.error("【数据库操作异常,订单信息:】" + JsonUtil.entity2Json(orderDo));
}
...订单详情
后端通过http协议调用艺龙的hotel.order.detail接口,进行订单详情回显
public class HotelOrderDetailApi {
private static double version = 1.50;
private static EnumLocal locale = EnumLocal.zh_CN;
private static boolean isHttps = true; // 测试环境换为false
...
...
/**
* 通过http工具类调用艺龙接口,将前端参数拼接为URL
*/
public HotelOrderDetailResult getOrderDetail(OrderIdCondition condition,
String userName, String appKey, String secretKey) {
HotelOrderDetailResult result = new HotelOrderDetailResult();
String url = "";
String responseData = "";
try{
BaseRequest<OrderIdCondition> req = new BaseRequest<OrderIdCondition>();
req.Version = version;
req.Local = locale;
req.Request = condition;
//请求参数转换为Json字符串
String str = JsonUtil.entity2Json(req);
//产生签名
long epoch = System.currentTimeMillis()/1000;
String sig = Tool.md5(epoch + Tool.md5(str + appKey) + secretKey);
//产生请求链接
url = "http"+(this.isHttps ? "s": "")+ "://"
+ serverHost + "/rest?format=json&method=hotel.order.detail";
url += "&user="+ userName +"×tamp=";
url += epoch;
url += "&signature=";
url += sig;
url += "&data=" + Tool.encodeUri(str);
//发送请求
responseData = HttpUtil.Send("GET", url, "", "application/json");
//返回值处理
result = JsonUtil.jsonToObject(responseData, HotelOrderDetailResult.class);
} catch (Exception e) {
log.info("[HotelOrderDetailNgApi] 异常: " + e);
log.info("发送的url: " + url);
log.info("返回值: " + responseData);
}
return result;
}
...
...
}效果展示
下单成功后,跳转到订单详情页面

