雷蛇支付fixed
雷蛇支付验签 雷蛇支付1
This commit is contained in:
@@ -487,6 +487,8 @@ public class Constant {
|
||||
public static final String my_card = "MyCard";
|
||||
// StartPay
|
||||
public static final String start_pay = "start_pay";
|
||||
// razer
|
||||
public static final String razer = "razer";
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,17 @@
|
||||
package com.accompany.payment.razer;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties("razer")
|
||||
@Data
|
||||
public class RazerPayConfig {
|
||||
private String createUrl;//下单url
|
||||
private String returnUrl;
|
||||
private String callbackUrl;
|
||||
private String applicationCode;
|
||||
private String secretKey;
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.accompany.payment.razer;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RazerPayResDTO {
|
||||
private String applicationCode;
|
||||
private String referenceId;
|
||||
private String version;
|
||||
private Long amount;
|
||||
private String currencyCode;
|
||||
private String paymentId;
|
||||
private String paymentUrl;
|
||||
private String hashType;
|
||||
private String signature;
|
||||
private String paymentStatusCode;
|
||||
private String paymentStatusDate;
|
||||
private Long virtualCurrencyAmount;
|
||||
}
|
@@ -0,0 +1,100 @@
|
||||
package com.accompany.payment.razer;
|
||||
|
||||
import com.accompany.common.utils.HttpUtils;
|
||||
import com.accompany.payment.model.ChargeProd;
|
||||
import com.accompany.payment.model.ChargeRecord;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class RazerPayService {
|
||||
|
||||
@Autowired
|
||||
private RazerPayConfig razerPayConfig;
|
||||
|
||||
public RazerPayResDTO createOrder(ChargeRecord chargeRecord, ChargeProd chargeProd, String successUrl) {
|
||||
try {
|
||||
Map<String, String> formMap = new HashMap<>();
|
||||
String applicationCode = razerPayConfig.getApplicationCode();
|
||||
formMap.put("applicationCode", applicationCode);
|
||||
String referenceId = chargeRecord.getChargeRecordId();
|
||||
formMap.put("referenceId", referenceId);
|
||||
String version = "v1";
|
||||
formMap.put("version", version);
|
||||
long amount = chargeRecord.getAmount();
|
||||
formMap.put("amount", String.valueOf(amount));
|
||||
String currencyCode = chargeProd.getLocalCurrencyCode();
|
||||
formMap.put("currencyCode", currencyCode);
|
||||
String returnUrl = successUrl;
|
||||
formMap.put("returnUrl", returnUrl);
|
||||
String callbackUrl = razerPayConfig.getCallbackUrl();
|
||||
formMap.put("callbackUrl", callbackUrl);
|
||||
Long customerId = chargeRecord.getUid();
|
||||
formMap.put("customerId", String.valueOf(customerId));
|
||||
String description = chargeProd.getChargeGoldNum() + "Gold";
|
||||
formMap.put("description", description);
|
||||
|
||||
String hashType = "hmac-sha256";
|
||||
formMap.put("hashType", hashType);
|
||||
if (!"razer".equals(chargeRecord.getPaymentType())){
|
||||
formMap.put("channelId",chargeRecord.getPaymentType());
|
||||
}
|
||||
String signStr = formatMapToSignStr(formMap);
|
||||
String signature = signature(signStr);
|
||||
formMap.put("signature", signature);
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
headerMap.put("Content-Type", "application/x-www-form-urlencoded");
|
||||
log.info("post :{}", JSON.toJSONString(formMap));
|
||||
String resultBody = HttpUtils.doPost(razerPayConfig.getCreateUrl(), formMap, headerMap);
|
||||
log.info("RazerPayService.createOrder resultBody:{}", resultBody);
|
||||
RazerPayResDTO result = JSONObject.parseObject(resultBody, RazerPayResDTO.class);
|
||||
return result;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
log.error("RazerPayService.createOrder:e:{}", e);
|
||||
} catch (InvalidKeyException e) {
|
||||
log.error("RazerPayService.createOrder:e:{}", e);
|
||||
} catch (IOException e) {
|
||||
log.error("RazerPayService.createOrder:e:{}", e);
|
||||
}
|
||||
return new RazerPayResDTO();
|
||||
}
|
||||
|
||||
public String formatMapToSignStr(Map<String, String> paramMap) {
|
||||
Map tmpMap = paramMap;
|
||||
List<Map.Entry<String, String>> infoIds = new ArrayList(tmpMap.entrySet());
|
||||
Collections.sort(infoIds, (Comparator) (o1, o2) -> (((Map.Entry<String, Object>) o1).getKey()).toString().compareTo(((Map.Entry<String, Object>) o2).getKey()));
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (Map.Entry<String, String> item : infoIds) {
|
||||
if ((!StringUtils.isEmpty(item.getKey()))
|
||||
&& (!("signature".equals(item.getKey())))) {
|
||||
buf.append(item.getValue());
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String signature(String signStr) throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Mac hmac = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(razerPayConfig.getSecretKey().getBytes(StandardCharsets.UTF_8), "HmacSHA256");
|
||||
hmac.init(keySpec);
|
||||
byte[] hmacBytes = hmac.doFinal(signStr.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for(byte b : hmacBytes) {
|
||||
stringBuilder.append(String.format("%02x",b));
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
@@ -33,6 +33,11 @@ public class ChargeRecordService extends BaseService {
|
||||
return chargeRecordMapper.selectByPrimaryKey(chargeRecordId);
|
||||
}
|
||||
|
||||
public void updateChargeRecord(ChargeRecord record) {
|
||||
record.setUpdateTime(new Date());
|
||||
chargeRecordMapper.updateByPrimaryKey(record);
|
||||
}
|
||||
|
||||
public List<ChargeRecord> listChargeRecordByPingXXId(List<String> pingxxIdList) {
|
||||
ChargeRecordExample example = new ChargeRecordExample();
|
||||
example.createCriteria().andPingxxChargeIdIn(pingxxIdList);
|
||||
|
@@ -0,0 +1,50 @@
|
||||
package com.accompany.payment.strategy;
|
||||
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.core.base.UidContextHolder;
|
||||
import com.accompany.payment.annotation.PayChannelSupport;
|
||||
import com.accompany.payment.constant.ChargeUserLimitConstant;
|
||||
import com.accompany.payment.constant.PayConstant;
|
||||
import com.accompany.payment.model.ChargeProd;
|
||||
import com.accompany.payment.model.ChargeRecord;
|
||||
import com.accompany.payment.payermax.PayermaxService;
|
||||
import com.accompany.payment.payermax.dto.CreateOrderResDTO;
|
||||
import com.accompany.payment.payermax.params.CreateOrderParams;
|
||||
import com.accompany.payment.razer.RazerPayResDTO;
|
||||
import com.accompany.payment.razer.RazerPayService;
|
||||
import com.accompany.payment.service.ChargeUserLimitService;
|
||||
import com.accompany.payment.utils.CommonPayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@PayChannelSupport(Constant.ChargeChannel.razer)
|
||||
public class RazerStrategy extends AbstractPayStrategy {
|
||||
|
||||
private final String SPILT_PREFIX = "-";
|
||||
|
||||
@Autowired
|
||||
private ChargeUserLimitService chargeUserLimitService;
|
||||
|
||||
@Autowired
|
||||
private RazerPayService razerPayService;
|
||||
|
||||
@Override
|
||||
public Object pay(PayContext context) throws Exception {
|
||||
chargeUserLimitService.chargeLimitCheck(UidContextHolder.get(), ChargeUserLimitConstant.LIMIT_TYPE_OF_H5);
|
||||
ChargeRecord chargeRecord = context.getChargeRecord();
|
||||
ChargeProd chargeProd = context.getChargeProd();
|
||||
RazerPayResDTO orderRes = razerPayService.createOrder(chargeRecord, chargeProd, context.getSuccessUrl());
|
||||
chargeRecord.setPingxxChargeId(orderRes.getPaymentId());
|
||||
Map<String, Object> appMap = new HashMap<>();
|
||||
appMap.put(PayConstant.H5_PAY_URL_FIELD, orderRes.getPaymentUrl());
|
||||
appMap.put(PayConstant.H5_PAY_NICK_FIELD, context.getNick());
|
||||
appMap.put(PayConstant.H5_PAY_ERBANNO_FIELD, context.getErbanNo());
|
||||
return appMap;
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
package com.accompany.business.controller.apppay;
|
||||
|
||||
import com.accompany.business.service.ChargeService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.payment.model.ChargeRecord;
|
||||
import com.accompany.payment.razer.RazerPayService;
|
||||
import com.accompany.payment.service.ChargeRecordService;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/payment/razer")
|
||||
@Slf4j
|
||||
public class RazerPayController {
|
||||
|
||||
@Autowired
|
||||
private ChargeRecordService chargeRecordService;
|
||||
@Autowired
|
||||
private ChargeService chargeService;
|
||||
@Autowired
|
||||
private RazerPayService razerPayService;
|
||||
|
||||
@RequestMapping(value = "/callback", method = RequestMethod.POST)
|
||||
public void callback(HttpServletRequest request) throws NoSuchAlgorithmException, InvalidKeyException, ParseException {
|
||||
log.info("handle razerPay notification:request:{}", JSONObject.toJSONString(request.getParameterMap()));
|
||||
// 创建一个Map来存储请求参数
|
||||
Map<String, String> params = new HashMap<>();
|
||||
// 获取所有参数名
|
||||
Enumeration<String> paramNames = request.getParameterNames();
|
||||
while (paramNames.hasMoreElements()) {
|
||||
String paramName = paramNames.nextElement();
|
||||
// 获取参数值
|
||||
String paramValue = request.getParameter(paramName);
|
||||
// 将参数名和值放入Map中
|
||||
params.put(paramName, paramValue);
|
||||
}
|
||||
log.info("RazerPayController:params:{}", params);
|
||||
String signStr = razerPayService.formatMapToSignStr(params);
|
||||
String signature = razerPayService.signature(signStr);
|
||||
String paramSignature = params.get("signature");
|
||||
if (!signature.equals(paramSignature)) {
|
||||
log.info("RazerPayController:signatureError,signStr:{},signature:{},paramSignature:{}", signStr, signature, paramSignature);
|
||||
throw new ServiceException(BusiStatus.SERVERBUSY);
|
||||
}
|
||||
String chargeRecordId = params.get("referenceId");
|
||||
ChargeRecord chargeRecordById =
|
||||
chargeRecordService.getChargeRecordById(chargeRecordId);
|
||||
if (chargeRecordById == null) {
|
||||
log.info("RazerPayController empty charge, chargeId:{}", chargeRecordId);
|
||||
return;
|
||||
}
|
||||
if (Constant.ChargeRecordStatus.finish.equals(chargeRecordById.getChargeStatus())) {
|
||||
log.info("RazerPayController charge finish, chargeId:{}", chargeRecordId);
|
||||
return;
|
||||
}
|
||||
if (!Constant.ChargeRecordStatus.create.equals(chargeRecordById.getChargeStatus())) {
|
||||
log.info("RazerPayController charge_status fail, charge:{}", JSONObject.toJSONString(chargeRecordById));
|
||||
return;
|
||||
}
|
||||
String paymentStatusCode = params.get("paymentStatusCode");
|
||||
if ("00".equals(paymentStatusCode)) {
|
||||
String amount = params.get("amount");
|
||||
String currencyCode = params.get("currencyCode");
|
||||
Long amountValue = Long.valueOf(amount);
|
||||
if (!chargeRecordById.getAmount().equals(amountValue) || !chargeRecordById.getLocalCurrencyCode().equals(currencyCode)) {
|
||||
log.info("RazerPayController amount fail, chargeRecordId:{},chargeAmount:{}, callBackAmound:{}",
|
||||
chargeRecordId, chargeRecordById.getAmount(), amount);
|
||||
return;
|
||||
}
|
||||
String paymentId = params.get("paymentId");
|
||||
|
||||
chargeRecordById.setLocalCurrencyCode(currencyCode);
|
||||
chargeRecordById.setLocalAmount(amountValue);
|
||||
|
||||
chargeRecordById.setPingxxChargeId(paymentId);
|
||||
String paymentStatusDate = params.get("paymentStatusDate");
|
||||
chargeRecordById.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(paymentStatusDate));
|
||||
|
||||
chargeService.updateAppPayData(chargeRecordById);
|
||||
} else {
|
||||
chargeRecordById.setChargeStatus(Constant.ChargeRecordStatus.error);
|
||||
chargeRecordById.setChargeDesc(paymentStatusCode);
|
||||
chargeRecordService.updateChargeRecord(chargeRecordById);
|
||||
}
|
||||
log.info("end handle razer alipay notification");
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user