|
@@ -0,0 +1,221 @@
|
|
|
+package com.miaxis.app.controller.tt;
|
|
|
+
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.miaxis.common.config.WxpayConfig;
|
|
|
+import com.miaxis.common.constant.Constants;
|
|
|
+import com.miaxis.common.core.domain.entity.UserInfo;
|
|
|
+import com.miaxis.common.exception.CustomException;
|
|
|
+import com.miaxis.common.utils.AesUtil;
|
|
|
+import com.miaxis.tt.domain.TtOrder;
|
|
|
+import com.miaxis.tt.dto.TtNotifyReturnDTO;
|
|
|
+import com.miaxis.tt.dto.TtpayNotifyDTO;
|
|
|
+import com.miaxis.tt.dto.TtpaySource;
|
|
|
+import com.miaxis.tt.service.ITtOrderService;
|
|
|
+import com.miaxis.user.service.IUserInfoService;
|
|
|
+import com.miaxis.vip.domain.VipCode;
|
|
|
+import com.miaxis.vip.service.IVipCodeService;
|
|
|
+import com.miaxis.wx.domain.RefundRecord;
|
|
|
+import com.miaxis.wx.domain.WxOrder;
|
|
|
+import com.miaxis.wx.dto.WxNotifyReturnDTO;
|
|
|
+import com.miaxis.wx.dto.WxpayNotifyDTO;
|
|
|
+import com.miaxis.wx.service.IRefundRecordService;
|
|
|
+import com.miaxis.wx.service.IWxOrderService;
|
|
|
+import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.joda.time.DateTime;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.util.Base64Utils;
|
|
|
+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 javax.servlet.http.HttpServletRequest;
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.security.*;
|
|
|
+import java.security.cert.X509Certificate;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.Random;
|
|
|
+
|
|
|
+@RestController
|
|
|
+@RequiredArgsConstructor
|
|
|
+@RequestMapping(Constants.OPEN_PREFIX+"/tt/notify")
|
|
|
+@Api(tags = {"【小程序-微信回调】"})
|
|
|
+@Slf4j
|
|
|
+public class TtNotifyController {
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WxpayConfig wxpayConfig;
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IWxOrderService wxOrderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ITtOrderService ttOrderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IVipCodeService vipCodeService;
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IUserInfoService userInfoService;
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IRefundRecordService refundRecordService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private AutoUpdateCertificatesVerifier verifier;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 微信支付回调接口
|
|
|
+ */
|
|
|
+ @PostMapping(value = "/ttpay")
|
|
|
+ @ApiOperation("头条支付回调")
|
|
|
+ public TtNotifyReturnDTO wxpayNotify(@RequestBody TtpayNotifyDTO ttpayNotifyDTO) {
|
|
|
+
|
|
|
+ //将回调数据写入数据库
|
|
|
+ TtpaySource msg = JSONObject.parseObject(ttpayNotifyDTO.getMsg(), TtpaySource.class);
|
|
|
+ writeNotifyDataToDb(msg);
|
|
|
+ //创建兑换码
|
|
|
+ String code = createCode();
|
|
|
+ //激活用户
|
|
|
+ avtivityCode(msg.getCp_orderno(),code);
|
|
|
+
|
|
|
+ TtNotifyReturnDTO ttNotifyReturnDTO = new TtNotifyReturnDTO();
|
|
|
+ ttNotifyReturnDTO.setErr_no(0);
|
|
|
+ ttNotifyReturnDTO.setErr_tips("success");
|
|
|
+ return ttNotifyReturnDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void avtivityCode(String outTradeNo, String vipCode) {
|
|
|
+ TtOrder order= ttOrderService.getOne(new QueryWrapper<TtOrder>().eq("cp_orderno",outTradeNo));
|
|
|
+ if (order == null){
|
|
|
+ throw new CustomException("该订单不存在");
|
|
|
+ }
|
|
|
+ UserInfo userInfo = userInfoService.getOne(new QueryWrapper<UserInfo>().eq("union_id", order.getUnionId()));
|
|
|
+ QueryWrapper<VipCode> queryWrapper = new QueryWrapper<VipCode>();
|
|
|
+ queryWrapper.eq("vip_code", vipCode);
|
|
|
+ VipCode vipCodeEntity = vipCodeService.getOne(queryWrapper);
|
|
|
+ if (vipCodeEntity == null){
|
|
|
+ throw new CustomException("该激活码不存在");
|
|
|
+ }
|
|
|
+ if (vipCodeEntity.getStatus() == 1){
|
|
|
+ throw new CustomException("该激活码已被激活");
|
|
|
+ }
|
|
|
+ if (vipCodeEntity.getStatus() == 2){
|
|
|
+ throw new CustomException("该激活码已作废");
|
|
|
+ }
|
|
|
+ vipCodeEntity.setStatus(1);
|
|
|
+ vipCodeEntity.setActivationUserId(userInfo.getId());
|
|
|
+ vipCodeEntity.setActivationTime(new Date());
|
|
|
+ vipCodeService.updateById(vipCodeEntity);
|
|
|
+ userInfo.setIsVip(1);
|
|
|
+ userInfoService.updateById(userInfo);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private String createCode() {
|
|
|
+ VipCode vipCode = new VipCode();
|
|
|
+ String rVipCode = null ;
|
|
|
+ do {
|
|
|
+ rVipCode = randomVipcode();
|
|
|
+ }while (isRepeat(rVipCode));
|
|
|
+ vipCode.setVipCode(rVipCode);
|
|
|
+ vipCodeService.save(vipCode);
|
|
|
+ return rVipCode;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private Boolean validate(HttpServletRequest request, String bodyString) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
|
|
|
+ String sign = request.getHeader("Wechatpay-Signature");
|
|
|
+ String timestamp = request.getHeader("Wechatpay-Timestamp");
|
|
|
+ String nonce = request.getHeader("Wechatpay-Nonce");
|
|
|
+
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ sb.append(timestamp + "\n");
|
|
|
+ sb.append(nonce + "\n");
|
|
|
+ sb.append(bodyString + "\n");
|
|
|
+ X509Certificate validCertificate = verifier.getValidCertificate();
|
|
|
+ // 进行签名服务
|
|
|
+ Signature signature = Signature.getInstance("SHA256withRSA");
|
|
|
+ // 用微信平台公钥对签名器进行初始化
|
|
|
+ signature.initVerify(validCertificate);
|
|
|
+ // 把我们构造的验签名串更新到签名器中
|
|
|
+ signature.update(sb.toString().getBytes(StandardCharsets.UTF_8));
|
|
|
+ Boolean result = signature.verify(Base64Utils.decodeFromString(sign));
|
|
|
+ log.info("微信支付回调验签:"+result.toString());
|
|
|
+ return result;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public void writeNotifyDataToDb(TtpaySource msg) {
|
|
|
+ TtOrder order= ttOrderService.getOne(new QueryWrapper<TtOrder>().eq("cp_orderno",msg.getCp_orderno()));
|
|
|
+ if (order == null) {
|
|
|
+ throw new CustomException("该订单不存在");
|
|
|
+ }
|
|
|
+ order.setPaymentOrderNo(msg.getPayment_order_no());
|
|
|
+ order.setChannelNo(msg.getChannel_no());
|
|
|
+ order.setWay(msg.getWay());
|
|
|
+ order.setCpExtra(msg.getCp_extra());
|
|
|
+ order.setItemId(msg.getItem_id());
|
|
|
+ order.setSellerUid(msg.getSeller_uid());
|
|
|
+ order.setStatus(msg.getStatus());
|
|
|
+ order.setTotalAmount(msg.getTotal_amount());
|
|
|
+ order.setPaidAt(new Date(msg.getPaid_at()));
|
|
|
+ ttOrderService.updateById(order);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getSourString(WxpayNotifyDTO wxpayNotifyDTO) throws GeneralSecurityException, IOException {
|
|
|
+ AesUtil aesUtil = new AesUtil(wxpayConfig.getV3key().getBytes());
|
|
|
+ WxpayNotifyDTO.WxpaySource wxpaySource = wxpayNotifyDTO.getResource();
|
|
|
+ return aesUtil.decryptToString(wxpaySource.getAssociated_data().getBytes(), wxpaySource.getNonce().getBytes(), wxpaySource.getCiphertext());
|
|
|
+ }
|
|
|
+
|
|
|
+ private String randomVipcode() {
|
|
|
+ String result = "";
|
|
|
+ Random random = new Random();
|
|
|
+ for(int i =0 ;i <11 ;i ++){
|
|
|
+ result+=random.nextInt(10);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ private boolean isRepeat(String rVipCode) {
|
|
|
+ QueryWrapper<VipCode> wrapper = new QueryWrapper<VipCode>();
|
|
|
+ wrapper.eq("vip_code",rVipCode);
|
|
|
+ VipCode one = vipCodeService.getOne(wrapper);
|
|
|
+ return one!= null;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|