## 去掉微信、支付宝官方支付;去掉京东支付;去掉图片、视频压缩依赖包引入;
This commit is contained in:
parent
8cddbcde89
commit
4fbffd1544
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"),
|
||||
|
||||
/**
|
||||
* 宝付
|
||||
*/
|
||||
|
|
|
@ -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 Second,简:FPS)或“赫兹”(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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
}
|
|
@ -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";
|
||||
// 通联银行卡
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("解绑失败,请刷新后重试");
|
||||
}
|
||||
|
||||
}
|
|
@ -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("退款异常,请刷新后重试");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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)) {
|
||||
|
|
|
@ -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 +
|
||||
"×tamp=" + request.getHeader("timestamp") +
|
||||
"&body=" + reqBody;
|
||||
String tokenCheck = SecureUtil.sha1(shaStr).toUpperCase();
|
||||
return tokenCheck.equals(request.getHeader("token"));
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package com.hzs.third.pay.dto.jd;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 京东查询订单错误返回
|
||||
*/
|
||||
@Data
|
||||
public class JdAgentQueryError {
|
||||
|
||||
/**
|
||||
* 错误编码
|
||||
*/
|
||||
private String errorCode;
|
||||
/**
|
||||
* 错误内容
|
||||
*/
|
||||
private String errorMsg;
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
/**
|
||||
* 订单有效单位(Day:天,Hour:时,Minute:分)
|
||||
*/
|
||||
private String periodUnit;
|
||||
|
||||
/**
|
||||
* 扩展字段(长度:32)
|
||||
*/
|
||||
private String extraInfo;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package com.hzs.third.pay.dto.jd;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 京东扫码返回Data
|
||||
*/
|
||||
@Data
|
||||
public class JdScanResultData {
|
||||
|
||||
/**
|
||||
* 扫码URL
|
||||
*/
|
||||
private String url;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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("读取京东支付商户公钥证书为空");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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);
|
||||
// }
|
||||
}
|
|
@ -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/";
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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("验签异常");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* 通联退款处理
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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支付调用处理失败");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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_QR:PC扫码)
|
||||
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
Loading…
Reference in New Issue