diff --git a/ghy-common/pom.xml b/ghy-common/pom.xml
index 968f3cdb..a1029ff3 100644
--- a/ghy-common/pom.xml
+++ b/ghy-common/pom.xml
@@ -116,6 +116,35 @@
javax.servlet-api
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+
+
+ com.huifu.adapay.core
+ adapay-core-sdk
+
+
+ com.huifu.adapay
+ adapay-java-sdk
+
+
+
+
+ org.apache.httpcomponents
+ httpmime
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+
+
\ No newline at end of file
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/AdapayAutoConfiguration.java b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayAutoConfiguration.java
new file mode 100644
index 00000000..64c69c72
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayAutoConfiguration.java
@@ -0,0 +1,22 @@
+package com.ghy.common.adapay;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Adapay 自动装载
+ *
+ * @author HH 2022/3/25
+ */
+@Configuration
+@EnableConfigurationProperties(AdapayProperties.class)
+public class AdapayAutoConfiguration {
+
+ @Bean
+ public AdapayService adapayService(AdapayProperties adapayProperties) {
+ AdapayService adapayService = new AdapayService();
+ adapayService.setAdapayProperties(adapayProperties);
+ return adapayService;
+ }
+}
\ No newline at end of file
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/AdapayProperties.java b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayProperties.java
new file mode 100644
index 00000000..19583146
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayProperties.java
@@ -0,0 +1,58 @@
+package com.ghy.common.adapay;
+
+import com.huifu.adapay.Adapay;
+import com.huifu.adapay.model.MerConfig;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.util.Assert;
+
+/**
+ * Adapay 配置类
+ *
+ * @author HH 2022/3/25
+ */
+@Data
+@Slf4j
+@ConfigurationProperties("adapay")
+public class AdapayProperties implements InitializingBean {
+
+ /**
+ * 是否打印调用日志,默认不打印
+ */
+ private boolean debug = false;
+
+ /**
+ * 是否是prod_mode 默认为 true
+ */
+ private boolean prodMode = true;
+
+ private String appId;
+ private String notifyUrl;
+
+ /**
+ * 初始化商户配置,服务器启动前,必须通过该方式初始化商户配置完成
+ * apiKey为prod模式的API KEY
+ * mockApiKey为mock模式的API KEY
+ * rsaPrivateKey为商户发起请求时,用于请求参数加签所需要的RSA私钥
+ */
+ private String apiKey;
+ private String mockApiKey;
+ private String rsaPrivateKey;
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ log.info("Adapay.debug={}, Adapay.prodMode={}", debug, prodMode);
+ Assert.hasText(appId, "Adapay.appId is blank!");
+ Assert.hasText(apiKey, "Adapay.apiKey is blank!");
+ Assert.hasText(mockApiKey, "Adapay.mockApiKey is blank!");
+ Assert.hasText(rsaPrivateKey, "Adapay.rsaPrivateKey is blank!");
+
+ MerConfig merConfig = new MerConfig();
+ merConfig.setApiKey(apiKey);
+ merConfig.setApiMockKey(mockApiKey);
+ merConfig.setRSAPrivateKey(rsaPrivateKey);
+ Adapay.initWithMerConfig(merConfig);
+ }
+}
\ No newline at end of file
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/AdapayService.java b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayService.java
new file mode 100644
index 00000000..82e4f35a
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/AdapayService.java
@@ -0,0 +1,43 @@
+package com.ghy.common.adapay;
+
+import com.ghy.common.adapay.callback.PayCallback;
+import com.huifu.adapay.core.exception.BaseAdaPayException;
+import com.huifu.adapay.model.Payment;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author HH 2022/3/25
+ */
+@Slf4j
+@Setter
+public class AdapayService {
+
+ AdapayProperties adapayProperties;
+
+ /**
+ * @param callback 处理支付结果的回调接口
+ * @param orderNo 订单号
+ * @param payAmt 支付金额
+ * @param goodsTittle 商品名称
+ * @param goodsDesc 商品描述
+ * @param description 订单附加说明
+ */
+ public Map wxLitePay(PayCallback callback, String orderNo, String payAmt, String goodsTittle, String goodsDesc, String description) throws BaseAdaPayException {
+ Map paymentParams = new HashMap<>(10);
+ paymentParams.put("app_id", adapayProperties.getAppId());
+ paymentParams.put("notify_url", adapayProperties.getNotifyUrl());
+ paymentParams.put("order_no", orderNo);
+ paymentParams.put("pay_channel", PayChannelEnum.WX_LITE.getCode());
+ paymentParams.put("pay_amt", payAmt);
+ paymentParams.put("goods_title", goodsTittle);
+ paymentParams.put("goods_desc", goodsDesc);
+ paymentParams.put("description", description);
+ PayResultMapping.putCallback(orderNo, callback);
+ return Payment.create(paymentParams);
+ }
+
+}
\ No newline at end of file
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/EventEnum.java b/ghy-common/src/main/java/com/ghy/common/adapay/EventEnum.java
new file mode 100644
index 00000000..3fbe34de
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/EventEnum.java
@@ -0,0 +1,49 @@
+package com.ghy.common.adapay;
+
+/**
+ * Event时间枚举
+ *
+ * @author HH 2022/3/25
+ */
+public enum EventEnum {
+
+ PAY_SUCCEEDED("payment.succeeded", "支付成功"),
+ PAY_FAILED("payment.failed", "支付失败"),
+
+ PAY_CLOSE_SUCCEEDED("payment.close.succeeded", "关闭支付订单成功"),
+ PAY_CLOSE_FAILED("payment.close.failed", "关闭支付订单失败"),
+
+ REFUND_SUCCEEDED("refund.succeeded", "退款成功"),
+ REFUND_FAILED("refund.failed", "退款失败"),
+
+ CORP_MEMBER_SUCCEEDED("corp_member.succeeded", "开户成功"),
+ CORP_MEMBER_FAILED("corp_member.failed", "开户失败"),
+
+ PAYMENT_REVERSE_SUCCEEDED("payment_reverse.succeeded", "支付撤销成功"),
+ PAYMENT_REVERSE_FAILED("payment_reverse.failed", "支付撤销失败"),
+
+ CASH_SUCCEEDED("cash.succeeded", "取现成功"),
+ CASH_FAILED("cash.failed", "取现失败"),
+
+ ACCOUNT_PAYMENT_SUCCEEDED("account_payment.succeeded", "钱包支付成功"),
+ ACCOUNT_PAYMENT_FAILED("account_payment.failed", "钱包支付失败"),
+
+ FASTPAY_SUCCEEDED("fastpay.succeeded", "快捷支付成功"),
+ FASTPAY_FAILED("fastpay.failed", "快捷支付失败");
+
+ private final String type;
+ private final String description;
+
+ EventEnum(String type, String description) {
+ this.type = type;
+ this.description = description;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/PayChannelEnum.java b/ghy-common/src/main/java/com/ghy/common/adapay/PayChannelEnum.java
new file mode 100644
index 00000000..dd3189a1
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/PayChannelEnum.java
@@ -0,0 +1,28 @@
+package com.ghy.common.adapay;
+
+/**
+ * 支付渠道
+ *
+ * @author HH 2022/3/25
+ */
+public enum PayChannelEnum {
+
+ ALIPAY_QR("alipay_qr", "支付宝正扫"),
+ WX_LITE("wx_lite", "wx_lite");
+
+ private final String code;
+ private final String description;
+
+ PayChannelEnum(String code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/PayResultMapping.java b/ghy-common/src/main/java/com/ghy/common/adapay/PayResultMapping.java
new file mode 100644
index 00000000..4b13ce03
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/PayResultMapping.java
@@ -0,0 +1,40 @@
+package com.ghy.common.adapay;
+
+import com.alibaba.fastjson.JSON;
+import com.ghy.common.adapay.callback.Event;
+import com.ghy.common.adapay.callback.PayCallback;
+import com.huifu.adapay.model.Payment;
+import org.springframework.util.Assert;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 支付结果匹配池
+ *
+ * @author HH 2022/3/25
+ */
+public class PayResultMapping {
+
+ /**
+ * 临时保存支付结果
+ * key: orderNo
+ * value: 处理支付结果的回调接口
+ */
+ private final static ConcurrentHashMap PAY_RESULT_CALLBACK_MAP = new ConcurrentHashMap<>(1024);
+
+ public static void putResult(Event event) {
+ String data = event.getData();
+ Payment payment = JSON.parseObject(data, Payment.class);
+ Assert.hasText(payment.getOrderNo(), "orderNo is blank !!!");
+ PayCallback callback = PAY_RESULT_CALLBACK_MAP.remove(payment.getOrderNo());
+ if (callback != null) {
+ callback.onResponse(payment);
+ }
+ }
+
+ public static void putCallback(String orderNo, PayCallback callback) {
+ Assert.hasText(orderNo, "orderNo is blank !!!");
+ Assert.notNull(callback, "PayCallback is null !!!");
+ PAY_RESULT_CALLBACK_MAP.put(orderNo, callback);
+ }
+}
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/callback/AdapayCallbackController.java b/ghy-common/src/main/java/com/ghy/common/adapay/callback/AdapayCallbackController.java
new file mode 100644
index 00000000..c5eebe74
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/callback/AdapayCallbackController.java
@@ -0,0 +1,71 @@
+package com.ghy.common.adapay.callback;
+
+import com.ghy.common.adapay.PayResultMapping;
+import com.huifu.adapay.core.AdapayCore;
+import com.huifu.adapay.core.util.AdapaySign;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.Assert;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 提供给 Adapay 的回调接口
+ *
+ * @author HH 2022/3/25
+ */
+@Slf4j
+@RestController
+public class AdapayCallbackController {
+
+ @PostMapping("/adapay/callback")
+ public String callback(@RequestBody Event event) {
+ //验签请参data
+ String data = event.getData();
+ //验签请参sign
+ String sign = event.getSign();
+ boolean verifySign = false;
+ try {
+ verifySign = verifySign(data, sign);
+ } catch (Exception e) {
+ log.error("签名验证失败 {}", e.getMessage());
+ }
+ if (verifySign) {
+ //Event事件类型
+ String type = event.getType();
+ if (StringUtils.isBlank(type)) {
+ return "NG";
+ }
+ switch (type) {
+ case "payment.succeeded":
+ case "payment.failed":
+ PayResultMapping.putResult(event);
+ break;
+ default:
+ log.warn("UNKNOWN EVENT TYPE [{}]", type);
+ return "NG";
+ }
+ return "OK";
+ }
+ log.warn("签名验证失败 data=[{}], sign=[{}]", data, sign);
+ return "NG";
+ }
+
+ /**
+ * 校验签名
+ *
+ * @param data AdapayCallback.data
+ * @param sign AdapayCallback.sign
+ * @return TRUE=校验成功
+ */
+ private boolean verifySign(String data, String sign) throws Exception {
+ Assert.hasText(data, "data is blank!");
+ Assert.hasText(sign, "sign is blank!");
+ //验签请参publicKey
+ String publicKey = AdapayCore.PUBLIC_KEY;
+ log.debug("验签请参:data={}sign={}", data, sign);
+ //验签
+ return AdapaySign.verifySign(data, sign, publicKey);
+ }
+}
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/callback/Event.java b/ghy-common/src/main/java/com/ghy/common/adapay/callback/Event.java
new file mode 100644
index 00000000..269d7949
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/callback/Event.java
@@ -0,0 +1,40 @@
+package com.ghy.common.adapay.callback;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+/**
+ * 支付结果
+ *
+ * @author HH 2022/3/25
+ */
+@Data
+public class Event {
+
+ /**
+ * 由 Adapay 生成的支付对象 id, 该 id 在 Adapay 系统内唯一
+ */
+ private String id;
+ /**
+ * 签名
+ */
+ private String sign;
+ /**
+ * 支付创建时的 10 位时间戳
+ */
+ @JSONField(name = "created_time")
+ private Long createdTime;
+ /**
+ * 是否 prod模式,true 是 prod模式,false 是 mock模式
+ */
+ @JSONField(name = "created_time")
+ private String prodMode;
+ /**
+ * Event 事件类型
+ */
+ private String type;
+ /**
+ * 支付对象
+ */
+ private String data;
+}
\ No newline at end of file
diff --git a/ghy-common/src/main/java/com/ghy/common/adapay/callback/PayCallback.java b/ghy-common/src/main/java/com/ghy/common/adapay/callback/PayCallback.java
new file mode 100644
index 00000000..35800b94
--- /dev/null
+++ b/ghy-common/src/main/java/com/ghy/common/adapay/callback/PayCallback.java
@@ -0,0 +1,13 @@
+package com.ghy.common.adapay.callback;
+
+import com.huifu.adapay.model.Payment;
+
+/**
+ * 处理支付结果的回调接口
+ *
+ * @author HH 2022/3/25
+ */
+public interface PayCallback {
+
+ void onResponse(Payment payment);
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8002d1f6..855ff8ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,8 @@
7.4.0
2.8.5
0.4.3
+ 1.2.10
+ 4.5.13
@@ -199,6 +201,32 @@
${fastjson.version}
+
+
+ com.huifu.adapay.core
+ adapay-core-sdk
+ ${Adapay.version}
+
+
+ com.huifu.adapay
+ adapay-java-sdk
+ ${Adapay.version}
+
+
+
+
+ org.apache.httpcomponents
+ httpmime
+ ${httpcomponents.version}
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpcomponents.version}
+
+
org.apache.logging.log4j