From 3790b8ee7235f340d4f077f25bf3c98685697b06 Mon Sep 17 00:00:00 2001 From: xupei Date: Wed, 15 May 2024 15:38:11 +0800 Subject: [PATCH] =?UTF-8?q?Alipay-HK=20=E5=88=9B=E5=BB=BA=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=92=8C=E5=BC=82=E6=AD=A5=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 + .../da/common/constant/AlipayHKConstant.java | 20 ++ .../com/ai/da/common/enums/PayTypeEnum.java | 7 +- .../security/filter/AuthenticationFilter.java | 2 +- .../common/utils/AlipayHKEncryptionUtil.java | 60 ++++- .../da/common/utils/AlipayHKRequestUtil.java | 22 +- .../ai/da/controller/AlipayHKController.java | 30 ++- .../da/mapper/primary/entity/PaymentInfo.java | 2 +- .../ai/da/model/dto/AlipayHKCallbackDTO.java | 30 +++ .../com/ai/da/service/AlipayHKService.java | 10 + .../com/ai/da/service/PaymentInfoService.java | 3 + .../da/service/impl/AlipayHKServiceImpl.java | 245 ++++++++++++++++-- .../service/impl/PaymentInfoServiceImpl.java | 41 ++- src/main/resources/alipay-hk.properties | 11 - src/main/resources/alipay-sandbox.properties | 7 + src/main/resources/application-dev.properties | 2 +- 16 files changed, 429 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/ai/da/common/constant/AlipayHKConstant.java create mode 100644 src/main/java/com/ai/da/model/dto/AlipayHKCallbackDTO.java delete mode 100644 src/main/resources/alipay-hk.properties diff --git a/pom.xml b/pom.xml index 21b1264b..f816c5ca 100644 --- a/pom.xml +++ b/pom.xml @@ -226,6 +226,12 @@ 2.17.1 + + com.stripe + stripe-java + 25.0.0 + + diff --git a/src/main/java/com/ai/da/common/constant/AlipayHKConstant.java b/src/main/java/com/ai/da/common/constant/AlipayHKConstant.java new file mode 100644 index 00000000..aa290cc1 --- /dev/null +++ b/src/main/java/com/ai/da/common/constant/AlipayHKConstant.java @@ -0,0 +1,20 @@ +package com.ai.da.common.constant; + +public class AlipayHKConstant { + + // 服务名 + public static final String CREATE_ORDER = "create_order"; + public static final String ORDER_DETAILS = "order_details"; + public static final String TRANSACTION_DETAILS = "transaction_details"; + public static final String GET_FILE = "get_file"; + public static final String CREATE_AUTO_DEBIT = "create_auto_debit"; + public static final String REFRESH_TRANSACTION_STATUS = "refresh_transaction_status"; + public static final String REFUND_TRANSACTION = "refund_transaction"; + + // 订单状态 + public static final String STATUS_NEW = "new"; + public static final String STATUS_WAIT = "wait"; + public static final String STATUS_PAID = "paid"; + public static final String STATUS_EXPIRED = "expired"; + public static final String STATUS_LIQUIDATED = "liquidated"; +} diff --git a/src/main/java/com/ai/da/common/enums/PayTypeEnum.java b/src/main/java/com/ai/da/common/enums/PayTypeEnum.java index 70067578..5bc14b21 100644 --- a/src/main/java/com/ai/da/common/enums/PayTypeEnum.java +++ b/src/main/java/com/ai/da/common/enums/PayTypeEnum.java @@ -19,7 +19,12 @@ public enum PayTypeEnum { /** * PayPal */ - PAYPAL("PayPal"); + PAYPAL("PayPal"), + + /** + * 香港支付宝 + */ + ALIPAY_HK("Alipay-HK"); /** * 类型 diff --git a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java index 9e404107..4256b8fe 100644 --- a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java +++ b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java @@ -49,7 +49,7 @@ public class AuthenticationFilter extends OncePerRequestFilter { "/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew", "/api/third/party/existNoLoginRequired","/api/third/party/getRedirectUrl", // "/api/python/chatStream", - "/api/python/flush","/api/account/healthy","/api/ali-pay/trade/notify","/api/paypal/ipn/back" + "/api/python/flush","/api/account/healthy","/api/ali-pay/trade/notify","/api/paypal/ipn/back","/api/alipay-hk/trade/notify" ); @Override diff --git a/src/main/java/com/ai/da/common/utils/AlipayHKEncryptionUtil.java b/src/main/java/com/ai/da/common/utils/AlipayHKEncryptionUtil.java index 205c7f94..5e8662a3 100644 --- a/src/main/java/com/ai/da/common/utils/AlipayHKEncryptionUtil.java +++ b/src/main/java/com/ai/da/common/utils/AlipayHKEncryptionUtil.java @@ -6,9 +6,16 @@ import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import lombok.extern.slf4j.Slf4j; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.crypto.signers.RSADigestSigner; +import org.bouncycastle.crypto.util.PublicKeyFactory; +import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; @@ -25,22 +32,24 @@ import java.util.HashMap; import java.util.UUID; @Slf4j +@Component public class AlipayHKEncryptionUtil { - @Value("${alipay.hk.merchant-id}") - private static String merchantId; + @Value("${alipayHK.merchantId}") + private String merchantId; - @Value("${alipay.hk.segment-id}") - private static String segmentId; + @Value("${alipayHK.segmentId}") + private String segmentId; - @Value("${alipay.hk.AESKey}") - private static String aesKey; + @Value("${alipayHK.AESKey}") + private String aesKey; - @Value("${alipay.hk.rsaPrivateKey}") - private static String privateKeyPath; + @Value("${alipayHK.rsaPrivateKey}") + private String privateKeyPath; + + @Value("${alipayHK.rsaPublicKey}") + private String publicKeyPath; - @Value("${alipay.hk.rsaPublicKey}") - private static String publicKeyPath; /** * 加密 @@ -55,7 +64,7 @@ public class AlipayHKEncryptionUtil { * @throws BadPaddingException * @throws IOException */ - public static AlipayHKRequestDTO AESCBCWithRSA(HashMap param, String serviceName) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { + public AlipayHKRequestDTO AESCBCWithRSA(HashMap param, String serviceName) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException { // Pre-shared secret key, DO NOT hardcode this key String key = aesKey; // The path to the rsa private key file, DO NOT save this key to a publicly accessible location @@ -187,7 +196,7 @@ public class AlipayHKEncryptionUtil { /** * 使用 AES 密钥和随机向量进行解密 */ - public static String decryptAES(String encryptedText, String iv) throws Exception { + public String decryptAES(String encryptedText, String iv) throws Exception { byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText); byte[] ivBytes = Base64.getDecoder().decode(iv); @@ -201,7 +210,7 @@ public class AlipayHKEncryptionUtil { return new String(decryptedBytes, StandardCharsets.UTF_8); } - public static void test() throws Exception { + public void test() throws Exception { // 加密数据 AlipayHKParametersDTO requestMessage = new AlipayHKParametersDTO(); requestMessage.setService("create_order"); @@ -326,4 +335,29 @@ public class AlipayHKEncryptionUtil { random.nextBytes(iv); return iv; } + + public Boolean signatureVerification(String data, String signatureBase64){ + + Base64.Decoder decoder = Base64.getDecoder(); + // Verify key + try { +// PublicKey publicKey = readPublicKey(new File(publicKeyPath)); + InputStreamReader isrPub = new InputStreamReader(new FileInputStream(publicKeyPath)); + PEMParser pemParserPub = new PEMParser(isrPub); + SubjectPublicKeyInfo pubInfo = (SubjectPublicKeyInfo) pemParserPub.readObject(); + AsymmetricKeyParameter pubKey = PublicKeyFactory.createKey(pubInfo); + // Verifying + RSADigestSigner verifier = new RSADigestSigner(new SHA256Digest()); + verifier.init(false, pubKey); + byte[] signMessageForVerifing = data.getBytes(); + byte[] signatureBase64ForVerifing = decoder.decode(signatureBase64); + verifier.update(signMessageForVerifing, 0, signMessageForVerifing.length); + Boolean verifyResult = verifier.verifySignature(signatureBase64ForVerifing); + return verifyResult; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + } diff --git a/src/main/java/com/ai/da/common/utils/AlipayHKRequestUtil.java b/src/main/java/com/ai/da/common/utils/AlipayHKRequestUtil.java index 331c01ed..771f5154 100644 --- a/src/main/java/com/ai/da/common/utils/AlipayHKRequestUtil.java +++ b/src/main/java/com/ai/da/common/utils/AlipayHKRequestUtil.java @@ -11,11 +11,13 @@ import java.time.Instant; import java.util.concurrent.TimeUnit; import com.alibaba.fastjson.JSONObject; +import org.springframework.stereotype.Component; @Slf4j +@Component public class AlipayHKRequestUtil { - public static String createOrder(AlipayHKRequestDTO alipayHKRequestDTO) throws IOException { + public String createOrder(AlipayHKRequestDTO alipayHKRequestDTO) throws IOException { OkHttpClient client = new OkHttpClient().newBuilder() .connectTimeout(30, TimeUnit.SECONDS) .pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒) @@ -32,22 +34,28 @@ public class AlipayHKRequestUtil { RequestBody body = RequestBody.create(mediaType, jsonString); Request request = new Request.Builder() -// .url("https://aqs-api.sandbox-codpayment.com") .url("https://aqs-api.sandbox-codpayment.com/v1/service") .method("POST", body) .addHeader("Content-Type", "application/json;charset=utf-8") .build(); - Response response = null; + Response response; String bodyString; try { -// log.info("generateSketchOrPrint请求入参content###{}", JSON.toJSONString(alipayHKRequestDTO, SerializerFeature.WriteMapNullValue)); response = client.newCall(request).execute(); + assert response.body() != null; + bodyString = response.body().string(); } catch (Exception e) { -// log.error("PythonService##generateSketchOrPrint异常###{}", ExceptionUtil.getThrowableList(ioException)); -// throw new BusinessException("generate.interface.error"); throw new BusinessException(e.getMessage()); } - return response.body().string(); + JSONObject jsonObject = JSONObject.parseObject(bodyString); + boolean success = (boolean) jsonObject.get("success"); + if (success){ + return bodyString; + } else { + String message = jsonObject.get("error_code").toString() + ":" + jsonObject.get("error"); + log.error("Alipay return message : {}", message); + throw new BusinessException("Alipay return message : " + message); + } } } diff --git a/src/main/java/com/ai/da/controller/AlipayHKController.java b/src/main/java/com/ai/da/controller/AlipayHKController.java index 9b2fca11..38f2da9b 100644 --- a/src/main/java/com/ai/da/controller/AlipayHKController.java +++ b/src/main/java/com/ai/da/controller/AlipayHKController.java @@ -1,22 +1,40 @@ package com.ai.da.controller; import com.ai.da.common.response.Response; +import com.ai.da.service.AlipayHKService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Map; @CrossOrigin @RestController -@RequestMapping("/api/ali-pay-hk") +@RequestMapping("/api/alipay-hk") @Api(tags = "网站支付 香港支付宝") @Slf4j public class AlipayHKController { - public Response createOrder(){ - return Response.success(); + @Resource + private AlipayHKService alipayHKService; + + @ApiOperation(value = "创建订单") + @PostMapping(value = "/createOrder") + public Response createOrder(@RequestParam Integer amount, @RequestParam String wallet) { + String order = alipayHKService.createOrder(amount, wallet); + return Response.success(order); + } + + @ApiOperation("支付通知") + @PostMapping("/trade/notify") + public String callback(@RequestParam Map params){ + return alipayHKService.callback(params); } + + + } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/PaymentInfo.java b/src/main/java/com/ai/da/mapper/primary/entity/PaymentInfo.java index 8557aa83..2d7cf881 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/PaymentInfo.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/PaymentInfo.java @@ -17,7 +17,7 @@ public class PaymentInfo extends BaseEntity{ private String tradeState;//交易状态 - private Integer payerTotal;//支付金额(分) + private Long payerTotal;//支付金额(元) private String content;//通知参数 } diff --git a/src/main/java/com/ai/da/model/dto/AlipayHKCallbackDTO.java b/src/main/java/com/ai/da/model/dto/AlipayHKCallbackDTO.java new file mode 100644 index 00000000..d1e40107 --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/AlipayHKCallbackDTO.java @@ -0,0 +1,30 @@ +package com.ai.da.model.dto; + +import lombok.Data; + +@Data +public class AlipayHKCallbackDTO { + + private String transaction_id; + + private Long amount; + + private String currency; + + private String payment_time; + + private String merchant_id; + + private String segment_id; + + private String out_trade_no; + + private String type; + + private String status; + + private String pid; + + private String subject; + +} diff --git a/src/main/java/com/ai/da/service/AlipayHKService.java b/src/main/java/com/ai/da/service/AlipayHKService.java index baf56c8e..47f06d2b 100644 --- a/src/main/java/com/ai/da/service/AlipayHKService.java +++ b/src/main/java/com/ai/da/service/AlipayHKService.java @@ -1,4 +1,14 @@ package com.ai.da.service; +import com.ai.da.model.dto.AlipayHKCallbackDTO; + +import java.util.Map; + public interface AlipayHKService { + + String createOrder(Integer amount, String wallet); + + String callback(Map params); + + void processOrder(AlipayHKCallbackDTO alipayHKCallbackDTO); } diff --git a/src/main/java/com/ai/da/service/PaymentInfoService.java b/src/main/java/com/ai/da/service/PaymentInfoService.java index 4a350dff..de9526b1 100644 --- a/src/main/java/com/ai/da/service/PaymentInfoService.java +++ b/src/main/java/com/ai/da/service/PaymentInfoService.java @@ -1,5 +1,6 @@ package com.ai.da.service; +import com.ai.da.model.dto.AlipayHKCallbackDTO; import com.paypal.orders.Order; import java.util.Map; @@ -11,4 +12,6 @@ public interface PaymentInfoService { void createPaymentInfoForAliPay(Map params); void createPaymentInfoForPayPal(Order order); + + void createPaymentInfoForAliPayHK(AlipayHKCallbackDTO alipayHKCallbackDTO); } diff --git a/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java b/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java index 4445c6cb..0876991a 100644 --- a/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java @@ -1,50 +1,113 @@ package com.ai.da.service.impl; +import com.ai.da.common.constant.AlipayHKConstant; import com.ai.da.common.enums.CreditsEventsEnum; -import com.ai.da.service.AlipayHKService; +import com.ai.da.common.enums.OrderStatusEnum; +import com.ai.da.common.enums.PayTypeEnum; +import com.ai.da.common.utils.AlipayHKEncryptionUtil; +import com.ai.da.common.utils.AlipayHKRequestUtil; +import com.ai.da.mapper.primary.entity.OrderInfo; +import com.ai.da.model.dto.AlipayHKCallbackDTO; +import com.ai.da.model.dto.AlipayHKRequestDTO; +import com.ai.da.service.*; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.Arrays; import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; @Service @Slf4j public class AlipayHKServiceImpl implements AlipayHKService { - @Value("${alipay.hk.merchant-id}") - private static String merchantId; + @Value("${alipayHK.merchantId}") + private String merchantId; - @Value("${alipay.hk.segment-id}") - private static String segmentId; + @Value("${alipayHK.segmentId}") + private String segmentId; - @Value("${alipay.hk.AESKey}") - private static String aesKey; + @Value("${alipayHK.AESKey}") + private String aesKey; - @Value("${alipay.hk.rsaPrivateKey}") - private static String privateKeyPath; + @Value("${alipayHK.rsaPrivateKey}") + private String privateKeyPath; - @Value("${alipay.hk.rsaPublicKey}") - private static String publicKeyPath; + @Value("${alipayHK.rsaPublicKey}") + private String publicKeyPath; + + @Resource + private OrderInfoService orderInfoService; + @Resource + private PaymentInfoService paymentInfoService; + @Resource + private CreditsService creditsService; + @Resource + private AlipayHKEncryptionUtil alipayHKEncryptionUtil; + @Resource + private AlipayHKRequestUtil alipayHKRequestUtil; /** * 创建订单 */ - public void createOrder(Integer amount){ + @Override + public String createOrder(Integer amount, String wallet){ - HashMap param = new HashMap<>(); - String orderRef = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); - param.put("order_ref", orderRef); - param.put("amount", Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); - param.put("subject", "AiDA Credits Purchase"); - param.put("wallet", "ALIPAYHK"); - param.put("segment_id", segmentId); - param.put("payment_solution", "WAP"); + try{ + HashMap param = new HashMap<>(); + String orderRef = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); + param.put("order_ref", orderRef); + param.put("amount", Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); + param.put("subject", "AiDA Credits Purchase"); + // ALIPAYHK 或者 ALIPAYCN + param.put("wallet", wallet); + param.put("segment_id", segmentId); + param.put("payment_solution", "WAP"); + log.info("alipay-hk 创建订单,参数信息: {}", param); + // 生成订单 + log.info("创建订单"); + OrderInfo orderInfo = orderInfoService.createOrderByProductId(amount, PayTypeEnum.ALIPAY_HK.getType()); + // 加密 + AlipayHKRequestDTO alipayHKRequestDTO = alipayHKEncryptionUtil.AESCBCWithRSA(param, AlipayHKConstant.CREATE_ORDER); + // 请求Alipay服务端 + String response = alipayHKRequestUtil.createOrder(alipayHKRequestDTO); + // 获取response中的加密数据 + JSONObject responseObj = JSONObject.parseObject(response); + JSONObject resultObj = JSONObject.parseObject(responseObj.get("result").toString()); + String nonce = resultObj.get("nonce").toString(); + String message = resultObj.get("message").toString(); + // 解密 + String s = alipayHKEncryptionUtil.decryptAES(message, nonce); + JSONObject jsonObject = JSONObject.parseObject(s); + String orderId = jsonObject.get("out_trade_no").toString(); + + orderInfoService.updateOrderNoById(orderInfo.getId(), orderId); + + + log.info("create_order 接口返回信息 :{}", s); + + return s; + + + }catch (Exception e){ + log.error("订单创建失败 : {}", e.getMessage()); + // todo 或者抛异常 + return null; + } } @@ -53,8 +116,122 @@ public class AlipayHKServiceImpl implements AlipayHKService { * 异步回调 * @return */ - public void callback(){ + public String callback(Map params){ + log.info("支付通知正在执行"); + log.info("通知参数 ===> {}", params); + String result = "failure"; + + String data = params.get("data"); + String signature = params.get("signature"); + + try { + // 异步回调验签 + Boolean verification = alipayHKEncryptionUtil.signatureVerification(data, signature); + + if (!verification){ + log.error("alipay-hk 验签失败"); + return result; + } + + AlipayHKCallbackDTO alipayHKCallbackDTO = JSONObject.parseObject(data, AlipayHKCallbackDTO.class); + //按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验, + //1 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号 + String outTradeNo = alipayHKCallbackDTO.getOut_trade_no(); + OrderInfo order = orderInfoService.getOrderByOrderNo(outTradeNo); + if(order == null){ + log.error("订单不存在"); + return result; + } + + //2 判断 total_amount 是否确实为该订单的实际金额(即商户订单创建时的金额) + Long totalAmount = alipayHKCallbackDTO.getAmount(); + Long totalFee = order.getTotalFee().longValue(); + if(totalAmount != totalFee){ + log.error("金额校验失败"); + return result; + } + + //3 校验通知中的 seller_id(或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方 + String sellerId = alipayHKCallbackDTO.getMerchant_id(); + String sellerIdProperty = merchantId; + if(!sellerId.equals(sellerIdProperty)){ + log.error("商家pid校验失败"); + return result; + } + + //4 验证 app_id 是否为该商户本身 + String segId = alipayHKCallbackDTO.getSegment_id(); + String segmentIdProperty = segmentId; + if(!segId.equals(segmentIdProperty)){ + log.error("segmentId校验失败"); + return result; + } + + //在支付宝的业务通知中,只有交易通知状态为 TRADE_SUCCESS时, + // 支付宝才会认定为买家付款成功。 + String tradeStatus = alipayHKCallbackDTO.getStatus(); + if(!AlipayHKConstant.STATUS_PAID.equals(tradeStatus)){ + log.error("支付未成功"); + return result; + } + + processOrder(alipayHKCallbackDTO); + result = "success"; + }catch (Exception e){ + log.error(e.getMessage()); + } + + + return result; + + } + + private final ReentrantLock lock = new ReentrantLock(); + + + @Transactional(rollbackFor = Exception.class) + @Override + public void processOrder(AlipayHKCallbackDTO alipayHKCallbackDTO) { + + log.info("处理订单"); + + //获取订单号 + String orderNo = alipayHKCallbackDTO.getOut_trade_no(); + String totalAmount = alipayHKCallbackDTO.getAmount().toString(); + + /*在对业务数据进行状态检查和处理之前, + 要采用数据锁进行并发控制, + 以避免函数重入造成的数据混乱*/ + //尝试获取锁: + // 成功获取则立即返回true,获取失败则立即返回false。不必一直等待锁的释放 + if(lock.tryLock()) { + try { + //处理重复通知 + //接口调用的幂等性:无论接口被调用多少次,以下业务执行一次 +// String orderStatus = orderInfoService.getOrderStatus(orderNo); + OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo); + String orderStatus = orderByOrderNo.getOrderStatus(); + // 当订单状态处于未支付或超时已关闭时,更新订单状态 + if (!OrderStatusEnum.NOT_PAY.getType().equals(orderStatus) || !OrderStatusEnum.TIMEOUT_CLOSED.getType().equals(orderStatus)) { + return; + } + //更新订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS); + //记录支付日志 + paymentInfoService.createPaymentInfoForAliPayHK(alipayHKCallbackDTO); + // 添加积分变更记录 + creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(), + CreditsEventsEnum.BUY_CREDITS.getName() + "--AlipayHK", + CreditsEventsEnum.BUY_CREDITS.getValue(), + "positive"); + // 更新积分 + creditsService.buyCredits(orderByOrderNo.getAccountId(),Integer.parseInt(totalAmount) / Integer.parseInt(CreditsEventsEnum.PRICE.getValue())); + } finally { + //要主动释放锁 + lock.unlock(); + } + } } @@ -88,10 +265,28 @@ public class AlipayHKServiceImpl implements AlipayHKService { - public static void main(String[] args) throws Exception { -// test(); -// AESCBCWithRSA(); -// decrypt(); +// public static void main(String[] args) throws Exception { +//// test(); +//// AESCBCWithRSA(); +//// decrypt(); +// } + + public static void main(String[] args) { + System.out.println("Supported TLS versions:"); + String[] tlsVersions = getSupportedTLSVersions(); + Arrays.stream(tlsVersions).forEach(System.out::println); + } + + public static String[] getSupportedTLSVersions() { + try { + SSLContext context = SSLContext.getDefault(); + SSLSocketFactory factory = context.getSocketFactory(); + String[] supportedProtocols = factory.getDefaultCipherSuites(); + return supportedProtocols; + } catch (Exception e) { + e.printStackTrace(); + return new String[0]; + } } diff --git a/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java b/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java index 367dd376..224bfd91 100644 --- a/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java @@ -3,6 +3,7 @@ package com.ai.da.service.impl; import com.ai.da.common.enums.PayTypeEnum; import com.ai.da.mapper.primary.PaymentInfoMapper; import com.ai.da.mapper.primary.entity.PaymentInfo; +import com.ai.da.model.dto.AlipayHKCallbackDTO; import com.ai.da.service.PaymentInfoService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.gson.Gson; @@ -48,7 +49,8 @@ public class PaymentInfoServiceImpl extends ServiceImpl