Browse Source

停车厂商

release_toaliyun_real
Stormeye.Wu 7 years ago
parent
commit
91ee79becc
6 changed files with 2094 additions and 21 deletions
  1. +21
    -21
      mallinkCApi/src/main/java/com/simple/controller/BaseController.java
  2. +670
    -0
      mallinkCApi/src/main/java/com/simple/controller/WxCarController.java
  3. +13
    -0
      mallinkService/src/main/java/com/simple/common/ErrorCode.java
  4. +38
    -0
      mallinkService/src/main/java/com/simple/enums/EnumCarVendor.java
  5. +804
    -0
      mallinkService/src/main/java/com/simple/utils/ETCPUtil.java
  6. +548
    -0
      mallinkService/src/main/java/com/simple/utils/TJDCarUtil.java

+ 21
- 21
mallinkCApi/src/main/java/com/simple/controller/BaseController.java View File

@@ -11,25 +11,25 @@ import org.springframework.web.bind.annotation.RestController;

@RestController
public class BaseController {
@InitBinder
public void InitBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
public void setAsText(String value) {
try {
setValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value));
} catch(ParseException e) {
try {
setValue(new SimpleDateFormat("yyyy-MM-dd ").parse(value));
} catch (ParseException e1) {
setValue(null);
}
}
}
public String getAsText() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) getValue());
}
});
}
@InitBinder
public void InitBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
public void setAsText(String value) {
try {
setValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value));
} catch (ParseException e) {
try {
setValue(new SimpleDateFormat("yyyy-MM-dd ").parse(value));
} catch (ParseException e1) {
setValue(null);
}
}
}
public String getAsText() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) getValue());
}
});
}
}

+ 670
- 0
mallinkCApi/src/main/java/com/simple/controller/WxCarController.java View File

@@ -0,0 +1,670 @@
package com.simple.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.simple.common.ErrorCode;
import com.simple.common.Result;
import com.simple.common.ResultData;
import com.simple.domain.po.WxCarCmdLogs;
import com.simple.domain.po.WxPark;
import com.simple.enums.EnumCarVendor;
import com.simple.service.WxCarCmdLogsService;
import com.simple.service.WxParkService;
import com.simple.utils.ETCPUtil;
import com.simple.utils.TJDCarUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("car")
public class WxCarController extends BaseController
{
private Logger logger = Logger.getLogger(WxCarController.class);

ETCPUtil etcp = new ETCPUtil();

TJDCarUtil tjd = new TJDCarUtil();

@Autowired
WxParkService wxParkService;



private WxPark getCurrentPark() {
// 1, get mall's park
// future use redis to optimize
final PageInfo<WxPark> wxParkList = wxParkService.listAsPage(new WxPark(), 1, 1);
if (wxParkList.getSize() <= 0) {
return null;
}
WxPark park = wxParkList.getList().get(0);
return park;
}

@ApiOperation(value = "获取车场支持的厂家",notes="")
@GetMapping("getVendor")
public ResultData getVendor() {
// 1, get mall's park
WxPark park = getCurrentPark();
Map map = new HashMap();
map.put("vendor", park.getVendorType());
return new ResultData(map);
}

/**
* 初始化/etcp共同登录
* @param paramMap
* @return
*/
@ApiOperation(value = "初始化/etcp共同登录",notes="{\"phone\":\"string\"}")
@PostMapping("init")
public ResultData init(Map<String, String > paramMap) {
// 1, get mall's park
WxPark park = getCurrentPark();
// 2. get vendor params
if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
String phone = paramMap.get("phone");
if (StringUtils.isBlank(phone)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "phone为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String appId = objParams.getString("appId");
String merchantNo = objParams.getString("merchantNo");
String merchantKey = objParams.getString("merchantKey");
String version = objParams.getString("version");

String ret = etcp.userSignin(url, appId, merchantNo, merchantKey, version, phone);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("code") == 0) {
// 获取绑定的车牌
JSONObject dataObj = retObj.getJSONObject("data");
String etcpToken = dataObj.getString("token");
// TODO 异步
ret = etcp.carNum(url, merchantNo, merchantKey, version, etcpToken);
/*
{
"code": 0,
"msg": "ok",
"data": {
"number": 3,
"carList": [
"晋 BMZ105",
"云 C12345"
]
}
}
*/
retObj = JSON.parseObject(ret);
JSONObject dataObj1 = retObj.getJSONObject("data");
dataObj1.put("vendor", park.getVendorType());
JSONArray arr = dataObj1.getJSONArray("carList");
for(int i=0;i<arr.size();i++) {
// TODO save car
}
// c端必须保存此token
return new ResultData(dataObj1);
} else {
return new ResultData(ErrorCode.ETCP_LOGIN_FAIL.getCode(), "共同登录失败");
}
} else if (park.getVendorType() == EnumCarVendor.CAR_TJD.getCode()){
// TJD不需要共同登录
return new ResultData();
}

return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "登录失败");
}

/**
* 绑车牌
* @param paramMap
* @return
*/
@ApiOperation(value = "绑车牌", notes = "ETCP:={\"etcpToken\":\"string\",\"carNumber\":\"string\"}\n" +
"TJD:={\"carNumber\":\"string\",\"carNumColor\":\"string\",\"outCarId\":\"string\"}")
@PostMapping("bindCar")
public ResultData bindCar(Map<String, String > paramMap) {
// 1, get mall's park
WxPark park = getCurrentPark();
// 2. get vendor params
if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
String etcpToken = paramMap.get("etcpToken");
if (StringUtils.isBlank(etcpToken)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
}
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String merchantNo = objParams.getString("merchantNo");
String merchantKey = objParams.getString("merchantKey");
String version = objParams.getString("version");

String ret = etcp.bindCar(url, merchantNo, merchantKey, version, etcpToken, carNumber, null);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("code") == 0) {
// TODO insert carNumber
JSONObject dataObj = retObj.getJSONObject("data");
dataObj.put("vendor", park.getVendorType());
return new ResultData(dataObj);
} else {
return new ResultData(ErrorCode.ETCP_BIND_FAIL.getCode(), "绑车牌失败");
}
}
else if (park.getVendorType() == EnumCarVendor.CAR_TJD.getCode()) {
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
String carNumColor = paramMap.get("carNumColor");
if (StringUtils.isBlank(carNumColor)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumColor为空");
}
String outCarId = paramMap.get("outCarId");
if (StringUtils.isBlank(outCarId)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "outCarId为空");
}
// TODO insert carNumber
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String partner = objParams.getString("partner");
String key = objParams.getString("key");
String version = objParams.getString("version");
String ret = tjd.registerCar(url, partner, key, version,
carNumber, carNumColor, null, outCarId);
/*
{
"timestamp": "1464235239561",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
"carId": "5836b8b52ada463ebc6199579f029561"
}
*/
JSONObject retObj = JSON.parseObject(ret);
retObj.put("vendor", park.getVendorType());
if (retObj.getString("returnCode") == "T") {
// TODO save car id
String carId = retObj.getString("carId");
return new ResultData(retObj);
} else {
return new ResultData(ErrorCode.TJD_BIND_FAIL.getCode(), "绑车牌失败", retObj);
}
}
return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "绑车牌失败");
}

/**
* 解绑车牌
* @param paramMap
* @return
*/
@ApiOperation(value = "解绑车牌", notes = "ETCP:={\"etcpToken\":\"string\",\"carNumber\":\"string\"}\n" +
"TJD:={\"carNumber\":\"string\",\"carNumColor\":\"string\",\"outCarId\":\"string\"}")
@PostMapping("unbindCar")
public ResultData unbindCar(Map<String, String > paramMap) {
// 1, get mall's park
WxPark park = getCurrentPark();
if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
String etcpToken = paramMap.get("etcpToken");
if (StringUtils.isBlank(etcpToken)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
}
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String merchantNo = objParams.getString("merchantNo");
String merchantKey = objParams.getString("merchantKey");
String version = objParams.getString("version");


String ret = etcp.unbindCar(url, merchantNo, merchantKey, version, etcpToken, carNumber);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("code") == 0) {
// TODO delete carNumber
return new ResultData();
} else {
return new ResultData(ErrorCode.ETCP_UNBIND_FAIL.getCode(), "解绑车牌失败");
}
}
else if (park.getVendorType() == EnumCarVendor.CAR_TJD.getCode()) {
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
String carId = paramMap.get("carId");
if (StringUtils.isBlank(carId)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carId为空");
}
// TODO to get TJD carId
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String partner = objParams.getString("partner");
String key = objParams.getString("key");
String version = objParams.getString("version");
String ret = tjd.writeOffCar(url, partner, key, version, carId);
/*
{
"timestamp": "1464235239561",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
"carId": "5836b8b52ada463ebc6199579f029561"
}
*/
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getString("returnCode") == "T") {
// TODO remove carNumber
return new ResultData();
} else {
return new ResultData(500, "解绑车牌失败");
}
}
return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "解绑车牌失败");
}

/**
* 停车费
* @param paramMap
* @return
*/
@ApiOperation(value = "停车费", notes = "ETCP:={\"etcpToken\":\"string\",\"carNumber\":\"string\"}\n" +
"TJD:={\"carNumber\":\"string\",\"carNumColor\":\"string\",\"outCarId\":\"string\"}")
@PostMapping("getCarStopFee")
public ResultData getCarStopFee(Map<String, String > paramMap) {
// 1, get mall's park
WxPark park = getCurrentPark();
if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
String etcpToken = paramMap.get("etcpToken");
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(etcpToken)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
}
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String appId = objParams.getString("appId");
String merchantNo = objParams.getString("merchantNo");
String merchantKey = objParams.getString("merchantKey");
String version = objParams.getString("version");

String ret = etcp.orderUnpay(url, appId, merchantNo, merchantKey, version, etcpToken, carNumber);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("code") == 0) {
// TODO 停车费
/*
{
"carNumber": "渝****87",
"entranceTime": "2017-06-11 11:19:27",
"exitTime": "2017-06-11 11:59:47",
"orderId": "B9466E26-7420-4BDF-958D-E90106AB5F20", "parkingFee": 2.00,
"remainingServiceFee": 0,
"payedServiceFee": 0,
"remainingParkFee": 2.00,
"discountAmount": 0,
"parkingId": 3126,
"parkingName": "ETCP 停车场",
"remainingFee": 2.00,
"paidFee": 0,
"verificationInfo": "FSED9JvxgAU6XJUd8YRF5YH/LpfQYzCAfcPbAOKPV3BjKSatbgIsh7EBH2JBiRoGBe3btr gzKRMTfIoFuCn1XX7HUsJYlb7JSCBArnNmEVU4JuDLLjzoqB7qhQ8KnP16"
}
*/
JSONObject feeObj = retObj.getJSONArray("data").getJSONObject(0);
feeObj.put("vendor", park.getVendorType());
return new ResultData(feeObj);
} else {
return new ResultData(ErrorCode.ETCP_STOP_FEE_FAIL.getCode(), "停车费获取失败");
}
}
else if (park.getVendorType() == EnumCarVendor.CAR_TJD.getCode()) {
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
// TODO to get TJD carId
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String partner = objParams.getString("partner");
String key = objParams.getString("key");
String version = objParams.getString("version");
String ret = tjd.infoForFreeMins(url, partner, key, version, carNumber);
/*
{
"inDt": "20160526112000",
"timestamp": "1464235239561",
"returnCode": "T",
"errorMsg": "",
"tradeId": "d49aeaedcf144f1faf569846d6b1667e",
"parkTime": "2439593",
"returnMsg": "OK",
"totalAmount": "0.03",
"isSuccess": "0",
"unPayAmount": "0.03",
"paidAmount": "0.00",
"freeThroughTime": "15",
"outDt": "20170321121212",
"payUrl": "http://prep.tingjiandan.com/tcweixin/letter/prePay/payInPark.html?
prePayType=16&channel=10001",
"accountId": "d49aeaedcf144f1faf569846d6b16671",
"freeMinsAmount": "0.00",
"pmParkId": "d49aeaedcf144f1faf569846d6b16670"
}
*/
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getString("returnCode") == "T") {
// TODO remove carNumber
return new ResultData(retObj);
} else {
return new ResultData(ErrorCode.TJD_STOP_FEE_FAIL.getCode(), "停车费获取失败");
}
}
return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "停车费获取失败");
}

/**
* 停车费抵扣
*
*/
@ApiOperation("停车费抵扣")
@PostMapping("deductionFee")
public ResultData deductionFee(Map<String, String > paramMap) {
/// 1, get mall's park
WxPark park = getCurrentPark();
if (park.getVendorType() == EnumCarVendor.CAR_TJD.getCode()) {
String tradeId = paramMap.get("tradeId");
String deductionAmount = paramMap.get("deductionAmount");
// TODO out wx_records id
String outTradeNo = paramMap.get("outTradeNo");
String accountId = paramMap.get("accountId");
if (StringUtils.isBlank(tradeId)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "tradeId为空");
}
if (StringUtils.isBlank(deductionAmount)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "deductionAmount为空");
}
if (StringUtils.isBlank(outTradeNo)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "outTradeNo为空");
}
if (StringUtils.isBlank(accountId)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "accountId为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String partner = objParams.getString("partner");
String key = objParams.getString("key");
String version = objParams.getString("version");
String ret = tjd.deductionNotSettle(url, partner, key, version, tradeId, deductionAmount, outTradeNo, accountId);
/*
{
"timestamp": "1464235239561",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
"carId": "5836b8b52ada463ebc6199579f029561"
}
*/
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getString("returnCode") == "T") {
// TODO remove carNumber
return new ResultData();
} else {
return new ResultData(ErrorCode.TJD_DEDUCE_FEE_FAIL.getCode(), "停车费抵扣失败");
}
}
return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "停车费抵扣失败");
}

// 优免券模板
/*
{
"id": 4974, //优免券模板 ID
"parkId": "fbqXUlfVvfc=", //车场标识
"businessId": "ZcWQ26TeJuQ=", //商家标识
title -- "businessName": "天洋广场", //商家名称
subtitle -- "name": "商家 1 小时优免券", //优免券名称
"category": "1", //优免券类型 1:小时优惠券,2:金额优惠券,3:折扣优惠券,4:免费券
price -- "categoryValue": "1.00", //优免券价值
total -- "amount": 100000, //优免券数量
valid_start_date -- "effectiveStart": "2018-02-01", //生效开始时间
valid_end_date -- "effectiveEnd": "2028-02-01",//生效结束时间
-"couponType": "0",//优惠券类型
number 库存 -- "avaliavleNum": 99993 //可用优惠券
},
*/
@ApiOperation("优免券模板")
@PostMapping("quanTemplate")
public ResultData quanTemplate(Map<String, String > paramMap) {
/// 1, get mall's park
WxPark park = getCurrentPark();
if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String merchantNo = objParams.getString("merchantNo");
String merchantKey = objParams.getString("merchantKey");
String version = objParams.getString("version");
String parkId = objParams.getString("parkId");
// bussinessId from 参数信息
String businessId = paramMap.get("businessId");
if (StringUtils.isBlank(businessId)) {
// TODO 1期只有一个虚拟商户,可以写在商场配置里
businessId = objParams.getString("businessId");
}
String ret = etcp.getBCouponList(url, merchantNo, merchantKey, version, parkId, businessId);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("code") == 0) {
/*
"data": {
"count": 4, "couponPlatformModels": [
{
"id": 4974, //优免券模板 ID
"parkId": "fbqXUlfVvfc=", //车场标识 "businessId": "ZcWQ26TeJuQ=", //商家标识 "businessName": "天洋广场", //商家名称 "name": "商家 1 小时优免券", //优免券名称 "category": "1", //优免券类型
1:小时优惠券,2:金额优惠券,3:折扣优惠券,4:免费券 "categoryValue": "1.00", //优免券价值
"amount": 100000, //优免券数量
"effectiveStart": "2018-02-01", //生效开始时间
"effectiveEnd": "2028-02-01",//生效结束时间
"couponType": "0",//优惠券类型
"avaliavleNum": 99993 //可用优惠券
},
{...},
{...}
]
*/
return new ResultData(retObj.getJSONObject("data"));
} else {
return new ResultData(ErrorCode.ETCP_QUAN_TEMP_FAIL.getCode(), "优免券模板未发现");
}
}
return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "优免券模板失败");
}

/**
* 优免券领取
* 优免券不可退
*/
@ApiOperation(value = "优免券领取", notes="ETCP:={\"etcpToken\":\"string\",\"carNumber\":\"string\",\"couponFreeId\":\"string\"}")
@PostMapping("getCoupon")
public ResultData getCoupon(Map<String, String > paramMap) {
/// 1, get mall's park
WxPark park = getCurrentPark();
if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) {
String etcpToken = paramMap.get("etcpToken");
String carNumber = paramMap.get("carNumber");
String couponFreeId = paramMap.get("couponFreeId");
if (StringUtils.isBlank(etcpToken)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "etcpToken为空");
}
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
if (StringUtils.isBlank(couponFreeId)) {
return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "couponFreeId为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String url = objParams.getString("url");
String merchantNo = objParams.getString("merchantNo");
String merchantKey = objParams.getString("merchantKey");
String version = objParams.getString("version");
String parkId = objParams.getString("parkId");
String businessId = paramMap.get("businessId");
if (StringUtils.isBlank(businessId)) {
// TODO 1期只有一个虚拟商户,可以写在商场配置里
businessId = objParams.getString("businessId");
}

String ret = etcp.bCouponRecord(url, merchantNo, merchantKey, version,
etcpToken, parkId, businessId, carNumber, couponFreeId);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("code") == 0) {
return new ResultData();
} else {
return new ResultData(ErrorCode.ETCP_QUAN_SEND_FAIL.getCode(), "优免券领取失败");
}
}
return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "优免券领取失败");
}

// callback
// ETCP 车辆入场通知
@RequestMapping(value = "/etcpParkInCallback")
public Result etcpParkInCallback(@RequestParam Map<String,String> param) {
/*
{
"synId": "4ebd80ff-cfcf-462a-94cb-727e9fa9547c",
"plateNumber": "渝 ATX061",
"parkName": "ETCP 智慧停车场",
"parkId": "1",
"entranceTime": "2017-08-20 12:59:54",
"userType": "76",
"pushTime": "2017-08-20 12:59:57",
"fixParkingId": "U7",
"remainingDays": "11" }
*/
return new Result(0, "ok");
}
// ETCP 车辆出场通知
@RequestMapping(value = "/etcpParkOutCallback")
public Result etcpParkOutCallback(@RequestParam Map<String,String> param) {
/*
{
"synId": "fd92f645-880e-4c2a-9d7d-7081a2488181",
"plateNumber": "渝 ATX061",
"parkName": "ETCP 智慧停车场",
"parkId": "1",
"entranceTime": "2017-08-17 18:44:19",
"userType": "76",
"pushTime": "2017-08-20 11:57:51",
"exitTime": "2017-08-19 12:07:19",
"stayedTime": 148980,
"receivableFee": 0,
"paidServiceFee": 0,
"fixParkingId": "U7",
"remainingDays": "12"
}
*/
return new Result(0, "ok");
}
// ETCP 车辆解绑通知
@RequestMapping(value = "/etcpUnbindCarCallBack")
public Result etcpUnbindCarCallBack(@RequestParam Map<String,String> param) {
/*
{
"plateNumber": "渝 ATX061",
"time": "2017-08-20 11:57:51"
}
*/
return new Result(0, "ok");
}
// ETCP 主动支付结果通知
@RequestMapping(value = "/etcpPaidCallback")
public Result etcpPaidCallback(@RequestParam Map<String,String> param) {
/*
{
"plateNumber": "渝 ATX061",
"orderId": "fd92f645-880e-4c2a-9d7d-7081a2488181",
"fee": 7.65,
"paidServiceFee": 0.07,
"coupon": 0,
"time": "2017-08-20 11:57:51"
}
*/
return new Result(0, "ok");
}
// TJD 车辆入场通知
@RequestMapping(value = "/tjdParkInCallback")
public Map tjdParkInCallback(@RequestParam Map<String,String> param) {
/*
{
"tradeId": "5836b8b52ada463ebc6199579f029565",
"outCarId": "45454545454",
"carNum": "京A45413",
"carNumColor ": "blue",
"inDt": "20170319202020",
"parkName": "测试停车场",
"parkId": "5836b8b52ada463ebc6199579f029561",
"lon": "74.000272",
"lat": "159.768703",
"wLon": "123.523032",
"wLat": "35.430735",
"payUrl": "http://prep.tingjiandan.com/tcweixin/letter/prePay/payInPark.html?prePayType=16&channel=10001",
"canFindCar": "0"
}
*/
Map map = new HashMap();
map.put("isSuccess", "0");
map.put("errorMsg", "");
return map;
}
// TJD 车辆出场通知
@RequestMapping(value = "/tjdParkoutCallback")
public Map tjdParkOutCallback(@RequestParam Map<String,String> param) {
/*
{
"tradeId": "5836b8b52ada463ebc6199579f029565",
"outDt": "20170319232020",
"lon": "74.000272",
"lat": "159.768703",
"wLon": "123.523032",
"wLat": "35.430735",
"parkAmount": "5.20"
}
*/
Map map = new HashMap();
map.put("isSuccess", "0");
map.put("errorMsg", "");
return map;
}
}

+ 13
- 0
mallinkService/src/main/java/com/simple/common/ErrorCode.java View File

@@ -45,6 +45,19 @@ public enum ErrorCode{
/**
* 车流 2050
*/
CAR_VENDOR_NOT_SUPPORT(2050, "不支持的停车厂家"),
ETCP_LOGIN_FAIL(2051, "ETCP共同登录失败"),
ETCP_BIND_FAIL(2052, "ETCP绑车牌失败"),
ETCP_UNBIND_FAIL(2053, "ETCP解绑车牌失败"),
ETCP_STOP_FEE_FAIL(2054, "ETCP停车费失败"),
ETCP_QUAN_TEMP_FAIL(2055, "ETCP优免券模板失败"),
ETCP_QUAN_SEND_FAIL(2056, "ETCP优免券发放失败"),

TJD_BIND_FAIL(2060,"TJD绑车牌失败"),
TJD_UNBIND_FAIL(2061,"TJD解绑车牌失败"),
TJD_STOP_FEE_FAIL(2062, "TJD停车费失败"),
TJD_DEDUCE_FEE_FAIL(2063, "TJD停车费抵扣失败"),


/**
* 订单


+ 38
- 0
mallinkService/src/main/java/com/simple/enums/EnumCarVendor.java View File

@@ -0,0 +1,38 @@
package com.simple.enums;

/**
* Created by Stormeye on 2018/08/09.
*/
public enum EnumCarVendor {

// 1-ETCP, 2-TJD

CAR_ETCP(1, "ETCP"),
CAR_TJD(2, "TJD")
;

public static EnumCarVendor getEnum(Integer code) {
for (EnumCarVendor value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumCarVendor(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 804
- 0
mallinkService/src/main/java/com/simple/utils/ETCPUtil.java View File

@@ -0,0 +1,804 @@
package com.simple.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
* @Title: OpenapiCaller
* @Package: cn.etcp.openplatform.service
* @Description: ETCP开放平台接口调用示例
* @author: zhiyong.fan
* @date: 2018/3/8 17:41
* @version: V1.0
*/
public class ETCPUtil {

private static final Logger logger = LoggerFactory.getLogger(ETCPUtil.class);

/**
* 域名地址
*/
private static final String domain = "http://mapi.test.etcp.cn";

//
private static final String appId = "FMLK";

private static final int payType = 5;

/**
* 商户号 测试时请换成ETCP开放平台为商户平台分配的商户号
*/
private static final String merchantNo = "C7AEAF80BA8C44ADB42F3DB3CBC7D18A";

/**
* 商户密钥 测试时请换成ETCP开放平台为商户平台分配的商户密钥
*/
private static final String merchantKey = "C292FFC7DCFB46AFB02792CD43F6DCC7";

/**
* 接口服务版本号
*/
private static final String version = "1.0.0";

/**
* 6.1. 联合登录
*/
private static final String userSigninUrl = "/merchant/open/{version}/openapi/usersigin";

/**
* 7.1. 车牌绑定
*/
private static final String bindCarUrl = "/merchant/open/{version}/openapi/bindcar";

/**
* 7.2. 车牌解绑
*/
private static final String unbindCarUrl = "/merchant/open/{version}/openapi/unbindcar";

/**
* 7.3. 车牌认证
*/
private static final String carAuthUrl = "/merchant/open/{version}/openapi/carauth";

/**
* 7.4. 车牌找回
*/
private static final String carRetrieveUrl = "/merchant/open/{version}/openapi/carretrieve";

/**
* 7.5. 已绑车辆信息查询
*/
private static final String carNumUrl = "/merchant/open/{version}/openapi/carnum";

/**
* 8.1. 停车费查询
*/
private static final String orderUnpayUrl = "/merchant/open/{version}/openapi/orderunpay";

/**
* 8.2. 优惠券查询
*/
private static final String couponListUrl = "/merchant/open/{version}/openapi/couponlist";

/**
* 8.3. 历史停车查询
*/
private static final String orderHistoryUrl = "/merchant/open/{version}/openapi/orderhistory";

/**
* 9.1. 主动支付(ETCP 收款)
*/
private static final String orderpayUrl = "/merchant/open/{version}/openapi/orderpay";

/**
* 9.2. 主动支付(商户平台收款)
*/
private static final String orderPaidUrl = "/merchant/open/{version}/openapi/orderpaid";

/**
* 10.1. 签约地址获取
*/
private static final String signUrl = "/merchant/open/{version}/withhold/sign";

/**
* 10.2. 签约状态查询
*/
private static final String statusUrl = "/merchant/open/{version}/withhold/status";

/**
* 11.1. 车场信息查询
*/
private static final String parkingInfoUrl = "/merchant/open/{version}/openapi/surroundingparking";

/**
* 11.2. 车场状态查询
*/
private static final String parkingStatusUrl = "/merchant/open/{version}/openapi/parkingstatus";

/**
* 12.1. 坏账查询
*/
private static final String getDebtUrl = "/merchant/open/{version}/openapi/getdebt";

/**
* 12.2. 坏账清缴
*/
private static final String repayDebtUrl = "/merchant/open/{version}/openapi/repaydebt";

/**
* 13.1. 商家优免券模板查询
*/
private static final String bCouponListUrl = "/merchant/open/{version}/openapi/b/coupon/list";

/**
* 13.2. 商家优免券发放
*/
private static final String bCouponRecordUrl = "/merchant/open/{version}/openapi/b/coupon/record";

/**
* 14.1. 车辆进出场模拟接口
*/
private static final String bCarSimulationUrl = "/merchant/open/{version}/openapi/car/simulation";

private final OkHttpClient client = new OkHttpClient();

private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

/** 错误码
* 0 成功
* 1 失败
* 2 服务器异常
* 3 时间戳超时
* 4 签名校验非法
* 5 没有找到商户密钥
* 6 参数错误
* 7 更新订单失败
* 8 生产订单失败
* 20100 操作失败
* 20101 无效 token
* 20102 缺少必要参数
* 20106 参数错误
* 20201 手机号错误
* 20202 获取验证码失败
* 20203 手机验证码错误
* 20206 支付金额与应付金额不匹配
* 20207 60s 内只能发送一次验证码
* 20208 APP 未有该权限
* 20209 优惠金额与应付金额不匹配
* 20301 签约失败
* 20302 签约成功
* 20401 无效车架号
* 20407 车辆信息不匹配
* 20408 操作失败,请稍后重试
* 20501 操作失败,请稍后重试
* 20602 returnUrl 为空
* 20603 未查询到费用
* 20604 请先清偿坏账
* 20605 synId 错误
* 20606 待支付费用为 0,无需支付
* 20607 支付链接失效
* 20608 查费失败
* 20701 appId 错误
* 20801 未绑定该车辆
* 20802 该车辆已被他人绑定
* 20803 绑定数量超限
* 20804 30 天内最多绑定 4 辆不同的车
* 20805 在场车辆不可解绑
* 20901 车辆不在场
* 20902 车场不支持电子支付
* 20903 没有车场查费权限
* 20904 用户未绑定该查费车牌
* 20905 查询费用异常
* 20906 用户不存在
* 20907 商户未配置查费车场
* 20908 长租车,费用为 0
* 20909 车牌错误
* 21001 查询失败
* 21002 请稍后再试
* 21003 未查询到坏账
* 21004 错误支付类型
* 21101 签约号已存在
*/

public static void main(String[] args) {
ETCPUtil caller = new ETCPUtil();
String ret = "";
JSONObject objret = null;
String etcpToken = "44529274-7a31-4fb5-a35d-91d5b0be8641";
String carNumber = "京D12345";
String parkId = "Wj7YdvqyiYM=";
String businessId = "testasfsfsd";
//caller.carSimulation(appId, merchantNo, merchantKey, version, carNumber);

caller.getBCouponList(domain, merchantNo, merchantKey, version, parkId, businessId);

// 联合登录测试
/*ret = caller.userSignin(appId, merchantNo, merchantKey, version, "13910154397");

objret = JSON.parseObject(ret);
if (objret.getIntValue("code") != 0)
return;

etcpToken = objret.getJSONObject("data").getString("token");
System.out.println(etcpToken);


// 绑定车牌查询
ret = caller.carNum(merchantNo, merchantKey, version, etcpToken);
System.out.println(ret);
objret = JSON.parseObject(ret);
if (objret.getIntValue("code") != 0)
return;
JSONObject data = objret.getJSONObject("data");
if (data.getIntValue("number") <= 0) {
// 车牌绑定测试
ret = caller.bindCar(etcpToken, carNumber, null, merchantNo, merchantKey, version);
objret = JSON.parseObject(ret);
if (objret.getIntValue("code") != 0)
return;
}
JSONArray carArry = data.getJSONArray("carList");
carNumber = JSON.toJSONString(carArry.get(0));
carNumber = carNumber.substring(1, carNumber.length() -1);
System.out.println(carNumber);
// 停车费查询
ret = caller.orderUnpay(appId, merchantNo, merchantKey, version, etcpToken, carNumber);
System.out.println(ret);
objret = JSON.parseObject(ret);
if (objret.getIntValue("code") != 0)
return;
JSONArray payArr = objret.getJSONArray("data");
JSONObject payObj = payArr.getJSONObject(0);
String orderId = payObj.getString("orderId");
// 微信h5支付
ret = caller.orderPay(merchantNo, merchantKey, version, etcpToken, orderId, "http://test.cn", null);
System.out.println(ret);
*/
// 车牌解绑测试
//caller.unbindCar(merchantNo, merchantKey, version, etcpToken, carNumber);


//String orderId = "867C6F2F-4F3A-4767-890E-BA7F53F9C601";
//caller.orderPay(etcpToken, 5, orderId, "test.cn", null);

// 支付完成通知测试
/*caller.orderPaid(etcpToken, "51C3E00A-4F87-43FB-A71B-C1287ED956CB",
"201803120000001", BigDecimal.valueOf(8.85), "2018-03-12 11:58:31",
"FSED9JvxgAU6XJUd8YRF5f7OuzyQ/lGJch0h8dVVkNaHUpPISCLBshnn0AIoEdIdi2aQMOrrcmdVz2Smy+UbQ8pXl95Mv50aPNnUgaDlxSDqHQ8iOD6FT5XV7ikozZ0800CJKDkvQrmCZS2O21G+xg==",
"ETCP");*/
}

public static int getPayType() {
return payType;
}

/**
* 6.1. 联合登录
*
* @param appId appId(非空)
* @param merchantNo merchantNo(非空)
* @param merchantKey merchantKey(非空)
* @param version version(非空)
* @param mobilePhone 手机号(非空)
* @return 联合登录响应信息
* {
* "code": 0,
* "data": {
* "token": "0b59582d-ea6f-4bf1-a570-e803cc24ebe0"
* },
* "message": "ok"
* }
*/
public String userSignin(String baseUrl, String appId, String merchantNo, String merchantKey, String version,
String mobilePhone) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("appId", appId);
jsonObject.put("mobilePhone", mobilePhone);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + userSigninUrl.replaceAll("\\{version}", version), data, sign,
timeStamp, merchantNo);
}

/**
* 7.1. 车牌绑定
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @param plateNumber 车牌号(非空)
* @param plateColor 车牌颜色(可空)
* @return 绑牌响应信息
* {
* "code": 0,
* "message": "ok"
* }
*/
public String bindCar(String baseUrl, String merchantNo, String merchantKey, String version,
String etcpToken,
String plateNumber, String plateColor) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("plateNumber", plateNumber);
if ("1".equals(plateColor) || "2".equals(plateColor) || "3".equals(plateColor)
|| "4".equals(plateColor)) {
jsonObject.put("plateColor", plateColor);
}

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + bindCarUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 7.2. 车牌解绑
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @param plateNumber 车牌号(非空)
* @return 车牌解绑响应信息
* {
* "code": 0,
* "message": "ok"
* }
*/
public String unbindCar(String baseUrl, String merchantNo, String merchantKey, String version,
String etcpToken,
String plateNumber) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("plateNumber", plateNumber);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + unbindCarUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 7.3. 车牌认证
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @param carFrameNum 车架号(非空)
* @param plateNumber 车牌号(非空)
* @param carEngineNum 发动机号(非空)
* @return 车牌解绑响应信息
* {
* "code": 0,
* "message": "ok"
* }
*/
public String carAuth(String baseUrl, String merchantNo, String merchantKey, String version,
String etcpToken,
String carFrameNum, String plateNumber, String carEngineNum
) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("carFrameNum", carFrameNum);
jsonObject.put("plateNumber", plateNumber);
jsonObject.put("carEngineNum", carEngineNum);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + carAuthUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 7.4. 车牌找回
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @param carFrameNum 车架号(非空)
* @param plateNumber 车牌号(非空)
* @param carEngineNum 发机号(非空)
* @param plateColor 车牌颜色(1 蓝 2 黑 3 黄 4 白)
* @return 车牌找回响应信息
* {
* "code": 0,
* "message": "ok"
* }
*/
public String carRetrieve(String baseUrl, String merchantNo, String merchantKey, String version,
String etcpToken,
String carFrameNum, String plateNumber, String carEngineNum, String plateColor ) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("carFrameNum", carFrameNum);
jsonObject.put("plateNumber", plateNumber);
jsonObject.put("carEngineNum", carEngineNum);
if (!StringUtils.isBlank(plateColor))
jsonObject.put("plateColor", plateColor);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + carRetrieveUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 7.5. 已绑车辆信息查询
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @return 已绑车辆信息查询响应信息
* {
* "code": 0,
* "msg": "ok",
* "data": {
* "number": 3,
* "carList": [
* "晋 BMZ105",
* "云 C12345"
* ]
* }
* }
*/
public String carNum(String baseUrl, String merchantNo, String merchantKey, String version,
String etcpToken) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doGet(baseUrl + carNumUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 8.1. 停车费查询
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @param plateNumber 车牌号(非空)
* @param appId appId(可空)
* @return 停车费查询响应信息
*/
public String orderUnpay(String baseUrl,
String appId, String merchantNo, String merchantKey, String version,
String etcpToken,
String plateNumber) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("plateNumber", plateNumber);
if (appId != null && appId.length() > 0) {
jsonObject.put("appId", appId);
}

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doGet(baseUrl + orderUnpayUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 8.2. 优惠券查询
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @param lastCode 上一分页代码(可空)
* @param pageSize 1-200 之间的分页每页数量(非空)
* @return 停车费查询响应信息
*/
public String couponList(String baseUrl,
String merchantNo, String merchantKey, String version,
String etcpToken,
String lastCode, String pageSize) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
if (!StringUtils.isBlank(lastCode))
jsonObject.put("lastCode", lastCode);
jsonObject.put("pageSize", pageSize);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doGet(baseUrl + couponListUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 8.3.历史停车查询
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin}) (非空)
* @return 停车费查询响应信息
*/
public String orderHistory(String baseUrl,
String merchantNo, String merchantKey, String version,
String etcpToken) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doGet(baseUrl + orderHistoryUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 9.1. 主动支付(ETCP 收款)
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin})(非空)
* @param orderId 停车记录ID ({@link ETCPUtil#orderUnpay})(非空)
* @param returnUrl 外部支付流水号(商户平台生成)(非空)
* @param couponCode 支付金额 ({@link ETCPUtil#orderUnpay})(非空)
* @return
*/
public String orderPay(String baseUrl,
String merchantNo, String merchantKey, String version,
String etcpToken, String orderId,
String returnUrl, String couponCode) {
// payType 支付方式(1 微信公众号内支付 2 支付宝 H5 支付 3 微信二维码 4 支付宝二维码 5 微信 H5)(非空)
int payType = 5;
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("payType", payType);
jsonObject.put("synId", orderId);
jsonObject.put("returnUrl", returnUrl);
if (couponCode != null && couponCode.length() > 0) {
jsonObject.put("couponCode", couponCode);
}

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + orderpayUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 9.2. 主动支付(商户平台收款)
*
* @param etcpToken 商户平台调用联合接口获取的token({@link ETCPUtil#userSignin})(非空)
* @param orderId 停车记录ID ({@link ETCPUtil#orderUnpay})(非空)
* @param externalOrderId 外部支付流水号(商户平台生成)(非空)
* @param payment 支付金额 ({@link ETCPUtil#orderUnpay})(非空)
* @param payTime 支付时间, 格式:yyyy-MM-dd HH:mm:ss(非空)
* @param verificationInfo 验证信息串 ({@link ETCPUtil#orderUnpay})(非空)
* @param appId appId(可空)
* @return
*/
public String orderPaid(String baseUrl,
String appId, String merchantNo, String merchantKey, String version,
String etcpToken,
String orderId, String externalOrderId,
BigDecimal payment, String payTime, String verificationInfo) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("orderId", orderId);
jsonObject.put("externalOrderId", externalOrderId);
jsonObject.put("payment", payment);
jsonObject.put("payTime", payTime);
jsonObject.put("verificationInfo", verificationInfo);
if (appId != null && appId.length() > 0) {
jsonObject.put("appId", appId);
}

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + orderPaidUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 11.2. 车场状态查询
*
* @param parkingId 车场ID(非空)
* @return 车场状态查询响应信息
*/
public String parkingStatusUrl(String baseUrl,
String merchantNo, String merchantKey, String version,
String parkingId) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("parkingId", parkingId);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + parkingStatusUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 12.1. 坏账查询
*
* @param etcpToken
* @return 车场状态查询响应信息
*/
public String getDebt(String baseUrl,
String appId, String merchantNo, String merchantKey, String version,
String etcpToken, String carNumber) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("appId", appId);
jsonObject.put("plateNumber", carNumber);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + parkingStatusUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 12.2. 坏账清缴
*
* @param etcpToken
* @param
* @param returnUrl
* @return 车场状态查询响应信息
*/
public String repayDebt(String baseUrl,
String merchantNo, String merchantKey, String version,
String etcpToken, String returnUrl) {
// payType(1:支付宝 2:微信H5)
int payType = 2;
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("payType", payType);
jsonObject.put("returnUrl", returnUrl);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + parkingStatusUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 13.1. 商家优免券模板查询
*
* @return 商家优免券模板查询结果
*/
public String getBCouponList(String baseUrl,
String merchantNo, String merchantKey, String version,
String parkId, String businessId) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("parkId", parkId);
jsonObject.put("businessId", businessId);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + bCouponListUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 13.2. 商家优免券发放
*
* @param etcpToken
* @return 商家优免券发放结果
*/
public String bCouponRecord(String baseUrl,
String merchantNo, String merchantKey, String version,
String etcpToken,
String parkId, String businessId, String carNumber, String couponFreeId) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", etcpToken);
jsonObject.put("parkId", parkId);
jsonObject.put("businessId", businessId);
jsonObject.put("vehicleNo", carNumber);
jsonObject.put("couponFreeId", couponFreeId);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + bCouponRecordUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

/**
* 14.1. 车辆进出场模拟接口
*
* @param appId, plateNumber
* @return 车场状态查询响应信息
*/
public String carSimulation(String baseUrl,
String appId, String merchantNo, String merchantKey, String version,
String plateNumber) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("appId", appId);
jsonObject.put("plateNumber", plateNumber);

String data = jsonObject.toJSONString();
String timeStamp = dateTimeFormatter.format(LocalDateTime.now());
String sign = genSign(data, merchantKey, timeStamp);

return doPost(baseUrl + bCarSimulationUrl.replaceAll("\\{version}", version),
data, sign, timeStamp, merchantNo);
}

private String doPost(String url, String data, String sign, String timeStamp, String merchantNo) {
logger.info("请求url地址:{}, 请求参数为:data={}, sign={}, time_stamp={}, merchant_no={}", url, data,
sign, timeStamp, merchantNo);
RequestBody body = new FormBody.Builder().add("data", data).add("sign", sign)
.add("time_stamp", timeStamp).add("merchant_no", merchantNo).build();
Request request = new Request.Builder().url(url).post(body).build();
try (Response response = client.newCall(request).execute()) {
String responseStr = response.body().string();
logger.info("post接口响应信息为:{}", responseStr);
return responseStr;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

private String doGet(String sourceUrl, String data, String sign, String timeStamp, String merchantNo) {
logger.info("请求url地址:{}, 请求参数为:data={}, sign={}, time_stamp={}, merchant_no={}", sourceUrl,
data, sign, timeStamp, merchantNo);
HttpUrl url = HttpUrl.parse(sourceUrl).newBuilder().addQueryParameter("data", data)
.addQueryParameter("sign", sign).addQueryParameter("time_stamp", timeStamp)
.addQueryParameter("merchant_no", merchantNo).build();
Request request = new Request.Builder().url(url).build();
try (Response response = client.newCall(request).execute()) {
String responseStr = response.body().string();
logger.info("get请求接口响应信息为:{}", responseStr);
return responseStr;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

// 签名
private String genSign(String param, String merchantKey, String time) {
String preparedString = new StringBuilder(param).append(merchantKey).append(time).toString();
return md5Encode(preparedString.replaceAll("[ \r\t\n]", ""));
}

private String md5Encode(String content) {
StringBuilder sb = new StringBuilder();
try {
if (content == null || content.length() == 0) {
return null;
}
MessageDigest digestInstance = MessageDigest.getInstance("MD5");
digestInstance.update(content.getBytes("UTF-8"));
byte[] md = digestInstance.digest();
for (int i = 0; i < md.length; ++i) {
int val = md[i] & 0xff;
if (val < 16) {
sb.append("0");
}
sb.append(Integer.toHexString(val));
}
} catch (Exception ex) {

}
return sb.toString().toUpperCase();
}

}

+ 548
- 0
mallinkService/src/main/java/com/simple/utils/TJDCarUtil.java View File

@@ -0,0 +1,548 @@
package com.simple.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
* 停简单 停车管理
*/
@Component
public class TJDCarUtil {

private final static Logger logger = LoggerFactory.getLogger(TJDCarUtil.class);

private static String baseurl = "http://prep.tingjiandan.com/openapi/gateway";

private static String partner = "7dbc8ec9037d403b822cb60addfdc681";
private static String key = "f356cb1bf5a74fb7a564e86128d2c49f";
private static String version = "1.0";

public static void main(String[] args) throws Exception {
String carNumber = "京HLTT01";

String result = infoForFreeMins(baseurl, partner, key, version, carNumber);

JSONObject obj = JSON.parseObject(result);
/*

Map<String, String> paramMap1 = MapUtil.getOrderMap();
paramMap1.put("tradeId", obj.getString("tradeId"));
paramMap1.put("deductionAmount", obj.getString("totalAmount"));
paramMap1.put("outTradeNo", "utf-8");
paramMap1.put("accountId", obj.getString("accountId"));
paramMap1.put("charset", "utf-8");
paramMap1.put("partner", partner);
paramMap1.put("version", version);

deductionNotSettle(baseurl, key, paramMap1);
*/
}

/**
* 获取带排序的Map
* @return
*/
public static Map<String, String> getOrderMap() {
Map<String, String> paramMap = new TreeMap<String, String>(
new Comparator<String>() {
public int compare(String obj1, String obj2) {
// 降序排序
return obj1.compareTo(obj2);
}
});
return paramMap;
}

/**
* md5算法
* @param data
* @return
* @throws NoSuchAlgorithmException
*/

public static String md5(String data) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data.getBytes());
StringBuffer buf = new StringBuffer();
byte[] bits = md.digest();
for(int i=0;i<bits.length;i++){
int a = bits[i];
if(a<0) a+=256;
if(a<16) buf.append("0");
buf.append(Integer.toHexString(a));
}
return buf.toString();
}

/**
* getCurrentDate 获取当前时间
*/
public static String getCurrentDate() {
Date currentDate = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String timestamp = sdf.format(currentDate);
return timestamp;
}

/**
* 签名
* @param map
* @param keysign
* @return
* @throws NoSuchAlgorithmException
*/
public static String getSign(Map<String,String> map, String keysign) throws NoSuchAlgorithmException {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : map.entrySet()) {
if (entry.getValue() != null || entry.getValue() != "") {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
sb.deleteCharAt(sb.length()-1);// ?
sb.append(keysign);
logger.debug("签名前的字符串输出:"+sb.toString());
String signValue = md5(sb.toString()).toUpperCase();
logger.debug("sign: " + signValue);
return signValue;
}

/**
* 注册车牌
* @param url
* @param partner
* @param key // 密钥
* @param version
*
* {
* "carNum": "京A45781",
* "carNumColor": "blue",
* "phone": "15210501514",
* "outCarId": "45454545454",
* "partner": "5836b8b52ada463ebc6199579f029566",
* "timestamp": "2016-05-26 11:30:10",
* "version": "1.0"
* }
* @throws Exception
*/
public static String registerCar(String url, String partner, String key, String version,
String carNum, String carNumColor, String phone, String outCarId) {
String service = "parkhub.car.register";

Map<String, String> paramMap = getOrderMap();
paramMap.put("carNum", carNum);
paramMap.put("carNumColor", carNumColor);
if (phone != null) {
paramMap.put("phone", phone);
}
if (outCarId != null) {
paramMap.put("outCardId", outCarId);
}
paramMap.put("charset", "utf-8");
paramMap.put("partner", partner);
paramMap.put("version", version);

String result = Proc(url, key, service, paramMap);

/*
{
"timestamp": "1464235239561",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
"carId": "5836b8b52ada463ebc6199579f029561"
}*/
return result;
}

/**
* 注销车牌
* @param url
* @param partner
* @param key // 密钥
* @param version
*
* {
* "service": "parkhub.car.writeOff",
* "version":"1.0",
* "sign":"3347b109a1e44f3fd5baa78b74a84948",
* "partner":"5836b8b52ada463ebc6199579f029566",
* "carId":"3347b109a1e44f3fd5baa78b74a84948",
* "timestamp":"2016-05-26 11:30:10",
* "charset":"utf-8",
* "signType":"md5"
* }
* @throws Exception
*/
public static String writeOffCar(String url, String partner, String key, String version,
String carId) {
String service = "parkhub.car.writeOff";

Map<String, String> paramMap = getOrderMap();
paramMap.put("carId", carId);
paramMap.put("charset", "utf-8");
paramMap.put("partner", partner);
paramMap.put("version", version);

String result = Proc(url, key, service, paramMap);

/*
{
"timestamp": "1464235239561",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
}*/
return result;
}


/**
* 在场订单查询
* @param url
* @param partner
* @param key // 密钥
* @param version
*
* {
* "carNum": "京A45781",
* "freeMins": "0",
* "partner": "5836b8b52ada463ebc6199579f029566",
* "pmParkId": "5836b8b52ada463ebc6199579f029565",
* "timestamp": "2016-05-26 11:30:10",
* "tradeId": "5836b8b52ada463ebc6199579f029565",
* "version": "1.0"
* }
* @throws Exception
*/
public static String infoForFreeMins(String url, String partner, String key, String version, String carNum) {
String service = "parkhub.order.infoForFreeMins";

String freeMins = "0";

Map<String, String> paramMap = getOrderMap();
paramMap.put("carNum", carNum);
//paramMap.put("carNumColor", "");
//paramMap.put("pmParkId", "");
paramMap.put("freeMins", freeMins);
//paramMap.put("tradeId", "");
paramMap.put("charset", "utf-8");
paramMap.put("partner", partner);
paramMap.put("version", version);

String result = Proc(url, key, service, paramMap);

/*
"{
\"wLon\":\"116.310335\",
\"returnCode\":\"T\",
\"lon\":\"116.316819\",
\"accountId\":\"5b3c15e15235486eba9abae41ae3f820\",
\"freeThroughTime\":\"30\",
\"customerServicePhone\":\"400-001-0606\",
\"tradeId\":\"3a3475c501f8464cbb3ff1b6670690d6\",
\"returnMsg\":\"OK\",
\"outDt\":\"20180609164753\",
\"isSuccess\":\"0\",
\"pmParkId\":\"7715622dff834b34a44448b801c27607\",
\"unPayAmount\":\"12.00\",
\"timestamp\":\"1528534070691\",
\"errorMSG\":\"\",
\"parkTime\":\"107273\",
\"wLat\":\"39.93609\",
\"totalAmount\":\"12.00\",
\"paidAmount\":\"0.00\",
\"freeMinsAmount\":\"0\",
\"payUrl\":\"https://prep.tingjiandan.com/tcweixin/letter/prePay/payInPark.html?prePayType=16&channel=30040&isShowDetail=true&orderId=3a3475c501f8464cbb3ff1b6670690d6\",
\"lat\":\"39.942078\",
\"inDt\":\"20180608110000\"
}\n";
*/
return result;
}

/**
* deductionNotSettle 停车费无结算抵扣
* @param url
* @param partner
* @param key // 密钥
* @param version
* {
"service": "",
"version":"1.0",
"sign":"3347b109a1e44f3fd5baa78b74a84948",
"partner":"5836b8b52ada463ebc6199579f029566",
"timestamp":"2016-05-26 11:30:10",
"charset":"utf-8",
"signType":"md5",
"tradeId": "224478781859452794f2a68a756fe461",
"deductionAmount": "0.1",
"outTradeNo":"4738473847834378",
"accountId":"3347b109a1e44f3fd5baa78b74a84941",
}
* @throws Exception
*/
public static String deductionNotSettle(String url, String partner, String key, String version,
String tradeId, String outTradeNo, String accountId, String deductionAmount) {
// TODO
// 为指定订单抵扣停车费,如果此时车辆已经出场,返回isSuccess错误码为3,
// 停简单系统不再接收此笔抵扣信息,对方系统需要给用户发起退款(后续业务中无结算)
String service = "parkhub.order.deductionNotSettle";
Map<String, String> paramMap = getOrderMap();
paramMap.put("tradeId", tradeId);
paramMap.put("deductionAmount", deductionAmount);
paramMap.put("outTradeNo", outTradeNo);
paramMap.put("accountId", accountId);
paramMap.put("charset", "utf-8");
paramMap.put("partner", partner);
paramMap.put("version", version);

String result = Proc(url, key, service, paramMap);
/*
"{\"timestamp\":\"1528534986636\",
\"returnCode\":\"T\",
\"prePayId\":\"7a1d52aa77ca487db4e61130394285bd\",
\"errorMSG\":\"\",
\"returnMsg\":\"OK\",
\"isSuccess\":\"0\"}[\\r][\\n]"
*/
return result;
}

/**
* bindTime 绑定时长优惠券
* @param url
* @param partner //
* @param key // 密钥
* @param version // 1.0
*
* {
* "service": "parkhub.ticket.bindTime",
* "version":"1.0",
* "sign":"3347b109a1e44f3fd5baa78b74a84948",
* "partner":"5836b8b52ada463ebc6199579f029566",
* "timestamp":"2016-05-26 11:30:10",
* "charset":"utf-8",
* "signType":"md5",
* "tradeId": "224478781859452794f2a68a756fe461",
* "outTicketNo": "224478781859452794f2a68a756fe461",
* "accountId":"3347b109a1e44f3fd5baa78b74a84941",
* "prePayType": "3",
* "minutes": "30",
* "memo": "测试绑定时长优惠券"
* }
* @throws Exception
*/
public static String bindTime(String url, String partner, String key, String version,
String tradeId, String outTicketNo, String accountId, String prePayType, String minutes, String memo) throws Exception {
String service = "parkhub.ticket.bindTime";

Map<String, String> paramMap = getOrderMap();
paramMap.put("tradeId", tradeId);
paramMap.put("outTicketNo", outTicketNo);
paramMap.put("accountId", accountId);
paramMap.put("prePayType", prePayType);
paramMap.put("minutes", minutes);
paramMap.put("memo", memo);
paramMap.put("charset", "utf-8");
paramMap.put("partner", partner);
paramMap.put("version", version);

String result = Proc(url, key, service, paramMap);
/*{
"timestamp": "1464247094636",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
"ticketId": "224478781859452794f2a68a756fe441"
}*/
return result;
}

/**
* 绑定区间优惠券
* @param url
* @param partner
* @param key // 密钥
* @param version
*
* {
* "service": "parkhub.ticket.bindPeriod",
* "version": "1.0",
* "sign": "3347b109a1e44f3fd5baa78b74a84948",
* "partner": "5836b8b52ada463ebc6199579f029566",
* "timestamp": "2016-05-26 11:30:10",
* "charset": "utf-8",
* "signType": "md5",
* "tradeId": "224478781859452794f2a68a756fe461",
* "outTicketNo": "224478781859452794f2a68a756fe461",
* "accountId": "3347b109a1e44f3fd5baa78b74a84941",
* "prePayType": "3",
* "startDt": "20160526113010",
* "endDt": "20160526123010",
* "expireDt": "20160527113010",
* "memo": "测试绑定时长优惠券"
* }
* @throws Exception
*/
public static String bindPeriod(String url, String partner, String key, String version,
String tradeId, String outTicketNo, String accountId, String prePayType,
String startDt, String EndDt, String expireDt, String memo) throws Exception {
String service = "parkhub.ticket.bindPeriod";

Map<String, String> paramMap = getOrderMap();
paramMap.put("tradeId", tradeId);
paramMap.put("outTicketNo", outTicketNo);
paramMap.put("accountId", accountId);
paramMap.put("prePayType", prePayType);
paramMap.put("startDt", startDt);
paramMap.put("EndDt", EndDt);
paramMap.put("expireDt", expireDt);
paramMap.put("memo", memo);
paramMap.put("charset", "utf-8");
paramMap.put("partner", partner);
paramMap.put("version", version);

String result = Proc(url, key, service, paramMap);
/*{
"timestamp": "1464247094636",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
"ticketId": "224478781859452794f2a68a756fe441"
}*/
return result;
}

/**
* 绑定区间优惠券
* @param url
* @param partner // 密钥
* @param key // 密钥
* @param version
*
* {
* "service": "parkhub.ticket.unbind",
* "version": "1.0",
* "sign": "3347b109a1e44f3fd5baa78b74a84948",
* "partner": "5836b8b52ada463ebc6199579f029566",
* "timestamp": "2016-05-26 11:30:10",
* "charset": "utf-8",
* "signType": "md5",
* "tradeId ": "3347b109a1e44f3fd5baa78b74a84948",
* "ticketId": "224478781859452794f2a68a756fe461"
* }
* @throws Exception
*/
public static String unbind(String url, String partner, String key, String version,
String tradeId, String ticketid) throws Exception {
String service = "parkhub.ticket.unbind";

Map<String, String> paramMap = getOrderMap();
paramMap.put("tradeId", tradeId);
paramMap.put("ticketid", ticketid);
paramMap.put("charset", "utf-8");
paramMap.put("partner", partner);
paramMap.put("version", version);

String result = Proc(url, key, service, paramMap);
/*{
"timestamp": "1464247094636",
"returnCode": "T",
"errorMsg": "",
"returnMsg": "OK",
"isSuccess": "0",
}*/
return result;
}

private static String Proc(String url, String key, String service, Map<String, String> paramMap) {
CloseableHttpClient httpClient = HttpClients.createDefault();

HttpPost httpPost = new HttpPost(url);
httpPost.addHeader(HTTP.CONTENT_TYPE,"application/json");
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Accept-Encoding", "UTF-8");

String timestamp = getCurrentDate();
paramMap.put("timestamp", timestamp);

paramMap.put("service", service);

String sign = null;
try{
sign = getSign(paramMap, key);
}catch(NoSuchAlgorithmException e) {
logger.error(e.getLocalizedMessage());
}

paramMap.put("sign", sign);
paramMap.put("signType", "md5");

String jsonstr = JSON.toJSONString(paramMap);

try {
StringEntity se = new StringEntity(jsonstr, Consts.UTF_8);
se.setContentType("application/json");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"UTF-8"));
httpPost.setEntity(se);
} catch (Exception e) {
logger.error(e.getMessage());
}

HttpResponse response = null;
try {
response = httpClient.execute(httpPost);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
}

String result = null;

//打印StatusLine
logger.debug("StatusLine: " + response.getStatusLine());
try{
//获取实体
HttpEntity httpEntity= response.getEntity();
result = EntityUtils.toString(httpEntity, "UTF-8");
logger.debug(result);
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
}

try { //关闭流并释放资源
httpClient.close();
} catch (IOException e) {
logger.error(e.getLocalizedMessage());
}

return result;
}

}


Loading…
Cancel
Save