payermax-回调

This commit is contained in:
2023-10-22 21:56:29 +08:00
committed by khalil
parent 844a50191f
commit 5ce6dfeca0
2 changed files with 78 additions and 109 deletions

View File

@@ -1,12 +1,9 @@
package com.accompany.payment.payermax.params;
import lombok.Data;
import java.io.IOException;
import java.io.Serializable;
@lombok.Data
public class PayCallbackReqVo implements Serializable {
public class PayCallbackReqVo {
/**
* 商户app id
*/
@@ -38,7 +35,7 @@ public class PayCallbackReqVo implements Serializable {
private String notifyType;
@lombok.Data
public static class Order implements Serializable {
public class Order {
/**
* 渠道订单号
*/
@@ -93,7 +90,7 @@ public class PayCallbackReqVo implements Serializable {
private String tradeToken;
@lombok.Data
public static class PaymentDetail implements Serializable {
public class PaymentDetail {
/**
* 卡信息
*/
@@ -125,7 +122,7 @@ public class PayCallbackReqVo implements Serializable {
/**
* 交易状态SUCCESS-支付成功FAILED -支付失败CLOSED-关单
*/
public static enum Status implements Serializable{
public enum Status {
CLOSED, FAILED, SUCCESS;
public String toValue() {

View File

@@ -1,30 +1,28 @@
package com.accompany.business.controller.apppay;
import com.accompany.business.service.ChargeService;
import com.accompany.common.constant.Constant;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.exception.ServiceException;
import com.accompany.payment.constant.PayConstant;
import com.accompany.payment.model.ChargeRecord;
import com.accompany.payment.payermax.config.PayermaxConfig;
import com.accompany.payment.payermax.params.PayCallbackReqVO;
import com.accompany.payment.payermax.params.PayCallbackReqVo;
import com.accompany.payment.service.ChargeRecordService;
import com.accompany.payment.utils.PayermaxUtils;
import com.alibaba.fastjson.JSONObject;
import com.payermax.sdk.client.DefaultPayermaxClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
/**
@@ -43,100 +41,74 @@ public class PayermaxPayController {
@Autowired
private ChargeService chargeService;
@Autowired
private PayermaxConfig payermaxConfig;
@Autowired
private RedissonClient redissonClient;
private final static Integer TRADE_STATUS_SUCCESS = 1;
private final static Integer TRADE_STATUS_FAIL = 2;
@PostMapping("/callback")
public BusiResult<Void> callback(HttpServletRequest request,
@RequestBody PayCallbackReqVo payCallbackReqVo) {
String sign = request.getHeader("sign");
String paramsString = JSONObject.toJSONString(payCallbackReqVo);
log.info("[payermax] 接受回调参数为:{}",paramsString);
// @RequestMapping(value = "/callback", method = RequestMethod.POST)
// public Map<String, Object> callback(@RequestBody PayCallbackReqVO payCallbackReqVO) {
// log.info("start handle payermax pay notification");
// String paramsString = JSONObject.toJSONString(payCallbackReqVO);
// log.info("payermax接受回调参数为:{}",paramsString);
// Map<String, Object> map = new HashMap<>();
//
// //1.1 Verify signature
// Map<String, Object> param = JSONObject.parseObject(paramsString, Map.class);
// //Use the test environment link: secretKey needs to be secretKey for the test environment
// //Use the production environment link: the secretKey needs to be secretKey for the production environment
// boolean result = PayermaxUtils.verifyForMD5(param, payCallbackReqVO.getSign(), payermaxConfig.getSecretKey());
//
// if (!result) {
// //1.2 Verify signature failure
// //default response format without modify
// map.put("bizCode", "400");
// map.put("message", "Signature verification failure");
// return map;
// }
//
// String chargeRecordId = payCallbackReqVO.getOrderId();
//
// if (!TRADE_STATUS_SUCCESS.equals(payCallbackReqVO.getStatus())) {
// log.warn("【payermax支付回调】订单 {} 支付状态不是成功,忽略。", chargeRecordId);
// map.put("bizCode", "0000");
// map.put("message", "success");
// return map;
// }
//
// String lockKey = RedisKey.lock_pay_callback_notify.getKey(chargeRecordId);
// RLock lock = redissonClient.getLock(lockKey);
// boolean isLocked = false;
// try {
// isLocked = lock.tryLock(5L, TimeUnit.SECONDS);
// if (!isLocked){
// log.error("【payermax支付回调】加锁失败 chargeRecordId: {}", chargeRecordId);
// throw new ServiceException(BusiStatus.SERVER_BUSY);
// }
//
// ChargeRecord chargeRecord = chargeRecordService.getChargeRecordById(chargeRecordId);
// if (chargeRecord == null) {
// log.warn("【payermax支付回调】订单 {} 不存在", chargeRecordId);
// map.put("bizCode", "500");
// map.put("message", "charge order not exsists");
// return map;
// }
// if (StringUtils.isBlank(payCallbackReqVO.getCurrency()) || !payCallbackReqVO.getCurrency().equalsIgnoreCase(chargeRecord.getLocalCurrencyCode())) {
// log.warn("【payermax支付回调】回调的货币代码为空或与订单 {} 中的 {} 不匹配", chargeRecordId, chargeRecord.getLocalCurrencyCode());
// map.put("bizCode", "500");
// map.put("message", "charge currency error");
// return map;
// }
// Long payAmount = new BigDecimal(payCallbackReqVO.getPayAmount()).multiply(PayConstant.HUNDRED).longValue();
// // 校验金额
// boolean validateAmount = payAmount.equals(chargeRecord.getLocalAmount());
// if (!validateAmount) {
// log.warn("【payermax支付回调】订单 {} 金额 {} 校验失败", chargeRecordId, payAmount);
// map.put("bizCode", "500");
// map.put("message", "total amount error");
// return map;
// }
// chargeRecord.setCountry(payCallbackReqVO.getCountryCode());
// chargeRecord.setLocalCurrencyCode(payCallbackReqVO.getPayCurrency());
// chargeRecord.setLocalAmount(payAmount);
//
// chargeRecord.setPingxxChargeId(payCallbackReqVO.getTradeOrderNo());
// chargeRecord.setUpdateTime(Calendar.getInstance().getTime());
//
// chargeService.updateAppPayData(chargeRecord);
//
// //3 Return success
// //default response format without modify
// map.put("bizCode", "0000");
// map.put("message", "success");
// return map;
// } catch (Exception e) {
// //4 Return exception
// //default response format without modify
// map.put("bizCode", "500");
// map.put("message", "Exception happened " + e.getMessage());
// return map;
// } finally {
// if (isLocked || lock.isLocked()){
// lock.unlock();
// }
// }
// }
if (!DefaultPayermaxClient.getInstance().verifyNotification(paramsString, sign)) {
log.error("[payermax] 验签失败");
return BusiResult.success();
}
PayCallbackReqVo.Order order = payCallbackReqVo.getData();
String chargeRecordId = order.getOutTradeNo();
if (!PayCallbackReqVo.Status.SUCCESS.equals(order.getStatus())) {
log.warn("[payermax] 支付回调 订单 {} 支付状态不是成功,忽略。", chargeRecordId);
return BusiResult.success();
}
String lockKey = RedisKey.lock_pay_callback_notify.getKey(chargeRecordId);
RLock lock = redissonClient.getLock(lockKey);
boolean isLocked = false;
try {
isLocked = lock.tryLock(5L, TimeUnit.SECONDS);
if (!isLocked){
log.error("[payermax] 支付回调 加锁失败 chargeRecordId: {}", chargeRecordId);
throw new ServiceException(BusiStatus.SERVER_BUSY);
}
ChargeRecord chargeRecord = chargeRecordService.getChargeRecordById(chargeRecordId);
if (null == chargeRecord || !Constant.ChargeRecordStatus.create.equals(chargeRecord.getChargeStatus())) {
log.warn("[payermax] 支付回调 订单 {} 不存在", chargeRecordId);
return BusiResult.success();
}
if (StringUtils.isBlank(order.getCurrency()) || !order.getCurrency().equalsIgnoreCase(chargeRecord.getLocalCurrencyCode())) {
log.warn("[payermax] 支付回调 回调的货币代码为空或与订单 {} 中的 {} 不匹配", chargeRecordId, chargeRecord.getLocalCurrencyCode());
return BusiResult.success();
}
Long payAmount = BigDecimal.valueOf(order.getTotalAmount()).multiply(PayConstant.HUNDRED).longValue();
// 校验金额
boolean validateAmount = payAmount.equals(chargeRecord.getLocalAmount());
if (!validateAmount) {
log.warn("[payermax] 支付回调 订单 {} 金额 {} 校验失败", chargeRecordId, payAmount);
return BusiResult.success();
}
chargeRecord.setCountry(order.getCountry());
chargeRecord.setLocalCurrencyCode(order.getCurrency());
chargeRecord.setLocalAmount(payAmount);
chargeRecord.setPingxxChargeId(order.getTradeToken());
chargeRecord.setUpdateTime(DateTimeUtil.converLocalDateTimeToDate(LocalDateTime.parse(order.getCompleteTime())));
chargeService.updateAppPayData(chargeRecord);
return BusiResult.success();
} catch (Exception e) {
//todo log
log.error("{}", e);
return BusiResult.fail(BusiStatus.SERVERERROR);
} finally {
if (isLocked || lock.isLocked()){
lock.unlock();
}
}
}
}