PaymentService.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package com.webchat.ugc.service;
  2. import com.google.common.cache.Cache;
  3. import com.google.common.cache.CacheBuilder;
  4. import com.webchat.common.bean.APIResponseBean;
  5. import com.webchat.common.bean.APIResponseBeanUtil;
  6. import com.webchat.common.enums.RedisKeyEnum;
  7. import com.webchat.common.exception.BusinessException;
  8. import com.webchat.common.service.RedisService;
  9. import com.webchat.common.util.JsonUtil;
  10. import com.webchat.common.util.SignUtil;
  11. import com.webchat.rmi.pay.PaymentApiServiceClient;
  12. import com.webchat.ugc.config.PaymentAppConfig;
  13. import lombok.extern.slf4j.Slf4j;
  14. import org.apache.commons.lang3.StringUtils;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.stereotype.Service;
  17. import java.util.Date;
  18. import java.util.concurrent.TimeUnit;
  19. import java.util.concurrent.locks.ReentrantLock;
  20. @Slf4j
  21. @Service
  22. public class PaymentService {
  23. @Autowired
  24. private PaymentApiServiceClient paymentApiServiceClient;
  25. @Autowired
  26. private PaymentAppConfig paymentAppConfig;
  27. @Autowired
  28. private RedisService redisService;
  29. private ReentrantLock lock = new ReentrantLock();
  30. public String token() {
  31. String key = this.getTokenCacheKey();
  32. String cache = redisService.get(key);
  33. if (StringUtils.isNotBlank(cache)) {
  34. return cache;
  35. }
  36. String token;
  37. try {
  38. lock.lock();
  39. // 双重检查锁
  40. token = redisService.get(key);
  41. if (StringUtils.isNotBlank(token)) {
  42. return token;
  43. }
  44. token = refreshAccessTokenCache();
  45. } catch (Exception e) {
  46. throw new BusinessException("支付Token请求失败!");
  47. } finally {
  48. if (lock.isHeldByCurrentThread()) {
  49. lock.unlock();
  50. }
  51. }
  52. return token;
  53. }
  54. /**
  55. * 刷新token redis缓存
  56. *
  57. * @return
  58. */
  59. private String refreshAccessTokenCache() {
  60. String token = this.getTokenByClient();
  61. String key = this.getTokenCacheKey();
  62. redisService.set(key, token, RedisKeyEnum.PAYMENT_ACCESS_TOKEN_CACHE.getExpireTime());
  63. return token;
  64. }
  65. /**
  66. * 获取Token redis缓存
  67. * @return
  68. */
  69. private String getTokenCacheKey() {
  70. return RedisKeyEnum.PAYMENT_ACCESS_TOKEN_CACHE.getKey();
  71. }
  72. /**
  73. * 获取token
  74. *
  75. * @return
  76. */
  77. public String getTokenByClient() {
  78. String logId = generateLogId();
  79. // 13位时间戳
  80. Long timestamp = System.currentTimeMillis();
  81. // 计算签名(5分钟内有效期)
  82. // SHA256(sk, "appId - accessKey - timestamp")
  83. String signature = SignUtil.generateSignature(paymentAppConfig.getSecretKey(),
  84. String.valueOf(paymentAppConfig.getAppId()),
  85. paymentAppConfig.getAccessKey(),
  86. String.valueOf(timestamp));
  87. APIResponseBean<String> responseBean = paymentApiServiceClient.accessToken(paymentAppConfig.getAppId(),
  88. paymentAppConfig.getAccessKey(),
  89. paymentAppConfig.getSecretKey(),
  90. timestamp,
  91. signature,
  92. logId);
  93. if (APIResponseBeanUtil.isOk(responseBean)) {
  94. return responseBean.getData();
  95. }
  96. log.error("UGC 支付服务异常 =====> 获取Token异常!logId:{}, responseBean:{}",
  97. logId, JsonUtil.toJsonString(responseBean));
  98. throw new BusinessException("支付Token请求失败!");
  99. }
  100. public String transId() {
  101. String accessToken = token();
  102. String logId = generateLogId();
  103. APIResponseBean<String> responseBean = paymentApiServiceClient.transId(accessToken, logId);
  104. if (APIResponseBeanUtil.isOk(responseBean)) {
  105. return responseBean.getData();
  106. }
  107. log.error("UGC 支付服务异常 =====> 获取TransId异常!logId:{}, responseBean:{}",
  108. logId, JsonUtil.toJsonString(responseBean));
  109. throw new BusinessException("支付TransId请求失败!");
  110. }
  111. private String generateLogId() {
  112. // TODO 预留:
  113. // 支持雪花算法ID生成
  114. return null;
  115. }
  116. }