Procházet zdrojové kódy

feat: "获取实时汇率,增加美元金额到对应账户钱包,海外线上订单日期调整"

Ritchie před 1 rokem
rodič
revize
0e85fbc74a

+ 2 - 0
src/main/java/com/szwl/constant/AirwallexConstant.java

@@ -19,6 +19,8 @@ public class AirwallexConstant {
 
     public final static String QR_URL = "http://localhost:8080/shenze/#/hpp";
 
+//    public final static String QR_URL = "http://szwlh.sunzee.com.cn/shenze/#/hpp";
+
 
     public final static String MODE = "payment";
     /**

+ 49 - 7
src/main/java/com/szwl/controller/AirwallexPayController.java

@@ -24,6 +24,7 @@ import com.szwl.service.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.*;
@@ -31,6 +32,8 @@ import org.springframework.web.bind.annotation.*;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.time.OffsetDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -144,9 +147,8 @@ public class AirwallexPayController {
         // 如果是海外客户,使用的是 Airwallex ,就要判断他有没有设置分销
         // 在 Airwallex 支付之前,要先判断
 
+        String createDate = paymentIntentRequestBody.getCreateDate();
         BigDecimal amount = paymentIntentRequestBody.getAmount();
-        Date createDate = paymentIntentRequestBody.getCreateDate();
-        Date modifyDate = paymentIntentRequestBody.getModifyDate();
         String currency = paymentIntentRequestBody.getCurrency();
         String merchantOrderId = paymentIntentRequestBody.getMerchantOrderId();
 //        String requestId = paymentIntentRequestBody.getRequestId();
@@ -191,8 +193,23 @@ public class AirwallexPayController {
         // 创建订单
         TCoinOrder tCoinOrder = new TCoinOrder();
         tCoinOrder.setAdminId(adminById.getId());
-        tCoinOrder.setCreateDate(createDate);
-        tCoinOrder.setModifyDate(modifyDate);
+
+        if (StringUtils.isNotEmpty(createDate)) {
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            Date parse = null;
+            try {
+                parse = simpleDateFormat.parse(createDate);
+            } catch (ParseException e) {
+                throw new RuntimeException(e);
+            }
+            tCoinOrder.setCreateDate(parse);
+            tCoinOrder.setModifyDate(parse);
+
+        } else {
+            tCoinOrder.setCreateDate(new Date());
+            tCoinOrder.setModifyDate(new Date());
+        }
+        tCoinOrder.setPayDate(new Date());
         tCoinOrder.setSn(sn);
         tCoinOrder.setAmount(amount);
         tCoinOrder.setCurrency(currency);
@@ -243,8 +260,18 @@ public class AirwallexPayController {
         tOrderDetails.setId(merchantOrderId);
         tOrderDetails.setAdminId(adminById.getId());
         tOrderDetails.setEquipmentId(equipmentId);
-        tOrderDetails.setCreateDate(createDate);
-        tOrderDetails.setModifyDate(modifyDate);
+        if (StringUtils.isNotEmpty(createDate)) {
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            Date parse = null;
+            try {
+                parse = simpleDateFormat.parse(createDate);
+            } catch (ParseException e) {
+                throw new RuntimeException(e);
+            }
+            tOrderDetails.setCreateDate(parse);
+        } else {
+            tOrderDetails.setCreateDate(new Date());
+        }
         tOrderDetails.setOrderSn(sn);
         tOrderDetails.setPrice(amount);
         tOrderDetails.setProductName(productName);
@@ -403,6 +430,7 @@ public class AirwallexPayController {
         coinOrder.setRefundDate(refundDate);
         tCoinOrderService.updateById(coinOrder);
 
+        // TODO: 退款要扣除用户钱包中的金额,如果金额为0或者不足,改为负数?或者提示余额不足,联系商家手动退款
 
         // 发起退款
 //        String refund = airwallexService.createARefund(requestId, paymentIntentId, reason);
@@ -527,7 +555,7 @@ public class AirwallexPayController {
         tAirwallexPayment.setAdminId(adminId);
         tAirwallexPaymentService.save(tAirwallexPayment);
 
-        // TODO: 从当前余额中扣除提现金额,考虑货币,改成每次将余额全部提现
+        // TODO: 默认每次将余额全部提现,考虑货币
 //        tAirwallexWalletService.list()
 //        LambdaQueryWrapper<TAirwallexWallet> wrapper = Wrappers.lambdaQuery();
 //        wrapper.eq(TAirwallexWallet::getAdminId, adminId);
@@ -765,4 +793,18 @@ public class AirwallexPayController {
         return distributionDetails;
     }
 
+
+    // 查询实时汇率
+    // Retrieve an indicative MarketFX quote
+    @ApiOperation(value = "查询实时汇率")
+    @GetMapping("/getMarketFX")
+    public Map<String, Object> getMarketFX(@RequestParam Map<String, String> params) {
+        String buyCurrency = params.get("buy_currency");
+        String sellCurrency = params.get("sell_currency");
+        BigDecimal buyAmount = new BigDecimal(params.get("buy_amount"));
+
+        Map<String, Object> marketFX = airwallexService.getMarketFX(buyCurrency, sellCurrency, buyAmount);
+
+        return marketFX;
+    }
 }

+ 26 - 2
src/main/java/com/szwl/controller/WebhookController.java

@@ -8,8 +8,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.szwl.model.entity.TAirwallexWallet;
 import com.szwl.model.entity.TCoinOrder;
 import com.szwl.model.utils.PushUtils;
+import com.szwl.service.TAirwallexWalletService;
 import com.szwl.service.TCoinOrderService;
 import com.szwl.service.TEquipmentService;
 import lombok.extern.slf4j.Slf4j;
@@ -21,6 +23,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
 import java.util.Objects;
 
 import static com.szwl.common.WebhooksCommon.WEBHOOKS_KEY_PAYMENT_INTENT;
@@ -35,6 +38,9 @@ public class WebhookController {
     TCoinOrderService tCoinOrderService;
 
     @Resource
+    TAirwallexWalletService tAirwallexWalletService;
+
+    @Resource
     TEquipmentService tEquipmentService;
 //    @Resource
 //    AirwallexService airwallexService;
@@ -162,6 +168,7 @@ public class WebhookController {
 //            QueryWrapper<TOrderAbroad> tOrderAbroadQueryWrapper = new QueryWrapper<>();
 //            tOrderAbroadQueryWrapper.eq("payment_intent_id",paymentIntentId);
             String paymentIntentId = JSON.parseObject(payload).getJSONObject("data").getJSONObject("object").getString("id");
+            String currency = JSON.parseObject(payload).getJSONObject("data").getJSONObject("object").getString("currency");
 //            JSONObject jsonObj = Optional.ofNullable(jsonObject)
 //                    .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("data")))
 //                    .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("object")))
@@ -188,7 +195,7 @@ public class WebhookController {
 
             coinOrder.setStatus(1); // 订单状态设置为已支付
             tCoinOrderService.updateById(coinOrder);
-            // TODO: 然后再去分销,给每个账户钱包加钱
+            // 然后再去分销,给每个账户钱包加钱
             // 先获取订单信息中的 altInfo 字段,然后拆分,获取其中每个 adminId 和对应的金额
             String altInfo = coinOrder.getAltInfo();
             try {
@@ -196,12 +203,29 @@ public class WebhookController {
                 JsonNode jsonNode = objectMapper.readTree(altInfo);
                 for (JsonNode node : jsonNode) {
                     String airBeneId = node.get("airBeneId").asText();
-                    String airAmount = node.get("airAmount").asText();
+                    String airAmountStr = node.get("airAmount").asText();
+                    BigDecimal airAmountBigDec = new BigDecimal(airAmountStr);
+                    // 获取 airBeneId 对应的账户钱包信息
+                    LambdaQueryWrapper<TAirwallexWallet> wrapper = Wrappers.lambdaQuery();
+                    wrapper.eq(TAirwallexWallet::getAdminId, airBeneId);
+                    TAirwallexWallet airwallexWallet = tAirwallexWalletService.getOne(wrapper);
+                    BigDecimal accountAmount = airwallexWallet.getAccountAmount();
+                    String accountCurrency = airwallexWallet.getAccountCurrency();
+                    if (currency.equals(accountCurrency)) {
+                        BigDecimal added = accountAmount.add(airAmountBigDec);
+                        airwallexWallet.setAccountAmount(added);
+                        tAirwallexWalletService.saveOrUpdate(airwallexWallet);
+                    } else {
+                        // 货币种类不一致,账户钱包金额统一是美元$,如果不一致,要先获取当前汇率,然后转换成对应的美元金额
+                        return "货币种类不一致";
+                    }
+
                 }
             } catch (JsonProcessingException e) {
                 throw new RuntimeException(e);
             }
 
+
             // 通知做糖
             JSONObject kindData = new JSONObject();
             kindData.put("sn", coinOrder.getMerchantOrderId());

+ 2 - 3
src/main/java/com/szwl/model/bean/PaymentIntentRequestBody.java

@@ -10,9 +10,9 @@ import java.util.Date;
 @Data
 public class PaymentIntentRequestBody {
 
-    private Date createDate;
+    private String createDate;
 
-    private Date modifyDate;
+//    private Date modifyDate;
 
     private BigDecimal amount;
 
@@ -20,7 +20,6 @@ public class PaymentIntentRequestBody {
 
     private String merchantOrderId;
 
-    // 这个不用前端传递
 //    private String requestId;
 
     private Long productId;

+ 8 - 0
src/main/java/com/szwl/service/AirwallexService.java

@@ -116,4 +116,12 @@ public interface AirwallexService  {
 //    void caWebhook(String[] envents, String requiredId, String url, String version);
 
 
+    /**
+     * 获取实时汇率
+     * @param buyCurrency
+     * @param sellCurrency
+     * @param buyAmount
+     * @return
+     */
+    Map<String, Object> getMarketFX(String buyCurrency, String sellCurrency, BigDecimal buyAmount);
 }

+ 39 - 4
src/main/java/com/szwl/service/impl/AirwallexServiceImpl.java

@@ -402,10 +402,45 @@ public class AirwallexServiceImpl implements AirwallexService {
     }
 
 
-//    @Override
-//    public String refundWebhooks(HttpServletRequest request, HttpServletResponse response) {
-//        return null;
-//    }
+    /**
+     * 获取实时汇率
+     * @param buyCurrency
+     * @param sellCurrency
+     * @param buyAmount
+     * @return
+     */
+    @Override
+    public Map<String, Object> getMarketFX(String buyCurrency, String sellCurrency, BigDecimal buyAmount) {
+
+        // GET /api/v1/marketfx/quote
+        String accessToken = AccessTokenCommon.ACCESS_TOKEN;
+
+        if(accessToken == null || "".equals(accessToken)) {
+            accessToken = AccessTokenThreadUtil.getAccessToken();
+        }
+
+        String url = AirwallexConstant.url + "/api/v1/marketfx/quote?buy_amount=" + buyAmount + "&buy_currency=" + buyCurrency + "&sell_currency=" + sellCurrency;
+        // 请求头
+        List<BasicHeader> headers = new ArrayList<>();
+        BasicHeader header = new BasicHeader("Authorization", AirwallexConstant.BEARER + accessToken);
+        headers.add(header);
+
+        // body参数
+//        Map<String, Object> bodyMap = new HashMap<>();
+//        String data = JSON.toJSONString(bodyMap);
+
+        Map<String, Object> responseMap = new HashMap<>();
+        String resp = null;
+        try {
+            resp = HttpClientSslUtils.doGet(url, ContentType.APPLICATION_JSON, headers);
+            responseMap = JSON.parseObject(resp);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return responseMap;
+    }
+
 
 
     /**