| @@ -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()); | |||
| } | |||
| }); | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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停车费抵扣失败"), | |||
| /** | |||
| * 订单 | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||