v1.1 payermax ios第三方支付
This commit is contained in:
@@ -1750,6 +1750,12 @@ public class Constant {
|
||||
* 深海活动预警配置
|
||||
*/
|
||||
public static final String LUCKY_SEA_PREWARNING_CONFIG = "lucky_sea_prewarning_config";
|
||||
|
||||
/**
|
||||
* h5充值中,各区域的配置
|
||||
*/
|
||||
public static final String H5_AREA_CHARGE_CONFIG = "h5_area_charge_config";
|
||||
|
||||
}
|
||||
|
||||
public static class ActiveMq {
|
||||
|
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 文 件 名: ClanPkStatusEnum
|
||||
* 版 权:
|
||||
* 描 述: <描述>
|
||||
* 创建人: H1
|
||||
* 创建时间: 2021/3/23
|
||||
* 修改人:
|
||||
* 修改内容:
|
||||
* 修改时间:
|
||||
*/
|
||||
package com.accompany.payment.constant;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* <br>枚举类描述: 地区货币类型
|
||||
* <br>功能详细描述:
|
||||
*
|
||||
* @date [2021年05月25日]
|
||||
*/
|
||||
public enum CurrencyTypeEnum {
|
||||
CNY("CNY", "CN", "人民币", "¥"),
|
||||
TWD("TWD", "TW","新台币","NT$"),
|
||||
HKD("HKD", "HK","港币", "HK$"),
|
||||
USD("USD", "USA","美元", "$"),
|
||||
SGD("SGD", "SG","新加坡币", "$"),
|
||||
MYR("MYR", "MY","马来西亚币", "RM"),
|
||||
UNKNOW("UNKNOW", "UNKNOW","未知类型", ""),
|
||||
;
|
||||
private String value;
|
||||
private String countryCode;
|
||||
private String desc;
|
||||
private String sign;
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
CurrencyTypeEnum(String value, String countryCode, String desc, String sign) {
|
||||
this.value = value;
|
||||
this.desc = desc;
|
||||
this.countryCode = countryCode;
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getCountryCode() {
|
||||
return countryCode;
|
||||
}
|
||||
|
||||
public void setCountryCode(String countryCode) {
|
||||
this.countryCode = countryCode;
|
||||
}
|
||||
|
||||
public static CurrencyTypeEnum getByValue(String value) {
|
||||
Optional<CurrencyTypeEnum> result = Arrays.stream(CurrencyTypeEnum.values()).filter(currencyEnum ->
|
||||
currencyEnum.value.equalsIgnoreCase(value)).findAny();
|
||||
if (result.isPresent()) {
|
||||
return result.get();
|
||||
}
|
||||
return UNKNOW;
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package com.accompany.payment.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class AreaChargeConfigDTO {
|
||||
|
||||
@Data
|
||||
public static class AreaChargeConfigeItem {
|
||||
|
||||
private Boolean enable;
|
||||
|
||||
private String desc;
|
||||
|
||||
private Integer seq;
|
||||
|
||||
private List<String> chargeWays;
|
||||
|
||||
private List<AreaChargeWayGroup> chargeWayGroups;
|
||||
|
||||
private BigDecimal toLocalCommission;
|
||||
|
||||
private Boolean useLocalCurrency;
|
||||
|
||||
private String localCurrencyCode;
|
||||
|
||||
private String localCurrencySign;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class AreaChargeWayGroup {
|
||||
private String groupName;
|
||||
|
||||
private List<String> chargeWays;
|
||||
}
|
||||
|
||||
private Map<String, AreaChargeConfigeItem> areaConfig;
|
||||
}
|
@@ -11,6 +11,8 @@ public class ChargeProd {
|
||||
|
||||
private String country;
|
||||
|
||||
private String localCurrencyCode;
|
||||
|
||||
private Long money;
|
||||
|
||||
private Integer changeGoldRate;
|
||||
@@ -65,6 +67,14 @@ public class ChargeProd {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getLocalCurrencyCode() {
|
||||
return localCurrencyCode;
|
||||
}
|
||||
|
||||
public void setLocalCurrencyCode(String localCurrencyCode) {
|
||||
this.localCurrencyCode = localCurrencyCode;
|
||||
}
|
||||
|
||||
public Long getMoney() {
|
||||
return money;
|
||||
}
|
||||
|
@@ -15,6 +15,8 @@ public class ChargeRecord {
|
||||
|
||||
private String channel;
|
||||
|
||||
private String paymentType;
|
||||
|
||||
private Byte bussType;
|
||||
|
||||
private Byte chargeStatus;
|
||||
@@ -33,6 +35,8 @@ public class ChargeRecord {
|
||||
|
||||
private String clientIp;
|
||||
|
||||
private String clientDeviceId;
|
||||
|
||||
private String wxPubOpenid;
|
||||
|
||||
private String subject;
|
||||
@@ -103,6 +107,14 @@ public class ChargeRecord {
|
||||
this.channel = channel == null ? null : channel.trim();
|
||||
}
|
||||
|
||||
public String getPaymentType() {
|
||||
return paymentType;
|
||||
}
|
||||
|
||||
public void setPaymentType(String paymentType) {
|
||||
this.paymentType = paymentType;
|
||||
}
|
||||
|
||||
public Byte getBussType() {
|
||||
return bussType;
|
||||
}
|
||||
@@ -175,6 +187,14 @@ public class ChargeRecord {
|
||||
this.clientIp = clientIp == null ? null : clientIp.trim();
|
||||
}
|
||||
|
||||
public String getClientDeviceId() {
|
||||
return clientDeviceId;
|
||||
}
|
||||
|
||||
public void setClientDeviceId(String clientDeviceId) {
|
||||
this.clientDeviceId = clientDeviceId;
|
||||
}
|
||||
|
||||
public String getWxPubOpenid() {
|
||||
return wxPubOpenid;
|
||||
}
|
||||
|
@@ -0,0 +1,123 @@
|
||||
package com.accompany.payment.payermax;
|
||||
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.BeanUtil;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.accompany.core.util.OkHttpUtils;
|
||||
import com.accompany.payment.payermax.config.PayermaxConfig;
|
||||
import com.accompany.payment.payermax.dto.CreateOrderResDTO;
|
||||
import com.accompany.payment.payermax.params.CreateOrderParams;
|
||||
import com.accompany.payment.utils.CommonPayUtils;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PayermaxService {
|
||||
|
||||
@Autowired
|
||||
private PayermaxConfig payermaxConfig;
|
||||
@Autowired
|
||||
private SysConfService sysConfService;
|
||||
|
||||
/**
|
||||
* 调用成功
|
||||
*/
|
||||
private static final String RES_CODE_SUCCESS = "0000";
|
||||
|
||||
private static final String PAYMENT_DETAIL_FIELD_NAME = "paymentDetail";
|
||||
|
||||
private static final String BIZ_TYPE_CUSTOMIZE = "CUSTOMIZE";
|
||||
|
||||
private static final String BIZ_TYPE_IN_CB = "IN_CB";
|
||||
|
||||
private static final String API_VERSION = "2.3";
|
||||
|
||||
private static final String CURRENCY_USD = "USD";
|
||||
|
||||
private static final String AREA_CODE_IN = "IN";
|
||||
|
||||
public CreateOrderResDTO createOrder(CreateOrderParams params) {
|
||||
checkCreateOrderParams(params);
|
||||
|
||||
String result = null;
|
||||
try {
|
||||
Map<String, String> mapParams = toMapCreateOrderParams(params);
|
||||
|
||||
log.info("payermax请求参数:{}", JSONObject.toJSONString(mapParams));
|
||||
|
||||
result = OkHttpUtils.postWithBody(payermaxConfig.getCreateOrderUrl(), mapParams);
|
||||
|
||||
log.info("payermax请求结果:{}",result);
|
||||
} catch (Exception e) {
|
||||
log.error("payermax创建订单失败。params:" + JSONObject.toJSONString(params), e);
|
||||
throw new ServiceException(BusiStatus.PAYMENT_FAIL);
|
||||
}
|
||||
|
||||
CreateOrderResDTO res = JSONObject.parseObject(result, CreateOrderResDTO.class);
|
||||
if (!RES_CODE_SUCCESS.equalsIgnoreCase(res.getBizCode())) {
|
||||
throw new ServiceException(BusiStatus.PAYMENT_FAIL);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private Map<String, String> toMapCreateOrderParams(CreateOrderParams params) {
|
||||
Map<String, String> tmpParams = new HashMap<>();
|
||||
tmpParams.put("merchantId", payermaxConfig.getMerchantId());
|
||||
// 印度的bizType固定是IN_CB
|
||||
tmpParams.put("bizType", AREA_CODE_IN.equalsIgnoreCase(params.getCountryCode())? BIZ_TYPE_IN_CB: BIZ_TYPE_CUSTOMIZE);
|
||||
tmpParams.put("version", API_VERSION);
|
||||
tmpParams.put("sign", CommonPayUtils.signParams(tmpParams, "key", payermaxConfig.getSecretKey()));
|
||||
tmpParams.put("orderId", params.getOrderId());
|
||||
tmpParams.put("userId", params.getUserId());
|
||||
tmpParams.put("subject", params.getSubject());
|
||||
tmpParams.put("countryCode", params.getCountryCode());
|
||||
tmpParams.put("currency", params.getCurrency());
|
||||
tmpParams.put("totalAmount", params.getTotalAmount());
|
||||
tmpParams.put("frontCallBackUrl", params.getFrontCallBackUrl());
|
||||
|
||||
if (params.getPaymentDetail() != null) {
|
||||
tmpParams.put(PAYMENT_DETAIL_FIELD_NAME, JSONObject.toJSONString(params.getPaymentDetail()));
|
||||
}
|
||||
|
||||
log.info("payermax待处理请求参数:{}", JSONObject.toJSONString(tmpParams));
|
||||
Map<String, String> requestParams = tmpParams.keySet().stream().filter(it -> tmpParams.get(it) != null)
|
||||
.collect(Collectors.toMap(it -> it, it -> {
|
||||
if (tmpParams.containsKey(it) && tmpParams.get(it) != null) {
|
||||
return tmpParams.get(it).toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}));
|
||||
return requestParams;
|
||||
}
|
||||
|
||||
private void checkCreateOrderParams(CreateOrderParams params) {
|
||||
if (params == null) {
|
||||
throw new ServiceException(BusiStatus.PARAMERROR);
|
||||
}
|
||||
if (params.getTotalAmount() == null || new BigDecimal(params.getTotalAmount()).compareTo(BigDecimal.ZERO) <= 0) {
|
||||
params.setTotalAmount("0.01");
|
||||
}
|
||||
if (StringUtils.isBlank(params.getOrderId())) {
|
||||
throw new ServiceException(BusiStatus.PARAMERROR, "商户订单号不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(params.getSubject())) {
|
||||
throw new ServiceException(BusiStatus.PARAMERROR, "商品订单描述不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(params.getCountryCode())) {
|
||||
throw new ServiceException(BusiStatus.PARAMERROR, "国家代码不能为空");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package com.accompany.payment.payermax.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties("payermax")
|
||||
@Data
|
||||
public class PayermaxConfig {
|
||||
|
||||
private String merchantId;
|
||||
|
||||
private String secretKey;
|
||||
|
||||
private String callBackUrl;
|
||||
|
||||
private String createOrderUrl;
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package com.accompany.payment.payermax.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BaseResDTO<T> {
|
||||
|
||||
private String bizCode;
|
||||
|
||||
private String message;
|
||||
|
||||
private T data;
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package com.accompany.payment.payermax.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CreateOrderResDTO extends BaseResDTO<CreateOrderResDTO.OrderRes> {
|
||||
|
||||
@Data
|
||||
public static class OrderRes {
|
||||
private String tradeNo;
|
||||
private String orderId;
|
||||
private String requestUrl;
|
||||
private String status;
|
||||
private String sign;
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package com.accompany.payment.payermax.params;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CreateOrderParams {
|
||||
|
||||
@Data
|
||||
public static class PaymentDetail {
|
||||
private String paymentType;
|
||||
}
|
||||
|
||||
private String orderId;
|
||||
|
||||
private String userId;
|
||||
|
||||
private String subject;
|
||||
|
||||
private String countryCode;
|
||||
|
||||
private String currency;
|
||||
|
||||
private String totalAmount;
|
||||
|
||||
private String frontCallBackUrl;
|
||||
|
||||
private PaymentDetail paymentDetail;
|
||||
|
||||
private String paymentType;
|
||||
}
|
@@ -0,0 +1,95 @@
|
||||
package com.accompany.payment.payermax.params;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class PayCallbackReqVO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4984094248339397495L;
|
||||
|
||||
/**
|
||||
* Merchant ID
|
||||
*/
|
||||
private String merchantId;
|
||||
|
||||
/**
|
||||
* SHAREit Order No
|
||||
*/
|
||||
private String tradeOrderNo;
|
||||
|
||||
/**
|
||||
* Merchant Order No
|
||||
*/
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* Pay Order Status
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* Country Code
|
||||
*/
|
||||
private String countryCode;
|
||||
|
||||
/**
|
||||
* reference
|
||||
*/
|
||||
private String reference;
|
||||
|
||||
/**
|
||||
* Error Code
|
||||
*/
|
||||
private String errorCode;
|
||||
|
||||
/**
|
||||
* Error Message
|
||||
*/
|
||||
private String errorMsg;
|
||||
|
||||
/**
|
||||
* Signature
|
||||
*/
|
||||
private String sign;
|
||||
|
||||
/**
|
||||
* Pay Amount
|
||||
*/
|
||||
private String payAmount;
|
||||
|
||||
|
||||
/**
|
||||
* Pay Currency
|
||||
*/
|
||||
private String payCurrency;
|
||||
|
||||
/**
|
||||
* Trade Amount
|
||||
*/
|
||||
private String totalAmount;
|
||||
|
||||
|
||||
/**
|
||||
* Trade Currency
|
||||
*/
|
||||
private String currency;
|
||||
|
||||
/**
|
||||
* exchange rate
|
||||
*/
|
||||
private String exchangeRate;
|
||||
|
||||
/**
|
||||
* paymentType
|
||||
*/
|
||||
private String paymentType;
|
||||
|
||||
}
|
@@ -18,8 +18,10 @@ import com.accompany.payment.alipay.AlipayService;
|
||||
import com.accompany.payment.alipay.YinyouAlipayService;
|
||||
import com.accompany.payment.config.AliPayConfig;
|
||||
import com.accompany.payment.config.BaseWxPayConfig;
|
||||
import com.accompany.payment.constant.CurrencyTypeEnum;
|
||||
import com.accompany.payment.constant.PayConstant;
|
||||
import com.accompany.payment.dto.AlipayAgentDTO;
|
||||
import com.accompany.payment.dto.AreaChargeConfigDTO;
|
||||
import com.accompany.payment.event.ChargeEvent;
|
||||
import com.accompany.payment.model.ChargeProd;
|
||||
import com.accompany.payment.model.ChargeRecord;
|
||||
@@ -28,6 +30,7 @@ import com.accompany.payment.model.UserVipRecord;
|
||||
import com.accompany.payment.strategy.PayContext;
|
||||
import com.accompany.payment.strategy.PayStrategy;
|
||||
import com.accompany.payment.strategy.factory.PayStrategyFactory;
|
||||
import com.accompany.payment.utils.ChargeConfigUtils;
|
||||
import com.accompany.payment.vo.TarotChargeRetVo;
|
||||
import com.accompany.payment.wxpay.*;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@@ -39,11 +42,13 @@ import com.alipay.api.request.AlipayTradeWapPayRequest;
|
||||
import com.alipay.api.response.AlipayTradeAppPayResponse;
|
||||
import com.alipay.api.response.AlipayTradeWapPayResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -90,25 +95,16 @@ public class PayCenterService {
|
||||
* @param clientIp 客户端 ip
|
||||
* @param successUrl 页面成功跳转 url
|
||||
* @param deviceInfo
|
||||
* @param paymentType
|
||||
* @param countryCode
|
||||
* @return BusiResult
|
||||
*/
|
||||
public BusiResult createOrder(
|
||||
Long uid,
|
||||
String chargeProdId,
|
||||
String channel,
|
||||
String clientIp,
|
||||
String successUrl,
|
||||
ChargeProd chargeProd,
|
||||
Long erbanNo,
|
||||
String nick,
|
||||
String openId,
|
||||
String realName,
|
||||
String idCardNum, DeviceInfo deviceInfo)
|
||||
throws Exception {
|
||||
public BusiResult createOrder(Long uid, String chargeProdId, String channel, String clientIp, String successUrl, ChargeProd chargeProd,
|
||||
Long erbanNo, String nick, String openId, String realName, String idCardNum, DeviceInfo deviceInfo, String paymentType, String countryCode) throws Exception {
|
||||
BusiResult<Object> BusiResult = new BusiResult<>(BusiStatus.SUCCESS);
|
||||
String recordChannel = getChannelUseInRecord(channel);
|
||||
ChargeRecord chargeRecord =
|
||||
buildChargeRecord(uid, chargeProdId, recordChannel, clientIp, chargeProd, openId, deviceInfo);
|
||||
buildChargeRecord(uid, chargeProdId, recordChannel, clientIp, chargeProd, openId, deviceInfo, paymentType, countryCode);
|
||||
if (isTarotLowChargeAmountOpen()) {
|
||||
chargeRecord.setAmount(chargeRecord.getAmount()/100);
|
||||
}
|
||||
@@ -260,15 +256,12 @@ public class PayCenterService {
|
||||
* @param clientIp
|
||||
* @param chargeProd
|
||||
* @param deviceInfo
|
||||
* @param paymentType
|
||||
* @param countryCode
|
||||
* @return
|
||||
*/
|
||||
public ChargeRecord buildChargeRecord(
|
||||
Long uid,
|
||||
String chargeProdId,
|
||||
String channel,
|
||||
String clientIp,
|
||||
ChargeProd chargeProd,
|
||||
String openId, DeviceInfo deviceInfo) {
|
||||
public ChargeRecord buildChargeRecord(Long uid, String chargeProdId, String channel, String clientIp, ChargeProd chargeProd,
|
||||
String openId, DeviceInfo deviceInfo, String paymentType, String countryCode) {
|
||||
String chargeRecordId = UUIDUitl.get();
|
||||
ChargeRecord chargeRecord = new ChargeRecord();
|
||||
chargeRecord.setChargeRecordId(chargeRecordId);
|
||||
@@ -277,11 +270,28 @@ public class PayCenterService {
|
||||
chargeRecord.setChannel(channel);
|
||||
chargeRecord.setBussType(Constant.PayBussType.charge);
|
||||
chargeRecord.setChargeStatus(Constant.ChargeRecordStatus.create);
|
||||
Long money = chargeProd.getMoney();
|
||||
// 支付宝充值,以分为单位
|
||||
Long amount = money * 100;
|
||||
// //测试生产环境,充值1分钱
|
||||
chargeRecord.setAmount(amount);
|
||||
|
||||
if (StringUtils.isBlank(chargeProd.getLocalCurrencyCode()) || CurrencyTypeEnum.USD.getValue().equalsIgnoreCase(chargeProd.getLocalCurrencyCode())) {
|
||||
// 没有货币代码或货币代码是美元
|
||||
chargeRecord.setAmount(chargeProd.getMoney());
|
||||
chargeRecord.setLocalCurrencyCode(CurrencyTypeEnum.USD.getValue());
|
||||
chargeRecord.setLocalAmount(chargeProd.getMoney());
|
||||
} else {
|
||||
AreaChargeConfigDTO.AreaChargeConfigeItem areaChargeConfig = ChargeConfigUtils.getAreaChargeConfig(countryCode);
|
||||
if (areaChargeConfig == null) {
|
||||
log.info("充值下单失败,相关地区没有配置。countryCode: {}", countryCode);
|
||||
throw new ServiceException(BusiStatus.PARAMETERILLEGAL);
|
||||
}
|
||||
if (areaChargeConfig.getToLocalCommission() == null) {
|
||||
log.info("充值下单失败,没有配置汇率。countryCode: {}", countryCode);
|
||||
throw new ServiceException(BusiStatus.BUSIERROR);
|
||||
}
|
||||
// 本地货币转成美元
|
||||
chargeRecord.setAmount(new BigDecimal(chargeProd.getMoney()).divide(areaChargeConfig.getToLocalCommission(), 0, BigDecimal.ROUND_DOWN).longValue());
|
||||
|
||||
chargeRecord.setLocalAmount(chargeProd.getMoney());
|
||||
chargeRecord.setLocalCurrencyCode(chargeProd.getLocalCurrencyCode());
|
||||
}
|
||||
String body = chargeProd.getProdName() + "充值";
|
||||
String subject = chargeProd.getProdName() + "充值";
|
||||
chargeRecord.setSubject(subject);
|
||||
@@ -290,20 +300,18 @@ public class PayCenterService {
|
||||
chargeRecord.setCreateTime(Calendar.getInstance().getTime());
|
||||
chargeRecord.setWxPubOpenid(openId);
|
||||
if (deviceInfo != null) {
|
||||
chargeRecord.setClientDeviceId(deviceInfo.getDeviceId());
|
||||
chargeRecord.setChargeApp(deviceInfo.getApp());
|
||||
}
|
||||
chargeRecord.setTotalGold(chargeProd.getChargeGoldNum());
|
||||
chargeRecord.setPaymentType(paymentType);
|
||||
chargeRecord.setCountry(countryCode);
|
||||
|
||||
return chargeRecord;
|
||||
}
|
||||
|
||||
private PayContext buildPayContext(
|
||||
Long erbanNo,
|
||||
String nick,
|
||||
String successUrl,
|
||||
ChargeProd chargeProd,
|
||||
ChargeRecord chargeRecord,
|
||||
String realName,
|
||||
String idCardNum, DeviceInfo deviceInfo) {
|
||||
private PayContext buildPayContext(Long erbanNo, String nick, String successUrl, ChargeProd chargeProd, ChargeRecord chargeRecord,
|
||||
String realName, String idCardNum, DeviceInfo deviceInfo) {
|
||||
PayContext payContext = new PayContext();
|
||||
payContext.setErbanNo(erbanNo);
|
||||
payContext.setNick(nick);
|
||||
@@ -439,10 +447,7 @@ public class PayCenterService {
|
||||
chargeRecord.setBussType(Constant.PayBussType.OPEN_VIP);
|
||||
chargeRecord.setChargeStatus(Constant.ChargeRecordStatus.create);
|
||||
chargeRecord.setWxPubOpenid(openId);
|
||||
Long money = chargeProd.getMoney();
|
||||
// 充值金额,以分为单位
|
||||
Long amount = money * 100;
|
||||
chargeRecord.setAmount(amount);
|
||||
chargeRecord.setAmount(chargeProd.getMoney());
|
||||
String body = chargeProd.getProdName();
|
||||
String subject = chargeProd.getProdName();
|
||||
chargeRecord.setSubject(subject);
|
||||
@@ -450,6 +455,7 @@ public class PayCenterService {
|
||||
chargeRecord.setClientIp(clientIp);
|
||||
chargeRecord.setCreateTime(Calendar.getInstance().getTime());
|
||||
if (deviceInfo != null) {
|
||||
chargeRecord.setClientDeviceId(deviceInfo.getDeviceId());
|
||||
chargeRecord.setChargeApp(deviceInfo.getApp());
|
||||
}
|
||||
return chargeRecord;
|
||||
|
@@ -0,0 +1,51 @@
|
||||
package com.accompany.payment.strategy;
|
||||
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.payment.annotation.PayChannelSupport;
|
||||
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 org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@PayChannelSupport(Constant.ChargeChannel.payermax)
|
||||
public class PayerMaxStrategy extends AbstractPayStrategy {
|
||||
|
||||
@Autowired
|
||||
private PayermaxService payermaxService;
|
||||
|
||||
@Override
|
||||
public Object pay(PayContext context) throws Exception {
|
||||
ChargeRecord chargeRecord = context.getChargeRecord();
|
||||
ChargeProd chargeProd = context.getChargeProd();
|
||||
|
||||
CreateOrderParams params = new CreateOrderParams();
|
||||
params.setOrderId(chargeRecord.getChargeRecordId());
|
||||
params.setUserId(chargeRecord.getUid().toString());
|
||||
params.setCountryCode(chargeRecord.getCountry());
|
||||
params.setCurrency(chargeRecord.getLocalCurrencyCode());
|
||||
params.setTotalAmount(new BigDecimal(chargeRecord.getAmount()).divide(Constant.HUNDRED, 2, BigDecimal.ROUND_HALF_UP).toString());
|
||||
params.setSubject(chargeProd.getProdName());
|
||||
params.setFrontCallBackUrl(context.getSuccessUrl());
|
||||
CreateOrderParams.PaymentDetail paymentDetail = new CreateOrderParams.PaymentDetail();
|
||||
paymentDetail.setPaymentType(chargeRecord.getPaymentType());
|
||||
params.setPaymentDetail(paymentDetail);
|
||||
|
||||
CreateOrderResDTO orderRes = payermaxService.createOrder(params);
|
||||
|
||||
Map<String, Object> appMap = new HashMap<>();
|
||||
appMap.put(PayConstant.H5_PAY_URL_FIELD, orderRes.getData().getRequestUrl());
|
||||
appMap.put(PayConstant.H5_PAY_NICK_FIELD, context.getNick());
|
||||
appMap.put(PayConstant.H5_PAY_ERBANNO_FIELD, context.getErbanNo());
|
||||
|
||||
return appMap;
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package com.accompany.payment.utils;
|
||||
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
import com.accompany.payment.dto.AreaChargeConfigDTO;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public final class ChargeConfigUtils {
|
||||
|
||||
private static SysConfService sysConfService;
|
||||
|
||||
@Autowired
|
||||
private void setSysConfService(SysConfService sysConfService) {
|
||||
ChargeConfigUtils.sysConfService = sysConfService;
|
||||
}
|
||||
|
||||
|
||||
public static AreaChargeConfigDTO.AreaChargeConfigeItem getAreaChargeConfig(String countryCode) {
|
||||
AreaChargeConfigDTO h5AreaChargeConfig = JSONObject.parseObject(sysConfService.getDefaultSysConfValueById(Constant.SysConfId.H5_AREA_CHARGE_CONFIG, "{}"), AreaChargeConfigDTO.class);
|
||||
Map<String, AreaChargeConfigDTO.AreaChargeConfigeItem> areaConfigMap = h5AreaChargeConfig.getAreaConfig();
|
||||
if (areaConfigMap == null) {
|
||||
areaConfigMap = new HashMap<>();
|
||||
}
|
||||
|
||||
AreaChargeConfigDTO.AreaChargeConfigeItem areaChargeConfig = areaConfigMap.get(countryCode);
|
||||
|
||||
return areaChargeConfig;
|
||||
}
|
||||
}
|
@@ -0,0 +1,160 @@
|
||||
package com.accompany.payment.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* TODO 对外提供签名工具类方法以及使用示例
|
||||
*
|
||||
* @author xinxiang_jiang@foxmail.com
|
||||
*/
|
||||
public class SignMD5Utils {
|
||||
|
||||
/**
|
||||
* 根据请求参数生成签名:请求参数排序并后面补充key值,最后进行MD5加密,返回大写结果
|
||||
*
|
||||
* @param params 请求参数
|
||||
* @param key 约定Key值
|
||||
* @return 返回签名sign
|
||||
*/
|
||||
public static String signForMD5(Map<String, Object> params, String key) {
|
||||
String signatures = "";
|
||||
try {
|
||||
String s = formatMapToSignStr(params);
|
||||
System.out.println(s);
|
||||
signatures = getMD5(s + "&key=" + key).toUpperCase();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return signatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证sign是否正确
|
||||
*
|
||||
* @param paraMap 请求参数
|
||||
* @param sign 传入的sign
|
||||
* @param key 约定秘钥
|
||||
* @return 返回是否正确
|
||||
*/
|
||||
public static boolean verifyForMD5(Map<String, Object> paraMap, String sign, String key) {
|
||||
String signFromParams = signForMD5(paraMap, key);
|
||||
return sign.equals(signFromParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数字符串生成加密后字符串
|
||||
*
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("All")
|
||||
public static String getMD5(String message) {
|
||||
String md5 = "";
|
||||
try {
|
||||
// 创建一个md5算法对象
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] messageByte = message.getBytes("UTF-8");
|
||||
// 获得MD5字节数组,16*8=128位
|
||||
byte[] md5Byte = md.digest(messageByte);
|
||||
// 转换为16进制字符串
|
||||
md5 = bytesToHex(md5Byte);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 2进制转16进制
|
||||
*
|
||||
* @param bytes 字节数组
|
||||
* @return 返回十六进制字符串
|
||||
*/
|
||||
@SuppressWarnings("All")
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
StringBuffer hexStr = new StringBuffer();
|
||||
int num;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
num = bytes[i];
|
||||
if (num < 0) {
|
||||
num += 256;
|
||||
}
|
||||
if (num < 16) {
|
||||
hexStr.append("0");
|
||||
}
|
||||
hexStr.append(Integer.toHexString(num));
|
||||
}
|
||||
return hexStr.toString().toUpperCase();
|
||||
}
|
||||
|
||||
@SuppressWarnings("All")
|
||||
private static String formatMapToSignStr(Map<String, Object> paramMap) {
|
||||
String buff = "";
|
||||
Map tmpMap = paramMap;
|
||||
List<Map.Entry> infoIds = new ArrayList(tmpMap.entrySet());
|
||||
Collections.sort(infoIds, new Comparator() {
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
return (((Map.Entry<String, Object>) o1).getKey()).toString().compareTo(((Map.Entry<String, Object>) o2).getKey());
|
||||
}
|
||||
});
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (Map.Entry item : infoIds) {
|
||||
if ((!StringUtils.isEmpty((String) item.getKey()))
|
||||
&& (!("sign".equals(item.getKey())))) {
|
||||
String key = (String) item.getKey();
|
||||
Object val = item.getValue();
|
||||
if (val instanceof JSONObject || val instanceof HashMap) {
|
||||
buf.append(key + "=" + formatMapToSignStr((Map) val));
|
||||
buf.append("&");
|
||||
} else if(val instanceof JSONArray){
|
||||
for (int i = 0; i < ((JSONArray) val).size(); i++) {
|
||||
buf.append(key + "=" + formatMapToSignStr(((JSONArray) val).getJSONObject(i)));
|
||||
buf.append("&");
|
||||
}
|
||||
} else {
|
||||
buf.append(key + "=" + val);
|
||||
buf.append("&");
|
||||
}
|
||||
}
|
||||
}
|
||||
buff = buf.toString();
|
||||
if (!(buff.isEmpty())) {
|
||||
buff = buff.substring(0, buff.length() - 1);
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
//演示实例
|
||||
String merchantMD5Key = "123456789";
|
||||
Map<String, Object> params = new HashMap<>(16);
|
||||
|
||||
Map<String, Object> aa = new HashMap<>(16);
|
||||
aa.put("bizType", "test");
|
||||
Map<String, Object> bb = new HashMap<>(16);
|
||||
bb.put("version", "test");
|
||||
List<Map<String, Object>> a = Arrays.asList(aa,bb);
|
||||
|
||||
params.put("bizType", "test");
|
||||
params.put("version", "2.0");
|
||||
params.put("merchantId", "SP4189603");
|
||||
params.put("orderId", "1535433516149");
|
||||
params.put("amount", "13.6");
|
||||
params.put("currency", "INR");
|
||||
params.put("countryCode", a);
|
||||
|
||||
String sign = signForMD5(params, merchantMD5Key);
|
||||
params.put("sign", sign);
|
||||
System.out.println("this is your request params with sign: " + params);
|
||||
boolean flag = verifyForMD5(params, sign, merchantMD5Key);
|
||||
System.out.println("verify sign result is: " + flag);
|
||||
}
|
||||
|
||||
}
|
@@ -6,6 +6,8 @@
|
||||
<result column="prod_name" property="prodName" jdbcType="VARCHAR"/>
|
||||
<result column="prod_desc" property="prodDesc" jdbcType="VARCHAR"/>
|
||||
<result column="prod_status" property="prodStatus" jdbcType="TINYINT"/>
|
||||
<result column="country" property="country" jdbcType="VARCHAR"/>
|
||||
<result column="local_currency_code" property="localCurrencyCode" jdbcType="TINYINT"/>
|
||||
<result column="money" property="money" jdbcType="BIGINT"/>
|
||||
<result column="change_gold_rate" property="changeGoldRate" jdbcType="INTEGER"/>
|
||||
<result column="gift_gold_num" property="giftGoldNum" jdbcType="INTEGER"/>
|
||||
@@ -75,7 +77,7 @@
|
||||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
charge_prod_id, prod_name, prod_desc, prod_status, country, money, change_gold_rate, gift_gold_num,
|
||||
charge_prod_id, prod_name, prod_desc, prod_status, country, local_currency_code, money, change_gold_rate, gift_gold_num,
|
||||
first_gift_gold_num, channel, seq_no, charge_gold_num
|
||||
</sql>
|
||||
<select id="selectByExample" resultMap="BaseResultMap"
|
||||
|
@@ -8,10 +8,14 @@
|
||||
<result column="pingxx_charge_id" property="pingxxChargeId" jdbcType="VARCHAR"/>
|
||||
<result column="charge_prod_id" property="chargeProdId" jdbcType="VARCHAR"/>
|
||||
<result column="channel" property="channel" jdbcType="VARCHAR"/>
|
||||
<result column="payment_type" property="paymentType" jdbcType="VARCHAR"/>
|
||||
<result column="buss_type" property="bussType" jdbcType="TINYINT"/>
|
||||
<result column="charge_status" property="chargeStatus" jdbcType="TINYINT"/>
|
||||
<result column="charge_status_desc" property="chargeStatusDesc" jdbcType="VARCHAR"/>
|
||||
<result column="amount" property="amount" jdbcType="BIGINT"/>
|
||||
<result column="country" property="country" jdbcType="VARCHAR"/>
|
||||
<result column="local_currency_code" property="localCurrencyCode" jdbcType="VARCHAR"/>
|
||||
<result column="local_amount" property="localAmount" jdbcType="BIGINT"/>
|
||||
<result column="total_gold" property="totalGold" jdbcType="BIGINT"/>
|
||||
<result column="client_ip" property="clientIp" jdbcType="VARCHAR"/>
|
||||
<result column="wx_pub_openid" property="wxPubOpenid" jdbcType="VARCHAR"/>
|
||||
@@ -168,6 +172,9 @@
|
||||
<if test="channel != null">
|
||||
channel,
|
||||
</if>
|
||||
<if test="paymentType != null">
|
||||
payment_type,
|
||||
</if>
|
||||
<if test="bussType != null">
|
||||
buss_type,
|
||||
</if>
|
||||
@@ -180,12 +187,24 @@
|
||||
<if test="amount != null">
|
||||
amount,
|
||||
</if>
|
||||
<if test="country != null">
|
||||
country,
|
||||
</if>
|
||||
<if test="localCurrencyCode != null">
|
||||
local_currency_code,
|
||||
</if>
|
||||
<if test="localAmount != null">
|
||||
local_amount,
|
||||
</if>
|
||||
<if test="totalGold != null">
|
||||
total_gold,
|
||||
</if>
|
||||
<if test="clientIp != null">
|
||||
client_ip,
|
||||
</if>
|
||||
<if test="clientDeviceId != null">
|
||||
client_device_id,
|
||||
</if>
|
||||
<if test="wxPubOpenid != null">
|
||||
wx_pub_openid,
|
||||
</if>
|
||||
@@ -239,6 +258,9 @@
|
||||
<if test="channel != null">
|
||||
#{channel,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="paymentType != null">
|
||||
#{paymentType,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="bussType != null">
|
||||
#{bussType,jdbcType=TINYINT},
|
||||
</if>
|
||||
@@ -251,12 +273,24 @@
|
||||
<if test="amount != null">
|
||||
#{amount,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="country != null">
|
||||
#{country,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="localCurrencyCode != null">
|
||||
#{localCurrencyCode,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="localAmount != null">
|
||||
#{localAmount,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="totalGold != null">
|
||||
#{totalGold,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="clientIp != null">
|
||||
#{clientIp,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="clientDeviceId != null">
|
||||
#{clientDeviceId,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="wxPubOpenid != null">
|
||||
#{wxPubOpenid,jdbcType=VARCHAR},
|
||||
</if>
|
||||
|
Reference in New Issue
Block a user