| @@ -0,0 +1,71 @@ | |||
| package com.simple.controller; | |||
| import org.apache.log4j.Logger; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.util.Assert; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.simple.common.Result; | |||
| import com.simple.common.ResultData; | |||
| import com.simple.domain.po.WxPayAccount; | |||
| import com.simple.service.WxPayAccountService; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| @RestController | |||
| @RequestMapping("wxPayAccount") | |||
| public class WxPayAccountController extends BaseController | |||
| { | |||
| @Autowired | |||
| private WxPayAccountService wxPayAccountService; | |||
| private Logger logger = Logger.getLogger(WxPayAccountController.class); | |||
| @ApiOperation("分页列表接口") | |||
| @GetMapping("list") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name="pageNum",value="页数",dataType="int", paramType = "query",required=true), | |||
| @ApiImplicitParam(name="pageSize",value="每页条数",dataType="int", paramType = "query",required=true)}) | |||
| public ResultData list(@ModelAttribute WxPayAccount wxPayAccount,Integer pageNum, Integer pageSize) { | |||
| if (null == wxPayAccount) wxPayAccount = new WxPayAccount(); | |||
| final PageInfo<WxPayAccount> page = wxPayAccountService.listAsPage(wxPayAccount, pageNum, pageSize); | |||
| return new ResultData(page); | |||
| } | |||
| @ApiOperation("新增接口") | |||
| @PostMapping("add") | |||
| public ResultData add(@RequestBody WxPayAccount wxPayAccount) { | |||
| //Assert.notNull(wxPayAccount.getName(), "角色名不能为空"); | |||
| //Assert.isTrue(!checkUnique(sysRole.getName(), null), "重复的角色名"); | |||
| wxPayAccountService.saveOrUpdate(wxPayAccount); | |||
| return new ResultData(); | |||
| } | |||
| @ApiOperation("根据id更新接口") | |||
| @PostMapping("update") | |||
| public ResultData update(@RequestBody WxPayAccount wxPayAccount) { | |||
| wxPayAccountService.saveOrUpdate(wxPayAccount); | |||
| return new ResultData(); | |||
| } | |||
| @ApiOperation("根据id删除接口") | |||
| @GetMapping("/del") | |||
| @ApiImplicitParam(name="id",value="id",dataType="Long", paramType = "query",required=true) | |||
| public ResultData delete(Long id) { | |||
| wxPayAccountService.deleteById(id); | |||
| return new ResultData(Result.SUCCESS, "删除成功", null); | |||
| } | |||
| @ApiOperation("根据id查询接口") | |||
| @GetMapping("/findById") | |||
| @ApiImplicitParam(name="id",value="id",dataType="Long", paramType = "query",required=true) | |||
| public ResultData findById(Long id) { | |||
| return new ResultData(Result.SUCCESS,"查询成功",wxPayAccountService.getById(id)); | |||
| } | |||
| } | |||
| @@ -56,16 +56,21 @@ public class WxUserGrantController extends BaseController { | |||
| Map resultMap = new HashMap(); | |||
| String appId = map.get("appId"); | |||
| WxMaService wxMaService = getWeappService(appId); | |||
| String code = map.get("code"); | |||
| String scene = map.get("scene"); | |||
| String sceneAddress = map.get("sceneAddress"); | |||
| //登录凭证不能为空 | |||
| if (StringUtils.isBlank(appId)) { | |||
| return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "appId不能为空"); | |||
| } | |||
| if (StringUtils.isBlank(code)) { | |||
| return new ResultData(ErrorCode.PARAMETER_NOT_NULL.getCode(), "code不能为空"); | |||
| } | |||
| // 通过appinfo得到tenant_id | |||
| WxAppinfo wxAppinfo = getAppInfo(appId); | |||
| WxMaService wxMaService = getWeappService(appId); | |||
| String token = null; | |||
| String session_key = null; | |||
| String openId = null; | |||
| @@ -102,6 +107,7 @@ public class WxUserGrantController extends BaseController { | |||
| wxCUserService.saveOrUpdate(user1); | |||
| resultMap.put("token", token); | |||
| } else { | |||
| user.setTenantId(wxAppinfo.getTenantId()); | |||
| user.createToken(new Date()); | |||
| token = user.getToken(); | |||
| user.setRegisterIp(ipaddress); | |||
| @@ -72,6 +72,9 @@ public class WxAppinfo implements Serializable { | |||
| /*微信token有效时间单位(秒)**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信token有效时间单位(秒)",name="expiresIn") | |||
| private Integer expiresIn; | |||
| /*支付ID,参看wx_pay_account**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付ID,参看wx_pay_account",name="payId") | |||
| private Long payId; | |||
| public String getTenantId() { | |||
| return tenantId; | |||
| } | |||
| @@ -132,6 +135,12 @@ public class WxAppinfo implements Serializable { | |||
| public void setExpiresIn(Integer _expiresIn) { | |||
| expiresIn = _expiresIn; | |||
| } | |||
| public Long getPayId() { | |||
| return payId; | |||
| } | |||
| public void setPayId(Long _payId) { | |||
| payId = _payId; | |||
| } | |||
| @@ -148,6 +157,7 @@ public class WxAppinfo implements Serializable { | |||
| ,AccessToken_ASC("`accessToken` ASC"),AccessToken_DESC("`accessToken` DESC") | |||
| ,LastTokenTime_ASC("`lastTokenTime` ASC"),LastTokenTime_DESC("`lastTokenTime` DESC") | |||
| ,ExpiresIn_ASC("`expiresIn` ASC"),ExpiresIn_DESC("`expiresIn` DESC") | |||
| ,PayId_ASC("`payId` ASC"),PayId_DESC("`payId` DESC") | |||
| ; | |||
| private String value; | |||
| Field(String value){ | |||
| @@ -42,12 +42,15 @@ public class WxPayAccount implements Serializable { | |||
| /***/ | |||
| @io.swagger.annotations.ApiModelProperty(value="",name="mchId") | |||
| /*微信商户号**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信商户号",name="mchId") | |||
| private String mchId; | |||
| /***/ | |||
| @io.swagger.annotations.ApiModelProperty(value="",name="apiKey") | |||
| /*支付密钥**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="支付密钥",name="apiKey") | |||
| private String apiKey; | |||
| /*微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="微信回调,支持3种回调,(1.url/pay 2.url/refund3.url/separate)",name="notifyUrl") | |||
| private String notifyUrl; | |||
| /*证书本地存放位置**/ | |||
| @io.swagger.annotations.ApiModelProperty(value="证书本地存放位置",name="certPath") | |||
| private String certPath; | |||
| @@ -63,6 +66,12 @@ public class WxPayAccount implements Serializable { | |||
| public void setApiKey(String _apiKey) { | |||
| apiKey = _apiKey; | |||
| } | |||
| public String getNotifyUrl() { | |||
| return notifyUrl; | |||
| } | |||
| public void setNotifyUrl(String _notifyUrl) { | |||
| notifyUrl = _notifyUrl; | |||
| } | |||
| public String getCertPath() { | |||
| return certPath; | |||
| } | |||
| @@ -70,13 +79,22 @@ public class WxPayAccount implements Serializable { | |||
| certPath = _certPath; | |||
| } | |||
| public String getPayNotifyUrl() { | |||
| return notifyUrl + "/pay"; | |||
| } | |||
| public String getRefundNotifyUrl() { | |||
| return notifyUrl + "/refund"; | |||
| } | |||
| public String getSeparateNotifyUrl() { | |||
| return notifyUrl + "/separate"; | |||
| } | |||
| public static enum Field | |||
| { | |||
| Id_ASC("`id` ASC"),Id_DESC("`id` DESC") | |||
| ,MchId_ASC("`mchId` ASC"),MchId_DESC("`mchId` DESC") | |||
| ,ApiKey_ASC("`apiKey` ASC"),ApiKey_DESC("`apiKey` DESC") | |||
| ,NotifyUrl_ASC("`notifyUrl` ASC"),NotifyUrl_DESC("`notifyUrl` DESC") | |||
| ,CertPath_ASC("`certPath` ASC"),CertPath_DESC("`certPath` DESC") | |||
| ; | |||
| private String value; | |||
| @@ -8,10 +8,7 @@ import com.simple.domain.po.WxMall; | |||
| public interface WxMallMapper extends CommonMapper<WxMall, Long> { | |||
| List<WxMall> findList(WxMall wxMall); | |||
| } | |||
| @@ -32,8 +32,9 @@ public class WxMallServiceImpl implements WxMallService { | |||
| if (record.getId() == null) { | |||
| //record.setId(UUID.randomUUID().toString().replaceAll("-", "")); | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| record.setId(idWorker.nextId()); | |||
| record.setTenantId(String.valueOf(idWorker.nextId())); | |||
| Long id = idWorker.nextId(); | |||
| record.setId(id); | |||
| record.setTenantId(String.valueOf(id)); | |||
| wxMallMapper.insertSelective(record); | |||
| } else { | |||
| wxMallMapper.updateByPrimaryKeySelective(record); | |||
| @@ -6,21 +6,16 @@ import java.util.*; | |||
| import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.simple.common.ErrorCode; | |||
| import com.simple.domain.po.WxCUser; | |||
| import com.simple.domain.po.WxCoupon; | |||
| import com.simple.domain.po.WxCouponOrder; | |||
| import com.simple.domain.po.WxOrder; | |||
| import com.simple.domain.po.*; | |||
| import com.simple.domain.vo.OrderVo; | |||
| import com.simple.enums.EnumCouponOrderStatus; | |||
| import com.simple.enums.EnumOrderStatus; | |||
| import com.simple.enums.EnumPayType; | |||
| import com.simple.enums.EnumValidStatus; | |||
| import com.simple.exception.MallinkException; | |||
| import com.simple.mapper.WxCUserMapper; | |||
| import com.simple.mapper.WxCouponMapper; | |||
| import com.simple.mapper.WxCouponOrderMapper; | |||
| import com.simple.mapper.WxOrderMapper; | |||
| import com.simple.mapper.*; | |||
| import com.simple.service.WxOrderService; | |||
| import com.simple.service.WxPayAccountService; | |||
| import com.simple.utils.RedisLock; | |||
| import org.apache.log4j.Logger; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| @@ -37,6 +32,18 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| @Autowired | |||
| RedisLock redisLock; | |||
| @Autowired | |||
| WxAppinfoMapper wxAppinfoMapper; | |||
| @Autowired | |||
| WxPayAccountMapper wxPayAccountMapper; | |||
| @Autowired | |||
| WxMallMapper wxMallMapper; | |||
| @Autowired | |||
| WxMerchantMapper wxMerchantMapper; | |||
| @Autowired | |||
| WxCUserMapper wxCUserMapper; | |||
| @@ -113,8 +120,6 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| throw new MallinkException(ErrorCode.ORDER_IS_FAIL); | |||
| } | |||
| try { | |||
| // 减库存 | |||
| coupon.setRemainInventory(coupon.getRemainInventory() - 1); | |||
| @@ -138,12 +143,11 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| Long orderNumber = idWorker.nextId(); | |||
| WxOrder record = new WxOrder(); | |||
| // body | |||
| // tenant_id + merchant_id + title + subtitle | |||
| String bodyStr = coupon.getTitle() + "/" + coupon.getSubTitle(); | |||
| WxOrder record = new WxOrder(); | |||
| try { | |||
| // 保存订单 | |||
| @@ -153,6 +157,7 @@ public class WxOrderServiceImpl implements WxOrderService { | |||
| record.setPaymentType(EnumPayType.PAY_PAYMENT.getCode()); | |||
| record.setPayment(payment); | |||
| record.setOrderStatus(EnumOrderStatus.ORDER_STATUS_PENDING_PAYMENT.getCode()); | |||
| record.setDetail(bodyStr); | |||
| record.setCreateDate(curr); | |||
| record.setUpdateDate(curr); | |||
| wxOrderMapper.insertSelective(record); | |||
| @@ -10,15 +10,13 @@ import com.github.pagehelper.PageHelper; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.simple.common.ErrorCode; | |||
| import com.simple.common.ResultData; | |||
| import com.simple.domain.po.WxAppinfo; | |||
| import com.simple.domain.po.WxCUser; | |||
| import com.simple.domain.po.WxOrder; | |||
| import com.simple.domain.po.WxPayOrder; | |||
| import com.simple.domain.po.*; | |||
| import com.simple.enums.EnumOrderStatus; | |||
| import com.simple.enums.EnumPayStatus; | |||
| import com.simple.enums.EnumPayWay; | |||
| import com.simple.exception.MallinkException; | |||
| import com.simple.mapper.WxOrderMapper; | |||
| import com.simple.mapper.WxPayAccountMapper; | |||
| import com.simple.mapper.WxPayOrderMapper; | |||
| import com.simple.pay.WxPay; | |||
| import com.simple.pay.WxPayOrderP; | |||
| @@ -40,6 +38,9 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| private Logger logger = Logger.getLogger(getClass()); | |||
| @Autowired | |||
| WxPayAccountMapper wxPayAccountMapper; | |||
| @Autowired | |||
| WxOrderMapper wxOrderMapper; | |||
| @@ -80,17 +81,15 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| logger.warn("pay order, order status not allow, repaymentReq: " + order.toString() + " , payWay: " + payWay.toString()); | |||
| throw new MallinkException(ErrorCode.ORDER_IS_NOT_PAY); | |||
| } | |||
| // TODO body | |||
| String body = "test"; | |||
| // 2. check 是否有支付订单 | |||
| List<WxPayOrder> list = wxPayOrderMapper.findList(record); | |||
| if (list.size() > 0) { | |||
| throw new MallinkException(ErrorCode.PAY_ORDER_EXIST); | |||
| } | |||
| // 3. 创建支付订单 | |||
| Long id = idworker.nextId(); | |||
| Date currentDate = new Date(); | |||
| Long id = idworker.nextId(); | |||
| record.setId(id); | |||
| record.setCreateTime(currentDate); | |||
| record.setUpdateTime(currentDate); | |||
| @@ -107,23 +106,24 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| if(sqlRow == 1) { | |||
| throw new MallinkException(ErrorCode.DB_FAIL); | |||
| } | |||
| WxPayAccount payAccount = wxPayAccountMapper.selectByPrimaryKey(appInfo.getPayId()); | |||
| { | |||
| // 统一下单 | |||
| String noncestr = Utility.generate32UUID(); | |||
| WxPayOrderP wxPayOrderP = new WxPayOrderP(); | |||
| wxPayOrderP.setAppid(appInfo.getAppId()); | |||
| //wxPayOrderP.setMch_id(appInfo.getMchId()); | |||
| wxPayOrderP.setMch_id(payAccount.getMchId()); | |||
| wxPayOrderP.setNonce_str(noncestr); | |||
| wxPayOrderP.setBody(body); | |||
| wxPayOrderP.setBody(order.getDetail()); | |||
| wxPayOrderP.setOut_trade_no(record.getPayOrderNo()); | |||
| wxPayOrderP.setTotal_fee(order.getPayment()); | |||
| wxPayOrderP.setSpbill_create_ip(record.getIp()); // 终端IP | |||
| //wxPayOrderP.setNotify_url(appInfo.getNotifyUrl()); | |||
| wxPayOrderP.setNotify_url(payAccount.getPayNotifyUrl()); | |||
| wxPayOrderP.setTrade_type(WxPay.TradeType.APP.name()); // 终端类型 | |||
| wxPayOrderP.setProduct_id(String.valueOf(order.getId())); // 订单ID | |||
| wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentTime)); | |||
| wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentTime + 15 * 60)); // 15分钟结束 | |||
| wxPayOrderP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayOrderP), appInfo.getSecret())); | |||
| wxPayOrderP.setSign(WxPayment.createSign(BeanUtils.toStringMap(wxPayOrderP), payAccount.getApiKey())); | |||
| String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); | |||
| logger.info("pay order, wechat pushOrder, wxPayOrder:" + wxPayOrderP.toString() + ", response: " + response.toString()); | |||
| Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||
| @@ -157,8 +157,8 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { | |||
| @Override | |||
| public String notify(Map<String, String> paramMap, EnumPayWay payWay) { | |||
| // how to get wechatAppId, wechatMchId, partnerKey | |||
| String wechatAppId = ""; | |||
| String wechatMchId = ""; | |||
| String wechatAppId = paramMap.get("appId"); | |||
| String wechatMchId = paramMap.get("mch_id"); | |||
| String partnerKey = ""; | |||
| try { | |||
| if (payWay == EnumPayWay.PAY_WAY_WEAPP) { | |||
| @@ -13,10 +13,11 @@ | |||
| <result column="access_token" jdbcType="VARCHAR" property="accessToken" /> | |||
| <result column="last_token_time" jdbcType="TIMESTAMP" property="lastTokenTime" /> | |||
| <result column="expires_in" jdbcType="INTEGER" property="expiresIn" /> | |||
| <result column="pay_id" jdbcType="BIGINT" property="payId" /> | |||
| </resultMap> | |||
| <sql id="allColumns"> | |||
| `id`,`tenant_id`,`app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`access_token`,`last_token_time`,`expires_in` | |||
| `id`,`tenant_id`,`app_id`,`name`,`secret`,`token`,`aes_key`,`msg_data_format`,`access_token`,`last_token_time`,`expires_in`,`pay_id` | |||
| </sql> | |||
| <sql id="dynamicWhereConditions"> | |||
| @@ -75,6 +76,11 @@ | |||
| <if test=" null != expiresIn "> | |||
| and `expires_in` = #{expiresIn} | |||
| </if> | |||
| <if test=" null != payId "> | |||
| and `pay_id` = #{payId} | |||
| </if> | |||
| <if test=" null != ids "> | |||
| and id in | |||
| @@ -5,11 +5,12 @@ | |||
| <id column="id" jdbcType="BIGINT" property="id" /> | |||
| <result column="mch_id" jdbcType="VARCHAR" property="mchId" /> | |||
| <result column="api_key" jdbcType="VARCHAR" property="apiKey" /> | |||
| <result column="notify_url" jdbcType="VARCHAR" property="notifyUrl" /> | |||
| <result column="cert_path" jdbcType="VARCHAR" property="certPath" /> | |||
| </resultMap> | |||
| <sql id="allColumns"> | |||
| `id`,`mch_id`,`api_key`,`cert_path` | |||
| `id`,`mch_id`,`api_key`,`notify_url`,`cert_path` | |||
| </sql> | |||
| <sql id="dynamicWhereConditions"> | |||
| @@ -30,6 +31,11 @@ | |||
| </if> | |||
| <if test=" null != notifyUrl "> | |||
| and `notify_url` like concat('%', #{notifyUrl},'%') | |||
| </if> | |||
| <if test=" null != certPath "> | |||
| and `cert_path` like concat('%', #{certPath},'%') | |||