## 去掉微信、支付宝官方支付;去掉京东支付;去掉图片、视频压缩依赖包引入;

This commit is contained in:
cabbage 2025-05-23 09:20:22 +08:00
parent 8cddbcde89
commit 4fbffd1544
119 changed files with 337 additions and 6547 deletions

View File

@ -28,7 +28,6 @@
</dependencies>
<modules>
<!-- <module>bd-api-activity</module>-->
<module>bd-api-bonus</module>
<module>bd-api-member</module>
<module>bd-api-report</module>

View File

@ -35,13 +35,6 @@
<artifactId>bd-api-third</artifactId>
</dependency>
<!-- 活动服务
<dependency>
<groupId>com.bd</groupId>
<artifactId>bd-api-activity</artifactId>
</dependency>
-->
<dependency>
<groupId>com.bd</groupId>
<artifactId>bd-common-aop</artifactId>

View File

@ -42,13 +42,6 @@
<artifactId>spring-rabbit</artifactId>
</dependency>
<!-- 活动服务接口
<dependency>
<groupId>com.bd</groupId>
<artifactId>bd-api-activity</artifactId>
</dependency>
-->
<dependency>
<groupId>com.bd</groupId>
<artifactId>bd-api-bonus</artifactId>

View File

@ -42,13 +42,6 @@
<artifactId>bd-api-third</artifactId>
</dependency>
<!-- 活动服务接口
<dependency>
<groupId>com.bd</groupId>
<artifactId>bd-api-activity</artifactId>
</dependency>
-->
<!-- 统计服务接口 -->
<dependency>
<groupId>com.bd</groupId>

View File

@ -187,26 +187,6 @@
<artifactId>javase</artifactId>
</dependency>
<!-- 图片压缩 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
</dependency>
<!-- 视频压缩 -->
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-core</artifactId>
</dependency>
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-nativebin-win64</artifactId>
</dependency>
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-nativebin-linux64</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -16,26 +16,11 @@ public enum EPayChannel {
*/
SAND(0, "杉德", 0, EnumsPrefixConstants.PAY_CHANNEL + "0"),
/**
* 支付宝
*/
ALI(1, "支付宝", 0, EnumsPrefixConstants.PAY_CHANNEL + "1"),
/**
* 微信
*/
WECHAT(2, "微信", 0, EnumsPrefixConstants.PAY_CHANNEL + "2"),
/**
* 通联
*/
ALLIN(3, "通联", 0, EnumsPrefixConstants.PAY_CHANNEL + "3"),
/**
* 京东
*/
JD(4, "京东", 0, EnumsPrefixConstants.PAY_CHANNEL + "4"),
/**
* 宝付
*/

View File

@ -3,18 +3,12 @@ package com.hzs.common.core.utils;
import com.hzs.common.core.config.OssConfig;
import com.hzs.common.core.domain.FileResult;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.*;
import java.io.*;
/**
* @Description: 文件上传工具
* @Author: jiang chao
* @Time: 2023/1/13 11:24
* @Classname: UploadUtil
* @PackageName: com.hzs.member.tool
* 文件上传工具
*/
@Slf4j
public class UploadFileUtil {
@ -89,116 +83,4 @@ public class UploadFileUtil {
return null;
}
/**
* 图片压缩上传
*
* @param inputStream 图片流
* @param ext 扩展名
* @param path 文件上传路径不传入默认按年月日创建
* @return
*/
public static FileResult imageZipUpload(InputStream inputStream, String ext, String path) {
try {
ByteArrayOutputStream thumbnailOutputStream = new ByteArrayOutputStream();
Thumbnails.of(inputStream)
.scale(0.5f) // 值在0到1之间,1f就是原图大小,0.5就是原图的一半大小
.outputQuality(0.5f) // 值也是在0到1,越接近于1质量越好,越接近于0质量越差
.toOutputStream(thumbnailOutputStream);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(thumbnailOutputStream.toByteArray());
return UploadFileUtil.upload(byteArrayInputStream, ext, path);
} catch (Exception e) {
log.error("上传文件失败", e);
}
return null;
}
/**
* @Param source: 原文件
*/
public static FileResult videoZipUpload(String url, String filePath) throws IOException {
File source = new File(url);
File target = File.createTempFile(CommonUtil.createSerialNumber(), ".mp4");
try {
MultimediaObject multimediaObject = new MultimediaObject(source);
AudioInfo audioInfo = multimediaObject.getInfo().getAudio();
//根据视频大小来判断是否需要压缩
int maxSize = 5;
double mb = Math.ceil(source.length() / 1024 / 1024);
// int second = (int) multimediaObject.getInfo().getDuration();
// BigDecimal bigDecimal = new BigDecimal(String.format("%.4f", mb / second));
// 当视频大于5M或每秒>0.5M时进行压缩
// boolean temp = mb > maxSize || bigDecimal.compareTo(new BigDecimal(0.5)) > 0;
// 当视频大于5M
boolean temp = mb > maxSize;
if (temp) {
// TODO视频属性
int maxBitRate = 160000;
int maxSamplingRate = 24000;
AudioAttributes audioAttributes = new AudioAttributes();
// 设置通用编码格式10
// 设置最大值比特率越高清晰度/音质越好
// 设置音频比特率,单位:b (比特率越高清晰度/音质越好当然文件也就越大 128000 = 182kb)
if (audioInfo.getBitRate() > maxBitRate) {
audioAttributes.setBitRate(maxBitRate);
}
// 设置重新编码的音频流中使用的声道数1 =单声道2 = 双声道立体声如果未设置任何声道值则编码器将选择默认值 0
audioAttributes.setChannels(audioInfo.getChannels());
// 采样率越高声音的还原度越好文件越大
// 设置音频采样率单位赫兹 hz
// 设置编码时候的音量值未设置为0,如果256则音量值不会改变
audioAttributes.setVolume(256);
if (audioInfo.getSamplingRate() > maxSamplingRate) {
audioAttributes.setSamplingRate(maxSamplingRate);
}
int bitRate = 1200000;
int maxFrameRate = 20;
//TODO视频编码属性配置
VideoInfo videoInfo = multimediaObject.getInfo().getVideo();
VideoAttributes video = new VideoAttributes();
video.setCodec("h264");
//设置视频比特率,单位:b (比特率越高清晰度/音质越好当然文件也就越大 800000 = 800kb)
if (videoInfo.getBitRate() > bitRate) {
video.setBitRate(bitRate);
}
// 视频帧率15 f / s 帧率越低效果越差
// 设置视频帧率帧率越低视频会出现断层越高让人感觉越连续视频帧率Frame rate是用于测量显示帧数的量度所谓的测量单位为每秒显示帧数(Frames per SecondFPS赫兹Hz
if (videoInfo.getFrameRate() > maxFrameRate) {
video.setFrameRate(maxFrameRate);
}
//限制视频的宽高
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp4");
attrs.setAudioAttributes(audioAttributes);
attrs.setVideoAttributes(video);
//使用多线程进行压缩
attrs.setEncodingThreads(Runtime.getRuntime().availableProcessors() / 2);
Encoder encoder = new Encoder();
long time = System.currentTimeMillis();
encoder.encode(multimediaObject, target, attrs);
System.out.println("压缩时间:" + (System.currentTimeMillis() - time) / 1000);
System.out.println(target.getAbsolutePath());
return UploadFileUtil.upload(target, filePath);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 压缩后删除原文件
if (target.length() > 0) {
source.deleteOnExit();
}
}
return null;
}
}

View File

@ -94,24 +94,6 @@
<artifactId>spring-rabbit</artifactId>
</dependency>
<!-- 微信支付集成 -->
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-WxPay</artifactId>
</dependency>
<!-- 支付宝支付集成 -->
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-AliPay</artifactId>
</dependency>
<!--邮件发送依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- apache common 校验工具包-->
<dependency>
<groupId>commons-validator</groupId>
@ -124,16 +106,6 @@
<artifactId>xxl-job-core</artifactId>
</dependency>
<!-- 汇付支付引入 -->
<dependency>
<groupId>com.huifu.adapay</groupId>
<artifactId>adapay-java-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.huifu.adapay.core</groupId>
<artifactId>adapay-core-sdk</artifactId>
</dependency>
<!-- 切面逻辑处理 -->
<dependency>
<groupId>com.bd</groupId>
@ -170,6 +142,16 @@
<artifactId>bd-api-scm</artifactId>
</dependency>
<!-- 汇付支付引入 -->
<dependency>
<groupId>com.huifu.adapay</groupId>
<artifactId>adapay-java-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.huifu.adapay.core</groupId>
<artifactId>adapay-core-sdk</artifactId>
</dependency>
<!-- 汇付新SDK -->
<dependency>
<groupId>com.huifu.bspay.sdk</groupId>

View File

@ -188,10 +188,6 @@ public class RefundOrderListener {
// 汇付
str = iRefundService.adaRefundHandle(refundDTO, tOnlinePayment);
break;
case JD:
// 京东
str = iRefundService.jdRefundHandle(refundDTO, tOnlinePayment);
break;
case ALLIN:
// 通联
str = iRefundService.allInRefundHandle(refundDTO, tOnlinePayment);

View File

@ -1,45 +0,0 @@
package com.hzs.third.pay.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 阿里支付相关配置
*/
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
/**
* 支付appId
*/
private String appId;
/**
* 开发者私钥
*/
private String privateKey;
/**
* 支付宝公钥
*/
private String publicKey;
/**
* 支付网关
*/
private String serverUrl;
/**
* 支付回调地址
*/
private String notifyUrl;
/**
* 请求格式
*/
private String format = "json";
/**
* 请求加密方式
*/
private String signType = "RSA2";
}

View File

@ -1,50 +0,0 @@
package com.hzs.third.pay.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 京东支付配置
*/
@Data
@Component
@ConfigurationProperties(prefix = "jdpay")
public class JdPayConfig {
/**
* 商户编号
*/
private String customerNum;
/**
* 店铺编号
*/
private String shopNum;
/**
* 公钥
*/
private String accessKey;
/**
* 私钥
*/
private String secretKey;
/**
* 回调地址
*/
private String callbackUrl;
/**
* 代付回调地址
*/
private String agentCallbackUrl;
/**
* 退款回调地址
*/
private String refundCallbackUrl;
}

View File

@ -12,20 +12,6 @@ import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "wechat")
public class WeChatConfig {
//////////////////// 基础支付相关 ////////////////////
/**
* 商户号
*/
private String mchId;
/**
* v2密钥
*/
private String v2Key;
/**
* 微信支付回调地址
*/
private String notifyUrl;
//////////////////// 公众号相关 ////////////////////
/**
* 公众号appId
@ -36,11 +22,4 @@ public class WeChatConfig {
*/
private String publicAppSecret;
//////////////////// 全球一体化APP ////////////////////
/**
* 移动应用appId
*/
private String appId;
}

View File

@ -1,23 +0,0 @@
package com.hzs.third.pay.constants;
/**
* 阿里支付常量类
*/
public class AliPayConstants {
/**
* 业务成功码
*/
public static final String SUCCESS = "TRADE_SUCCESS";
/**
* 返回成功
*/
public static final String RETURN_SUCCESS = "success";
/**
* 返回失败
*/
public static final String RETURN_FAIL = "failure";
}

View File

@ -1,11 +1,7 @@
package com.hzs.third.pay.constants;
/**
* @Description: 汇付新支付常量
* @Author: jiang chao
* @Time: 2024/12/5 15:51
* @Classname: HuiFuPayConstants
* @PackageName: com.hzs.third.pay.constants
* 汇付新支付常量
*/
public class HuiFuPayConstants {

View File

@ -1,154 +0,0 @@
package com.hzs.third.pay.constants;
/**
* 京东支付常量类
*/
public class JdPayConstants {
/**
* 终端标记暂用京东注册手机号
*/
public static final String TERMINAL_ID = "18246334501";
/**
* 用户注册账号暂用京东注册手机号
*/
public static final String USER_ACCOUNT = "18246334501";
/**
* 应用名称
*/
public static final String APP_NAME = "盛美源";
// TODO 上面3项考试动态化配置
/**
* 订单状态 - 交易处理中
*/
public static final String ORDER_INT = "INT";
/**
* 订单状态 - 成功
*/
public static final String ORDER_SUCCESS = "SUCCESS";
/**
* 查询状态 - 交易处理中
*/
public static final String QUERY_INIT = "INIT";
/**
* 查询状态 - 成功
*/
public static final String QUERY_SUCCESS = "SUCCESS";
/**
* 查询状态 - 失败
*/
public static final String QUERY_FAIL = "FAIL";
/**
* 处理成功
*/
public static final String RESULT_SUCCESS = "success";
/**
* 处理成功业务响应码
*/
public static final String RESULT_SUCCESS_CODE = "C000000";
/**
* 银行卡交易不支持错误编码
*/
public static final String RESULT_FAIL_CODE_6 = "C000006";
/**
* 请求成功
*/
public static final String SUCCESS = "true";
/**
* 返回成功
*/
public static final String RETURN_SUCCESS = "200";
/**
* 返回失败
*/
public static final String RETURN_FAIL = "500";
/**
* 支付接口版本
*/
public static final String PAY_VERSION = "V4.0";
/**
* 绑卡类型 身份证
*/
public static final String ID_CARD_TYPE = "IDCARD";
/**
* 快捷支付标准业务场景
*/
public static final String FAST_TRADESCENE_QUICKPAY = "QUICKPAY";
/**
* 代付业务类型
*/
public static final String AGENT_BUSINESS_TYPE = "DEFY";
/**
* 代付支付方式
*/
public static final String AGENT_BANK_TYPE = "DEFY";
/**
* 支付地址
*/
public static final String PAY_URL = "https://openapi.duolabao.com";
/**
* 扫码支付调用方法
*/
public static final String METHOD_SCAN = "/v3/order/payurl/create";
/**
* 快捷支付绑卡方法
*/
public static final String METHOD_BIND_CARD = "/api/applyBindCard";
/**
* 快捷支付绑卡确认方法
*/
public static final String METHOD_CONFIRM_BIND = "/api/confirmBindCard";
/**
* 快捷支付解绑方法
*/
public static final String METHOD_UNBIND = "/api/unBindCard";
/**
* 快捷支付预下单
*/
public static final String METHOD_PRE_ORDER = "/api/applyQuickPayWithCheck";
/**
* 快捷支付确认订单
*/
public static final String METHOD_CONFIRM_ORDER = "/api/confirmQuickPay";
/**
* 京东代付余额查询方法
*/
public static final String METHOD_QUERY_BALANCE = "/api/queryBalance";
/**
* 京东代付调用方法
*/
public static final String METHOD_AGENT = "/api/payWithCheck";
/**
* 京东查询订单路径
*/
public static final String QUERY_ORDER = "/v3/order/query";
/**
* 京东退款路径
*/
public static final String REFUND_ORDER = "/v3/order/refund/part";
}

View File

@ -1,21 +1,10 @@
package com.hzs.third.pay.constants;
/**
* @Description: 支付配置常量
* @Author: jiang chao
* @Time: 2022/11/17 9:59
* @Classname: PayConfigConstants
* @PackageName: com.hzs.common.constant
* 支付配置常量
*/
public class PayConfigConstants {
// // 京东银行卡
// public static final String PAY_CONFIG_4 = "PAY:CONFIG:%s:4";
// 京东收银台H5
public static final String PAY_CONFIG_5 = "PAY:CONFIG:%s:5";
// 京东收银台PC
public static final String PAY_CONFIG_6 = "PAY:CONFIG:%s:6";
// 宝付微信
public static final String PAY_CONFIG_11 = "PAY:CONFIG:%s:11";
// 宝付微信扫码
@ -26,9 +15,6 @@ public class PayConfigConstants {
// 汇付银行卡
public static final String PAY_CONFIG_15 = "PAY:CONFIG:%s:15";
// // 微信APP
// public static final String PAY_CONFIG_20 = "PAY:CONFIG:%s:20";
// 通联微信
public static final String PAY_CONFIG_32 = "PAY:CONFIG:%s:32";
// 通联银行卡

View File

@ -3,11 +3,7 @@ package com.hzs.third.pay.constants;
import com.hzs.common.core.constant.CacheConstants;
/**
* @Description: 支付redis常量
* @Author: jiang chao
* @Time: 2022/12/23 15:02
* @Classname: PayRedisConstants
* @PackageName: com.hzs.third.pay.constants
* 支付redis常量
*/
public class PayRedisConstants {
@ -16,11 +12,6 @@ public class PayRedisConstants {
*/
public static final String SAND_SCAN_KEY = CacheConstants.CACHE_PREFIX + "SANDPAY:SCAN:%s:%s:%s";
/**
* jd扫码KEY
*/
public static final String JD_SCAN_KEY = CacheConstants.CACHE_PREFIX + "JDPAY:SCAN:%s:%s";
/**
* 通联扫码KEY
*/

View File

@ -36,11 +36,7 @@ import java.util.HashMap;
import java.util.Map;
/**
* @Description: 汇付二维码支付控制器
* @Author: jiang chao
* @Time: 2023/3/21 11:26
* @Classname: AdaPayCodeController
* @PackageName: com.hzs.third.pay.controller.api
* 汇付二维码支付控制器
*/
@Slf4j
@RestController

View File

@ -36,11 +36,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* @Description: 汇付快捷支付控制器
* @Author: jiang chao
* @Time: 2023/3/17 15:40
* @Classname: AdaPayFastController
* @PackageName: com.hzs.third.pay.controller.api
* 汇付快捷支付控制器
*/
@Slf4j
@RestController

View File

@ -19,11 +19,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description: 汇付退款控制器
* @Author: jiang chao
* @Time: 2023/8/17 11:09
* @Classname: AdaRefundController
* @PackageName: com.hzs.third.pay.controller.api
* 汇付退款控制器
*/
@Slf4j
@RestController

View File

@ -32,11 +32,7 @@ import java.util.Map;
import java.util.TreeMap;
/**
* @Description: 通联二维码支付控制器
* @Author: jiang chao
* @Time: 2023/11/28 17:27
* @Classname: AllInPayCodeController
* @PackageName: com.hzs.third.pay.controller.api
* 通联二维码支付控制器
*/
@Slf4j
@RestController

View File

@ -31,11 +31,7 @@ import java.net.InetAddress;
import java.util.*;
/**
* @Description: 通联快捷支付控制器
* @Author: jiang chao
* @Time: 2022/12/27 14:56
* @Classname: AllInPayFastController
* @PackageName: com.hzs.third.pay.controller
* 通联快捷支付控制器
*/
@Slf4j
@RestController

View File

@ -19,11 +19,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description: 通联退款控制器
* @Author: jiang chao
* @Time: 2023/11/9 14:04
* @Classname: AllInRefundController
* @PackageName: com.hzs.third.pay.controller.api
* 通联退款控制器
*/
@Slf4j
@RestController

View File

@ -37,11 +37,7 @@ import java.util.HashMap;
import java.util.Map;
/**
* @Description: 宝付二维码支付控制器
* @Author: jiang chao
* @Time: 2023/3/21 11:26
* @Classname: AdaPayCodeController
* @PackageName: com.hzs.third.pay.controller.api
* 宝付二维码支付控制器
*/
@Slf4j
@RestController

View File

@ -16,11 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @Description: 宝付退款控制器
* @Author: jiang chao
* @Time: 2023/8/16 14:04
* @Classname: BaoFuRefundController
* @PackageName: com.hzs.third.pay.controller.api
* 宝付退款控制器
*/
@Slf4j
@RestController

View File

@ -36,11 +36,7 @@ import java.util.HashMap;
import java.util.Map;
/**
* @Description: 汇付新支付控制器
* @Author: jiang chao
* @Time: 2024/12/5 15:28
* @Classname: HuiFuPayController
* @PackageName: com.hzs.third.pay.controller.api
* 汇付新支付控制器
*/
@Slf4j
@RestController

View File

@ -1,391 +0,0 @@
package com.hzs.third.pay.controller.api;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.CommonUtil;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.third.pay.TOnlineCard;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.TransactionUtils;
import com.hzs.third.pay.config.JdPayConfig;
import com.hzs.third.pay.constants.JdPayConstants;
import com.hzs.third.pay.controller.base.PayBaseController;
import com.hzs.third.pay.dto.jd.*;
import com.hzs.third.pay.enums.EJdFastBankCode;
import com.hzs.third.pay.param.FastBindConfirmParam;
import com.hzs.third.pay.param.FastBindParam;
import com.hzs.third.pay.param.FastPayOrderParam;
import com.hzs.third.pay.param.FastUnBindParam;
import com.hzs.third.pay.service.ITOnlineCardService;
import com.hzs.third.pay.service.ITOnlinePaymentService;
import com.hzs.third.pay.util.JdPayUtil;
import com.hzs.third.pay.vo.BindCardVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Description: 京东快捷支付控制器
* @Author: jiang chao
* @Time: 2022/12/27 9:24
* @Classname: JdPayFastController
* @PackageName: com.hzs.third.pay.controller
*/
@Slf4j
@RestController
@RequestMapping("/jd-fast")
public class JdPayFastController extends PayBaseController {
@Autowired
private JdPayConfig jdPayConfig;
@Autowired
private ITOnlineCardService itOnlineCardService;
@Autowired
private ITOnlinePaymentService itOnlinePaymentService;
/**
* 绑卡列表
*
* @return
*/
@GetMapping("/list")
public AjaxResult list() {
List<BindCardVO> resultList = new ArrayList<>();
List<TOnlineCard> tOnlineCardList = itOnlineCardService.queryBankList(SecurityUtils.getUserId(), jdPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
for (TOnlineCard tOnlineCard : tOnlineCardList) {
String bankName = tOnlineCard.getBankName();
if (StringUtils.isEmpty(bankName)) {
EJdFastBankCode jdFastBankCode = EJdFastBankCode.getEnumByValue(tOnlineCard.getBankCode());
bankName = (null == jdFastBankCode ? tOnlineCard.getBankCode() : jdFastBankCode.getLabel());
}
resultList.add(BindCardVO.builder()
.bindCode(tOnlineCard.getCode())
// 银行卡只显示后4位
.bankNo(tOnlineCard.getBankNo().substring(tOnlineCard.getBankNo().length() - 4))
.bankName(bankName)
.build());
}
return AjaxResult.success(resultList);
}
/**
* 快捷绑卡
*
* @param param
* @return
*/
@RepeatSubmitSimple
@PostMapping("/bind")
public AjaxResult bind(@RequestBody FastBindParam param) {
if (StringUtils.isAnyEmpty(param.getName(), param.getIdCard(), param.getBankNo(), param.getPhone())) {
return AjaxResult.error("缺少参数");
}
// 银行卡号去空格
String bankNo = StringUtils.deleteWhitespace(param.getBankNo());
EBankCardType eBankCardType = EBankCardType.DEBIT;
String year = "";
String month = "";
if (StringUtils.isNotEmpty(param.getValiddate()) && StringUtils.isNotEmpty(param.getCvv2())) {
// 有效期和安全码都不为空则当作信用卡处理
eBankCardType = EBankCardType.CREDIT;
if (param.getValiddate().length() != 4) {
return AjaxResult.error("有效期格式不正确");
} else {
year = param.getValiddate().substring(0, 2);
month = param.getValiddate().substring(2, 4);
}
if (param.getCvv2().length() != 3 && param.getCvv2().length() != 4) {
return AjaxResult.error("安全码格式不正确");
}
}
// 当前用户
Long userId = SecurityUtils.getUserId();
// 所属国家
Integer pkCountry = SecurityUtils.getPkCountry();
TOnlineCard checkCard = itOnlineCardService.checkUserBankExist(userId, bankNo, jdPayConfig.getCustomerNum(), pkCountry);
if (checkCard != null) {
return AjaxResult.error("已经绑定过该卡,不能重复绑定");
}
// 绑卡编号
String bindCode = CommonUtil.createSerialNumber(EOrderPrefix.THIRD_CODE);
try {
JdFastBindDTO jdFastBindDTO = JdFastBindDTO.builder()
// 商户编号
.customerNum(jdPayConfig.getCustomerNum())
.userId(userId.toString())
.requestNum(bindCode)
.payerName(param.getName())
.idCardType(JdPayConstants.ID_CARD_TYPE)
// 证件号码
.idCardNo(JdPayUtil.encrypt(param.getIdCard(), JdPayUtil.getAesKey(jdPayConfig.getSecretKey())))
// 银行卡号
.cardNo(JdPayUtil.encrypt(bankNo, JdPayUtil.getAesKey(jdPayConfig.getSecretKey())))
// 预留手机号
.phone(JdPayUtil.encrypt(param.getPhone(), JdPayUtil.getAesKey(jdPayConfig.getSecretKey())))
.year(year)
.month(month)
.cvv2(param.getCvv2())
.build();
String body = JSONUtil.toJsonStr(jdFastBindDTO);
log.info("京东快捷绑卡请求参数: {}", body);
String postResult = JdPayUtil.requestOrder(JdPayConstants.METHOD_BIND_CARD, body, jdPayConfig.getSecretKey(), jdPayConfig.getAccessKey());
log.info("京东快捷绑卡返回数据: {}", postResult);
// 返回结果
JdFastBindResult fastBindResult = JSONUtil.toBean(postResult, JdFastBindResult.class);
if (fastBindResult.isSuccess() && JdPayConstants.RESULT_SUCCESS.equals(fastBindResult.getCode())) {
// 返回成功
// 插入银行卡明细表
TOnlineCard tOnlineCard = new TOnlineCard();
tOnlineCard.setCode(bindCode);
tOnlineCard.setBindType(eBankCardType.getValue());
tOnlineCard.setName(param.getName());
tOnlineCard.setIdCard(param.getIdCard());
tOnlineCard.setBankNo(bankNo);
tOnlineCard.setPhone(param.getPhone());
tOnlineCard.setCustomerNum(jdPayConfig.getCustomerNum());
tOnlineCard.setValiddate(param.getValiddate());
tOnlineCard.setCvv2(param.getCvv2());
tOnlineCard.setPkCreator(userId);
tOnlineCard.setPkCountry(pkCountry);
if (itOnlineCardService.save(tOnlineCard)) {
return AjaxResult.success("", bindCode);
} else {
log.error("京东快捷绑卡入库失败");
}
} else {
log.error("京东快捷绑卡返回失败! msg: {}", fastBindResult.getMsg());
return AjaxResult.error(fastBindResult.getMsg());
}
} catch (Exception e) {
log.error("京东快捷绑卡处理异常!", e);
}
return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.OPERATION_FAILED_FLUSH));
}
/**
* 绑卡确认
*
* @param param
* @return
*/
@RepeatSubmitSimple
@PostMapping("/bind-confirm")
public AjaxResult bindConfirm(@RequestBody FastBindConfirmParam param) {
if (StringUtils.isAnyEmpty(param.getBindCode(), param.getSmsCode())) {
return AjaxResult.error("缺少参数");
}
// 当前用户
Long userId = SecurityUtils.getUserId();
TOnlineCard tOnlineCard = itOnlineCardService.queryCardByCode(param.getBindCode(), userId, jdPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
if (null == tOnlineCard) {
return AjaxResult.error("用户未绑定该银行卡");
}
if (EBindStatus.BIND.getValue() == tOnlineCard.getBindStatus()) {
// 如果已经绑定成功则直接返回
return AjaxResult.success();
}
try {
JdFastBindConfirmDTO jdFastBindConfirmDTO = JdFastBindConfirmDTO.builder()
// 商户编号
.customerNum(jdPayConfig.getCustomerNum())
.requestNum(param.getBindCode())
.validateCode(param.getSmsCode())
.build();
String body = JSONUtil.toJsonStr(jdFastBindConfirmDTO);
log.info("京东绑卡确认请求参数: {}", body);
String postResult = JdPayUtil.requestOrder(JdPayConstants.METHOD_CONFIRM_BIND, body, jdPayConfig.getSecretKey(), jdPayConfig.getAccessKey());
log.info("京东绑卡确认返回数据: {}", postResult);
// 返回结果
JdFastBindConfirmResult fastBindConfirmResult = JSONUtil.toBean(postResult, JdFastBindConfirmResult.class);
if (fastBindConfirmResult.isSuccess() && JdPayConstants.RESULT_SUCCESS.equals(fastBindConfirmResult.getCode())) {
// 返回成功
EJdFastBankCode eJdFastBankCode = EJdFastBankCode.getEnumByValue(fastBindConfirmResult.getBankCode());
// 校验银行卡是否支持支付
if (null == eJdFastBankCode) {
// 更新银行卡明细表
tOnlineCard.setBindId(fastBindConfirmResult.getBindId());
tOnlineCard.setBindStatus(EBindStatus.UN_BIND.getValue());
tOnlineCard.setPkModified(userId);
tOnlineCard.setModifiedTime(new Date());
itOnlineCardService.updateBankInfo(tOnlineCard);
return AjaxResult.error("暂不支持该银行服务");
}
// 更新银行卡明细表
tOnlineCard.setBindId(fastBindConfirmResult.getBindId());
tOnlineCard.setBindStatus(EBindStatus.BIND.getValue());
tOnlineCard.setBankCode(fastBindConfirmResult.getBankCode());
tOnlineCard.setBankName(eJdFastBankCode.getLabel());
tOnlineCard.setPkModified(userId);
tOnlineCard.setModifiedTime(new Date());
if (itOnlineCardService.updateBankInfo(tOnlineCard) > 0) {
return AjaxResult.success();
} else {
log.error("京东绑卡确认入库失败");
}
} else {
log.error("京东绑卡确认返回失败! msg: {}", fastBindConfirmResult.getMsg());
return AjaxResult.error(fastBindConfirmResult.getMsg());
}
} catch (Exception e) {
log.error("京东绑卡确认处理异常!", e);
}
return AjaxResult.error("绑卡失败,请刷新后重试");
}
/**
* 确认支付
*
* @param param
* @return
*/
@RepeatSubmitSimple
@PostMapping("/pay-confirm")
public AjaxResult payConfirm(@RequestBody FastPayOrderParam param) {
if (StringUtils.isAnyEmpty(param.getBindCode(), param.getOrderCode(), param.getSmsCode())) {
return AjaxResult.error("缺少参数");
}
try {
// 查询用户绑卡信息
TOnlineCard tOnlineCard = itOnlineCardService.queryCardByCode(param.getBindCode(), SecurityUtils.getUserId(), jdPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
if (null == tOnlineCard) {
return AjaxResult.error("用户未绑定该银行卡");
}
// 查询需要流水号
QueryWrapper<TOnlinePayment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("BUSINESS_CODE", param.getOrderCode());
queryWrapper.eq("PAY_CHANNEL", EPayChannel.JD.getValue());
queryWrapper.eq("PAY_TYPE", EPayType.BANK_CARD.getValue());
queryWrapper.eq("PK_CREATOR", SecurityUtils.getUserId());
TOnlinePayment tOnlinePayment = itOnlinePaymentService.getOne(queryWrapper);
if (EPayStatus.PAID.getValue() == tOnlinePayment.getPayStatus()) {
return AjaxResult.error("该订单已支付");
}
JdFastConfirmDTO jdFastDTO = JdFastConfirmDTO.builder()
// 商户编号
.customerNum(jdPayConfig.getCustomerNum())
// 商户订单号
.requestNum(tOnlinePayment.getOriginalOrder())
// 短信验证码
.validateCode(param.getSmsCode())
.build();
String body = JSONUtil.toJsonStr(jdFastDTO);
log.info("京东银行卡确认支付请求参数: {}", body);
String postResult = JdPayUtil.requestOrder(JdPayConstants.METHOD_CONFIRM_ORDER, body, jdPayConfig.getSecretKey(), jdPayConfig.getAccessKey());
log.info("京东银行卡确认支付返回数据: {}", postResult);
// 返回结果
JdFastConfirmResult fastConfirmResult = JSONUtil.toBean(postResult, JdFastConfirmResult.class);
if (fastConfirmResult.isSuccess() && JdPayConstants.RESULT_SUCCESS_CODE.equals(fastConfirmResult.getCode())) {
// 返回成功
if (JdPayConstants.ORDER_SUCCESS.equals(fastConfirmResult.getOrderStatus())
|| JdPayConstants.ORDER_INT.equals(fastConfirmResult.getOrderStatus())) {
// 返回订单状态为 交易处理 成功 则返回请求成功
return AjaxResult.success();
}
}
log.error("京东银行卡确认支付失败: {}", fastConfirmResult.getMsg());
if (JdPayConstants.RESULT_FAIL_CODE_6.equals(fastConfirmResult.getCode())) {
return AjaxResult.error("支付失败," + fastConfirmResult.getMsg());
}
} catch (Exception e) {
log.error("京东银行卡确认支付处理异常!", e);
}
return AjaxResult.error("支付失败,请刷新后重试");
}
/**
* 银行卡解绑
*
* @param param
* @return
*/
@PostMapping("/unbind")
public AjaxResult unbind(@RequestBody FastUnBindParam param) {
if (StringUtils.isEmpty(param.getBindCode())) {
return AjaxResult.error("缺少参数");
}
// 当前用户
Long userId = SecurityUtils.getUserId();
TOnlineCard tOnlineCard = itOnlineCardService.queryCardByCode(param.getBindCode(), userId, jdPayConfig.getCustomerNum(), SecurityUtils.getPkCountry());
if (null == tOnlineCard) {
return AjaxResult.error("用户未绑定该银行卡");
}
try {
JdFastUnBindDTO jdFastUnBindDTO = JdFastUnBindDTO.builder()
// 商户编号
.customerNum(jdPayConfig.getCustomerNum())
.userId(userId.toString())
.requestNum(tOnlineCard.getCode())
.bindId(tOnlineCard.getBindId())
.build();
String body = JSONUtil.toJsonStr(jdFastUnBindDTO);
log.info("京东解绑请求参数: {}", body);
String postResult = JdPayUtil.requestOrder(JdPayConstants.METHOD_UNBIND, body, jdPayConfig.getSecretKey(), jdPayConfig.getAccessKey());
log.info("京东解绑返回数据: {}", postResult);
// 返回结果
JdFastUnBindResult fastUnBindResult = JSONUtil.toBean(postResult, JdFastUnBindResult.class);
if (fastUnBindResult.isSuccess() && JdPayConstants.RESULT_SUCCESS.equals(fastUnBindResult.getCode())) {
// 返回成功
// 解绑银行卡
itOnlineCardService.unBindBank(tOnlineCard.getCode(), userId, jdPayConfig.getCustomerNum());
return AjaxResult.success();
} else {
log.error("京东解绑失败");
}
} catch (Exception e) {
log.error("京东解绑处理异常!", e);
}
return AjaxResult.error("解绑失败,请刷新后重试");
}
}

View File

@ -1,91 +0,0 @@
package com.hzs.third.pay.controller.api;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.enums.EPayStatus;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.third.pay.controller.base.PayBaseController;
import com.hzs.third.pay.dto.RefundDTO;
import com.hzs.third.pay.param.PayParam;
import com.hzs.third.pay.service.IRefundService;
import com.hzs.third.pay.service.ITOnlinePaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
* @Description: 京东退款控制器
* @Author: jiang chao
* @Time: 2023/8/17 15:11
* @Classname: JdRefundController
* @PackageName: com.hzs.third.pay.controller.api
*/
@Slf4j
@RestController
@RequestMapping("/jd-refund")
public class JdRefundController extends PayBaseController {
@Autowired
private IRefundService iRefundService;
@Autowired
private ITOnlinePaymentService itOnlinePaymentService;
/**
* 京东退款接口
*
* @param param
* @return
*/
@PostMapping("/refund")
public AjaxResult refund(@RequestBody PayParam param) {
if (null == param.getBusinessType() || StringUtils.isEmpty(param.getBusinessCode())) {
// 缺少参数
return AjaxResult.error("缺少参数");
}
// 查询在线支付明细
TOnlinePayment tOnlinePayment = itOnlinePaymentService.queryByBusiness(param.getBusinessType(), param.getBusinessCode(), SecurityUtils.getPkCountry());
if (null == tOnlinePayment || EPayStatus.UNPAID.getValue() == tOnlinePayment.getPayStatus()) {
// 在线支付明细为空 或者 未支付成功则不能进行退款
return AjaxResult.error("订单不存在或未支付成功,不能进行退款");
}
// 获取支付渠道
EPayChannel ePayChannel = EPayChannel.getEnumByValue(tOnlinePayment.getPayChannel());
if (null == ePayChannel) {
return AjaxResult.error("订单支付信息有误,不能进行退款");
}
try {
// 京东收银台退款处理
String str = iRefundService.jdCashRefundHandle(RefundDTO.builder()
.businessType(param.getBusinessType())
.businessCode(param.getBusinessCode())
.refundAmount(tOnlinePayment.getPayMoney())
.userId(SecurityUtils.getUserId())
.pkCountry(SecurityUtils.getPkCountry())
.build(),
tOnlinePayment);
// 京东银行卡退款处理 --
// String str = iRefundService.jdRefundHandle(RefundDTO.builder()
// .businessType(param.getBusinessType())
// .businessCode(param.getBusinessCode())
// .refundAmount(tOnlinePayment.getPayMoney())
// .userId(SecurityUtils.getUserId())
// .pkCountry(SecurityUtils.getPkCountry())
// .build(),
// tOnlinePayment);
if (null == str) {
return AjaxResult.success();
}
return AjaxResult.error("退款失败:" + str);
} catch (Exception e) {
log.error("调用京东退款处理返回异常!", e);
return AjaxResult.error("退款异常,请刷新后重试");
}
}
}

View File

@ -28,11 +28,7 @@ import java.math.BigDecimal;
import java.util.Date;
/**
* @Description: 统一支付控制器
* @Author: jiang chao
* @Time: 2022/12/27 17:35
* @Classname: PayController
* @PackageName: com.hzs.third.pay.controller
* 统一支付控制器
*/
@Slf4j
@RestController
@ -44,12 +40,6 @@ public class PayController {
@Autowired
private ISandPayService iSandPayService;
@Autowired
private IJdPayService iJdPayService;
@Autowired
private IWeChatPayService iWeChatPayService;
@Autowired
private IAliPayService iAliPayService;
@Autowired
private IAllInPayService iAllInPayService;
@Autowired
private IAdaPayService iAdaPayService;
@ -217,65 +207,6 @@ public class PayController {
// break;
// }
// break;
// }
break;
case JD:
// 京东
switch (payType) {
// case WECHAT:
// case ALIPAY:
// // 微信支付宝 扫码支付
// payResult = iJdPayService.scanPay(onlinePayment);
// break;
// case BANK_CARD:
// // 银行卡支付
// if (StringUtils.isEmpty(payParam.getBindCode())) {
// return AjaxResult.error("银行绑卡编号不能为空");
// }
// payResult = iJdPayService.bankPay(onlinePayment, payParam.getBindCode());
// break;
case BANK_ONLINE:
// 网上银行收银台
payResult = iJdPayService.cashRegister(onlinePayment, dataSource);
break;
default:
}
break;
case WECHAT:
// 微信
switch (dataSource) {
// case PC:
// // PC端扫码支付
// payResult = iWeChatPayService.prePayScan(onlinePayment);
// break;
// case H5:
// // H5端调起微信应用
// payResult = iWeChatPayService.prePayH5(onlinePayment);
// break;
case APP:
// APP调起微信支付
payResult = iWeChatPayService.prePayAPP(onlinePayment);
// case WECHAT_APPLET_PROGRAM:
// // 微信小程序
// if (StringUtils.isEmpty(openId)) {
// return AjaxResult.error("用户openId不能为空");
// }
// resultR = iWeChatPayService.prePayApplet(onlinePayment, openId);
// break;
default:
}
break;
case ALI:
// 阿里
// switch (dataSource) {
// case PC:
// // PC端扫码支付
// payResult = iAliPayService.prePayScan(onlinePayment);
// break;
// case H5:
// // H5端调起支付宝应用
// payResult = iAliPayService.prePayH5(onlinePayment);
// break;
// }
break;
case ALLIN:
@ -429,23 +360,6 @@ public class PayController {
// 各支付方式 true=显示false=隐藏
// // 京东银行卡
// String pay4 = String.format(PayConfigConstants.PAY_CONFIG_4, pkCountry);
// if (redisTemplate.hasKey(pay4)) {
// payConfigVO.setPay4((Boolean) redisTemplate.opsForValue().get(pay4));
// }
// 京东收银台H5
String pay5 = String.format(PayConfigConstants.PAY_CONFIG_5, pkCountry);
if (redisTemplate.hasKey(pay5)) {
payConfigVO.setPay5((Boolean) redisTemplate.opsForValue().get(pay5));
}
// 京东收银台PC
String pay6 = String.format(PayConfigConstants.PAY_CONFIG_6, pkCountry);
if (redisTemplate.hasKey(pay6)) {
payConfigVO.setPay6((Boolean) redisTemplate.opsForValue().get(pay6));
}
// 宝付微信
String pay11 = String.format(PayConfigConstants.PAY_CONFIG_11, pkCountry);
if (redisTemplate.hasKey(pay11)) {
@ -468,12 +382,6 @@ public class PayController {
payConfigVO.setPay15((Boolean) redisTemplate.opsForValue().get(pay15));
}
// // 微信APP
// String pay20 = String.format(PayConfigConstants.PAY_CONFIG_20, pkCountry);
// if (redisTemplate.hasKey(pay20)) {
// payConfigVO.setPay20((Boolean) redisTemplate.opsForValue().get(pay20));
// }
// 通联微信
String pay32 = String.format(PayConfigConstants.PAY_CONFIG_32, pkCountry);
if (redisTemplate.hasKey(pay32)) {

View File

@ -1,64 +0,0 @@
package com.hzs.third.pay.controller.base;
import cn.hutool.crypto.SecureUtil;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @Description: 京东基础控制器
* @Author: jiang chao
* @Time: 2022/12/27 17:47
* @Classname: JdBaseController
* @PackageName: com.hzs.third.pay.controller.base
*/
public class JdBaseController {
/**
* 获取请求体
*
* @param request
* @return
* @throws Exception
*/
protected String getRequestBody(HttpServletRequest request) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(request.getInputStream()));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} finally {
if (null != br) {
try {
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 校验token
*
* @param request
* @param reqBody
* @param secretKey
* @return
*/
protected boolean checkToken(HttpServletRequest request, String reqBody, String secretKey) {
// SHA1 加密串
String shaStr = "secretKey=" + secretKey +
"&timestamp=" + request.getHeader("timestamp") +
"&body=" + reqBody;
String tokenCheck = SecureUtil.sha1(shaStr).toUpperCase();
return tokenCheck.equals(request.getHeader("token"));
}
}

View File

@ -10,11 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import java.util.TreeMap;
/**
* @Description: 支付基础控制器
* @Author: jiang chao
* @Time: 2023/2/16 14:01
* @Classname: FastPayController
* @PackageName: com.hzs.third.pay.controller.base
* 支付基础控制器
*/
@Slf4j
public class PayBaseController extends BaseController {

View File

@ -14,11 +14,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
/**
* @Description: 在线支付配置
* @Author: jiang chao
* @Time: 2023/3/23 16:15
* @Classname: OnlinePayConfigController
* @PackageName: com.hzs.third.pay.controller.manage
* 在线支付配置
*/
@RestController
@RequestMapping("/manage/online-config")
@ -40,21 +36,6 @@ public class OnlinePayConfigController {
OnlinePayConfigVO payConfigVO = new OnlinePayConfigVO();
// 各支付方式 true=显示false=隐藏
// // 京东银行卡
// String pay4 = String.format(PayConfigConstants.PAY_CONFIG_4, pkCountry);
// if (redisTemplate.hasKey(pay4)) {
// payConfigVO.setPay4((Boolean) redisTemplate.opsForValue().get(pay4));
// }
// 京东收银台H5
String pay5 = String.format(PayConfigConstants.PAY_CONFIG_5, pkCountry);
if (redisTemplate.hasKey(pay5)) {
payConfigVO.setPay5((Boolean) redisTemplate.opsForValue().get(pay5));
}
// 京东收银台PC
String pay6 = String.format(PayConfigConstants.PAY_CONFIG_6, pkCountry);
if (redisTemplate.hasKey(pay6)) {
payConfigVO.setPay6((Boolean) redisTemplate.opsForValue().get(pay6));
}
// 宝付微信
String pay11 = String.format(PayConfigConstants.PAY_CONFIG_11, pkCountry);
@ -78,12 +59,6 @@ public class OnlinePayConfigController {
payConfigVO.setPay15((Boolean) redisTemplate.opsForValue().get(pay15));
}
// // 微信APP
// String pay20 = String.format(PayConfigConstants.PAY_CONFIG_20, pkCountry);
// if (redisTemplate.hasKey(pay20)) {
// payConfigVO.setPay20((Boolean) redisTemplate.opsForValue().get(pay20));
// }
// 通联微信
String pay32 = String.format(PayConfigConstants.PAY_CONFIG_32, pkCountry);
if (redisTemplate.hasKey(pay32)) {
@ -121,18 +96,12 @@ public class OnlinePayConfigController {
public AjaxResult saveConfig(@RequestBody OnlinePayConfigParam param) {
Integer pkCountry = SecurityUtils.getPkCountry();
// redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_4, pkCountry), param.getPay4());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_5, pkCountry), param.getPay5());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_6, pkCountry), param.getPay6());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_11, pkCountry), param.getPay11());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_12, pkCountry), param.getPay12());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_13, pkCountry), param.getPay13());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_15, pkCountry), param.getPay15());
// redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_20, pkCountry), param.getPay20());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_32, pkCountry), param.getPay32());
redisTemplate.opsForValue().set(String.format(PayConfigConstants.PAY_CONFIG_33, pkCountry), param.getPay33());

View File

@ -33,11 +33,7 @@ import java.util.List;
import java.util.Map;
/**
* @Description: 在线支付明细
* @Author: jiang chao
* @Time: 2023/3/23 11:44
* @Classname: TOnlinePaymentController
* @PackageName: com.hzs.third.pay.controller.manage
* 在线支付明细
*/
@RestController
@RequestMapping("/manage/online-payment")

View File

@ -27,11 +27,7 @@ import java.util.List;
import java.util.Map;
/**
* @Description: 退款明细
* @Author: jiang chao
* @Time: 2023/8/16 18:50
* @Classname: OnlineRefundController
* @PackageName: com.hzs.third.pay.controller.manage
* 退款明细
*/
@RestController
@RequestMapping("/manage/online-refund")

View File

@ -27,11 +27,7 @@ import java.util.HashMap;
import java.util.List;
/**
* @Description: 汇付支付回调
* @Author: jiang chao
* @Time: 2023/3/22 16:58
* @Classname: AdaPayNotifyController
* @PackageName: com.hzs.third.pay.controller.notify
* 汇付支付回调
*/
@Slf4j
@RestController

View File

@ -20,11 +20,7 @@ import java.util.Date;
import java.util.HashMap;
/**
* @Description: 汇付退款回调控制器
* @Author: jiang chao
* @Time: 2023/8/17 13:58
* @Classname: AdaRefundNotifyController
* @PackageName: com.hzs.third.pay.controller.notify
* 汇付退款回调控制器
*/
@Slf4j
@RestController

View File

@ -1,88 +0,0 @@
package com.hzs.third.pay.controller.notify;
import com.alipay.api.internal.util.AlipaySignature;
import com.hzs.common.core.constant.Constants;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.third.pay.config.AliPayConfig;
import com.hzs.third.pay.constants.AliPayConstants;
import com.hzs.third.pay.service.IPayService;
import com.ijpay.alipay.AliPayApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
/**
* 阿里支付
*/
@Slf4j
@RestController
@RequestMapping("/ali")
public class AliPayNotifyController {
@Autowired
private AliPayConfig aliPayConfig;
@Autowired
private IPayService iPayService;
/**
* 阿里支付回调
*
* @param request
*/
@PostMapping("/notify")
public String notify(HttpServletRequest request) {
try {
Map<String, String> body = AliPayApi.toMap(request);
log.info("阿里支付回调! body {}", body);
if (AlipaySignature.rsaCheckV1(body, aliPayConfig.getPublicKey(), Constants.UTF8, aliPayConfig.getSignType())) {
// 签名校验通过
if (AliPayConstants.SUCCESS.equals(body.get("trade_status"))) {
// 交易成功
// 支付流水号
String payNumber = body.get("trade_no");
// 支付完成时间
Date payTime = DateUtils.parseDate(body.get("gmt_payment"), DateUtils.YAMMERERS);
// 支付金额由分转元
BigDecimal payMoney = new BigDecimal(Integer.parseInt(body.get("total_amount"))).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
// 支付扩展类型
String type = body.get("passback_params");
// 回调订单编号
String thirdOrderCode = body.get("out_trade_no");
// 支付信息编号
String orderCode = thirdOrderCode;
// 处理订单号以及扩展类型
if (orderCode.indexOf("-") > 0) {
// 带有分隔需要处理
orderCode = orderCode.split("-")[0];
}
// 支付后续业务处理
if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.ALI, "")) {
return AliPayConstants.RETURN_SUCCESS;
}
} else {
log.error("阿里支付回调交易失败");
}
} else {
log.error("阿里支付回调签名验证失败!");
}
} catch (Exception e) {
log.error("阿里支付回调处理异常", e);
}
return AliPayConstants.RETURN_FAIL;
}
}

View File

@ -24,11 +24,7 @@ import java.util.Map;
import java.util.TreeMap;
/**
* @Description: 宝付支付回调控制器
* @Author: jiang chao
* @Time: 2023/2/10 10:31
* @Classname: BaoFuNotifyController
* @PackageName: com.hzs.web.baofu.controller
* 宝付支付回调控制器
*/
@Slf4j
@RestController

View File

@ -24,11 +24,7 @@ import java.util.Map;
import java.util.TreeMap;
/**
* @Description: 宝付退款回调控制器
* @Author: jiang chao
* @Time: 2023/8/16 16:09
* @Classname: BaoFuRefundNotifyController
* @PackageName: com.hzs.third.pay.controller.notify
* 宝付退款回调控制器
*/
@Slf4j
@RestController

View File

@ -20,11 +20,7 @@ import java.math.BigDecimal;
import java.util.Date;
/**
* @Description: 汇付新支付回调控制器
* @Author: jiang chao
* @Time: 2024/12/5 10:34
* @Classname: HuiFuNotifyController
* @PackageName: com.hzs.third.pay.controller.notify
* 汇付新支付回调控制器
*/
@Slf4j
@RestController

View File

@ -1,210 +0,0 @@
package com.hzs.third.pay.controller.notify;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.third.pay.config.JdPayConfig;
import com.hzs.third.pay.constants.JdPayConstants;
import com.hzs.third.pay.controller.base.JdBaseController;
import com.hzs.third.pay.dto.jd.JdPayNotifyBody;
import com.hzs.third.pay.jdpay.dto.JdPayTradeSuccessNotify;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.jdpay.util.GsonUtil;
import com.hzs.third.pay.service.IPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
* 京东支付回调控制器
*/
@Slf4j
@RestController
@RequestMapping("/jd")
public class JdPayNotifyController extends JdBaseController {
@Autowired
private JdPayConfig jdPayConfig;
@Autowired
private IPayService iPayService;
/**
* 京东支付回调
*
* @param request
*/
@PostMapping("/notify")
public String notify(HttpServletRequest request) {
try {
String reqBody = this.getRequestBody(request);
log.info("京东支付回调! body {}", reqBody);
if (this.checkToken(request, reqBody, jdPayConfig.getSecretKey())) {
// 签名校验通过
JdPayNotifyBody notifyBody = JSONUtil.toBean(reqBody, JdPayNotifyBody.class);
// 支付流水号
String payNumber = notifyBody.getOrderNum();
// 支付时间
Date payTime = DateUtils.parseDate(notifyBody.getCompleteTime(), DateUtils.YYYY_MM_DD_HH_MM_SS);
// 支付金额
BigDecimal payMoney = new BigDecimal(notifyBody.getOrderAmount());
// 支付扩展类型
String type = notifyBody.getExtraInfo();
// 回调订单编号
String thirdOrderCode = notifyBody.getRequestNum();
// 支付信息编号
String orderCode = thirdOrderCode;
// 处理订单号以及扩展类型
if (orderCode.indexOf("-") > 0) {
// 带有分隔需要处理
orderCode = orderCode.split("-")[0];
}
// 支付后续业务处理
if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.JD, "")) {
return JdPayConstants.RETURN_SUCCESS;
}
} else {
log.error("京东支付回调签名校验失败!");
}
} catch (Exception e) {
log.error("京东支付回调处理异常", e);
}
return JdPayConstants.RETURN_FAIL;
}
@Resource
private JdPay jdPay;
/**
* 京东收银台处理成功返回
*/
private static final String SUCCESS = "SUCCESS";
/**
* 京东收银台处理失败返回
*/
private static final String ERROR = "ERROR";
/**
* 京东收银台异步支付回调
*
* @param reqText
* @return 成功返回"SUCCESS", 失败返回"ERROR",京东支付会再次发起通知通知频次见接口文档
*/
@PostMapping("/trade-notify")
public String tradeNotify(@RequestBody String reqText) {
log.info("京东收银台支付异步回调! reqText {}", reqText);
try {
// 验证签名与解密
String interData = jdPay.verifyResponse(reqText);
JdPayTradeSuccessNotify successNotify = GsonUtil.fromJson(interData, JdPayTradeSuccessNotify.class);
if (null != successNotify) {
if ("FINI".equals(successNotify.getTradeStatus())) {
// 支付成功处理
// 商户订单号
String payNumber = successNotify.getTradeNo();
// 渠道流水号
String channelNumber = "";
// 支付完成时间
Date payTime = DateUtils.parseDateOne(successNotify.getFinishDate(), DateUtils.YAMMERERS);
// 支付扩展类型
String type = successNotify.getReturnParams();
// 回调订单编号
String thirdOrderCode = successNotify.getOutTradeNo();
// 订单编号
String orderCode = thirdOrderCode;
// 订单金额
int tradeAmount = Integer.parseInt(successNotify.getTradeAmount());
BigDecimal payMoney = new BigDecimal(tradeAmount).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
// 支付后续业务处理
if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.JD, channelNumber)) {
return SUCCESS;
}
} else {
log.error("京东收银台支付异步回调失败resultDesc: {}", successNotify.getResultDesc());
}
} else {
log.error("京东收银台支付异步回调解密为空");
}
} catch (Exception e) {
log.error("京东收银台支付异步回调异常", e);
}
return ERROR;
}
/**
* 京东收银台页面回调
*
* @param request
* @return
*/
@PostMapping("/sync-notify")
public String syncNotify(HttpServletRequest request) {
// 签名验证逻辑需要支持添加通知字段不影响结果
Map<String, String> respMap = getAllRequestParam(request);
log.info("京东收银台支付页面回调! request: {}", respMap);
try {
if (jdPay.verifyPageCallBack(respMap)) {
if ("FINI".equals(respMap.get("status"))) {
// todo 支付成功
return SUCCESS;
} else if ("WPAR".equals(respMap.get("status"))) {
// todo 支付处理中
log.error("京东支付页面回调,支付处理中");
} else {
// todo 支付失败
log.error("京东支付页面回调,支付失败");
}
} else {
// 签名异常报错
log.error("京东收银台支付页面回调!签名异常!");
}
} catch (Exception e) {
log.error("京东支付页面回调参数", e);
}
return ERROR;
}
/**
* 获取客户端请求参数中所有的信息
*/
private Map<String, String> getAllRequestParam(final HttpServletRequest request) {
Map<String, String> respMap = new HashMap<>();
Enumeration<?> temp = request.getParameterNames();
if (null != temp) {
while (temp.hasMoreElements()) {
String en = (String) temp.nextElement();
String value = request.getParameter(en);
respMap.put(en, value);
//如果字段的值为空判断若值为空则删除这个字段>
if (null == respMap.get(en) || "".equals(respMap.get(en))) {
respMap.remove(en);
}
}
}
return respMap;
}
}

View File

@ -1,148 +0,0 @@
package com.hzs.third.pay.controller.notify;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.third.pay.config.JdPayConfig;
import com.hzs.third.pay.constants.JdPayConstants;
import com.hzs.third.pay.controller.base.JdBaseController;
import com.hzs.third.pay.jdpay.dto.JdPayRefundSuccessNotify;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.jdpay.util.GsonUtil;
import com.hzs.third.pay.service.IRefundService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: 京东退填回调控制器
* @Author: jiang chao
* @Time: 2023/8/17 15:50
* @Classname: JdRefundNotifyController
* @PackageName: com.hzs.third.pay.controller.notify
*/
@Slf4j
@RestController
@RequestMapping("/jd-refund")
public class JdRefundNotifyController extends JdBaseController {
@Autowired
private JdPayConfig jdPayConfig;
@Autowired
private IRefundService iRefundService;
/**
* 京东退款回调
*
* @param request
* @return
* @throws Exception
*/
@PostMapping("/notify")
public String refundNotify(HttpServletRequest request) {
try {
String reqBody = this.getRequestBody(request);
log.info("京东退款回调! body {}", reqBody);
if (this.checkToken(request, reqBody, jdPayConfig.getSecretKey())) {
// 签名校验通过
Map<String, String> dataMap = JSONUtil.toBean(reqBody, HashMap.class);
// 退款编号
String refundCode = dataMap.get("refundRequestNum");
// 京东交易流水号
String refundNumber = dataMap.get("orderNum");
// 退款完成时间
Date finishTime = DateUtils.parseDate(dataMap.get("refundSuccessTime"), DateUtils.YYYY_MM_DD_HH_MM_SS);
// 退款金额
BigDecimal finishMoney = new BigDecimal(dataMap.get("refundAmount"));
if (JdPayConstants.ORDER_SUCCESS.equals(dataMap.get("refundStatus"))) {
// 退款成功
// 退款后续业务处理
if (iRefundService.notifyHandle(EPayChannel.JD, refundCode, refundNumber, finishTime, finishMoney)) {
return JdPayConstants.RETURN_SUCCESS;
}
} else {
// 退款失败
log.error("京东退款失败: {}", dataMap.get("failReason"));
if (iRefundService.notifyErrorHandle(EPayChannel.JD, refundCode, refundNumber, dataMap.get("failReason"))) {
return JdPayConstants.RETURN_SUCCESS;
}
}
} else {
log.error("京东支付回调签名校验失败!");
}
} catch (Exception e) {
log.error("京东支付回调处理异常", e);
}
return JdPayConstants.RETURN_FAIL;
}
@Resource
private JdPay jdPay;
/**
* 京东收银台处理成功返回
*/
private static final String SUCCESS = "SUCCESS";
/**
* 京东收银台处理失败返回
*/
private static final String ERROR = "ERROR";
/**
* 京东收银台退款异步支付回调
*
* @param reqText
* @return 成功返回"SUCCESS", 失败返回"ERROR",退款通知会再次发起通知通知频次见接口文档
*/
@PostMapping("/trade-notify")
public String tradeNotify(@RequestBody String reqText) {
log.info("京东收银台退款异步回调! reqText {}", reqText);
try {
// 验证签名与解密
String interData = jdPay.verifyResponse(reqText);
JdPayRefundSuccessNotify successNotify = GsonUtil.fromJson(interData, JdPayRefundSuccessNotify.class);
if (null != successNotify) {
if ("FINI".equals(successNotify.getTradeStatus())) {
// 退款编号
String refundCode = successNotify.getOutTradeNo();
// 京东交易流水号
String refundNumber = successNotify.getTradeNo();
// 退款完成时间
Date finishTime = DateUtils.parseDate(successNotify.getFinishDate(), DateUtils.YAMMERERS);
// 退款金额
int tradeAmount = Integer.parseInt(successNotify.getTradeAmount());
BigDecimal finishMoney = new BigDecimal(tradeAmount).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
// 退款后续业务处理
if (iRefundService.notifyHandle(EPayChannel.JD, refundCode, refundNumber, finishTime, finishMoney)) {
return SUCCESS;
}
} else {
log.error("京东收银台退款异步回调失败resultDesc: {}", successNotify.getResultDesc());
}
} else {
log.error("京东收银台退款异步回调解密为空");
}
} catch (Exception e) {
log.error("京东收银台退款异步回调异常", e);
}
return ERROR;
}
}

View File

@ -1,6 +1,5 @@
package com.hzs.third.pay.controller.notify;
import com.alipay.api.internal.util.AlipaySignature;
import com.hzs.common.core.constant.Constants;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
@ -33,65 +32,65 @@ public class SandPayNotifyController {
@Autowired
private IPayService iPayService;
/**
* 杉德支付回调
*
* @param request
* @return
*/
@GetMapping("/notify")
public String notify(HttpServletRequest request) {
try {
// 通知传输的编码为UTF-8
request.setCharacterEncoding(Constants.UTF8);
// 动态遍历获取所有收到的参数,此步非常关键,因为收银宝以后可能会加字段,动态获取可以兼容
TreeMap<String, String> body = PayUtil.getParams(request);
log.info("杉德支付回调! body {}", body);
if (AlipaySignature.rsaCheckV2(body, sandPayConfig.getPublicKey(), Constants.UTF8, SandPayConstants.SIGN_TYPE)) {
// 签名校验通过
if (SandPayConstants.SUCCESS.equals(body.get("trade_status"))) {
// 交易成功
// 交易流水号
String payNumber = body.get("plat_trx_no");
// 支付完成时间
Date payTime = DateUtils.parseDateOne(body.get("pay_success_time"), DateUtils.YAMMERERS);
// 支付金额
BigDecimal payMoney = new BigDecimal(body.get("pay_amount"));
// 支付扩展类型
String type = body.get("req_reserved");
// 回调订单编号
String thirdOrderCode = body.get("out_order_no");
// 订单编号
String orderCode = thirdOrderCode;
// 处理订单号以及扩展类型
if (orderCode.indexOf("-") > 0) {
// 带有分隔需要处理
orderCode = orderCode.split("-")[0];
if (StringUtils.isEmpty(type)) {
// H5调起微信支付宝没有支付扩展参数
type = orderCode.split("-")[1].substring(0, 1);
}
}
// 支付后续业务处理
if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.SAND, "")) {
return SandPayConstants.SUCCESS;
}
} else {
log.error("杉德支付回调交易失败");
}
} else {
log.error("杉德支付回调签名验证失败!");
}
} catch (Exception e) {
log.error("杉德支付回调处理异常", e);
}
return SandPayConstants.ERROR;
}
// /**
// * 杉德支付回调
// *
// * @param request
// * @return
// */
// @GetMapping("/notify")
// public String notify(HttpServletRequest request) {
// try {
// // 通知传输的编码为UTF-8
// request.setCharacterEncoding(Constants.UTF8);
// // 动态遍历获取所有收到的参数,此步非常关键,因为收银宝以后可能会加字段,动态获取可以兼容
// TreeMap<String, String> body = PayUtil.getParams(request);
//
// log.info("杉德支付回调! body {}", body);
//
// if (AlipaySignature.rsaCheckV2(body, sandPayConfig.getPublicKey(), Constants.UTF8, SandPayConstants.SIGN_TYPE)) {
// // 签名校验通过
// if (SandPayConstants.SUCCESS.equals(body.get("trade_status"))) {
// // 交易成功
//
// // 交易流水号
// String payNumber = body.get("plat_trx_no");
// // 支付完成时间
// Date payTime = DateUtils.parseDateOne(body.get("pay_success_time"), DateUtils.YAMMERERS);
// // 支付金额
// BigDecimal payMoney = new BigDecimal(body.get("pay_amount"));
//
// // 支付扩展类型
// String type = body.get("req_reserved");
//
// // 回调订单编号
// String thirdOrderCode = body.get("out_order_no");
// // 订单编号
// String orderCode = thirdOrderCode;
// // 处理订单号以及扩展类型
// if (orderCode.indexOf("-") > 0) {
// // 带有分隔需要处理
// orderCode = orderCode.split("-")[0];
// if (StringUtils.isEmpty(type)) {
// // H5调起微信支付宝没有支付扩展参数
// type = orderCode.split("-")[1].substring(0, 1);
// }
// }
//
// // 支付后续业务处理
// if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.SAND, "")) {
// return SandPayConstants.SUCCESS;
// }
// } else {
// log.error("杉德支付回调交易失败");
// }
// } else {
// log.error("杉德支付回调签名验证失败!");
// }
// } catch (Exception e) {
// log.error("杉德支付回调处理异常", e);
// }
// return SandPayConstants.ERROR;
// }
}

View File

@ -1,91 +0,0 @@
package com.hzs.third.pay.controller.notify;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.third.pay.config.WeChatConfig;
import com.hzs.third.pay.service.IPayService;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.WxPayKit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 微信支付
*/
@Slf4j
@RestController
@RequestMapping("/weChat")
public class WeChatPayNotifyController {
@Autowired
private WeChatConfig weChatConfig;
@Autowired
private IPayService iPayService;
/**
* 微信支付回调
*
* @param request
*/
@PostMapping("/notify")
public String notify(HttpServletRequest request) {
try {
Map<String, String> body = WxPayKit.xmlToMap(HttpKit.readData(request));
log.info("微信支付回调! body : {}", body);
if (WxPayKit.verifyNotify(body, weChatConfig.getV2Key(), SignType.HMACSHA256)) {
// 签名校验通过
if (WxPayKit.codeIsOk(body.get("result_code"))) {
// 交易成功
// 支付流水号
String payNumber = body.get("transaction_id");
// 支付完成时间
Date payTime = DateUtils.parseDate(body.get("time_end"), DateUtils.YAMMERERS);
// 支付金额由分转元
BigDecimal payMoney = new BigDecimal(Integer.parseInt(body.get("total_fee"))).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
// 支付扩展类型
String type = body.get("attach");
// 回调订单编号
String thirdOrderCode = body.get("out_trade_no");
// 支付信息编号
String orderCode = thirdOrderCode;
// 处理订单号以及扩展类型
if (orderCode.indexOf("-") > 0) {
// 带有分隔需要处理
orderCode = orderCode.split("-")[0];
}
// 支付后续业务处理
if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.WECHAT, "")) {
Map<String, String> xml = new HashMap<>(2);
xml.put("return_code", "SUCCESS");
xml.put("return_msg", "OK");
return WxPayKit.toXml(xml);
}
} else {
log.error("微信支付回调交易失败");
}
} else {
log.error("微信支付回调签名校验失败!");
}
} catch (Exception e) {
log.error("微信支付回调处理异常", e);
}
return null;
}
}

View File

@ -3,11 +3,7 @@ package com.hzs.third.pay.dto;
import lombok.Data;
/**
* @Description: 微信公众号授权返回DTO
* @Author: jiang chao
* @Time: 2023/2/11 14:21
* @Classname: WechatPublicDTO
* @PackageName: com.hzs.web.baofu.dto
* 微信公众号授权返回DTO
*/
@Data
public class WechatPublicDTO {

View File

@ -3,11 +3,7 @@ package com.hzs.third.pay.dto;
import lombok.Data;
/**
* @Description: 微信公众号中转传参DTO宝付汇付目前使用
* @Author: jiang chao
* @Time: 2023/2/11 10:01
* @Classname: BaoFuDTO
* @PackageName: com.hzs.web.sand.dto
* 微信公众号中转传参DTO宝付汇付目前使用
*/
@Data
public class WechatStateDTO {

View File

@ -1,22 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东查询代付金额DTO
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class JdAgentBalanceDTO {
/**
* 商户编号
*/
private String customerNum;
}

View File

@ -1,31 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东查询代付金额返回
*/
@Data
public class JdAgentBalanceResult {
/**
* 请求状态true成功
*/
private boolean success;
/**
* 业务响应码
*/
private String code;
/**
* 业务响应描述
*/
private String msg;
/**
* 可代付余额
*/
private String remitBalAmount;
}

View File

@ -1,82 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东代付DTO
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class JdAgentDTO {
/**
* 版本号仅支持V4.0)
*/
private String version;
/**
* 商户编号
*/
private String customerNum;
/**
* 店铺编号
*/
private String shopNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 业务类型传入DEFY
*/
private String businessType;
/**
* 支付方式传入DEFY
*/
private String bankType;
/**
* 金额
*/
private String amount;
/**
* 银行编码
*/
private String bankCode;
/**
* 收款账号
*/
private String bankAccountNo;
/**
* 收款名称
*/
private String bankAccountName;
/**
* 账户类型B2B对公 B2C对私
*/
private String biz;
/**
* 通知地址
*/
private String callbackUrl;
/**
* 备注
*/
private String remark;
}

View File

@ -1,41 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Created with IntelliJ IDEA.
* Author: yuhui
* Description:
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class JdAgentQueryDTO {
/**
* 版本号仅支持V4.0)
*/
private String version;
/**
* 商户编号
*/
private String customerNum;
/**
* 店铺编号
*/
private String shopNum;
/**
* 系统订单号
*/
private String orderNum;
/**
* 用户请求流水号流(用户系统内唯一)
*/
private String requestNum;
private String agentNum;
}

View File

@ -1,35 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东查询订单返回Data
*/
@Data
public class JdAgentQueryData {
/**
* 订单完成时间
*/
private String completeTime;
/**
* 订单状态INIT交易处理中SUCCESS成功FAIL失败
*/
private String status;
/**
* 失败编码
*/
private String failCode;
/**
* 失败原因
*/
private String failReason;
/**
* 订单编号
*/
private String orderNum;
}

View File

@ -1,21 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东查询订单错误返回
*/
@Data
public class JdAgentQueryError {
/**
* 错误编码
*/
private String errorCode;
/**
* 错误内容
*/
private String errorMsg;
}

View File

@ -1,24 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东查询订单返回
*/
@Data
public class JdAgentQueryResult {
/**
* 响应状态success表示成功fail表示失败error表示异常
*/
private String result;
/**
* 返回实际内容
*/
private JdAgentQueryData data;
/**
* 返回异常内容
*/
private JdAgentQueryError error;
}

View File

@ -1,38 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东代付返回
*/
@Data
public class JdAgentResult {
/**
* 请求状态true请求成功
*/
private boolean success;
/**
* 业务响应码success表示成功
*/
private String code;
/**
* 业务响应描述
*/
private String msg;
/**
* 订单编号
*/
private String orderNum;
/**
* 银行流水号
*/
private String bankRequestNum;
/**
* 完成时间
*/
private String payFinishTime;
}

View File

@ -1,32 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东绑卡确认DTO
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class JdFastBindConfirmDTO {
/**
* 商户编号
*/
private String customerNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 验证短信
*/
private String validateCode;
}

View File

@ -1,49 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东绑卡确认返回结果
*/
@Data
public class JdFastBindConfirmResult {
/**
* 请求状态
*/
private boolean success;
/**
* 业务响应码
*/
private String code;
/**
* 业务响应描述
*/
private String msg;
/**
* 商户订单号
*/
private String requestNum;
/**
* 绑卡状态
*/
private String bindStatus;
/**
* 绑卡ID
*/
private String bindId;
/**
* 银行编号
*/
private String bankCode;
/**
* 银行卡后4位
*/
private String cardAfterFour;
}

View File

@ -1,70 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东快捷绑卡DTO
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class JdFastBindDTO {
/**
* 商户编号
*/
private String customerNum;
/**
* 用户编号
*/
private String userId;
/**
* 商户订单号
*/
private String requestNum;
/**
* 姓名
*/
private String payerName;
/**
* 证件类型身份证IDCARD
*/
private String idCardType;
/**
* 证件号码
*/
private String idCardNo;
/**
* 银行卡号
*/
private String cardNo;
/**
* 银行预留手机号
*/
private String phone;
/**
* 信用卡有效期年份
*/
private String year;
/**
* 信用卡有效期月份
*/
private String month;
/**
* 信用卡安全码
*/
private String cvv2;
}

View File

@ -1,31 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东快捷绑卡返回结果
*/
@Data
public class JdFastBindResult {
/**
* 请求状态
*/
private boolean success;
/**
* 业务响应码
*/
private String code;
/**
* 业务响应描述
*/
private String msg;
/**
* 商户订单号
*/
private String requestNum;
}

View File

@ -1,32 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东快捷支付确认DTO
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class JdFastConfirmDTO {
/**
* 商户编号
*/
private String customerNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 短信验证码
*/
private String validateCode;
}

View File

@ -1,56 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东快捷支付确认返回结果
*/
@Data
public class JdFastConfirmResult {
/**
* 请求状态
*/
private boolean success;
/**
* 业务响应码
*/
private String code;
/**
* 业务响应描述
*/
private String msg;
/**
* 商户编号
*/
private String customerNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 订单编号
*/
private String orderNum;
/**
* 银行流水号
*/
private String bankRequestNum;
/**
* 订单状态
*/
private String orderStatus;
/**
* 完成时间
*/
private String completeDate;
}

View File

@ -1,118 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东快捷预下单DTO
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class JdFastDTO {
/**
* 版本号仅支持V4.0)
*/
private String version;
/**
* 商户编号
*/
private String customerNum;
/**
* 店铺编号
*/
private String shopNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 交易金额
*/
private String orderAmount;
/**
* 客户端IP
*/
private String clientIp;
/**
* 通知地址
*/
private String callbackUrl;
/**
* 用户编号
*/
private String userId;
/**
* 绑卡ID
*/
private String bindId;
/**
* 商品名称
*/
private String goodsName;
/**
* 商品数量
*/
private String goodsQuantity;
/**
* 终端类型OTHER
*/
private String terminalType;
/**
* 终端标识
*/
private String terminalId;
/**
* 用户注册账号
*/
private String userAccount;
/**
* 应用类型H5 网页
*/
private String appType;
/**
* 应用名称
*/
private String appName;
/**
* 业务场景QUICKPAY 标准场景
*/
private String tradeScene;
/**
* 来源API
*/
private String source;
/**
* 订单有效时间
*/
private String period;
/**
* 订单有效单位DayHourMinute
*/
private String periodUnit;
/**
* 扩展字段长度32
*/
private String extraInfo;
}

View File

@ -1,46 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东快捷返回结果
*/
@Data
public class JdFastResult {
/**
* 请求状态
*/
private boolean success;
/**
* 业务响应码
*/
private String code;
/**
* 业务响应描述
*/
private String msg;
/**
* 商户编号
*/
private String customerNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 订单编号
*/
private String orderNum;
/**
* 银行流水号
*/
private String bankRequestNum;
}

View File

@ -1,37 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东快捷解绑DTO
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class JdFastUnBindDTO {
/**
* 商户编号
*/
private String customerNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 用户编号
*/
private String userId;
/**
* 绑卡ID
*/
private String bindId;
}

View File

@ -1,26 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东快捷解绑返回结果
*/
@Data
public class JdFastUnBindResult {
/**
* 请求状态true成功
*/
private boolean success;
/**
* 业务响应码
*/
private String code;
/**
* 业务响应描述
*/
private String msg;
}

View File

@ -1,68 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东支付回调body体
*/
@Data
public class JdPayNotifyBody {
/**
* 处理状态
*/
private String status;
/**
* 商户订单编号
*/
private String requestNum;
/**
* 订单金额
*/
private String orderAmount;
/**
* 订单完成时间
*/
private String completeTime;
/**
* 支付类型支付宝微信等
*/
private String payWay;
/**
* 扩展内容
*/
private String extraInfo;
/**
* 订单编号京东系统订单号
*/
private String orderNum;
/**
* 银行订单号银行流水号
*/
private String bankOutTradeNum;
/**
* 银行流水号渠道订单流水号
*/
private String bankRequestNum;
/**
* 订单类型
*/
private String orderType;
/**
* 订单子类型
*/
private String subOrderType;
/**
* 订单失败原因
*/
private String failReason;
/**
* 订单失败编码
*/
private String faiCode;
}

View File

@ -1,52 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 京东扫码DTO
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class JdScanDTO {
/**
* 商户编号
*/
private String customerNum;
/**
* 店铺编号
*/
private String shopNum;
/**
* 商户订单号
*/
private String requestNum;
/**
* 金额单元
*/
private String amount;
/**
* 回调地址
*/
private String callbackUrl;
/**
* 来源固定值API
*/
private String source;
/**
* 扩展字段长度32
*/
private String extraInfo;
}

View File

@ -1,29 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东扫码返回
*/
@Data
public class JdScanResult {
/**
* 响应状态success表示成功fail表示失败error表示异常
*/
private String result;
/**
* 返回实际内容
*/
private JdScanResultData data;
/**
* 错误代码https://mer.jd.com/open/?agg_recpt&APIDocument&30&153
*/
private String errorCode;
/**
* 错误描述
*/
private String errorMsg;
}

View File

@ -1,16 +0,0 @@
package com.hzs.third.pay.dto.jd;
import lombok.Data;
/**
* 京东扫码返回Data
*/
@Data
public class JdScanResultData {
/**
* 扫码URL
*/
private String url;
}

View File

@ -1,28 +0,0 @@
package com.hzs.third.pay.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 京东应用类型
*/
@AllArgsConstructor
@Getter
public enum EJdAppType {
IOS("IOS", "IOS"),
AND("AND", "AND"),
H5("H5", "H5"),
WX("WX", "WX"),
OTHER("OTHER", "OTHER"),
;
private final String value;
private final String label;
}

View File

@ -1,27 +0,0 @@
package com.hzs.third.pay.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 京东终端类型
*/
@AllArgsConstructor
@Getter
public enum EJdTerminalType {
IMEI("IMEI", "IMEI"),
MAC("MAC", "MAC"),
// 针对IOS系统
UUID("UUID", "UUID"),
OTHER("OTHER", "OTHER"),
;
private final String value;
private final String label;
}

View File

@ -1,54 +0,0 @@
package com.hzs.third.pay.jdpay.config;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.jdpay.sdk.JdPayNewConfig;
import com.hzs.third.pay.jdpay.sdk.JdPayDefaultNewConfig;
import com.hzs.third.pay.jdpay.util.FileUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*************************************************
*
* 京东支付sdk初始化
*
*************************************************/
@Configuration
public class JdPayAutoConfiguration {
@Value("${jd.pay.merchantNo}")
private String merchantNo;
@Value("${jd.pay.signKey}")
private String signKey;
@Value("${jd.pay.priCertPwd}")
private String priCertPwd;
@Value("${jd.pay.priCert}")
private String priCert;
@Value("${jd.pay.pubCert}")
private String pubCert;
@Value("${jd.pay.apiDomain}")
private String apiDomain;
@Bean(name = "jdPay")
public JdPay initJddPay() {
// 加载商户私钥证书
byte[] privateCert = FileUtil.readFile(priCert);
// 加载商户公钥证书
byte[] publicCert = FileUtil.readFile(pubCert);
// 检查商户证书
checkCert(privateCert, publicCert);
// 初始化京东支付配置对象
JdPayNewConfig myConfig = new JdPayDefaultNewConfig(merchantNo, signKey, privateCert, priCertPwd, publicCert, apiDomain);
return new JdPay(myConfig);
}
private void checkCert(byte[] privateCert, byte[] publicCert) {
if (privateCert == null) {
throw new RuntimeException("读取京东支付商户私钥证书为空");
}
if (publicCert == null) {
throw new RuntimeException("读取京东支付商户公钥证书为空");
}
}
}

View File

@ -1,129 +0,0 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.*;
import java.io.Serializable;
/**
* @Description: 京东聚合下单请求
* @Author: jiang chao
* @Time: 2025/3/19 14:32
* @Classname: JdPayAggregateCreateOrderRequest
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayAggregateCreateOrderRequest implements Serializable {
/**
* 商户订单号
*/
private String outTradeNo;
/**
* 订单总金额
*/
private String tradeAmount;
/**
* 订单创建时间
*/
private String createDate;
/**
* 订单时效时间 分钟
*/
private String tradeExpiryTime;
/**
* 交易名称
*/
private String tradeSubject;
/**
* 交易类型
*/
private String tradeType;
/**
* 交易描述
*/
private String tradeRemark;
/**
* 币种
*/
private String currency;
/**
* 用户ip
*/
private String userIp;
/**
* 回传字段
*/
private String returnParams;
/**
* 商品信息list-- json串
*/
private String goodsInfo;
/**
* 商户用户标识
*/
private String userId;
/**
* 交易异步通知url
*/
private String notifyUrl;
/**
* 同步通知页面url
*/
private String pageBackUrl;
/**
* 风控信息map-- json串
*/
private String riskInfo;
/**
* 行业分类码
*/
private String categoryCode;
/**
* 业务类型
*/
private String bizTp;
/**
* 订单类型
*/
private String orderType;
/**
* 报文格式
*/
private String messageFormat;
/**
* 收货信息
*/
private String receiverInfo;
/**
* 交易场景
*/
private String sceneType;
/**
* 指定支付信息
*/
private String identity;
/**
* 接入方式
*/
private String accessType;
/**
* openId
*/
private String subOpenId;
/**
* appId
*/
private String subAppId;
/**
* 分帐信息
*/
private String divisionAccount;
/**
* 门店号
*/
private String storeNum;
}

View File

@ -1,56 +0,0 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description: 京东聚合下单响应
* @Author: jiang chao
* @Time: 2025/3/19 14:40
* @Classname: JdPayAggregateCreateOrderResponse
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayAggregateCreateOrderResponse implements Serializable {
/**
* 业务结果
*/
private String resultCode;
/**
* 响应描述
*/
private String resultDesc;
/**
* 商户号
*/
private String merchantNo;
/**
* 京东交易订单号
*/
private String tradeNo;
/**
* 商户订单号
*/
private String outTradeNo;
/**
* 跳转收银台链接
*/
private String webUrl;
/**
* PC扫码支付
*/
private String qrCode;
/**
* 唤起通道参数
*/
private String payInfo;
}

View File

@ -1,58 +0,0 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description: 京东退款响应
* @Author: jiang chao
* @Time: 2025/3/21 9:26
* @Classname: JdPayRefundRequest
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayRefundRequest implements Serializable {
/**
* 商户原交易号
*/
private String originalOutTradeNo;
/**
* 商户退款单号
*/
private String outTradeNo;
/**
* 退款金额
*/
private String tradeAmount;
/**
* 异步通知URL
*/
private String notifyUrl;
/**
* 回传字段
*/
private String returnParams;
/**
* 币种
*/
private String currency;
/**
* 交易时间
*/
private String tradeDate;
/**
* 退款分账信息
*
* @see
*/
private String divisionAccountRefund;
}

View File

@ -1,62 +0,0 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description: 京东退款请求
* @Author: jiang chao
* @Time: 2025/3/21 9:32
* @Classname: JdPayRefundResponse
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayRefundResponse implements Serializable {
/**
* 业务结果
*/
private String resultCode;
/**
* 响应描述
*/
private String resultDesc;
/**
* 京东退款订单号
*/
private String tradeNo;
/**
* 商户退款订单号
*/
private String outTradeNo;
/**
* 商户原正单订单号
*/
private String originalOutTradeNo;
/**
* 订单总金额
*/
private String tradeAmount;
/**
* 交易状态
*/
private String tradeStatus;
/**
* 币种
*/
private String currency;
/**
* 退款完成时间
*/
private String finishDate;
}

View File

@ -1,66 +0,0 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description: 退款成功通知
* @Author: jiang chao
* @Time: 2025/3/21 10:24
* @Classname: JdPayRefundSuccessNotify
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayRefundSuccessNotify implements Serializable {
/**
* 业务结果
*/
private String resultCode;
/**
* 响应描述
*/
private String resultDesc;
/**
* 京东退款订单号
*/
private String tradeNo;
/**
* 商户退款订单号
*/
private String outTradeNo;
/**
* 商户原正单订单号
*/
private String originalOutTradeNo;
/**
* 订单总金额
*/
private String tradeAmount;
/**
* 退款完成时间
*/
private String finishDate;
/**
* 交易状态
*/
private String tradeStatus;
/**
* 回传字段
*/
private String returnParams;
/**
* 币种
*/
private String currency;
}

View File

@ -1,98 +0,0 @@
package com.hzs.third.pay.jdpay.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Description: 交易成功通知
* @Author: jiang chao
* @Time: 2025/3/21 10:24
* @Classname: JdPayRefundSuccessNotify
* @PackageName: com.hzs.third.pay.jdpay.dto
*/
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class JdPayTradeSuccessNotify implements Serializable {
/**
* 业务结果
*/
private String resultCode;
/**
* 响应描述
*/
private String resultDesc;
/**
* 京东交易订单号
*/
private String tradeNo;
/**
* 商户订单号
*/
private String outTradeNo;
/**
* 订单总金额
*/
private String tradeAmount;
/**
* 币种
*/
private String currency;
/**
* 支付完成时间
*/
private String finishDate;
/**
* 交易类型
*/
private String tradeType;
/**
* 交易状态
*/
private String tradeStatus;
/**
* 回传字段
*/
private String returnParams;
/**
* 请求的端
*/
private String clientType;
/**
* 商户用户标识
*/
private String userId;
/**
* 优惠金额
*/
private String discountAmount;
/**
* 支付工具
*/
private String payTool;
/**
* 掩码卡号
*/
private String maskCardNo;
/**
* 卡类型
*/
private String cardType;
/**
* 银行编码
*/
private String bankCode;
/**
* 白条分期数
*/
private String installmentNum;
}

View File

@ -1,175 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import com.hzs.third.pay.jdpay.dto.JdPayAggregateCreateOrderRequest;
import com.hzs.third.pay.jdpay.dto.JdPayAggregateCreateOrderResponse;
import com.hzs.third.pay.jdpay.dto.JdPayRefundRequest;
import com.hzs.third.pay.jdpay.dto.JdPayRefundResponse;
import com.hzs.third.pay.jdpay.util.GsonUtil;
import com.hzs.third.pay.jdpay.util.JdPayApiUtil;
import com.hzs.third.pay.jdpay.util.SignUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/*************************************************
*
* 京东支付api实现类
*
*************************************************/
@Slf4j
public class JdPay {
private JdPayNewConfig jdPayNewConfig;
private JdPayHttpClientProxy jdPayHttpClientProxy;
public JdPay(JdPayNewConfig jdPayNewConfig) {
this.jdPayNewConfig = jdPayNewConfig;
this.jdPayHttpClientProxy = new JdPayHttpClientProxy(jdPayNewConfig, new JdPayHttpClient());
}
// /**
// * 作用统一下单
// * 场景京东支付
// *
// * @param request 向jdPay post的请求数据
// * @return JdPayCreateOrderResponse 返回数据
// * @throws Exception
// */
// public JdPayCreateOrderResponse createOrder(JdPayCreateOrderRequest request) throws Exception {
// return this.baseExecute(JdPayConstant.CREATE_ORDER_URL, request, JdPayCreateOrderResponse.class);
// }
/**
* 作用三方聚合统一下单
* 场景三方聚合
*
* @param request 向jdPay post的请求数据
* @return JdPayAggregateCreateOrderResponse 返回数据
* @throws Exception
*/
public JdPayAggregateCreateOrderResponse aggregateCreateOrder(JdPayAggregateCreateOrderRequest request) throws Exception {
return this.baseExecute(JdPayConstant.AGGREGATE_CREATE_ORDER_URL, request, JdPayAggregateCreateOrderResponse.class);
}
// /**
// * 作用订单查询
// * 场景查询订单信息 - 包括首次支付订单与代扣订单
// *
// * @param request 向jdPay post的请求数据
// * @return JdPayQueryOrderResponse 返回数据
// * @throws Exception
// */
// public JdPayQueryOrderResponse queryOrder(JdPayQueryOrderRequest request) throws Exception {
// return this.baseExecute(JdPayConstant.TRADE_QUERY_URL, request, JdPayQueryOrderResponse.class);
// }
//
// /**
// * 作用代扣
// * 场景代扣交易场景
// *
// * @param request 向jdPay post的请求数据
// * @return JdPayAgreementPayResponse 返回数据
// * @throws Exception
// */
// public JdPayAgreementPayResponse agreementPay(JdPayAgreementPayRequest request) throws Exception {
// return this.baseExecute(JdPayConstant.AGREEMENT_PAY_URL, request, JdPayAgreementPayResponse.class);
// }
/**
* 作用申请退款
* 场景退款
*
* @param request 向jdPay post的请求数据
* @return JdPayRefundResponse 返回数据
* @throws Exception
*/
public JdPayRefundResponse refund(JdPayRefundRequest request) throws Exception {
return this.baseExecute(JdPayConstant.REFUND_URL, request, JdPayRefundResponse.class);
}
// /**
// * 作用退款查询
// * 场景查询退款信息
// *
// * @param request 向jdPay post的请求数据
// * @return JdPayQueryOrderResponse 返回数据
// * @throws Exception
// */
// public JdPayRefundQueryResponse refundQuery(JdPayRefundQueryRequest request) throws Exception {
// return this.baseExecute(JdPayConstant.REFUND_QUERY_URL, request, JdPayRefundQueryResponse.class);
// }
//
// /**
// * 作用解约
// * 场景接触签约关系
// *
// * @param request 向jdPay post的请求数据
// * @return JdPayAgreementCancelRequest 返回数据
// * @throws Exception
// */
// public JdPayAgreementCancelResponse agreementCancel(JdPayAgreementCancelRequest request) throws Exception {
// return this.baseExecute(JdPayConstant.AGREEMENT_CANCEL_URL, request, JdPayAgreementCancelResponse.class);
// }
//
//
// /**
// * 作用解约查询
// * 场景查询签约关系
// *
// * @param request 向jdPay post的请求数据
// * @return JdPayAgreementCancelRequest 返回数据
// * @throws Exception
// */
// public JdPayAgreementQueryResponse agreementQuery(JdPayAgreementQueryRequest request) throws Exception {
// return this.baseExecute(JdPayConstant.AGREEMENT_QUERY_URL, request, JdPayAgreementQueryResponse.class);
// }
//
// public JdPayAgreementSignResponse agreementNewSign(JdPayAgreementSignRequest request) throws Exception{
// return this.baseExecute(JdPayConstant.AGREEMENT_NEW_SIGN_URL, request, JdPayAgreementSignResponse.class);
// }
/**
* 验证接口参数签名
* 场景:api接口返回参数异步回调请求参数
*/
public String verifyResponse(String respText) throws Exception {
String interData = JdPayApiUtil.decryptAndVerifySign(jdPayNewConfig, respText);
log.info("京东支付异步通知-解析数据:{}", interData);
return interData;
}
/**
* 验证页面回调参数
*
* @param respMap 页面回调参数
* @return 验证结果
* @throws Exception 异常
*/
public boolean verifyPageCallBack(Map<String, String> respMap) throws Exception {
return SignUtil.verifyPageCallBackSign(respMap, jdPayNewConfig.getSignKey());
}
/**
* 执行接口调用
*
* @param request 请求对象
* @param clazz 返回对象类型
* @return 返回对象
* @throws Exception 异常
*/
public <REQ, RES> RES baseExecute(String urlSuffix, REQ request, Class<RES> clazz) throws Exception {
String reqJson = GsonUtil.toJson(request);
String respJson = jdPayHttpClientProxy.execute(urlSuffix, reqJson);
return GsonUtil.fromJson(respJson, clazz);
}
// /**
// * 账户签约
// * @param request
// * @return
// * @throws Exception
// */
// public JdPayAgreementSignApplyResponse agreementSignApply(JdPayAgreementSignApplyRequest request) throws Exception{
// return this.baseExecute(JdPayConstant.AGREEMENT_SIGN_APPLY_URL, request, JdPayAgreementSignApplyResponse.class);
// }
}

View File

@ -1,96 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import org.apache.http.client.HttpClient;
public class JdPayConstant {
/**
* 京东支付统一收单 url
**/
public static final String CREATE_ORDER_URL = "/api/createOrder";
/**
* 三方聚合统一收单 url
**/
public static final String AGGREGATE_CREATE_ORDER_URL = "/api/createAggregateOrder";
/**
* 交易查询 url
**/
public static final String TRADE_QUERY_URL = "/api/queryOrder";
/**
* 退款申请 url
**/
public static final String REFUND_URL = "/api/refund";
/**
* 退款查询 url
**/
public static final String REFUND_QUERY_URL = "/api/refundQuery";
/**
* 代扣 url
**/
public static final String AGREEMENT_PAY_URL = "/api/agreementPay";
/**
* 签约关系查询 url
**/
public static final String AGREEMENT_QUERY_URL = "/api/agreementQuery";
/**
* 解约申请 url
**/
public static final String AGREEMENT_CANCEL_URL = "/api/agreementCancel";
/**
* 无卡号签约
*/
public static final String AGREEMENT_NEW_SIGN_URL = "/api/agreementNewSign";
/**
* 账户签约
*/
public static final String AGREEMENT_SIGN_APPLY_URL = "/api/agreementSignApply";
/**
* 随机字符常量
*/
public static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
/**
* 公共字段常量 start
**/
public static final String CCM = "CCM";
public static final String MERCHANT_NO = "merchantNo";
public static final String REQ_NO = "reqNo";
public static final String CHARSET = "charset";
public static final String FORMAT_TYPE = "formatType";
public static final String SIGN_TYPE = "signType";
public static final String ENC_TYPE = "encType";
public static final String UTF8 = "UTF-8";
public static final String JSON = "JSON";
public static final String SHA256 = "SHA-256";
public static final String AP7 = "AP7";
public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static final String SIGN_DATA = "signData";
public static final String ENC_DATA = "encData";
public static final String RESP_DATA = "respData";
public static final String CODE = "code";
public static final String DESC = "desc";
public static final String SUCCESS_CODE = "00000";
/* 公共字段常量 end */
/**
* http请求常量 start
**/
public static final String HTTP = "http";
public static final String HTTPS = "https";
public static final String CONTENT_TYPE = "Content-Type";
public static final String UA = "User-Agent";
public static final String PKCS12 = "PKCS12";
public static final String TLS = "TLS";
public static final String APPLICATION_JSON = "application/json";
public static final String USER_AGENT = "jdPay" +
" (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") +
") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion();
/* http请求常量 end */
public static final String URL_PATH = "/api/";
}

View File

@ -1,73 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import com.hzs.third.pay.jdpay.util.FileUtil;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/*************************************************
*
* 商户默认配置类
* 商户也可以自行实现JdPayConfig调整配置属性
*
*************************************************/
public class JdPayDefaultNewConfig extends JdPayNewConfig {
private String merchantNo;
private String signKey;
private byte[] priCert;
private String priCertPwd;
private byte[] pubCert;
private String apiDomain;
public JdPayDefaultNewConfig(String merchantNo, String signKey, byte[] priCert, String priCertPwd, byte[] pubCert, String apiDomain) {
this.merchantNo = merchantNo;
this.signKey = signKey;
this.priCert = priCert;
this.priCertPwd = priCertPwd;
this.pubCert = pubCert;
this.apiDomain = apiDomain;
}
public JdPayDefaultNewConfig(String merchantNo, String signKey, String priCertPwd, String apiDomain, String priCertPath, String pubCertPath) {
this.merchantNo = merchantNo;
this.signKey = signKey;
this.priCertPwd = priCertPwd;
this.apiDomain = apiDomain;
//加载商户私钥证书
this.priCert = FileUtil.readFile(priCertPath);
//加载商户公钥证书
this.pubCert = FileUtil.readFile(pubCertPath);
}
@Override
public String getMerchantNo() {
return this.merchantNo;
}
@Override
public String getSignKey() {
return this.signKey;
}
@Override
public InputStream getPriCert() {
return new ByteArrayInputStream(this.priCert);
}
@Override
public String getPriCertPwd() {
return this.priCertPwd;
}
@Override
public InputStream getPubCert() {
return new ByteArrayInputStream(this.pubCert);
}
@Override
public String getApiDomain() {
return this.apiDomain;
}
}

View File

@ -1,173 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import com.hzs.common.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
@Slf4j
public class JdPayHttpClient {
private CloseableHttpClient httpClient = null;
public JdPayHttpClient() {
}
/**
* 远程调用
*
* @param jdPayNewConfig 京东支付配置
* @param urlSuffix 接口url后缀
* @param request 请求参数
* @return 返回参数看
* @throws Exception 远程调用异常信息
*/
public String execute(JdPayNewConfig jdPayNewConfig, String urlSuffix, String request) {
HttpClient httpClient = buildHttpClient(jdPayNewConfig);
String url = jdPayNewConfig.getApiDomain() + urlSuffix;
int connectTimeoutMs = jdPayNewConfig.getHttpConnectTimeoutMs();
int readTimeoutMs = jdPayNewConfig.getHttpReadTimeoutMs(urlSuffix);
try {
return this.sendRequest(httpClient, url, request, connectTimeoutMs, readTimeoutMs);
} catch (IOException e) {
throw new ServiceException("HTTP read timeout");
}
}
/**
* 获取httpClient
*
* @param jdPayNewConfig 京东支付配置
* @return httpClient
*/
private HttpClient buildHttpClient(JdPayNewConfig jdPayNewConfig) {
if (jdPayNewConfig.useHttpConnectPool()) {
return getHttpClientByPoolingConnectionManager(jdPayNewConfig);
} else {
return getHttpClientByBasicConnectionManager();
}
}
/**
* 发送请求
*
* @param httpClient httpClient
* @param url 请求地址
* @param data 请求数据
* @param connectTimeoutMs 连接超时时间单位是毫秒
* @param readTimeoutMs 读超时时间单位是毫秒
* @return api接口返回参数
*/
private String sendRequest(HttpClient httpClient, String url, String data, int connectTimeoutMs, int readTimeoutMs) throws IOException {
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
httpPost.setConfig(requestConfig);
StringEntity postEntity = new StringEntity(data, JdPayConstant.UTF8);
httpPost.addHeader(JdPayConstant.CONTENT_TYPE, JdPayConstant.APPLICATION_JSON);
httpPost.addHeader(JdPayConstant.UA, JdPayConstant.USER_AGENT);
httpPost.setEntity(postEntity);
HttpResponse httpResponse = httpClient.execute(httpPost);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK != statusCode) {
throw new ServiceException(String.format("httpStatusCode: %s", statusCode));
}
HttpEntity httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity, JdPayConstant.UTF8);
}
private HttpClient getHttpClientByBasicConnectionManager() {
HttpClientConnectionManager connManager = new BasicHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register(JdPayConstant.HTTP, PlainConnectionSocketFactory.getSocketFactory())
.register(JdPayConstant.HTTPS, SSLConnectionSocketFactory.getSocketFactory())
.build(),
null,
null,
null
);
return HttpClientBuilder.create()
// 连接池
.setConnectionManager(connManager)
// 重试策略
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)).build();
}
private HttpClient getHttpClientByPoolingConnectionManager(JdPayNewConfig jdPayNewConfig) {
if (httpClient != null) {
return httpClient;
}
synchronized (this) {
if (httpClient == null) {
long start = System.currentTimeMillis();
PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager(
RegistryBuilder.<ConnectionSocketFactory>create()
.register(JdPayConstant.HTTP, PlainConnectionSocketFactory.getSocketFactory())
.register(JdPayConstant.HTTPS, SSLConnectionSocketFactory.getSocketFactory())
.build()
);
// 设置最大连接数
httpClientConnectionManager.setMaxTotal(jdPayNewConfig.getHttpConnectMaxTotal());
// 将每个路由默认最大连接数
httpClientConnectionManager.setDefaultMaxPerRoute(jdPayNewConfig.getHttpConnectDefaultTotal());
httpClient = HttpClients.custom()
// 设置连接池
.setConnectionManager(httpClientConnectionManager)
// 连接存活策略
.setKeepAliveStrategy(getConnectionKeepAliveStrategy())
// 重试策略
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)).build();
// 连接回收策略
JdPayHttpConnectionMonitor idleConnectionMonitor = new JdPayHttpConnectionMonitor(httpClientConnectionManager, jdPayNewConfig.getHttpConnectIdleAliveMs());
idleConnectionMonitor.start();
log.info("初始化http连接池耗时:{}", System.currentTimeMillis() - start);
}
}
return httpClient;
}
private ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
return new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
// Honor 'keep-alive' header
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && "timeout".equalsIgnoreCase(param)) {
try {
log.info("Keep-Alive指定时长:{}", value);
return Long.parseLong(value) * 1000;
} catch (NumberFormatException ignore) {
}
}
}
// Keep alive for 300 seconds only
return 300 * 1000;
}
};
}
}

View File

@ -1,58 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import com.hzs.third.pay.jdpay.util.JdPayApiUtil;
import lombok.extern.slf4j.Slf4j;
import java.security.SecureRandom;
import java.util.Random;
@Slf4j
public class JdPayHttpClientProxy {
private static final Random RANDOM = new SecureRandom();
private final JdPayNewConfig jdPayNewConfig;
private final JdPayHttpClient jdPayHttpClient;
public JdPayHttpClientProxy(JdPayNewConfig jdPayNewConfig, JdPayHttpClient jdPayHttpClient) {
this.jdPayNewConfig = jdPayNewConfig;
this.jdPayHttpClient = jdPayHttpClient;
}
/**
* 获取随机字符串含数字和大小写英文字母
*/
private static String genNonceStr() {
char[] nonceChars = new char[32];
for (int index = 0; index < nonceChars.length; ++index) {
nonceChars[index] = JdPayConstant.SYMBOLS.charAt(RANDOM.nextInt(JdPayConstant.SYMBOLS.length()));
}
return new String(nonceChars);
}
public String execute(String urlSuffix, String request) throws Exception {
long startTimestampMs = System.currentTimeMillis();
String response;
// 接口名称
String apiName = urlSuffix.replaceFirst(JdPayConstant.URL_PATH, "");
// 唯一请求号
String reqNo = genNonceStr();
try {
log.info("1.{}接口请求参数:{}", apiName, request);
// 请求参数加密和签名
String httpRequest = JdPayApiUtil.encryptAndSignature(jdPayNewConfig, reqNo, request);
log.info("2.{}远程调用请求参数:{}", apiName, httpRequest);
String httpResponse = jdPayHttpClient.execute(jdPayNewConfig, urlSuffix, httpRequest);
log.info("3.{}远程调用返回参数:{}", apiName, httpResponse);
// 验证和解析返回参数
response = JdPayApiUtil.decryptAndVerifySign(jdPayNewConfig, httpResponse);
log.info("4.{}耗时:{},接口返回参数:{}", apiName, (System.currentTimeMillis() - startTimestampMs), response);
} catch (Exception e) {
log.error("{}远程调用异常,接口参数:{}", apiName, request, e);
throw e;
}
return response;
}
}

View File

@ -1,55 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.HttpClientConnectionManager;
import java.util.concurrent.TimeUnit;
/**
* 用于监控空闲的连接池连接
*/
@Slf4j
public class JdPayHttpConnectionMonitor extends Thread {
// 轮询检查时间间隔单位毫秒
private static final int MONITOR_INTERVAL_MS = 5000;
// 连接最大空闲时间单位毫秒
private static int IDLE_ALIVE_MS = 20000;
private final HttpClientConnectionManager httpClientConnectionManager;
private volatile boolean shutdown;
JdPayHttpConnectionMonitor(HttpClientConnectionManager httpClientConnectionManager, int idleAliveMs) {
super();
this.httpClientConnectionManager = httpClientConnectionManager;
IDLE_ALIVE_MS = idleAliveMs;
this.shutdown = false;
}
@Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(MONITOR_INTERVAL_MS);
// 关闭无效的连接
httpClientConnectionManager.closeExpiredConnections();
// 关闭空闲时间超过IDLE_ALIVE_MS的连接
httpClientConnectionManager.closeIdleConnections(IDLE_ALIVE_MS, TimeUnit.MILLISECONDS);
}
}
} catch (InterruptedException e) {
log.error("连接池管理任务异常:", e);
}
}
// 关闭后台连接
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
}
}

View File

@ -1,154 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import java.io.InputStream;
import java.util.HashMap;
/**
* 京东支付配置类
*/
public abstract class JdPayNewConfig {
/**
* 接口超时时间全局配置
*/
private static final HashMap<String, Integer> HTTP_READ_TIMEOUT_CONFIG = new HashMap<String, Integer>() {{
put(JdPayConstant.CREATE_ORDER_URL, 15000);
put(JdPayConstant.TRADE_QUERY_URL, 5000);
put(JdPayConstant.REFUND_URL, 5000);
put(JdPayConstant.REFUND_QUERY_URL, 5000);
put(JdPayConstant.AGREEMENT_PAY_URL, 10000);
put(JdPayConstant.AGREEMENT_QUERY_URL, 5000);
put(JdPayConstant.AGREEMENT_CANCEL_URL, 5000);
}};
/**
* 获取merchantNo
*
* @return merchantNo
*/
public abstract String getMerchantNo();
/**
* 获取signKey
*
* @return signKey
*/
public abstract String getSignKey();
/**
* 获取 私钥证书
*
* @return 私钥证书
*/
public abstract InputStream getPriCert();
/**
* 获取 私钥证书密钥
*
* @return 私钥证书密钥
*/
public abstract String getPriCertPwd();
/**
* 获取 公钥证书
*
* @return 公钥证书
*/
public abstract InputStream getPubCert();
/**
* 获取域名-新api接口
*
* @return 域名-新api接口
*/
public abstract String getApiDomain();
/**
* HTTP(S) 连接超时时间单位毫秒
*
* @return 连接时间
*/
public int getHttpConnectTimeoutMs() {
return 6 * 1000;
}
/**
* 设置HTTP(S) 读数据超时时间单位毫秒
*
* @param urlSuffix api地址除去域名后的路径
* @param httpReadTimeoutMs 读超时时间单位毫秒
*/
public void setHttpReadTimeoutMs(String urlSuffix, int httpReadTimeoutMs) {
HTTP_READ_TIMEOUT_CONFIG.put(urlSuffix, httpReadTimeoutMs);
}
/**
* 查询HTTP(S) 读数据超时时间单位毫秒
*
* @return 读超时时间单位毫秒
*/
public int getHttpReadTimeoutMs(String requestPath) {
if (!HTTP_READ_TIMEOUT_CONFIG.containsKey(requestPath)) {
return 15000;
}
return HTTP_READ_TIMEOUT_CONFIG.get(requestPath);
}
/**
* 是否自动上报异常请求默认为 true
* 若要关闭子类中实现该函数返回 false 即可
*/
public boolean shouldAutoReport() {
return true;
}
/**
* 进行异常上报的线程的数量
*/
public int getReportWorkerNum() {
return 1;
}
/**
* 批量上报一次报多条异常数据
*/
public int getReportBatchSize() {
return 5;
}
/**
* 异常上报缓存消息队列最大数量
* 队列满后不会上报新增的异常信息
*/
public int getReportQueueMaxSize() {
return 50;
}
/**
* 是否使用http连接池
*/
public boolean useHttpConnectPool() {
return false;
}
/**
* http连接池最大连接数量
*/
public int getHttpConnectMaxTotal() {
return 800;
}
/**
* http连接池默认连接数量
*/
public int getHttpConnectDefaultTotal() {
return 100;
}
/**
* http连接最大闲置时长单位毫秒
*/
public int getHttpConnectIdleAliveMs() {
return 20000;
}
}

View File

@ -1,19 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import org.bouncycastle.util.encoders.Base64;
import java.io.InputStream;
public class JdPaySecurity {
public String signEnvelop(InputStream signCert, String password, InputStream envelopCert, byte[] orgData) {
byte[] signData = JdPaySign.getInstance().attachSign(signCert, password, orgData);
byte[] envelop = JdPaySign.getInstance().encryptEnvelop(envelopCert, signData);
return new String(Base64.encode(envelop));
}
public byte[] verifyEnvelop(InputStream envelopCert, String password, byte[] envelopData) {
byte[] signData = JdPaySign.getInstance().decryptEnvelop(envelopCert, password, envelopData);
return JdPaySign.getInstance().verifyAttachSign(signData);
}
}

View File

@ -1,200 +0,0 @@
package com.hzs.third.pay.jdpay.sdk;
import com.hzs.common.core.exception.ServiceException;
import com.hzs.third.pay.jdpay.util.CertUtil;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.*;
import org.bouncycastle.cms.jcajce.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
import javax.security.auth.x500.X500PrivateCredential;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@Slf4j
public class JdPaySign {
private static final String SIGN_ALGORITHMS = "SHA1WITHRSA";
private static final String BC = "BC";
private static JdPaySign INSTANCE = null;
static {
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
}
private JdPaySign() {
}
/**
* 单例双重校验
*/
public static JdPaySign getInstance() {
if (INSTANCE == null) {
synchronized (JdPaySign.class) {
if (INSTANCE == null) {
INSTANCE = new JdPaySign();
}
}
}
return INSTANCE;
}
public byte[] attachSign(InputStream priCert, String password, byte[] data) {
return this.sign(priCert, password, data, true);
}
public byte[] detachSign(InputStream priCert, String password, byte[] data) {
return this.sign(priCert, password, data, false);
}
private byte[] sign(InputStream priCert, String password, byte[] data, boolean isDetach) {
try {
X500PrivateCredential privateCert = CertUtil.getPrivateCert(priCert, password.toCharArray());
X509Certificate x509Certificate = privateCert.getCertificate();
PrivateKey privateKey = privateCert.getPrivateKey();
List<X509Certificate> certList = new ArrayList<>();
certList.add(x509Certificate);
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder(SIGN_ALGORITHMS).setProvider(BC).build(privateKey);
generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build()).build(sha1Signer, x509Certificate));
generator.addCertificates(certs);
CMSTypedData msg = new CMSProcessableByteArray(data);
return generator.generate(msg, isDetach).getEncoded();
} catch (CertificateException e) {
log.error("=====", e);
log.error(e.getMessage());
throw new ServiceException(e.getMessage());
} catch (Exception e) {
log.error("-----", e);
log.error(e.getMessage());
throw new ServiceException("签名异常");
}
}
@SuppressWarnings("rawtypes")
public int verifyDetachSign(byte[] data, byte[] signData) {
try {
CMSProcessable content = new CMSProcessableByteArray(data);
CMSSignedData s = new CMSSignedData(content, signData);
Store certStore = s.getCertificates();
SignerInformationStore signers = s.getSignerInfos();
Collection c = signers.getSigners();
Iterator it = c.iterator();
int verified = 0, size = 0;
while (it.hasNext()) {
size++;
SignerInformation signer = (SignerInformation) it.next();
Collection certCollection = certStore.getMatches(signer.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder cert = (X509CertificateHolder) certIt.next();
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) {
verified++;
}
}
if (size == verified) {
return 1;
}
} catch (Exception e) {
return 0;
}
return 0;
}
@SuppressWarnings({"rawtypes"})
public byte[] verifyAttachSign(byte[] signData) {
try {
byte[] data = null;
CMSSignedData s = new CMSSignedData(signData);
Store certStore = s.getCertificates();
SignerInformationStore signers = s.getSignerInfos();
Collection c = signers.getSigners();
Iterator it = c.iterator();
int verified = 0, size = 0;
while (it.hasNext()) {
size++;
SignerInformation signer = (SignerInformation) it.next();
Collection certCollection = certStore.getMatches(signer.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder cert = (X509CertificateHolder) certIt.next();
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) {
verified++;
CMSTypedData cmsData = s.getSignedContent();
data = (byte[]) cmsData.getContent();
}
}
if (size == verified) {
return data;
}
} catch (Exception e) {
return null;
}
return null;
}
public byte[] encryptEnvelop(InputStream pubCert, byte[] bOrgData) {
try {
X509Certificate publicCert = CertUtil.getPublicCert(pubCert);
CMSEnvelopedDataGenerator generator = new CMSEnvelopedDataGenerator();
generator.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(publicCert).setProvider(BC));
CMSEnvelopedData enveloped = generator.generate(new CMSProcessableByteArray(bOrgData), new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build());
ByteArrayOutputStream out = new ByteArrayOutputStream();
new DEROutputStream(out).writeObject(enveloped.toASN1Structure());
byte[] result = out.toByteArray();
out.close();
return result;
} catch (CertificateException | CMSException | IOException e) {
log.error("加密异常:{}", e.getMessage());
throw new ServiceException("加密异常");
}
}
public byte[] decryptEnvelop(InputStream priCert, String privateKeyPassword, byte[] bEnvelop) {
try {
CMSEnvelopedData enveloped = new CMSEnvelopedData(bEnvelop);
RecipientInformationStore ris = enveloped.getRecipientInfos();
if (ris == null) {
log.error("数字信封格式不对:{}", new String(bEnvelop));
throw new ServiceException("验签异常");
}
X500PrivateCredential privateCert = CertUtil.getPrivateCert(priCert, privateKeyPassword.toCharArray());
PrivateKey privateKey = privateCert.getPrivateKey();
byte[] sign = null;
Collection recipients = ris.getRecipients();
for (Object object : recipients) {
RecipientInformation recipient = (RecipientInformation) object;
sign = recipient.getContent(new JceKeyTransEnvelopedRecipient(privateKey).setProvider(BC));
}
return sign;
} catch (CMSException | CertificateException e) {
log.error("验签异常:{}", e.getMessage());
throw new ServiceException("验签异常");
}
}
}

View File

@ -1,110 +0,0 @@
package com.hzs.third.pay.jdpay.util;
import lombok.extern.slf4j.Slf4j;
import javax.security.auth.x500.X500PrivateCredential;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
@Slf4j
public class CertUtil {
private static final String PKCS12 = "PKCS12";
public static X500PrivateCredential getPrivateCert(InputStream pfxCert, char[] privateKeyPassword) throws CertificateException {
KeyStore keyStore;
String keyStoreAlias = null;
/* Load KeyStore contents from file */
try {
keyStore = KeyStore.getInstance(CertUtil.PKCS12);
keyStore.load(pfxCert, privateKeyPassword);
/* Get aliases */
Enumeration aliases = keyStore.aliases();
if (aliases != null) {
while (aliases.hasMoreElements()) {
keyStoreAlias = (String) aliases.nextElement();
Certificate[] certs = keyStore.getCertificateChain(keyStoreAlias);
if (certs == null || certs.length == 0) {
continue;
}
X509Certificate cert = (X509Certificate) certs[0];
if (matchUsage(cert.getKeyUsage(), 1)) {
try {
cert.checkValidity();
} catch (CertificateException e) {
continue;
}
break;
}
}
}
} catch (GeneralSecurityException | IOException e) {
log.error("===============", e);
throw new CertificateException("Error initializing keystore");
}
if (keyStoreAlias == null) {
throw new CertificateException("None certificate for sign in this keystore");
}
/* Get certificate chain and create a certificate path */
Certificate[] fromKeyStore;
try {
fromKeyStore = keyStore.getCertificateChain(keyStoreAlias);
if (fromKeyStore == null
|| fromKeyStore.length == 0
|| !(fromKeyStore[0] instanceof X509Certificate)) {
throw new CertificateException("Unable to find X.509 certificate chain in keystore");
}
} catch (KeyStoreException e) {
throw new CertificateException("Error using keystore");
}
/* Get PrivateKey */
Key privateKey;
try {
privateKey = keyStore.getKey(keyStoreAlias, privateKeyPassword);
if (!(privateKey instanceof PrivateKey)) {
throw new CertificateException("Unable to recover key from keystore");
}
} catch (KeyStoreException | NoSuchAlgorithmException e) {
throw new CertificateException("Error using keystore");
} catch (UnrecoverableKeyException e) {
throw new CertificateException("Unable to recover key from keystore");
}
X509Certificate certificate = (X509Certificate) fromKeyStore[0];
return new X500PrivateCredential(certificate, (PrivateKey) privateKey, keyStoreAlias);
}
public static X509Certificate getPublicCert(InputStream publicCert) throws CertificateException {
try {
CertificateFactory cf = CertificateFactory.getInstance("X509");
Certificate certificate = cf.generateCertificate(publicCert);
return (X509Certificate) certificate;
} catch (CertificateException e) {
throw new CertificateException("Error loading public key certificate");
}
}
private static boolean matchUsage(boolean[] keyUsage, int usage) {
if (usage == 0 || keyUsage == null) {
return true;
}
for (int i = 0; i < Math.min(keyUsage.length, 32); i++) {
if ((usage & (1 << i)) != 0 && !keyUsage[i]) {
return false;
}
}
return true;
}
}

View File

@ -1,43 +0,0 @@
package com.hzs.third.pay.jdpay.util;
import org.springframework.core.io.ClassPathResource;
import java.io.*;
public class FileUtil {
public FileUtil() {
}
public static byte[] readFile(String filename) {
ClassPathResource classPathResource = new ClassPathResource(filename);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
BufferedInputStream in = null;
try {
in = new BufferedInputStream(classPathResource.getInputStream());
byte[] buffer = new byte[1024];
int len;
while (-1 != (len = in.read(buffer, 0, 1024))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException var21) {
var21.printStackTrace();
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException var20) {
var20.printStackTrace();
}
try {
bos.close();
} catch (IOException var19) {
var19.printStackTrace();
}
}
return null;
}
}

View File

@ -1,171 +0,0 @@
package com.hzs.third.pay.jdpay.util;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.Primitives;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
/*************************************************
*
* Gson工具类对Google的gson工具进行封装
* (1)日期格式yyyyMMddHHmmss
* (2)toJson时支持掩码
* (3)toJson时支持跳过指定属性
*************************************************/
public class GsonUtil {
private static final String EMPTY_JSON = "{}";
private static final String EMPTY_JSON_ARRAY = "[]";
private static final String DEFAULT_DATE_PATTERN = "yyyyMMddHHmmss";
private static final Gson DEFAULT_GSON;
static {
GsonBuilder builder = new GsonBuilder();
builder.setDateFormat(DEFAULT_DATE_PATTERN);
DEFAULT_GSON = builder.create();
DEFAULT_GSON.toJson(null);
}
public static String toJson(Object target) {
return toJson(target, null, null, null);
}
public static String toJson(Object target, Type targetType) {
return toJson(target, targetType, null, null);
}
public static String toMaskJson(Object target) {
return toJson(target, null, null, null);
}
public static String toMaskJson(Object target, List<String> excludeFields) {
return toJson(target, null, null, excludeFields);
}
/**
* 打印目标对象的json串
*
* @param target 目标对象
* @param targetType 对象类型可为null
* @param datePattern 日期格式可为null若为null则按 DEFAULT_DATE_PATTERN格式输出
* @param excludeFields 不打印的字段可为null
* @return 目标对象的标准json串
*/
public static String toJson(Object target, Type targetType, String datePattern, final List<String> excludeFields) {
if (target == null) {
return EMPTY_JSON;
}
Gson gson = DEFAULT_GSON;
if (null != datePattern && !"".equals(datePattern)) {
gson = getGson(datePattern);
}
if (isNotEmpty(excludeFields)) {
gson = getStrategyGson(excludeFields);
}
String result = emptyResult(target);
try {
if (targetType == null) {
targetType = target.getClass();
}
result = gson.toJson(target, targetType);
} catch (Exception ignore) {
}
return result;
}
public static <T> T fromJson(String json, TypeToken<T> token) {
return fromJson(json, token, null);
}
public static <T> T fromJson(String json, TypeToken<T> token, String datePattern) {
return fromJson(json, token.getType(), datePattern);
}
public static <T> T fromJson(String json, Class<T> classOfT) {
Object object = fromJson(json, (Type) classOfT, null);
return Primitives.wrap(classOfT).cast(object);
}
public static <T> T fromJson(String json, Class<T> classOfT, String datePattern) {
Object object = fromJson(json, (Type) classOfT, datePattern);
return Primitives.wrap(classOfT).cast(object);
}
/**
* 将json串转化为目标对象
*
* @param json json串
* @param type 目标对象类型
* @param datePattern json串中日期格式若为null则按两个标准日期尝试解析DEFAULT_DATE_PATTERN和DEFAULT_DATE_PATTERN_1
* @param <T>
* @return 目标对象
*/
public static <T> T fromJson(String json, Type type, String datePattern) {
if (null == json || "".equals(json)) {
return null;
}
if (null == datePattern || "".equals(datePattern)) {
try {
return DEFAULT_GSON.fromJson(json, type);
} catch (Exception ignore) {
}
return null;
}
try {
Gson gson = getGson(datePattern);
return gson.fromJson(json, type);
} catch (Exception ignore) {
}
return null;
}
private static Gson getGson(String datePattern) {
GsonBuilder builder = new GsonBuilder();
builder.setDateFormat(datePattern);
return builder.create();
}
private static Gson getStrategyGson(final List<String> excludeFields) {
ExclusionStrategy myExclusionStrategy = new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes fa) {
return excludeFields != null && excludeFields.contains(fa.getName());
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
};
return new GsonBuilder().setExclusionStrategies(myExclusionStrategy).create();
}
private static boolean isNotEmpty(final List<String> fieldNames) {
return fieldNames != null && !fieldNames.isEmpty();
}
private static String emptyResult(Object target) {
if (target == null) {
return EMPTY_JSON;
}
if (target instanceof Collection
|| target instanceof Iterator
|| target instanceof Enumeration
|| target.getClass().isArray()) {
return EMPTY_JSON_ARRAY;
}
return EMPTY_JSON;
}
}

View File

@ -1,81 +0,0 @@
package com.hzs.third.pay.jdpay.util;
import com.google.gson.reflect.TypeToken;
import com.hzs.third.pay.jdpay.sdk.JdPayNewConfig;
import com.hzs.third.pay.jdpay.sdk.JdPayConstant;
import com.hzs.third.pay.jdpay.sdk.JdPaySecurity;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/*************************************************
*
* 京东支付接口工具类
*
*************************************************/
public class JdPayApiUtil {
/**
* 加密和签名
*/
public static String encryptAndSignature(JdPayNewConfig jdPayNewConfig, String reqNo, String jsonParam) throws IOException {
// 组装公共请求参数
Map<String, String> commonParam = fillCommonParam(jdPayNewConfig.getMerchantNo(), reqNo);
// 加密
byte[] dataBytes = jsonParam.getBytes(StandardCharsets.UTF_8);
JdPaySecurity se = new JdPaySecurity();
String encData = se.signEnvelop(jdPayNewConfig.getPriCert(), jdPayNewConfig.getPriCertPwd(), jdPayNewConfig.getPubCert(), dataBytes);
commonParam.put(JdPayConstant.ENC_DATA, encData);
// 签名
String sign = SignUtil.sign(commonParam, JdPayConstant.SHA256, jdPayNewConfig.getSignKey(), JdPayConstant.UTF8);
commonParam.put(JdPayConstant.SIGN_DATA, sign);
return GsonUtil.toJson(commonParam);
}
/**
* 解密和验签
*/
public static String decryptAndVerifySign(JdPayNewConfig jdPayNewConfig, String respText) throws Exception {
Map<String, String> respMap = GsonUtil.fromJson(respText, new TypeToken<Map<String, String>>() {
});
String code = respMap.get(JdPayConstant.CODE);
if (!JdPayConstant.SUCCESS_CODE.equals(code)) {
return respText;
}
if (!respMap.containsKey(JdPayConstant.SIGN_DATA)) {
throw new Exception(String.format("No sign field in response: %s", respText));
}
String sign = respMap.remove(JdPayConstant.SIGN_DATA);
String signType = respMap.get(JdPayConstant.SIGN_TYPE);
String charset = respMap.get(JdPayConstant.CHARSET);
boolean isRespSignValid = SignUtil.verify(sign, respMap, signType, jdPayNewConfig.getSignKey(), charset);
if (!isRespSignValid) {
throw new Exception(String.format("Invalid sign value in response: %s", respText));
}
return SignUtil.decodeBase64(respMap.get(JdPayConstant.RESP_DATA), respMap.get(JdPayConstant.CHARSET), false, false);
}
/**
* 组装api公共参数赋值
*/
private static Map<String, String> fillCommonParam(String merchantNo, String reqNo) {
Map<String, String> reqMap = new HashMap<>();
// 二级商户号
reqMap.put(JdPayConstant.MERCHANT_NO, merchantNo);
//商户生成的唯一标识可以与outTradeNo一致
reqMap.put(JdPayConstant.REQ_NO, reqNo);
//字符集
reqMap.put(JdPayConstant.CHARSET, JdPayConstant.UTF8);
//固定值
reqMap.put(JdPayConstant.FORMAT_TYPE, JdPayConstant.JSON);
//签名类型
reqMap.put(JdPayConstant.SIGN_TYPE, JdPayConstant.SHA256);
//固定值证书加密
reqMap.put(JdPayConstant.ENC_TYPE, JdPayConstant.AP7);
return reqMap;
}
}

View File

@ -1,147 +0,0 @@
package com.hzs.third.pay.jdpay.util;
import com.hzs.third.pay.jdpay.sdk.JdPayConstant;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.BaseNCodec;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
public class SignUtil {
private static final String[] HEX_STRINGS;
static {
HEX_STRINGS = new String[256];
for (int i = 0; i < 256; i++) {
StringBuilder d = new StringBuilder(2);
char ch = Character.forDigit(((byte) i >> 4) & 0x0F, 16);
d.append(Character.toUpperCase(ch));
ch = Character.forDigit((byte) i & 0x0F, 16);
d.append(Character.toUpperCase(ch));
HEX_STRINGS[i] = d.toString();
}
}
/**
* 计算签名
*
* @param map 有key和value的map使用=&拼接所有参数
* "sign_type", "sign_data", "encrypt_type", "encrypt_data"不参加计算
* @param algorithm 签名算法 MD5, SHA-1, SHA-256
* @param salt 签名密钥
* @param charset 字符串编码
* @return 签名
*/
public static String sign(Map<String, String> map, String algorithm, String salt, String charset) throws UnsupportedEncodingException {
String linkString = map2LinkString(map);
String data = linkString + salt;
return digestHex(algorithm, data, charset);
}
/**
* 验证签名正确性
*
* @param sign 签名数据
* @param map 数据
* @param algorithm 签名算法 MD5, SHA-1, SHA-256
* @param salt 签名密钥
* @param charset 字符串
* @return 验证结果
*/
public static boolean verify(String sign,
Map<String, String> map,
String algorithm,
String salt,
String charset) throws UnsupportedEncodingException {
if (sign == null || "".equals(sign.trim()) || map.size() == 0) {
return false;
}
String newSign = sign(map, algorithm, salt, charset);
return newSign.equals(sign);
}
/**
* 验证页面回调
*
* @param respMap 页面回调参数
* @param signKey signKey
* @return 验证结果
* @throws NoSuchAlgorithmException
*/
public static boolean verifyPageCallBackSign(Map<String, String> respMap, String signKey) throws UnsupportedEncodingException {
String sign = respMap.remove("sign");
String newSign = sign(respMap, JdPayConstant.SHA256, signKey, JdPayConstant.UTF8);
return newSign.equals(sign);
}
/**
* 将MAP数据用=&拼接成String
*
* @param map 数据
* @return 字符串
*/
public static String map2LinkString(Map<String, String> map) {
ArrayList<String> mapKeys = new ArrayList<String>(map.keySet());
Collections.sort(mapKeys);
StringBuilder link = new StringBuilder(2048);
for (String key : mapKeys) {
String value = map.get(key);
// 属性为空不参与签名
if (value == null || "".equals(value.trim())) {
continue;
}
link.append(key).append("=").append(value).append("&");
}
// 删除末尾的&
link.deleteCharAt(link.length() - 1);
return link.toString();
}
/**
* 对数据进行指定算法的数据摘要
*
* @param algorithm 算法名如MD2, MD5, SHA-1, SHA-256, SHA-512
* @param data 待计算的数据
* @param charset 字符串的编码
* @return 摘要结果
*/
public static String digestHex(String algorithm, String data, String charset) throws UnsupportedEncodingException {
byte[] digest = DigestUtils.getDigest(algorithm).digest(data.getBytes(charset));
return hexString(digest);
}
/**
* 将字节数组转换成HEX String
*
* @param b
* @return HEX String
*/
public static String hexString(byte[] b) {
StringBuilder d = new StringBuilder(b.length * 2);
for (byte aB : b) {
d.append(HEX_STRINGS[(int) aB & 0xFF]);
}
return d.toString();
}
/**
* 对数据进行BASE64解码
*
* @param base64Data Base64数据
* @param charset 解码的编码格式
* @param urlSafe 是否是URL安全的如果为true则将会被URL编码的'+', '/'转成'-', '_'
* @param oneLine 是否是一行
* @return 解码后数据
*/
public static String decodeBase64(String base64Data, String charset, boolean urlSafe, boolean oneLine) throws UnsupportedEncodingException {
Base64 base64 = oneLine ? new Base64(BaseNCodec.MIME_CHUNK_SIZE, null, urlSafe) : new Base64(urlSafe);
byte[] binaryData = base64.decode(base64Data);
return new String(binaryData, charset);
}
}

View File

@ -14,11 +14,7 @@ import java.util.HashMap;
import java.util.Map;
/**
* @Description: 汇付支付启支配置
* @Author: jiang chao
* @Time: 2023/2/13 14:37
* @Classname: AdaPayLoadListener
* @PackageName: com.hzs.web.ada.listener
* 汇付支付启支配置
*/
//@Component
@Slf4j

View File

@ -12,11 +12,7 @@ import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @Description: 汇付新支付地启动配置
* @Author: jiang chao
* @Time: 2024/12/5 11:09
* @Classname: HuiFuLoadListener
* @PackageName: com.hzs.third.pay.listener
* 汇付新支付地启动配置
*/
//@Component
@Slf4j

View File

@ -1,27 +0,0 @@
package com.hzs.third.pay.service;
import com.hzs.common.core.domain.R;
import com.hzs.common.domain.third.pay.TOnlinePayment;
/**
* 阿里支付服务
*/
public interface IAliPayService {
/**
* 扫码预下单
*
* @param onlinePayment
* @return
*/
R<String> prePayScan(TOnlinePayment onlinePayment);
/**
* H5预下单
*
* @param onlinePayment
* @return
*/
R<String> prePayH5(TOnlinePayment onlinePayment);
}

View File

@ -1,38 +0,0 @@
package com.hzs.third.pay.service;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.EDataSource;
import com.hzs.common.domain.third.pay.TOnlinePayment;
/**
* 京东支付服务
*/
public interface IJdPayService {
/**
* 扫码支付
*
* @param onlinePayment
* @return
*/
R<String> scanPay(TOnlinePayment onlinePayment);
/**
* 银行卡支付
*
* @param onlinePayment
* @param bindCode
* @return
*/
R<String> bankPay(TOnlinePayment onlinePayment, String bindCode);
/**
* 收银台支付
*
* @param onlinePayment
* @param dataSource
* @return
*/
R<String> cashRegister(TOnlinePayment onlinePayment, EDataSource dataSource);
}

View File

@ -34,24 +34,6 @@ public interface IRefundService {
*/
String baoFuRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment);
/**
* 京东退款处理
*
* @param refundDTO 业务类型
* @param tOnlinePayment 退款对应支付信息
* @return
*/
String jdRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment);
/**
* 京东收银台退款处理
*
* @param refundDTO 业务类型
* @param tOnlinePayment 退款对应支付信息
* @return
*/
String jdCashRefundHandle(RefundDTO refundDTO, TOnlinePayment tOnlinePayment);
/**
* 通联退款处理
*

View File

@ -8,28 +8,28 @@ import com.hzs.common.domain.third.pay.TOnlinePayment;
*/
public interface ISandPayService {
/**
* 扫码支付微信支付宝
*
* @param onlinePayment 在线支付信息
* @return
*/
R<String> scanPay(TOnlinePayment onlinePayment);
/**
* H5微信支付
*
* @param onlinePayment 在线支付信息
* @return
*/
R<String> weChatH5(TOnlinePayment onlinePayment);
/**
* H5支付宝支付
*
* @param onlinePayment 在线支付信息
* @return
*/
R<String> aliH5(TOnlinePayment onlinePayment);
// /**
// * 扫码支付微信支付宝
// *
// * @param onlinePayment 在线支付信息
// * @return
// */
// R<String> scanPay(TOnlinePayment onlinePayment);
//
// /**
// * H5微信支付
// *
// * @param onlinePayment 在线支付信息
// * @return
// */
// R<String> weChatH5(TOnlinePayment onlinePayment);
//
// /**
// * H5支付宝支付
// *
// * @param onlinePayment 在线支付信息
// * @return
// */
// R<String> aliH5(TOnlinePayment onlinePayment);
}

View File

@ -1,44 +0,0 @@
package com.hzs.third.pay.service;
import com.hzs.common.core.domain.R;
import com.hzs.common.domain.third.pay.TOnlinePayment;
/**
* 微信支付服务
*/
public interface IWeChatPayService {
/**
* 扫码预下单
*
* @param onlinePayment
* @return
*/
R<String> prePayScan(TOnlinePayment onlinePayment);
/**
* H5预下单
*
* @param onlinePayment
* @return
*/
R<String> prePayH5(TOnlinePayment onlinePayment);
/**
* APP预下单
*
* @param onlinePayment
* @return
*/
R<Object> prePayAPP(TOnlinePayment onlinePayment);
// /**
// * 小程序下单
// *
// * @param onlinePayment
// * @param openId
// * @return
// */
// R<Object> prePayApplet(TOnlinePayment onlinePayment, String openId);
}

View File

@ -1,150 +0,0 @@
package com.hzs.third.pay.service.impl;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayResponse;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.hzs.common.core.constant.Constants;
import com.hzs.common.core.domain.R;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.third.pay.config.AliPayConfig;
import com.hzs.third.pay.service.IAliPayService;
import com.hzs.third.pay.util.AliPayUtil;
import com.hzs.third.pay.util.PayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 阿里支付服务
*/
@Slf4j
@Service
public class AliPayServiceImpl implements IAliPayService {
@Autowired
private AliPayConfig aliPayConfig;
/**
* 扫码预下单
*
* @param onlinePayment
* @return
*/
@Override
public R<String> prePayScan(TOnlinePayment onlinePayment) {
try {
// 与三方对接需要扩展支付订单号用于标记业务
String thirdOrderCode = PayUtil.getThirdOrderCode(onlinePayment.getBusinessCode(), null);
onlinePayment.setOriginalOrder(thirdOrderCode);
// 实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getServerUrl(), aliPayConfig.getAppId(), aliPayConfig.getPrivateKey(), aliPayConfig.getFormat(), Constants.UTF8, aliPayConfig.getPublicKey(), aliPayConfig.getSignType());
// PC支付实例化
AlipayTradePagePayRequest pcPayRequest = new AlipayTradePagePayRequest();
// 请求参数
JSONObject bizContent = new JSONObject();
// 商户订单号
bizContent.putOpt("out_trade_no", thirdOrderCode);
// 单位为元精确到小数点后两位
bizContent.putOpt("total_amount", onlinePayment.getPayMoney().toString());
// 订单标题
bizContent.putOpt("subject", "支付宝支付:" + onlinePayment.getBusinessCode());
// 支付宝会在异步通知时将该参数原样返回
bizContent.putOpt("passback_params", onlinePayment.getBusinessType());
// 销售产品码电脑支付场景FAST_INSTANT_TRADE_PAY
bizContent.putOpt("product_code", "FAST_INSTANT_TRADE_PAY");
// PC扫码支付的方式
bizContent.putOpt("qr_pay_mode", "4");
// 生成的扫码大小
bizContent.putOpt("qrcode_width", 200);
pcPayRequest.setBizContent(bizContent.toString());
pcPayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());
log.info("阿里PC支付请求参数 {}", JSONUtil.toJsonStr(pcPayRequest));
// 支付回调
AlipayResponse response = alipayClient.pageExecute(pcPayRequest);
log.info("阿里PC支付返回 {}", JSONUtil.toJsonStr(response));
if (response.isSuccess()) {
// 阿里返回PC订单信息
return R.ok(response.getBody());
} else {
// 返回错误结果
String resultError = AliPayUtil.handResultError(response);
if (null != resultError) {
log.error("阿里PC支付调用预下单失败 {}", resultError);
}
}
} catch (Exception e) {
log.error("阿里PC支付调用处理异常", e);
}
return R.fail("阿里PC支付调用处理失败");
}
/**
* H5预下单
*
* @param onlinePayment
* @return
*/
@Override
public R<String> prePayH5(TOnlinePayment onlinePayment) {
try {
// 与三方对接需要扩展支付订单号用于标记业务
String thirdOrderCode = PayUtil.getThirdOrderCode(onlinePayment.getBusinessCode(), null);
onlinePayment.setOriginalOrder(thirdOrderCode);
// 实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getServerUrl(), aliPayConfig.getAppId(), aliPayConfig.getPrivateKey(), aliPayConfig.getFormat(), Constants.UTF8, aliPayConfig.getPublicKey(), aliPayConfig.getSignType());
// APP支付实例化
AlipayTradeWapPayRequest appPayRequest = new AlipayTradeWapPayRequest();
// 请求参数
JSONObject bizContent = new JSONObject();
// 商户订单号
bizContent.putOpt("out_trade_no", thirdOrderCode);
// 单位为元精确到小数点后两位
bizContent.putOpt("total_amount", onlinePayment.getPayMoney().toString());
// 订单标题
bizContent.putOpt("subject", "支付宝支付:" + onlinePayment.getBusinessCode());
// 支付宝会在异步通知时将该参数原样返回
bizContent.putOpt("passback_params", onlinePayment.getBusinessType());
// 销售产品码手机支付场景QUICK_WAP_WAY
bizContent.putOpt("product_code", "QUICK_WAP_WAY");
appPayRequest.setBizContent(bizContent.toString());
appPayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());
log.info("阿里H5支付请求参数 {}", JSONUtil.toJsonStr(appPayRequest));
AlipayResponse response = alipayClient.pageExecute(appPayRequest);
log.info("阿里H5支付返回 {}", JSONUtil.toJsonStr(response));
if (response.isSuccess()) {
// 阿里返回APP订单信息
return R.ok(response.getBody());
} else {
// 返回错误结果
String resultError = AliPayUtil.handResultError(response);
if (null != resultError) {
log.error("阿里H5支付调用预下单失败 {}", resultError);
}
}
} catch (Exception e) {
log.error("阿里H5支付调用处理异常", e);
}
return R.fail("阿里H5支付调用处理失败");
}
}

View File

@ -1,264 +0,0 @@
package com.hzs.third.pay.service.impl;
import cn.hutool.json.JSONUtil;
import com.hzs.common.core.config.BdConfig;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.EBindStatus;
import com.hzs.common.core.enums.EDataSource;
import com.hzs.common.core.enums.EEnv;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.third.pay.TOnlineCard;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.third.pay.config.JdPayConfig;
import com.hzs.third.pay.constants.JdPayConstants;
import com.hzs.third.pay.constants.PayRedisConstants;
import com.hzs.third.pay.dto.jd.JdFastDTO;
import com.hzs.third.pay.dto.jd.JdFastResult;
import com.hzs.third.pay.dto.jd.JdScanDTO;
import com.hzs.third.pay.dto.jd.JdScanResult;
import com.hzs.third.pay.enums.EJdAppType;
import com.hzs.third.pay.enums.EJdTerminalType;
import com.hzs.third.pay.jdpay.dto.JdPayAggregateCreateOrderRequest;
import com.hzs.third.pay.jdpay.dto.JdPayAggregateCreateOrderResponse;
import com.hzs.third.pay.jdpay.sdk.JdPay;
import com.hzs.third.pay.service.IJdPayService;
import com.hzs.third.pay.service.ITOnlineCardService;
import com.hzs.third.pay.util.JdPayUtil;
import com.hzs.third.pay.util.PayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.concurrent.TimeUnit;
/**
* 京东支付服务
*/
@Slf4j
@Service
public class JdPayServiceImpl implements IJdPayService {
@Autowired
private JdPayConfig jdPayConfig;
@Autowired
private ITOnlineCardService itOnlineCardService;
@Resource
private JdPay jdPay;
@Autowired
private RedisTemplate redisTemplate;
/**
* 页面回调地址
*/
@Value("${jd.pay.pageBackUrl}")
private String pageBackUrl;
/**
* 支付回调地址
*/
@Value("${jd.pay.notifyUrl}")
private String notifyUrl;
@Override
public R<String> scanPay(TOnlinePayment onlinePayment) {
try {
// 京东付款码缓存KEY
String scanKey = String.format(PayRedisConstants.JD_SCAN_KEY, onlinePayment.getBusinessType(), onlinePayment.getBusinessCode());
if (redisTemplate.hasKey(scanKey)) {
Object payInfo = redisTemplate.opsForValue().get(scanKey);
if (null != payInfo) {
return R.ok(payInfo.toString());
}
}
// 生成请求实体
JdScanDTO jdScan = JdScanDTO.builder()
// 商户编号
.customerNum(jdPayConfig.getCustomerNum())
// 店铺编号
.shopNum(jdPayConfig.getShopNum())
// 回调地址
.callbackUrl(jdPayConfig.getCallbackUrl())
// 商户订单号
.requestNum(onlinePayment.getBusinessCode())
// 订单金额
.amount(onlinePayment.getPayMoney().toString())
// 固定传入API
.source("API")
// 扩展信息
.extraInfo(onlinePayment.getBusinessType().toString())
.build();
String body = JSONUtil.toJsonStr(jdScan);
log.info("京东扫码支付请求参数: {}", body);
String postResult = JdPayUtil.requestOrder(JdPayConstants.METHOD_SCAN, body, jdPayConfig.getSecretKey(), jdPayConfig.getAccessKey());
log.info("京东扫码支付返回数据: {}", postResult);
// 返回结果
JdScanResult scanResult = JSONUtil.toBean(postResult, JdScanResult.class);
if (JdPayConstants.RESULT_SUCCESS.equals(scanResult.getResult())) {
// 请求成功返回二维码
String qrCode = scanResult.getData().getUrl();
// 付款码redis保存24小时
redisTemplate.opsForValue().set(scanKey, qrCode, 24, TimeUnit.HOURS);
return R.ok(qrCode);
}
log.info("京东扫码支付返回失败");
} catch (Exception e) {
log.error("京东扫码支付返回异常", e);
}
return R.fail("京东扫码支付返回失败");
}
@Override
public R<String> bankPay(TOnlinePayment onlinePayment, String bindCode) {
try {
// 与三方对接需要扩展支付订单号用于标记业务
String thirdOrderCode = PayUtil.getThirdOrderCode(onlinePayment.getBusinessCode(), null);
onlinePayment.setOriginalOrder(thirdOrderCode);
TOnlineCard tOnlineCard = itOnlineCardService.queryCardByCode(bindCode, onlinePayment.getPkModified(), jdPayConfig.getCustomerNum(), onlinePayment.getPkCountry());
if (null == tOnlineCard || EBindStatus.BIND.getValue() != tOnlineCard.getBindStatus()) {
return R.fail("用户未绑定该银行卡");
}
JdFastDTO jdFastDTO = JdFastDTO.builder()
.version(JdPayConstants.PAY_VERSION)
// 商户编号
.customerNum(jdPayConfig.getCustomerNum())
// 店铺编号
.shopNum(jdPayConfig.getShopNum())
// 回调地址
.callbackUrl(jdPayConfig.getCallbackUrl())
.clientIp(InetAddress.getLocalHost().getHostAddress())
// 商户订单号
.requestNum(thirdOrderCode)
// 订单金额
.orderAmount(onlinePayment.getPayMoney().toString())
// 用户编号
.userId(onlinePayment.getPkModified().toString())
// 绑卡ID
.bindId(tOnlineCard.getBindId())
.goodsName("购买商品")
.goodsQuantity("1")
// 终端类型
.terminalType(EJdTerminalType.OTHER.getLabel())
// 终端标记
.terminalId(JdPayConstants.TERMINAL_ID)
// 用户注册账号
.userAccount(JdPayConstants.USER_ACCOUNT)
.appType(EJdAppType.H5.getLabel())
.appName(JdPayConstants.APP_NAME)
.tradeScene(JdPayConstants.FAST_TRADESCENE_QUICKPAY)
.source("API")
// 设置订单24小时失效
.period("24")
.periodUnit("Hour")
.extraInfo(onlinePayment.getBusinessType().toString())
.build();
String body = JSONUtil.toJsonStr(jdFastDTO);
log.info("京东银行卡下单请求参数: {}", body);
String postResult = JdPayUtil.requestOrder(JdPayConstants.METHOD_PRE_ORDER, body, jdPayConfig.getSecretKey(), jdPayConfig.getAccessKey());
log.info("京东银行卡下单返回数据: {}", postResult);
// 返回结果
JdFastResult fastResult = JSONUtil.toBean(postResult, JdFastResult.class);
if (fastResult.isSuccess() && JdPayConstants.RESULT_SUCCESS.equals(fastResult.getCode())) {
// 返回成功
return R.ok();
}
log.error("京东银行卡下单返回失败: {}", fastResult.getMsg());
} catch (Exception e) {
log.error("京东银行卡下单异常!", e);
}
return R.fail("京东银行卡下单返回失败");
}
@Override
public R<String> cashRegister(TOnlinePayment onlinePayment, EDataSource dataSource) {
try {
// 交易场景ONLINE_APP线上移动端 ONLINE_PC:线上PC
String sceneType = "ONLINE_APP";
// 交易类型AGGRE聚合收银台 AGGRE_QRPC扫码
String tradeType = "AGGRE";
if (null != dataSource && EDataSource.PC.getValue().equals(dataSource.getValue())) {
sceneType = "ONLINE_PC";
tradeType = "AGGRE_QR";
}
String userId = onlinePayment.getPkCreator().toString();
if (EEnv.TEST.getValue().equals(BdConfig.getEnv())) {
userId = "T_" + userId;
}
JdPayAggregateCreateOrderRequest request = JdPayAggregateCreateOrderRequest.builder()
// 商户订单号最大32位
.outTradeNo(onlinePayment.getBusinessCode())
// 订单总金额单位
.tradeAmount(onlinePayment.getPayMoney().multiply(new BigDecimal("100")).intValue() + "")
// 订单创建时间最大14位yyyyMMddHHmmss
.createDate(DateUtils.parseDateToFormat(DateUtils.YAMMERERS, onlinePayment.getCreationTime()))
// 订单有效时长分钟
.tradeExpiryTime("1440")
// 交易名称
.tradeSubject("支付:" + onlinePayment.getBusinessCode())
// 交易描述
.tradeRemark("支付:" + onlinePayment.getBusinessCode())
// 币种
.currency("CNY")
// 用户IP
.userIp(InetAddress.getLocalHost().getHostAddress())
// 通道业务类型
.bizTp("100001")
// 回传字段
.returnParams(onlinePayment.getBusinessType().toString())
// 用户标识收银台必传
.userId(userId)
// 同步通知URL收银台必传页面回调地址
.pageBackUrl(this.pageBackUrl)
// 支付回调地址
.notifyUrl(this.notifyUrl)
// 交易类型
.tradeType(tradeType)
// 交易场景ONLINE_APP线上移动端 ONLINE_PC:线上PC
.sceneType(sceneType)
.build();
// 请求京东支付接口
JdPayAggregateCreateOrderResponse response = jdPay.aggregateCreateOrder(request);
if ("0000".equals(response.getResultCode())) {
// 请求响应成功
// 京东唯一订单号
onlinePayment.setPayNumber(response.getTradeNo());
if ("AGGRE_QR".equals(tradeType)) {
return R.ok(response.getQrCode());
}
return R.ok(response.getWebUrl());
} else {
log.error("京东收银台返回失败resultDesc: {}", response.getResultDesc());
return R.fail("调用京东收银台返回失败");
}
} catch (Exception e) {
log.error("京东收银台处理异常!", e);
return R.fail("京东收银台处理异常");
}
}
}

Some files were not shown because too many files have changed in this diff Show More