| @@ -7,29 +7,19 @@ CREATE TABLE `wx_car_pay_order` ( | |||||
| `c_user_id` bigint(20) NOT NULL COMMENT '用户ID', | `c_user_id` bigint(20) NOT NULL COMMENT '用户ID', | ||||
| `car_number` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '车牌号', | `car_number` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '车牌号', | ||||
| `pay_amount` int(11) NOT NULL COMMENT '支付金额(分)', | `pay_amount` int(11) NOT NULL COMMENT '支付金额(分)', | ||||
| `pay_time_start` datetime NOT NULL COMMENT '支付发起时间', | |||||
| `pay_time_end` datetime NOT NULL COMMENT '支付结束时间', | |||||
| `prepay_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '微信预支付交易会话标识-发模板信息使用', | |||||
| `pay_time` datetime NOT NULL COMMENT '支付时间', | |||||
| `transaction_id` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '微信生成的订单号', | `transaction_id` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '微信生成的订单号', | ||||
| `pay_vendor` int(11) NOT NULL DEFAULT '0' COMMENT '支付渠道: 0-微信 1-支付宝 2-银联 ', | |||||
| `pay_version` smallint(1) DEFAULT NULL COMMENT '支付版本', | |||||
| `pay_order_no` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '支付订单号', | |||||
| `pay_order_status` int(11) NOT NULL DEFAULT '0' COMMENT '支付状态: 0-支付中;1-支付成功;2-支付失败', | |||||
| `pay_param` json DEFAULT NULL COMMENT '额外参数', | |||||
| `fail_reason` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '支付失败原因', | |||||
| `pay_end_from` smallint(2) DEFAULT NULL COMMENT '支付后结果来源(0:callback, 1:query)', | |||||
| `park_order_no` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '车场订单号', | |||||
| `merchant_account` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '商户收款账户', | `merchant_account` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '商户收款账户', | ||||
| `merchant_id` int(20) NOT NULL COMMENT '商户编号', | `merchant_id` int(20) NOT NULL COMMENT '商户编号', | ||||
| `merchant_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '商户名称', | `merchant_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '商户名称', | ||||
| `amount` int(11) NOT NULL COMMENT '订单金额', | |||||
| `free_amount` int(11) NOT NULL DEFAULT '0' COMMENT '优免金额', | |||||
| `free_coupon_id` int(20) DEFAULT NULL COMMENT '优免优惠券编号', | |||||
| `free_coupon_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '优免优惠券名称', | |||||
| PRIMARY KEY (`id`), | PRIMARY KEY (`id`), | ||||
| UNIQUE KEY `id_UNIQUE` (`id`), | UNIQUE KEY `id_UNIQUE` (`id`), | ||||
| UNIQUE KEY `pay_order_no` (`pay_order_no`) | |||||
| UNIQUE KEY `pay_order_no` (`park_order_no`) | |||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='支付单表'; | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='支付单表'; | ||||
| ALTER TABLE `mallink`.`wx_park` | ALTER TABLE `mallink`.`wx_park` | ||||
| ADD COLUMN `support_pay` int(1) COMMENT '会员小程序是否支持支付enumYesOrNo'; | ADD COLUMN `support_pay` int(1) COMMENT '会员小程序是否支持支付enumYesOrNo'; | ||||
| ALTER TABLE `mallink`.`wx_park` | |||||
| ADD COLUMN `paid_call_back` varchar(100) COMMENT '支付完成回调地址'; | |||||
| @@ -5,9 +5,11 @@ import com.iformall.common.Result; | |||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.po.*; | import com.iformall.domain.po.*; | ||||
| import com.iformall.domain.po.base.BaseEntity; | import com.iformall.domain.po.base.BaseEntity; | ||||
| import com.iformall.domain.po.base.BaseEntity.SortField; | |||||
| import com.iformall.domain.po.base.TenantEntity; | import com.iformall.domain.po.base.TenantEntity; | ||||
| import com.iformall.domain.vo.WxCouponOrderCarCVo; | import com.iformall.domain.vo.WxCouponOrderCarCVo; | ||||
| import com.iformall.enums.*; | import com.iformall.enums.*; | ||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.service.*; | import com.iformall.service.*; | ||||
| import com.iformall.service.park.ParkFactory; | import com.iformall.service.park.ParkFactory; | ||||
| import com.iformall.service.park.entity.ParkCreatePayOrder; | import com.iformall.service.park.entity.ParkCreatePayOrder; | ||||
| @@ -16,6 +18,8 @@ import com.iformall.service.park.impl.etcp.EtcpHelper; | |||||
| import com.iformall.service.park.impl.util.ParkHelper; | import com.iformall.service.park.impl.util.ParkHelper; | ||||
| import com.iformall.service.park.pay.WxParkPayService; | import com.iformall.service.park.pay.WxParkPayService; | ||||
| import com.iformall.service.park.utils.ParkCacheUtils; | import com.iformall.service.park.utils.ParkCacheUtils; | ||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | |||||
| import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
| import io.swagger.annotations.ApiImplicitParam; | import io.swagger.annotations.ApiImplicitParam; | ||||
| import io.swagger.annotations.ApiImplicitParams; | import io.swagger.annotations.ApiImplicitParams; | ||||
| @@ -28,6 +32,7 @@ import org.springframework.beans.factory.annotation.Qualifier; | |||||
| import org.springframework.data.redis.core.RedisTemplate; | import org.springframework.data.redis.core.RedisTemplate; | ||||
| import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||
| import java.util.Date; | |||||
| import java.util.HashMap; | import java.util.HashMap; | ||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| @@ -80,6 +85,15 @@ public class WxCarController extends BaseController { | |||||
| @Autowired | @Autowired | ||||
| EtcpHelper etcpHelper; | EtcpHelper etcpHelper; | ||||
| @Autowired | |||||
| WxAppinfoService wxAppinfoService; | |||||
| @Autowired | |||||
| WxPayAccountService wxPayAccountService; | |||||
| @Autowired | |||||
| WxProfitSharingReceiverService wxProfitSharingReceiverService; | |||||
| @Autowired | @Autowired | ||||
| @Qualifier("objectCommonRedisTemplate") | @Qualifier("objectCommonRedisTemplate") | ||||
| RedisTemplate<String, Object> redisTemplate; | RedisTemplate<String, Object> redisTemplate; | ||||
| @@ -414,7 +428,7 @@ public class WxCarController extends BaseController { | |||||
| * @param paramMap | * @param paramMap | ||||
| * @return | * @return | ||||
| */ | */ | ||||
| @ApiOperation(value = "停车费创建支付订单", notes = "") | |||||
| @ApiOperation(value = "停车费创建支付订单", notes = "{\"carNumber\":\"鄂AAAAAA\",\"carFee\":\"100\"}") | |||||
| @PostMapping("/createPayOrder") | @PostMapping("/createPayOrder") | ||||
| public ResultData createPayOrder(@RequestBody Map<String, String> paramMap) { | public ResultData createPayOrder(@RequestBody Map<String, String> paramMap) { | ||||
| WxPark park = getCurrentPark(getTenantInfo()); | WxPark park = getCurrentPark(getTenantInfo()); | ||||
| @@ -433,20 +447,52 @@ public class WxCarController extends BaseController { | |||||
| logger.error("暂未成为会员,请授权手机号"); | logger.error("暂未成为会员,请授权手机号"); | ||||
| return new ResultData(ErrorCode.USER_IS_NOT_MEMBER.getCode(), "暂未成为会员,请授权手机号"); | return new ResultData(ErrorCode.USER_IS_NOT_MEMBER.getCode(), "暂未成为会员,请授权手机号"); | ||||
| } | } | ||||
| try { | try { | ||||
| //创建车场支付订单 | //创建车场支付订单 | ||||
| ParkCreatePayOrder payOrder = parkFactory.getParkService(park.getVendorType()).createPayOrder(paramMap, park,carNumber); | ParkCreatePayOrder payOrder = parkFactory.getParkService(park.getVendorType()).createPayOrder(paramMap, park,carNumber); | ||||
| if (null == payOrder || StringUtils.isBlank(payOrder.getParkOrderNumber())) { | |||||
| if (null == payOrder || StringUtils.isBlank(payOrder.getUniqueParkOrderNumber())) { | |||||
| return new ResultData(Result.ERROR,"创建车场订单错误."); | return new ResultData(Result.ERROR,"创建车场订单错误."); | ||||
| } | } | ||||
| if (payOrder.getFee() <= 0 ) { | |||||
| return new ResultData(Result.ERROR,"当前无需支付停车费."); | |||||
| } | |||||
| String carFeeStr = paramMap.get("carFee"); | |||||
| Integer carFee = Integer.parseInt(carFeeStr); | |||||
| if (payOrder.getFee() != carFee) { | |||||
| return new ResultData(Result.ERROR,"停车费已发生变更,请下拉刷新."); | |||||
| } | |||||
| //查询当前停车商户的收款账号 | //查询当前停车商户的收款账号 | ||||
| String mchId = ""; | |||||
| WxMerchant parkMerchant = wxMerchantService.findParkMerchant(park); | |||||
| if (null == parkMerchant) { | |||||
| return new ResultData(Result.ERROR,"未设置停车商户."); | |||||
| } | |||||
| WxProfitSharingReceiver receiver = wxProfitSharingReceiverService.findReceiver(park, parkMerchant.getId(), EnumAppPlat.WX, EnumProfitSharingType.PROFIT_SHARING_TYPE_WECHAT_v2); | |||||
| if (null == receiver || StringUtils.isBlank(receiver.getReceiverAccount())) { | |||||
| return new ResultData(Result.ERROR,"停车商户未设置收款账号."); | |||||
| } | |||||
| StringBuffer attachSb = new StringBuffer("{") | |||||
| .append("\"t\":").append(park.getTenantId()).append(",\"pt\":").append(park.getParentTenantId()) | |||||
| .append(",\"v\":").append(park.getVendorType()) | |||||
| .append(",\"u\":").append(user.getUserId()) | |||||
| .append(",\"car:\":").append(carNumber) | |||||
| .append(",\"fee\":").append(payOrder.getFee()) | |||||
| .append(",\"ma\":").append(receiver.getReceiverAccount()) | |||||
| .append(",\"mid\":").append(parkMerchant.getId()) | |||||
| .append(",\"mn\":").append(parkMerchant.getName()) | |||||
| .append("}"); | |||||
| WxAppinfo cAppInfo = wxAppinfoService.getCAppInfoFromRedis(park.getTenantId(), EnumPayWay.PAY_WAY_WECHAT.getPlat()); | |||||
| if(cAppInfo == null){ | |||||
| new ResultData(Result.ERROR,ErrorCode.APP_ID_NOT_FOUND.name()); | |||||
| } | |||||
| WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(cAppInfo.getPayId()); | |||||
| if(payAccount == null){ | |||||
| new ResultData(Result.ERROR,ErrorCode.API_KEY_NOT_FOUND.name()); | |||||
| } | |||||
| //创建微信支付订单 | //创建微信支付订单 | ||||
| wxParkPayService.createWxPayOrder(user.getOpenId(), user.getAppId(), carNumber, carNumber, carNumber, carNumber, null, carNumber, carNumber, carNumber, null); | |||||
| return new ResultData(payOrder); | |||||
| PayAdapterResult wxResult = wxParkPayService.createWxPayOrder(user.getOpenId(), user.getAppId(), receiver.getReceiverAccount(), "停车费支付", attachSb.toString(), payOrder.getUniqueParkOrderNumber(), payOrder.getFee(), | |||||
| "127.0.0.1", park.getPaidCallBack(), payAccount.getApiKey(), new Date()); | |||||
| return new ResultData(wxResult); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error("park getCarStopFee error",e); | logger.error("park getCarStopFee error",e); | ||||
| return new ResultData(Result.ERROR,e.getMessage()); | return new ResultData(Result.ERROR,e.getMessage()); | ||||
| @@ -454,6 +500,38 @@ public class WxCarController extends BaseController { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 停车费支付订单列表 | |||||
| * | |||||
| * @param paramMap | |||||
| * @return | |||||
| */ | |||||
| @GetMapping("/payOrderList") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true), | |||||
| }) | |||||
| public ResultData payOrderList(Integer pageNum, Integer pageSize) { | |||||
| WxCarPayOrder carPayOrder = new WxCarPayOrder(); | |||||
| carPayOrder.updateTenantInfo(getTenantInfo()); | |||||
| carPayOrder.setSortColumn(SortField.CreateTime_DESC.getValue()); | |||||
| return new ResultData(wxParkPayService.listPayOrderAsPage(carPayOrder, pageNum, pageSize)); | |||||
| } | |||||
| /** | |||||
| * 停车费支付订单详情 | |||||
| * | |||||
| * @param paramMap | |||||
| * @return | |||||
| */ | |||||
| @GetMapping("/payOrderDetail") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) | |||||
| }) | |||||
| public ResultData payOrderDetail(Long id) { | |||||
| return new ResultData(wxParkPayService.detailWxCarPayOrder(id, getTenantInfo().getTenantId())); | |||||
| } | |||||
| @ApiOperation("券包分页列表接口") | @ApiOperation("券包分页列表接口") | ||||
| @GetMapping("/couponOrderList") | @GetMapping("/couponOrderList") | ||||
| @ApiImplicitParams({ | @ApiImplicitParams({ | ||||
| @@ -0,0 +1,175 @@ | |||||
| package com.iformall.controller.callback.car.pay; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.github.pagehelper.PageInfo; | |||||
| import com.iformall.common.Result; | |||||
| import com.iformall.controller.base.BaseController; | |||||
| import com.iformall.controller.callback.car.WxParkCallBackBaseController; | |||||
| import com.iformall.domain.po.*; | |||||
| import com.iformall.domain.po.msg.FmInsideNotifyCarPaidSuccessMsg; | |||||
| import com.iformall.domain.po.msg.FmInsideNotifyRefundSuccessMsg; | |||||
| import com.iformall.domain.vo.WxCarCYFVo; | |||||
| import com.iformall.enums.EnumCarCmd; | |||||
| import com.iformall.enums.EnumCarVendor; | |||||
| import com.iformall.enums.EnumCouponSendSendType; | |||||
| import com.iformall.enums.EnumMsgMqKey; | |||||
| import com.iformall.enums.EnumMsgMqTag; | |||||
| import com.iformall.enums.EnumMsgMqTopic; | |||||
| import com.iformall.enums.EnumMsgRecordType; | |||||
| import com.iformall.enums.EnumPayVersion; | |||||
| import com.iformall.enums.EnumPayWay; | |||||
| import com.iformall.exception.BizMessageException; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.mq.MqBaseProducer; | |||||
| import com.iformall.pay.WxPayment; | |||||
| import com.iformall.service.*; | |||||
| import com.iformall.service.park.impl.cyf.CYFUtil; | |||||
| import com.iformall.service.park.impl.tjd.TJDUtil; | |||||
| import com.iformall.utils.XmlUtil; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| import org.apache.commons.collections.CollectionUtils; | |||||
| import org.apache.commons.io.IOUtils; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.web.bind.annotation.PathVariable; | |||||
| import org.springframework.web.bind.annotation.PostMapping; | |||||
| import org.springframework.web.bind.annotation.RequestBody; | |||||
| import org.springframework.web.bind.annotation.RequestMapping; | |||||
| import org.springframework.web.bind.annotation.RestController; | |||||
| import java.nio.charset.Charset; | |||||
| import java.util.Date; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.SortedMap; | |||||
| import java.util.TreeMap; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| /** | |||||
| * @author: furunxin | |||||
| * @Date: 2020/7/6 15:29 | |||||
| * @Description: 车易付回调接口 | |||||
| */ | |||||
| @Slf4j | |||||
| @RestController | |||||
| @RequestMapping("/carPaidCallback") | |||||
| public class WxCarPaidCallBackController extends WxParkCallBackBaseController { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| WxParkService wxParkService; | |||||
| @Autowired | |||||
| WxCarCmdLogService wxCarCmdLogService; | |||||
| @Autowired | |||||
| WxCUserService wxCUserService; | |||||
| @Autowired | |||||
| WxCUserCarService wxCUserCarService; | |||||
| @Autowired | |||||
| WxCouponSendService wxCouponSendService; | |||||
| @Autowired | |||||
| WxCarPayRecordService wxCarPayRecordService; | |||||
| @Autowired | |||||
| WxCUserBasicInfoService wxCUserBasicInfoService; | |||||
| @Autowired | |||||
| private MqBaseProducer mqBaseProducer; | |||||
| /** | |||||
| * @description 停车费支付成功通知 | |||||
| * {dataItems=[{"inTime":"2020-12-09 11:21:15","carNumber":"浙-AF81797","inCarPhoto":"p201127315/NISSP_IMG_PARK_IN/20201209/a9f1130651b9493f8eab64f14afbdd47","isReal":0,"itemId":"a9f1130651b9493f8eab64f14afbdd47","inOperator":"超级管理员","equipName":"东门入口","parkName":"杭州东站西子国际","vehicleInfo":"{\"plateNo\":\"浙-AF81797\",\"plateColor\":\"GREEN\",\"plateBackColor\":0,\"plateWordColor\":0,\"vehicleColor\":null,\"vehicleLogo\":null,\"vehicleModel\":null,\"mainModel\":0,\"subModel\":0,\"vehicleModelTrust\":0,\"mainModelTrust\":0,\"subModelTrust\":0,\"plateNoTrust\":1,\"vehicleLogoTrust\":0,\"vehicleColorTrust\":0}","equipCode":"208202496","parkCode":"p201127315"}], pno=dzxzgj, sn=6C958D99D2769AA16F3A3F06E962263F, tn=-2, ts=20201209112118886, ve=1.0} | |||||
| * | |||||
| * | |||||
| * | |||||
| * @Params [paramMap] | |||||
| * @return com.iformall.common.Result | |||||
| * @Author furunxin | |||||
| * @Date 2020/7/8 上午8:27 | |||||
| **/ | |||||
| @RequestMapping(value = "/paid/{tenantId}") | |||||
| public String parkInCallback(@PathVariable String tenantId,HttpServletRequest request) { | |||||
| Map<String, String> paramMap = null; | |||||
| String response = ""; | |||||
| String xml = ""; | |||||
| try { | |||||
| xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8")); | |||||
| paramMap = WxPayment.xmlToMap(xml); | |||||
| paramMap.put("tenantId", tenantId); | |||||
| String jsonMsg = JSON.toJSONString(paramMap); | |||||
| FmInsideNotifyCarPaidSuccessMsg refundSuccessMsg = new FmInsideNotifyCarPaidSuccessMsg(); | |||||
| refundSuccessMsg.setTenantId(tenantId); | |||||
| refundSuccessMsg.setMsgType(EnumMsgRecordType.CAR_PAID.getCode()); | |||||
| refundSuccessMsg.setDelayTimeLevel(3); | |||||
| refundSuccessMsg.setPayWay(EnumPayWay.PAY_WAY_WECHAT.getCode()); | |||||
| refundSuccessMsg.setPayVersion(EnumPayVersion.WX_PAY_V2.getCode()); | |||||
| refundSuccessMsg.setJsonMsg(jsonMsg); | |||||
| // response = wxRefundOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP); | |||||
| mqBaseProducer.sendMessage(refundSuccessMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode()); | |||||
| logger.info("refund wxpay, notify success, req : " + xml + ", resp: " + response.toString()); | |||||
| return response; | |||||
| } catch (BizMessageException e) { | |||||
| logger.error("refund wxpay, notify error, req: " + xml + ", e:" + e.getLocalizedMessage()); | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "FAIL"); | |||||
| resultMap.put("return_msg", e.getMessage()); | |||||
| return XmlUtil.getRequestXml(resultMap); | |||||
| } catch (MallinkException e) { | |||||
| logger.error("refund wxpay, notify error, req: " + xml + ", e:" +e.getLocalizedMessage()); | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "FAIL"); | |||||
| resultMap.put("return_msg", e.getMessage()); | |||||
| return XmlUtil.getRequestXml(resultMap); | |||||
| } catch (Exception e) { | |||||
| logger.error("refund wxpay, order create error, req: " + xml + ", e: " + e.getMessage()); | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "FAIL"); | |||||
| resultMap.put("return_msg", e.getMessage()); | |||||
| return XmlUtil.getRequestXml(resultMap); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * @description 车易付 车辆离场通知 | |||||
| * @Params [param] | |||||
| * @return java.util.Map | |||||
| * @Author furunxin | |||||
| * @Date 2020/7/12 上午9:00 | |||||
| **/ | |||||
| @PostMapping(value = "/parkOut") | |||||
| public Result parkOutCallback(@RequestBody Map<String, Object> paramMap) { | |||||
| log.info("["+getIpAddr()+"] jieshunCarCallback parkOut: " + paramMap.toString()); | |||||
| return super.parkOutCallBack(EnumCarVendor.CAR_JIESHUN, EnumCarCmd.CAR_JIESHUN_CALLBACK_PARK_OUT, paramMap); | |||||
| } | |||||
| @PostMapping(value = "/unbind") | |||||
| public Result unbindCallback(@RequestBody Map<String, Object> paramMap) { | |||||
| log.info("["+getIpAddr()+"] jieshunCarCallback unbind: " + paramMap.toString()); | |||||
| //解析车易付参数 | |||||
| return super.unbindCarCallBack(EnumCarVendor.CAR_JIESHUN, EnumCarCmd.CAR_JIESHUN_CALLBACK_UNBIND, paramMap); | |||||
| } | |||||
| @PostMapping(value = "/paid") | |||||
| public Result paidCallback(@RequestBody Map<String, Object> paramMap) { | |||||
| log.info("["+getIpAddr()+"] jieshunCarCallback paid: " + paramMap.toString()); | |||||
| //解析车易付参数 | |||||
| return super.paidCallback(EnumCarVendor.CAR_JIESHUN, EnumCarCmd.CAR_JIESHUN_CALLBACK_PAID, paramMap); | |||||
| } | |||||
| } | |||||
| @@ -74,6 +74,9 @@ public class MqBaseConsumer { | |||||
| @Autowired | @Autowired | ||||
| private FmInsideBasicUserTenantMsgServiceImpl FmInsideBasicUserTenantMsgService; | private FmInsideBasicUserTenantMsgServiceImpl FmInsideBasicUserTenantMsgService; | ||||
| @Autowired | |||||
| private FmInsideNotifyCarPaidSuccessMsgServiceImpl fmInsideNotifyCarPaidSuccessMsgServiceImpl; | |||||
| public void doMessage(String message) { | public void doMessage(String message) { | ||||
| @@ -213,6 +216,11 @@ public class MqBaseConsumer { | |||||
| FmInsideBasicUserPushMsg msg = (FmInsideBasicUserPushMsg)JsonUtil.readValue(message,FmInsideBasicUserPushMsg.class); | FmInsideBasicUserPushMsg msg = (FmInsideBasicUserPushMsg)JsonUtil.readValue(message,FmInsideBasicUserPushMsg.class); | ||||
| FmInsideBasicUserTenantMsgService.send(msg); | FmInsideBasicUserTenantMsgService.send(msg); | ||||
| } | } | ||||
| else if (EnumMsgRecordType.CAR_PAID.getCode().equals(baseMsg.getMsgType())) { | |||||
| FmInsideNotifyCarPaidSuccessMsg msg = (FmInsideNotifyCarPaidSuccessMsg) JsonUtil.readValue(message,FmInsideNotifyCarPaidSuccessMsg.class); | |||||
| fmInsideNotifyCarPaidSuccessMsgServiceImpl.send(msg); | |||||
| } | |||||
| }catch (Throwable e){ | }catch (Throwable e){ | ||||
| log.error("consum received error: ", e); | log.error("consum received error: ", e); | ||||
| @@ -27,41 +27,16 @@ public class WxCarPayOrder extends TenantEntity { | |||||
| private String carNumber; | private String carNumber; | ||||
| @io.swagger.annotations.ApiModelProperty(value="支付金额(分)",name="payAmount") | @io.swagger.annotations.ApiModelProperty(value="支付金额(分)",name="payAmount") | ||||
| private Integer payAmount; | private Integer payAmount; | ||||
| @io.swagger.annotations.ApiModelProperty(value="支付发起时间",name="payTimeStart") | |||||
| private Date payTimeStart; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付结束时间",name="payTimeEnd") | |||||
| private Date payTimeEnd; | |||||
| @io.swagger.annotations.ApiModelProperty(value="微信预支付交易会话标识",name="prepayId") | |||||
| private String prepayId; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付时间",name="payTime") | |||||
| private Date payTime; | |||||
| @io.swagger.annotations.ApiModelProperty(value="微信生成的订单号",name="transactionId") | @io.swagger.annotations.ApiModelProperty(value="微信生成的订单号",name="transactionId") | ||||
| private String transactionId; | private String transactionId; | ||||
| @io.swagger.annotations.ApiModelProperty(value="支付渠道: 0-微信 1-支付宝 2-银联 ",name="payVendor") | |||||
| private Integer payVendor; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付渠道版本EnumPayVersion ",name="payVersion") | |||||
| private Integer payVersion; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付订单号",name="payOrderNo") | |||||
| private String payOrderNo; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付状态: 0-支付中;1-支付成功;2-支付失败",name="payOrderStatus") | |||||
| private Integer payOrderStatus; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付额外参数",name="payParam") | |||||
| private String payParam; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付失败原因",name="failReason") | |||||
| private String failReason; | |||||
| @io.swagger.annotations.ApiModelProperty(value="支付后结果来源(0:callback, 1:query)",name="payEndFrom") | |||||
| private Integer payEndFrom; | |||||
| @io.swagger.annotations.ApiModelProperty(value="车场订单号",name="parkOrderNo") | |||||
| private String parkOrderNo; | |||||
| @io.swagger.annotations.ApiModelProperty(value="商户收款账户",name="merchantAccount") | @io.swagger.annotations.ApiModelProperty(value="商户收款账户",name="merchantAccount") | ||||
| private String merchantAccount; | private String merchantAccount; | ||||
| @io.swagger.annotations.ApiModelProperty(value="商户编号",name="merchantId") | @io.swagger.annotations.ApiModelProperty(value="商户编号",name="merchantId") | ||||
| private Long merchantId; | private Long merchantId; | ||||
| @io.swagger.annotations.ApiModelProperty(value="商户名称",name="merchantName") | @io.swagger.annotations.ApiModelProperty(value="商户名称",name="merchantName") | ||||
| private String merchantName; | private String merchantName; | ||||
| @io.swagger.annotations.ApiModelProperty(value="订单金额(分)",name="amount") | |||||
| private Integer amount; | |||||
| @io.swagger.annotations.ApiModelProperty(value="优免金额(分)",name="freeAmount") | |||||
| private Integer freeAmount; | |||||
| @io.swagger.annotations.ApiModelProperty(value="优免券编号",name="freeCouponId") | |||||
| private Long freeCouponId; | |||||
| @io.swagger.annotations.ApiModelProperty(value="优免券名称",name="freeCouponName") | |||||
| private String freeCouponName; | |||||
| } | } | ||||
| @@ -400,5 +400,9 @@ public class WxMerchant extends TenantEntity { | |||||
| @io.swagger.annotations.ApiModelProperty(value="纬度",name="latitude") | @io.swagger.annotations.ApiModelProperty(value="纬度",name="latitude") | ||||
| @TableField(exist = false) | @TableField(exist = false) | ||||
| private BigDecimal latitude; | private BigDecimal latitude; | ||||
| //查询停车商户根据此字段 | |||||
| @TableField(exist = false) | |||||
| private Integer hasCarVendor; | |||||
| } | } | ||||
| @@ -40,4 +40,6 @@ public class WxPark extends TenantEntity { | |||||
| private String couponParams; | private String couponParams; | ||||
| @io.swagger.annotations.ApiModelProperty(value="会员小程序是否支持支付enumYesOrNo",name="supportPay") | @io.swagger.annotations.ApiModelProperty(value="会员小程序是否支持支付enumYesOrNo",name="supportPay") | ||||
| private Integer supportPay; | private Integer supportPay; | ||||
| @io.swagger.annotations.ApiModelProperty(value="支付完成回调地址",name="paidCallBack") | |||||
| private String paidCallBack; | |||||
| } | } | ||||
| @@ -0,0 +1,20 @@ | |||||
| package com.iformall.domain.po.msg; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| import lombok.ToString; | |||||
| @Data | |||||
| @ToString(callSuper = true) | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| public class FmInsideNotifyCarPaidSuccessMsg extends BaseMsg { | |||||
| @io.swagger.annotations.ApiModelProperty(value = "支付渠道", name = "payWay") | |||||
| private Integer payWay; | |||||
| @io.swagger.annotations.ApiModelProperty(value = "支付渠道版本", name = "payVersion") | |||||
| private Integer payVersion; | |||||
| @io.swagger.annotations.ApiModelProperty(value = "消息内容", name = "jsonMsg") | |||||
| private String jsonMsg; | |||||
| } | |||||
| @@ -33,6 +33,8 @@ public enum EnumMsgRecordType { | |||||
| MALL_COO_USER_PUSH(110, "猫酷同步会员"), | MALL_COO_USER_PUSH(110, "猫酷同步会员"), | ||||
| MEMBER_UPDATE_TENANT(111, "集团会员标签广场"), | MEMBER_UPDATE_TENANT(111, "集团会员标签广场"), | ||||
| CAR_PAID(112,"停车支付回调"), | |||||
| INSIDE_ORDER_PUSH_DELIVERY(200, "2.0核销同步"), | INSIDE_ORDER_PUSH_DELIVERY(200, "2.0核销同步"), | ||||
| ; | ; | ||||
| @@ -13,4 +13,6 @@ public interface WxCarPayOrderMapper extends CommonMapper<WxCarPayOrder, Long> { | |||||
| List<WxCarPayOrder> findList(WxCarPayOrder wxCarPayOrder); | List<WxCarPayOrder> findList(WxCarPayOrder wxCarPayOrder); | ||||
| WxCarPayOrder findOneByParkOderNo(@Param("parkOrderNo")String parkOrderNo,@Param("tenantId")String tenantId); | |||||
| } | } | ||||
| @@ -208,4 +208,6 @@ public interface WxMerchantService { | |||||
| WxMerchant findBrandAdmin(TenantEntity tenantEntity, Long brandId); | WxMerchant findBrandAdmin(TenantEntity tenantEntity, Long brandId); | ||||
| Map<Long, WxMerchant> findMerchantMap(WxMerchant merchantQ); | Map<Long, WxMerchant> findMerchantMap(WxMerchant merchantQ); | ||||
| WxMerchant findParkMerchant(TenantEntity tenantEntity); | |||||
| } | } | ||||
| @@ -22,6 +22,8 @@ import com.iformall.service.*; | |||||
| import com.iformall.service.util.CouponCacheUtils; | import com.iformall.service.util.CouponCacheUtils; | ||||
| import com.iformall.utils.Constant; | import com.iformall.utils.Constant; | ||||
| import com.iformall.utils.DateUtils; | import com.iformall.utils.DateUtils; | ||||
| import com.iformall.utils.RedisCacheUtils; | |||||
| import org.apache.commons.collections.CollectionUtils; | import org.apache.commons.collections.CollectionUtils; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| @@ -1937,4 +1939,23 @@ public class WxMerchantServiceImpl implements WxMerchantService { | |||||
| } | } | ||||
| return merchantMap; | return merchantMap; | ||||
| } | } | ||||
| @Override | |||||
| public WxMerchant findParkMerchant(TenantEntity tenantEntity) { | |||||
| WxMerchant record = null; | |||||
| String key = Constant.parkMerchantPrev + tenantEntity.getTenantId(); | |||||
| record = RedisCacheUtils.getCacheObject(redisTemplate, key, WxMerchant.class); | |||||
| if(record == null){ | |||||
| WxMerchant merchantQ = new WxMerchant(); | |||||
| merchantQ.updateTenantInfo(tenantEntity); | |||||
| merchantQ.setHasCarVendor(1); | |||||
| List<WxMerchant> merchantList = wxMerchantMapper.findList(merchantQ); | |||||
| if (null != merchantList && merchantList.size() > 0 ) { | |||||
| record = merchantList.get(0); | |||||
| RedisCacheUtils.cache(redisTemplate, key, record, 3600*24*7); | |||||
| } | |||||
| } | |||||
| return record; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,38 @@ | |||||
| package com.iformall.service.msg.impl; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.iformall.domain.po.msg.BaseMsg; | |||||
| import com.iformall.domain.po.msg.FmInsideNotifyCarPaidSuccessMsg; | |||||
| import com.iformall.domain.po.msg.FmInsideNotifyRefundSuccessMsg; | |||||
| import com.iformall.enums.EnumPayVersion; | |||||
| import com.iformall.enums.EnumPayWay; | |||||
| import com.iformall.service.WxRefundOrderService; | |||||
| import com.iformall.service.msg.MsgSendService; | |||||
| import com.iformall.service.park.pay.WxParkPayService; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * | |||||
| * @author Stormeye Wu | |||||
| * @date 2019/5/10 | |||||
| */ | |||||
| @Service | |||||
| public class FmInsideNotifyCarPaidSuccessMsgServiceImpl implements MsgSendService { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| private WxParkPayService wxParkPayService; | |||||
| @Override | |||||
| public void send(BaseMsg baseMsg) throws Exception { | |||||
| FmInsideNotifyCarPaidSuccessMsg msg = (FmInsideNotifyCarPaidSuccessMsg)baseMsg; | |||||
| Map<String, String> paramMap = JSON.parseObject(msg.getJsonMsg(), Map.class); | |||||
| wxParkPayService.handlePaidCallBack(paramMap); | |||||
| } | |||||
| } | |||||
| @@ -62,7 +62,7 @@ public interface ParkAdapterService { | |||||
| /** | /** | ||||
| * 停车订单成功通知车场 | * 停车订单成功通知车场 | ||||
| */ | */ | ||||
| ParkNotifyPaid notifyPaid(Map<String, String> paramMap,WxPark park,String parkOrderNumber) throws Exception; | |||||
| void notifyPaid(ParkNotifyPaid notifyPaid) throws Exception; | |||||
| /** | /** | ||||
| * 查询停车场状态, 给老的集成用 | * 查询停车场状态, 给老的集成用 | ||||
| @@ -3,19 +3,39 @@ package com.iformall.service.park.entity; | |||||
| import java.io.Serializable; | import java.io.Serializable; | ||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import com.iformall.enums.EnumCarVendor; | |||||
| public class ParkCreatePayOrder implements Serializable{ | public class ParkCreatePayOrder implements Serializable{ | ||||
| private static final long serialVersionUID = 5585069626450856545L; | private static final long serialVersionUID = 5585069626450856545L; | ||||
| private EnumCarVendor carVendor; | |||||
| /*停车场返回的订单ID**/ | /*停车场返回的订单ID**/ | ||||
| private String parkOrderNumber=""; | private String parkOrderNumber=""; | ||||
| /*停车费**/ | |||||
| private Integer fee; | |||||
| public ParkCreatePayOrder(String parkOrderNumber) { | |||||
| public ParkCreatePayOrder(EnumCarVendor carVendor,String parkOrderNumber,Integer fee) { | |||||
| this.carVendor = carVendor; | |||||
| if (!StringUtils.isBlank(parkOrderNumber)) { | if (!StringUtils.isBlank(parkOrderNumber)) { | ||||
| this.parkOrderNumber = parkOrderNumber; | this.parkOrderNumber = parkOrderNumber; | ||||
| } | } | ||||
| if (null != fee) { | |||||
| this.fee = fee; | |||||
| } | |||||
| } | } | ||||
| public String getParkOrderNumber() { | |||||
| return parkOrderNumber; | |||||
| public String getUniqueParkOrderNumber() { | |||||
| if (!StringUtils.isBlank(parkOrderNumber)) { | |||||
| return carVendor.getMessage()+"_"+parkOrderNumber; | |||||
| } | |||||
| return null; | |||||
| } | |||||
| public Integer getFee() { | |||||
| return fee; | |||||
| } | } | ||||
| } | } | ||||
| @@ -8,114 +8,24 @@ import java.util.Map; | |||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import lombok.AllArgsConstructor; | |||||
| import lombok.Data; | |||||
| @Data | |||||
| @AllArgsConstructor | |||||
| public class ParkNotifyPaid implements Serializable{ | public class ParkNotifyPaid implements Serializable{ | ||||
| private static final long serialVersionUID = 6478840764729191197L; | private static final long serialVersionUID = 6478840764729191197L; | ||||
| /*停车场返回的订单ID**/ | /*停车场返回的订单ID**/ | ||||
| private String orderId=""; | |||||
| /*入场时间 格式:yyyy-MM-dd HH:mm:ss**/ | |||||
| private String entranceTime=""; | |||||
| /*计费结束时间 格式:yyyy-MM-dd HH:mm:ss**/ | |||||
| private String exitTime=""; | |||||
| /*停车费**/ | |||||
| private String remainingFee=""; | |||||
| /*跳转的停车费支付小程序appId**/ | |||||
| private String appId=""; | |||||
| /*支付小程序页面路径**/ | |||||
| private String payPath=""; | |||||
| /*给支付小程序的额外数据**/ | |||||
| private Map extraData=new HashMap(); | |||||
| /*备注**/ | |||||
| private String remark=""; | |||||
| private String sysNotice="";//系统提示,非车厂提示; | |||||
| public ParkNotifyPaid(String orderId,Date startTime,Date endTime,String fee,String appId,String payPath,Map extraData,String remark,String sysNotice) { | |||||
| if (!StringUtils.isBlank(orderId)) { | |||||
| this.orderId = orderId; | |||||
| } | |||||
| if (null != startTime) { | |||||
| this.entranceTime = getLocalDate(startTime); | |||||
| } | |||||
| if (null != endTime) { | |||||
| this.exitTime = getLocalDate(endTime); | |||||
| } | |||||
| if (!StringUtils.isBlank(fee)) { | |||||
| this.remainingFee = fee; | |||||
| } | |||||
| if (!StringUtils.isBlank(appId)) { | |||||
| this.appId = appId; | |||||
| } | |||||
| if (!StringUtils.isBlank(payPath)) { | |||||
| this.payPath = payPath; | |||||
| } | |||||
| if (null != extraData) { | |||||
| this.extraData = extraData; | |||||
| } | |||||
| if (!StringUtils.isBlank(remark)) { | |||||
| this.remark = remark; | |||||
| } | |||||
| if (!StringUtils.isBlank(sysNotice)) { | |||||
| this.sysNotice = sysNotice; | |||||
| } | |||||
| } | |||||
| private String tenantId; | |||||
| /*停车场订单**/ | |||||
| private String parkOrderNo; | |||||
| /*支付金额**/ | |||||
| private Integer fee; | |||||
| /*支付时间 格式:yyyy-MM-dd HH:mm:ss**/ | |||||
| private Date payTime; | |||||
| private String getLocalDate(Date date){ | |||||
| SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
| return sdf.format(date); | |||||
| } | |||||
| public String getOrderId() { | |||||
| return orderId; | |||||
| } | |||||
| public void setOrderId(String orderId) { | |||||
| this.orderId = orderId; | |||||
| } | |||||
| public String getEntranceTime() { | |||||
| return entranceTime; | |||||
| } | |||||
| public void setEntranceTime(String entranceTime) { | |||||
| this.entranceTime = entranceTime; | |||||
| } | |||||
| public String getExitTime() { | |||||
| return exitTime; | |||||
| } | |||||
| public void setExitTime(String exitTime) { | |||||
| this.exitTime = exitTime; | |||||
| } | |||||
| public String getRemainingFee() { | |||||
| return remainingFee; | |||||
| } | |||||
| public void setRemainingFee(String remainingFee) { | |||||
| this.remainingFee = remainingFee; | |||||
| } | |||||
| public String getAppId() { | |||||
| return appId; | |||||
| } | |||||
| public void setAppId(String appId) { | |||||
| this.appId = appId; | |||||
| } | |||||
| public String getPayPath() { | |||||
| return payPath; | |||||
| } | |||||
| public void setPayPath(String payPath) { | |||||
| this.payPath = payPath; | |||||
| } | |||||
| public Map getExtraData() { | |||||
| return extraData; | |||||
| } | |||||
| public void setExtraData(Map extraData) { | |||||
| this.extraData = extraData; | |||||
| } | |||||
| public String getRemark() { | |||||
| return remark; | |||||
| } | |||||
| public void setRemark(String remark) { | |||||
| this.remark = remark; | |||||
| } | |||||
| public String getSysNotice() { | |||||
| return sysNotice; | |||||
| } | |||||
| } | } | ||||
| @@ -122,10 +122,8 @@ public class BoLinkParkService extends BaseParkService implements ParkAdapterSer | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ParkNotifyPaid notifyPaid(Map<String, String> paramMap, WxPark park, String parkOrderNumber) | |||||
| public void notifyPaid(ParkNotifyPaid notifyPaid) | |||||
| throws Exception { | throws Exception { | ||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| } | } | ||||
| @@ -205,9 +205,7 @@ public class CYFParkService extends BaseParkService implements ParkAdapterServic | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ParkNotifyPaid notifyPaid(Map<String, String> paramMap, WxPark park, String parkOrderNumber) | |||||
| throws Exception { | |||||
| return null; | |||||
| public void notifyPaid(ParkNotifyPaid notifyPaid) throws Exception { | |||||
| } | } | ||||
| } | } | ||||
| @@ -88,10 +88,7 @@ public class DaHuaParkService extends BaseParkService implements ParkAdapterServ | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ParkNotifyPaid notifyPaid(Map<String, String> paramMap, WxPark park, String parkOrderNumber) | |||||
| throws Exception { | |||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| public void notifyPaid(ParkNotifyPaid notifyPaid) throws Exception { | |||||
| } | } | ||||
| } | } | ||||
| @@ -240,9 +240,7 @@ public class HaiKangWeiShiParkService extends BaseParkService implements ParkAda | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ParkNotifyPaid notifyPaid(Map<String, String> paramMap, WxPark park, String parkOrderNumber) | |||||
| throws Exception { | |||||
| return null; | |||||
| public void notifyPaid(ParkNotifyPaid notifyPaid) throws Exception { | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -349,8 +349,7 @@ public class JieShunParkService extends BaseParkService implements ParkAdapterSe | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ParkNotifyPaid notifyPaid(Map<String, String> paramMap, WxPark park, String parkOrderNumber) throws Exception { | |||||
| return null; | |||||
| public void notifyPaid(ParkNotifyPaid notifyPaid) throws Exception { | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -107,9 +107,6 @@ public class ShangAnParkService extends BaseParkService implements ParkAdapterSe | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ParkNotifyPaid notifyPaid(Map<String, String> paramMap, WxPark park, String parkOrderNumber) | |||||
| throws Exception { | |||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| public void notifyPaid(ParkNotifyPaid notifyPaid) throws Exception { | |||||
| } | } | ||||
| } | } | ||||
| @@ -268,9 +268,6 @@ public class TJDParkService extends BaseParkService implements ParkAdapterServic | |||||
| } | } | ||||
| @Override | @Override | ||||
| public ParkNotifyPaid notifyPaid(Map<String, String> paramMap, WxPark park, String parkOrderNumber) | |||||
| throws Exception { | |||||
| // TODO Auto-generated method stub | |||||
| return null; | |||||
| public void notifyPaid(ParkNotifyPaid notifyPaid) throws Exception { | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,9 +1,12 @@ | |||||
| package com.iformall.service.park.pay; | package com.iformall.service.park.pay; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.Map; | |||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.iformall.domain.po.WxCarPayOrder; | import com.iformall.domain.po.WxCarPayOrder; | ||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.enums.EnumCarVendor; | |||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | ||||
| public interface WxParkPayService { | public interface WxParkPayService { | ||||
| @@ -12,4 +15,12 @@ public interface WxParkPayService { | |||||
| public PayAdapterResult createWxPayOrder(String openId,String appId,String mchId,String productName,String attach,String payOrderNo, | public PayAdapterResult createWxPayOrder(String openId,String appId,String mchId,String productName,String attach,String payOrderNo, | ||||
| Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate) throws Exception; | Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate) throws Exception; | ||||
| public String handlePaidCallBack(Map<String, String> paramMap); | |||||
| public void handlePaidSuccess(TenantEntity tenantEntity,Long cUserId,Integer carVendor,String carNumber,String parkOrderNo, | |||||
| Integer fee,Date paidTime,String transcationId,String merchantAccount,Long merchantId,String merchantName) throws Exception; | |||||
| public WxCarPayOrder detailWxCarPayOrder(Long id,String tenantId); | |||||
| } | } | ||||
| @@ -1,15 +1,42 @@ | |||||
| package com.iformall.service.park.pay; | package com.iformall.service.park.pay; | ||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.alibaba.fastjson.JSONObject; | |||||
| import com.github.pagehelper.PageHelper; | import com.github.pagehelper.PageHelper; | ||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.IdWorker; | |||||
| import com.iformall.domain.po.WxAppinfo; | |||||
| import com.iformall.domain.po.WxCarPayOrder; | import com.iformall.domain.po.WxCarPayOrder; | ||||
| import com.iformall.domain.po.WxCoupon; | |||||
| import com.iformall.domain.po.WxPayAccount; | |||||
| import com.iformall.domain.po.WxPayOrder; | |||||
| import com.iformall.domain.po.WxRefundOrder; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.enums.EnumCarVendor; | |||||
| import com.iformall.enums.EnumPayWay; | |||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.mapper.WxAppinfoMapper; | |||||
| import com.iformall.mapper.WxCarPayOrderMapper; | import com.iformall.mapper.WxCarPayOrderMapper; | ||||
| import com.iformall.mapper.WxPayAccountMapper; | |||||
| import com.iformall.pay.WxPayment; | |||||
| import com.iformall.service.ExcelService; | import com.iformall.service.ExcelService; | ||||
| import com.iformall.service.park.ParkFactory; | |||||
| import com.iformall.service.park.entity.ParkNotifyPaid; | |||||
| import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | ||||
| import com.iformall.service.pay.service.pay.wx.v2.miniApp.appPay.WxMiniAppPayAdapterService; | import com.iformall.service.pay.service.pay.wx.v2.miniApp.appPay.WxMiniAppPayAdapterService; | ||||
| import com.iformall.utils.CipherUtil; | |||||
| import com.iformall.utils.DateUtils; | |||||
| import com.iformall.utils.RedisLock; | |||||
| import com.iformall.utils.XmlUtil; | |||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.SortedMap; | |||||
| import java.util.TreeMap; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| @@ -29,6 +56,18 @@ public class WxParkPayServiceImpl implements WxParkPayService { | |||||
| @Autowired | @Autowired | ||||
| WxMiniAppPayAdapterService wxMiniAppPayAdapterService; | WxMiniAppPayAdapterService wxMiniAppPayAdapterService; | ||||
| @Autowired | |||||
| WxAppinfoMapper wxAppinfoMapper; | |||||
| @Autowired | |||||
| WxPayAccountMapper wxPayAccountMapper; | |||||
| @Autowired | |||||
| ParkFactory parkFactory; | |||||
| @Autowired | |||||
| RedisLock redisLock; | |||||
| @Override | @Override | ||||
| public PageInfo<WxCarPayOrder> listPayOrderAsPage(WxCarPayOrder record, Integer pageIndex, Integer pageSize) { | public PageInfo<WxCarPayOrder> listPayOrderAsPage(WxCarPayOrder record, Integer pageIndex, Integer pageSize) { | ||||
| @@ -40,7 +79,123 @@ public class WxParkPayServiceImpl implements WxParkPayService { | |||||
| Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate) throws Exception { | Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate) throws Exception { | ||||
| return wxMiniAppPayAdapterService.pay(openId, appId, mchId, productName, attach, payOrderNo, fee, ip, notifyUrl, apiKey, currentDate); | return wxMiniAppPayAdapterService.pay(openId, appId, mchId, productName, attach, payOrderNo, fee, ip, notifyUrl, apiKey, currentDate); | ||||
| } | } | ||||
| private String notifyErrorResult(String msg) { | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "FAIL"); | |||||
| resultMap.put("return_msg", msg); | |||||
| return XmlUtil.getRequestXml(resultMap); | |||||
| } | |||||
| private String notifySuccessResult() { | |||||
| SortedMap resultMap = new TreeMap(); | |||||
| resultMap.put("return_code", "SUCCESS"); | |||||
| resultMap.put("return_msg", "OK"); | |||||
| return XmlUtil.getRequestXml(resultMap); | |||||
| } | |||||
| @Override | |||||
| public String handlePaidCallBack(Map<String, String> paramMap) { | |||||
| //支付返回消息 | |||||
| String returnCode = paramMap.get("return_code"); | |||||
| if ("SUCCESS".equals(returnCode)) { | |||||
| String resultCode = paramMap.get("result_code"); | |||||
| if ("SUCCESS".equals(resultCode)) { | |||||
| //判断支付金额是否大于0 | |||||
| String cashFeeStr = paramMap.get("cash_fee"); | |||||
| Integer cashFee = Integer.parseInt(cashFeeStr); | |||||
| if (cashFee > 0 ) { | |||||
| try { | |||||
| String parkOrderNo = paramMap.get("out_trade_no"); | |||||
| String time_end = paramMap.get("time_end"); | |||||
| String transcationId = paramMap.get("transaction_id"); | |||||
| String attach = paramMap.get("attach"); | |||||
| JSONObject attachObj = JSON.parseObject(attach); | |||||
| String tenantId = attachObj.getString("t"); | |||||
| String parentTenantId = attachObj.getString("pt"); | |||||
| TenantEntity te = new TenantEntity(); | |||||
| te.setTenantId(tenantId); | |||||
| te.setParentTenantId(parentTenantId); | |||||
| Integer carVendor = attachObj.getInteger("v"); | |||||
| Long cUserId = attachObj.getLong("u"); | |||||
| String carNumber = attachObj.getString("car"); | |||||
| String merchantAccount = attachObj.getString("ma"); | |||||
| Long merchantId = attachObj.getLong("mid"); | |||||
| String merchantName = attachObj.getString("mn"); | |||||
| handlePaidSuccess(te,cUserId,carVendor,carNumber,parkOrderNo,Integer.parseInt(cashFeeStr), | |||||
| DateUtils.string2Date(time_end, DateUtils.DATE_PATTERN_ALL_NOSPACE).getTime(),transcationId, | |||||
| merchantAccount,merchantId,merchantName); | |||||
| } catch (Exception e) { | |||||
| logger.error("handlePaidCallBackError.",e); | |||||
| return notifyErrorResult(e.getMessage()); | |||||
| } | |||||
| } | |||||
| return notifySuccessResult(); | |||||
| }else { | |||||
| String errorMsg = paramMap.get("err_code_des"); | |||||
| return notifyErrorResult(errorMsg); | |||||
| } | |||||
| }else { | |||||
| String errorMsg = paramMap.get("return_msg"); | |||||
| return notifyErrorResult(errorMsg); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public void handlePaidSuccess(TenantEntity tenantEntity,Long cUserId,Integer carVendor,String carNumber, | |||||
| String parkOrderNo,Integer fee,Date paidTime,String transcationId,String merchantAccount, | |||||
| Long merchantId,String merchantName) throws Exception{ | |||||
| //查询该笔订单是否已经存在 | |||||
| WxCarPayOrder payOrder = wxCarPayOrderMapper.findOneByParkOderNo(parkOrderNo, tenantEntity.getTenantId()); | |||||
| if (null == payOrder) { | |||||
| //此处需要加锁,防止并发设置 | |||||
| long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||||
| String timeStr = String.valueOf(time); | |||||
| boolean stocksetlock = redisLock.lock("carPayOrderLock_"+parkOrderNo, timeStr); | |||||
| if (stocksetlock) { | |||||
| try { | |||||
| //创建停车支付订单记录 | |||||
| final IdWorker idworker = IdWorker.get(); | |||||
| payOrder = new WxCarPayOrder(); | |||||
| Long id = idworker.nextId(); | |||||
| payOrder.setId(id); | |||||
| payOrder.updateTenantInfo(tenantEntity); | |||||
| payOrder.setCreateTime(new Date()); | |||||
| payOrder.setUpdateTime(new Date()); | |||||
| payOrder.setCUserId(cUserId); | |||||
| payOrder.setCarNumber(carNumber); | |||||
| payOrder.setPayAmount(fee); | |||||
| payOrder.setPayTime(paidTime); | |||||
| payOrder.setTransactionId(transcationId); | |||||
| payOrder.setParkOrderNo(parkOrderNo); | |||||
| payOrder.setMerchantAccount(merchantAccount); | |||||
| payOrder.setMerchantId(merchantId); | |||||
| payOrder.setMerchantName(merchantName); | |||||
| wxCarPayOrderMapper.insert(payOrder); | |||||
| //通知车场支付成功 | |||||
| try { | |||||
| parkFactory.getParkService(carVendor).notifyPaid(new ParkNotifyPaid(tenantEntity.getTenantId(), parkOrderNo, fee, paidTime)); | |||||
| }catch(Exception e) { | |||||
| //TODO 重试 | |||||
| 111111111 | |||||
| } | |||||
| }catch(Exception e) { | |||||
| logger.error("handlePaidSuccess fail.",e); | |||||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL.getCode(),"支付同步失败"+parkOrderNo); | |||||
| }finally { | |||||
| redisLock.unlock("carPayOrderLock_"+parkOrderNo, timeStr); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public WxCarPayOrder detailWxCarPayOrder(Long id,String tenantId) { | |||||
| return wxCarPayOrderMapper.selectById(id, tenantId); | |||||
| } | |||||
| } | } | ||||
| @@ -108,6 +108,8 @@ public class Constant { | |||||
| public static final String levelConfigPrev = "levelConfig:"; | public static final String levelConfigPrev = "levelConfig:"; | ||||
| public static final String mallBuildingPrev = "mallBuilding:"; | public static final String mallBuildingPrev = "mallBuilding:"; | ||||
| public static final String parkMerchantPrev = "parkMerchant:"; | |||||
| //wiwide系统常量 | //wiwide系统常量 | ||||
| public static final Integer wiwideOldPlat = 0;//老平台 | public static final Integer wiwideOldPlat = 0;//老平台 | ||||
| @@ -28,6 +28,8 @@ public class DateUtils { | |||||
| public final static String[] weekObj=new String[]{"日","一","二","三","四","五","六"}; | public final static String[] weekObj=new String[]{"日","一","二","三","四","五","六"}; | ||||
| public final static String DATE_PATTERN_NOSPACE = "yyyyMMdd"; | public final static String DATE_PATTERN_NOSPACE = "yyyyMMdd"; | ||||
| public final static String DATE_PATTERN_ALL_NOSPACE = "yyyyMMddHHmmss"; | |||||
| public static String format(Date date) { | public static String format(Date date) { | ||||
| return format(date, DATE_PATTERN); | return format(date, DATE_PATTERN); | ||||
| @@ -10,43 +10,26 @@ | |||||
| <result column="c_user_id" jdbcType="BIGINT" property="cUserId"/> | <result column="c_user_id" jdbcType="BIGINT" property="cUserId"/> | ||||
| <result column="car_number" jdbcType="VARCHAR" property="carNumber"/> | <result column="car_number" jdbcType="VARCHAR" property="carNumber"/> | ||||
| <result column="pay_amount" jdbcType="INTEGER" property="payAmount"/> | <result column="pay_amount" jdbcType="INTEGER" property="payAmount"/> | ||||
| <result column="pay_time_start" jdbcType="TIMESTAMP" property="payTimeStart"/> | |||||
| <result column="pay_time_end" jdbcType="TIMESTAMP" property="payTimeEnd"/> | |||||
| <result column="prepay_id" jdbcType="VARCHAR" property="prepayId"/> | |||||
| <result column="pay_time" jdbcType="TIMESTAMP" property="payTime"/> | |||||
| <result column="transaction_id" jdbcType="VARCHAR" property="transactionId"/> | <result column="transaction_id" jdbcType="VARCHAR" property="transactionId"/> | ||||
| <result column="pay_vendor" jdbcType="INTEGER" property="payVendor"/> | |||||
| <result column="pay_version" jdbcType="INTEGER" property="payVersion"/> | |||||
| <result column="pay_order_no" jdbcType="VARCHAR" property="payOrderNo"/> | |||||
| <result column="pay_order_status" jdbcType="INTEGER" property="payOrderStatus"/> | |||||
| <result column="pay_param" jdbcType="VARCHAR" property="payParam"/> | |||||
| <result column="fail_reason" jdbcType="VARCHAR" property="failReason"/> | |||||
| <result column="pay_end_from" jdbcType="INTEGER" property="payEndFrom"/> | |||||
| <result column="park_order_no" jdbcType="VARCHAR" property="parkOrderNo"/> | |||||
| <result column="merchant_account" jdbcType="VARCHAR" property="merchantAccount"/> | <result column="merchant_account" jdbcType="VARCHAR" property="merchantAccount"/> | ||||
| <result column="merchant_id" jdbcType="BIGINT" property="merchantId"/> | <result column="merchant_id" jdbcType="BIGINT" property="merchantId"/> | ||||
| <result column="merchant_name" jdbcType="VARCHAR" property="merchantName"/> | <result column="merchant_name" jdbcType="VARCHAR" property="merchantName"/> | ||||
| <result column="amount" jdbcType="INTEGER" property="amount"/> | |||||
| <result column="free_amount" jdbcType="INTEGER" property="freeAmount"/> | |||||
| <result column="free_coupon_id" jdbcType="BIGINT" property="freeCouponId"/> | |||||
| <result column="free_coupon_name" jdbcType="VARCHAR" property="freeCouponName"/> | |||||
| </resultMap> | </resultMap> | ||||
| <sql id="allColumns"> | <sql id="allColumns"> | ||||
| `id`,`tenant_id`,`parent_tenant_id`,`create_time`,`update_time`,`c_user_id`,`car_number`,`pay_amount`, | `id`,`tenant_id`,`parent_tenant_id`,`create_time`,`update_time`,`c_user_id`,`car_number`,`pay_amount`, | ||||
| `pay_time_start`,`pay_time_end`,`prepay_id`,`transaction_id`,`pay_vendor`,`pay_version`,`pay_order_no`, | |||||
| `pay_order_status`,`pay_param`,`fail_reason`,`pay_end_from`,`merchant_account`,`merchant_id`,`merchant_name`, | |||||
| `amount`,`free_amount`,`free_coupon_id`,`free_coupon_name` | |||||
| `pay_time`,`transaction_id`,`park_order_no`,`merchant_account`,`merchant_id`,`merchant_name` | |||||
| </sql> | </sql> | ||||
| <sql id="dynamicWhereConditions"> | <sql id="dynamicWhereConditions"> | ||||
| where 1 = 1 | |||||
| where `tenant_id` = #{tenantId} | |||||
| <if test=" null != id "> | <if test=" null != id "> | ||||
| and `id` = #{id} | and `id` = #{id} | ||||
| </if> | </if> | ||||
| <if test=" null != tenantId and '' != tenantId"> | |||||
| and `tenant_id` = #{tenantId} | |||||
| </if> | |||||
| <if test=" null != parentTenantId and '' != parentTenantId"> | <if test=" null != parentTenantId and '' != parentTenantId"> | ||||
| and `parent_tenant_id` = #{parentTenantId} | and `parent_tenant_id` = #{parentTenantId} | ||||
| </if> | </if> | ||||
| @@ -71,42 +54,18 @@ | |||||
| and `pay_amount` = #{payAmount} | and `pay_amount` = #{payAmount} | ||||
| </if> | </if> | ||||
| <if test=" null != payTimeStart "> | |||||
| and `pay_time_start` = #{payTimeStart} | |||||
| </if> | |||||
| <if test=" null != payTimeEnd "> | |||||
| and `pay_time_end` = #{payTimeEnd} | |||||
| </if> | |||||
| <if test=" null != prepayId "> | |||||
| and `prepay_id` like concat('%', #{prepayId},'%') | |||||
| <if test=" null != payTime "> | |||||
| and `pay_time` = #{payTime} | |||||
| </if> | </if> | ||||
| <if test=" null != transactionId "> | <if test=" null != transactionId "> | ||||
| and `transaction_id` like concat('%', #{transactionId},'%') | and `transaction_id` like concat('%', #{transactionId},'%') | ||||
| </if> | </if> | ||||
| <if test=" null != payVendor "> | |||||
| and `pay_vendor` = #{payVendor} | |||||
| </if> | |||||
| <if test=" null != payVersion "> | |||||
| and `pay_version` = #{payVersion} | |||||
| </if> | |||||
| <if test=" null != payOrderNo "> | |||||
| and `pay_order_no` like concat('%', #{payOrderNo},'%') | |||||
| <if test=" null != parkOrderNo "> | |||||
| and `park_order_no` = #{parkOrderNo} | |||||
| </if> | </if> | ||||
| <if test=" null != payOrderStatus "> | |||||
| and `pay_order_status` = #{payOrderStatus} | |||||
| </if> | |||||
| <if test=" null != failReason "> | |||||
| and `fail_reason` like concat('%', #{failReason},'%') | |||||
| </if> | |||||
| <if test=" null != merchantAccount "> | <if test=" null != merchantAccount "> | ||||
| and `merchant_account` like concat('%', #{merchantAccount},'%') | and `merchant_account` like concat('%', #{merchantAccount},'%') | ||||
| </if> | </if> | ||||
| @@ -119,10 +78,6 @@ | |||||
| and `merchant_name` like concat('%', #{merchantName},'%') | and `merchant_name` like concat('%', #{merchantName},'%') | ||||
| </if> | </if> | ||||
| <if test=" null != freeCouponId "> | |||||
| and `free_coupon_id` = #{freeCouponId} | |||||
| </if> | |||||
| <if test=" null != ids "> | <if test=" null != ids "> | ||||
| and id in | and id in | ||||
| <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | ||||
| @@ -136,11 +91,17 @@ | |||||
| select <include refid="allColumns"/> from wx_car_pay_order where id = #{id} and tenant_id = #{tenantId} | select <include refid="allColumns"/> from wx_car_pay_order where id = #{id} and tenant_id = #{tenantId} | ||||
| </select> | </select> | ||||
| <select id="findList" parameterType="com.iformall.domain.po.WxPayOrder" resultMap="BaseResultMap"> | |||||
| <select id="findList" parameterType="com.iformall.domain.po.WxCarPayOrder" resultMap="BaseResultMap"> | |||||
| select | select | ||||
| <include refid="allColumns"/> | <include refid="allColumns"/> | ||||
| from wx_car_pay_order | from wx_car_pay_order | ||||
| <include refid="dynamicWhereConditions"/> | <include refid="dynamicWhereConditions"/> | ||||
| </select> | </select> | ||||
| <select id="findOneByParkOderNo" parameterType="HashMap" resultMap="BaseResultMap"> | |||||
| select | |||||
| <include refid="allColumns"/> | |||||
| from wx_car_pay_order where tenant_id = #{tenantId} and `park_order_no` = #{parkOrderNo} | |||||
| </select> | |||||
| </mapper> | </mapper> | ||||
| @@ -104,6 +104,10 @@ | |||||
| <if test=" null != carVendorType "> | <if test=" null != carVendorType "> | ||||
| and m.`car_vendor_type` = #{carVendorType} | and m.`car_vendor_type` = #{carVendorType} | ||||
| </if> | </if> | ||||
| <if test=" null != hasCarVendor "> | |||||
| and m.`car_vendor_type` is not null and m.`car_vendor_type` > 0 | |||||
| </if> | |||||
| <if test=" null != businessId "> | <if test=" null != businessId "> | ||||
| and m.`business_id` = #{businessId} | and m.`business_id` = #{businessId} | ||||
| @@ -18,11 +18,12 @@ | |||||
| <result column="vendor_params" jdbcType="VARCHAR" property="vendorParams"/> | <result column="vendor_params" jdbcType="VARCHAR" property="vendorParams"/> | ||||
| <result column="coupon_params" jdbcType="VARCHAR" property="couponParams"/> | <result column="coupon_params" jdbcType="VARCHAR" property="couponParams"/> | ||||
| <result column="support_pay" jdbcType="INTEGER" property="supportPay"/> | <result column="support_pay" jdbcType="INTEGER" property="supportPay"/> | ||||
| <result column="paid_call_back" jdbcType="VARCHAR" property="paidCallBack"/> | |||||
| </resultMap> | </resultMap> | ||||
| <sql id="allColumns"> | <sql id="allColumns"> | ||||
| `id`,`tenant_id`,`parent_tenant_id`,`img_url`,`addr`,`number`,`entry_exit`,`stop_fee`,`create_date`,`update_date`,`park_id`, | `id`,`tenant_id`,`parent_tenant_id`,`img_url`,`addr`,`number`,`entry_exit`,`stop_fee`,`create_date`,`update_date`,`park_id`, | ||||
| `parking_id`,`vendor_type`,`vendor_params`,`coupon_params`,`support_pay` | |||||
| `parking_id`,`vendor_type`,`vendor_params`,`coupon_params`,`support_pay`,`paid_call_back` | |||||
| </sql> | </sql> | ||||
| <sql id="dynamicWhereConditions"> | <sql id="dynamicWhereConditions"> | ||||