Quellcode durchsuchen

feat: "Airwallex退款功能"

ritchie vor 2 Jahren
Ursprung
Commit
f43bc48ca1

+ 1 - 0
src/main/java/com/szwl/common/AccessTokenCommon.java

@@ -22,4 +22,5 @@ public class AccessTokenCommon {
 
     public static String ACCESS_TOKEN = null;
 
+
 }

+ 10 - 0
src/main/java/com/szwl/common/WebhooksCommon.java

@@ -0,0 +1,10 @@
+package com.szwl.common;
+
+public class WebhooksCommon {
+    /**
+     * Webhooks密钥
+     */
+    public final static String WEBHOOKS_KEY_PAYMENT_INTENT = "whsec_KyZE-K9wIT2JBjpmE3Lf0JVm6q2rkyxX";
+    public final static String WEBHOOKS_KEY_REFUND = "whsec_qLqlm0tAH8v_j-SAHHCdU3yzBb2YBrS5";
+
+}

+ 4 - 4
src/main/java/com/szwl/constant/AirwallexConstant.java

@@ -1,5 +1,8 @@
 package com.szwl.constant;
 
+import com.szwl.controller.AirwallexPayController;
+
+import javax.annotation.Resource;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -16,10 +19,7 @@ public class AirwallexConstant {
 
     public final static String QR_URL = "http://localhost:8080/shenze/#/hpp";
 
-    /**
-     * Webhooks密钥
-     */
-    public final static String WEBHOOKS_KEY = "whsec_KyZE-K9wIT2JBjpmE3Lf0JVm6q2rkyxX";
+
     public final static String MODE = "payment";
     /**
      * staging | demo | prod

+ 74 - 30
src/main/java/com/szwl/controller/AirwallexPayController.java

@@ -84,7 +84,8 @@ public class AirwallexPayController {
         BigDecimal amount = paymentIntentRequestBody.getAmount();
         String currency = paymentIntentRequestBody.getCurrency();
         String merchantOrderId = paymentIntentRequestBody.getMerchantOrderId();
-        String requestId = paymentIntentRequestBody.getRequestId();
+//        String requestId = paymentIntentRequestBody.getRequestId();
+        String requestId = UUID.randomUUID().toString().trim().replaceAll("-", "");
         Long productId = paymentIntentRequestBody.getProductId();
         String productName = paymentIntentRequestBody.getProductName();
         String clientId = paymentIntentRequestBody.getClientId();
@@ -111,8 +112,9 @@ public class AirwallexPayController {
         // 把 paymentIntentId 保存到数据库
         tOrderAbroad.setPaymentIntentId(paymentIntentId);
         // 将订单存入数据库
-        boolean save = tOrderAbroadService.save(tOrderAbroad);
-        System.out.println("将订单存入数据库:" + save);
+        tOrderAbroadService.save(tOrderAbroad);
+//        boolean save = tOrderAbroadService.save(tOrderAbroad);
+//        System.out.println("将订单存入数据库:" + save);
 
         // 拼接二维码链接给前端
 //        String env = AirwallexConstant.ENV;
@@ -146,22 +148,40 @@ public class AirwallexPayController {
 //        JSONObject customerObj = JSON.parseObject(customer);
 //        String address = customerObj.getString("address");
 
-        JSONObject state = Optional.ofNullable(jsonObject)
-                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject.getJSONObject("customer")))
-                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject.getJSONObject("address")))
-                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject.getJSONObject("state")))
-                .orElse(null);
-        JSONObject city = Optional.ofNullable(jsonObject)
-                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject.getJSONObject("customer")))
-                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject.getJSONObject("address")))
-                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject.getJSONObject("city")))
-                .orElse(null);
+        // TODO: 要改
+        String type = jsonObject.getJSONObject("latest_payment_attempt").getJSONObject("payment_method").getString("type");
+//        JSONObject jsonObject4 = Optional.ofNullable(jsonObject)
+//                .flatMap(jsonObject3 -> Optional.ofNullable(jsonObject3.getJSONObject("customer")))
+//                .flatMap(jsonObject3 -> Optional.ofNullable(jsonObject3.getJSONObject("address")))
+//                .flatMap(jsonObject3 -> Optional.ofNullable(jsonObject3.getJSONObject("state")))
+//                .orElse(null);
+//        String state = JSON.toJSONString(jsonObject4);
+
+//        JSONObject jsonObject3 = Optional.ofNullable(jsonObject)
+//                .map(jsonObject1 -> jsonObject1.getJSONObject("latest_payment_attempt"))
+//                .map(jsonObject1 -> jsonObject1.getJSONObject("payment_method"))
+//                .map(jsonObject1 -> jsonObject1.getJSONObject("type"))
+//                .orElse(null);
+//        String state = JSON.toJSONString(jsonObject3);
+
+//        JSONObject stateJson = Optional.ofNullable(jsonObject)
+//                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("customer")))
+//                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("address")))
+//                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("state")))
+//                .orElse(null);
+//        String state = JSON.toJSONString(stateJson);
+//        JSONObject cityJson = Optional.ofNullable(jsonObject)
+//                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("latest_payment_attempt")))
+//                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("payment_method")))
+//                .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("id")))
+//                .orElse(null);
+//        String city = JSON.toJSONString(cityJson);
 
         Map<String, Object> intentDetails = new HashMap<>();
         intentDetails.put("amount",amount);
         intentDetails.put("currency",currency);
-        intentDetails.put("state",state);
-        intentDetails.put("city",city);
+//        intentDetails.put("state",state);
+        intentDetails.put("type",type);
         intentDetails.put("createdAt",createdAt);
         intentDetails.put("status",status);
 
@@ -252,32 +272,56 @@ public class AirwallexPayController {
 
     @ApiOperation(value = "查询某笔退款详情")
     @GetMapping("/retrieveARefund/{id}")
-    public String retrieveARefund(@PathVariable("id") String refundId) {
+    public Map<String, Object> retrieveARefund(@PathVariable("id") String refundId) {
         log.info("根据rfd_查询某笔退款详情");
+//        String requestId = UUID.randomUUID().toString().trim().replaceAll("-", "");
 
         String refundResp = airwallexService.retrieveARefund(refundId);
         JSONObject jsonObject = JSON.parseObject(refundResp);
+        String amount = jsonObject.getString("amount");
         String status = jsonObject.getString("status");
+        String currency = jsonObject.getString("currency");
+        String paymentIntentId = jsonObject.getString("payment_intent_id");
+        String createdAt = jsonObject.getString("created_at");
 
-        if (status.equals("SUCCEEDED")) {
-
-            LambdaQueryWrapper<TOrderAbroad> lambdaQueryWrapper = Wrappers.lambdaQuery();
-            lambdaQueryWrapper.eq(TOrderAbroad::getRefundId, refundId);
-            TOrderAbroad orderAbroad = tOrderAbroadService.getOne(lambdaQueryWrapper);
+        Map<String, Object> hashMap = new HashMap<>();
+        hashMap.put("amount", amount);
+        hashMap.put("status", status);
+        hashMap.put("currency", currency);
+        hashMap.put("payment_intent_id", paymentIntentId);
+        hashMap.put("created_at", createdAt);
 
-//            if (orderAbroad == null ) {
+//        if (status.equals("SUCCEEDED")) {
+//
+//            LambdaQueryWrapper<TOrderAbroad> lambdaQueryWrapper = Wrappers.lambdaQuery();
+//            lambdaQueryWrapper.eq(TOrderAbroad::getRefundId, refundId);
+//            TOrderAbroad orderAbroad = tOrderAbroadService.getOne(lambdaQueryWrapper);
+//
+////            if (orderAbroad == null ) {
+////                return "订单为空/error";
+////            }
+//            if (Objects.isNull(orderAbroad)) {
 //                return "订单为空/error";
 //            }
-            if (Objects.isNull(orderAbroad)) {
-                return "订单为空/error";
-            }
-            // 设置支付状态为 3已退款
-            orderAbroad.setPayStatus(3);
-            tOrderAbroadService.updateById(orderAbroad);
-        }
-        return status;
+//            // 设置支付状态为 3已退款
+//            orderAbroad.setPayStatus(3);
+//            tOrderAbroadService.updateById(orderAbroad);
+//        }
+        return hashMap;
 
     }
 
+//    @ApiOperation(value = "新建一笔转账")
+//    @PostMapping()
+//    public R caPayment(@RequestBody PaymentRequestBody paymentRequestBody) {
+//        log.info("发起一笔转账");
+//
+//
+//        airwallexService.caPayment()
+//
+//
+//        return R.ok();
+//    }
+
 }
 

+ 63 - 25
src/main/java/com/szwl/controller/WebhookController.java

@@ -19,14 +19,18 @@ import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.ResponseBody;
+import org.yaml.snakeyaml.events.Event;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.sql.Wrapper;
 import java.util.ArrayList;
+import java.util.Objects;
+import java.util.Optional;
 
-import static com.szwl.constant.AirwallexConstant.WEBHOOKS_KEY;
+import static com.szwl.common.WebhooksCommon.WEBHOOKS_KEY_PAYMENT_INTENT;
+import static com.szwl.common.WebhooksCommon.WEBHOOKS_KEY_REFUND;
 import static com.szwl.constant.AirwallexConstant.ENV;
 
 
@@ -73,7 +77,7 @@ public class WebhookController {
         String signature = request.getHeader("x-signature");
 
 // Get your secret
-        String secret = getSecret();
+        String secret = getSecretRefund();
 
         if (HmacUtils.hmacSha256Hex(secret, valueToDigest.toString()).equals(signature)) {
 
@@ -81,14 +85,18 @@ public class WebhookController {
 
             response.setStatus(HttpServletResponse.SC_OK);
 
-
             JSONObject jsonObject = JSON.parseObject(payload);
-            String data = jsonObject.getString("data");
-            JSONObject jsonObject1 = JSON.parseObject(data);
-            String dataObject = jsonObject1.getString("object");
-            JSONObject jsonObject2 = JSON.parseObject(dataObject);
-            String refundId = jsonObject2.getString("id");
-            String status = jsonObject2.getString("status");
+            JSONObject object = jsonObject.getJSONObject("data").getJSONObject("object");
+            String refundId = object.getString("id");
+            String status = object.getString("status");
+
+//            JSONObject jsonObject = JSON.parseObject(payload);
+//            String data = jsonObject.getString("data");
+//            JSONObject jsonObject1 = JSON.parseObject(data);
+//            String dataObject = jsonObject1.getString("object");
+//            JSONObject jsonObject2 = JSON.parseObject(dataObject);
+//            String refundId = jsonObject2.getString("id");
+//            String status = jsonObject2.getString("status");
 
             // 如果退款成功
             if (status.equals("RECEIVED") || status.equals("ACCEPTED") || status.equals("SUCCEEDED")) {
@@ -97,6 +105,9 @@ public class WebhookController {
                 lambdaQueryWrapper.eq(TOrderAbroad::getRefundId, refundId);
                 TOrderAbroad orderAbroad = tOrderAbroadService.getOne(lambdaQueryWrapper);
 
+                if (Objects.isNull(orderAbroad)) {
+                    return "订单为空/error";
+                }
                 // 设置订单支付状态为 已退款
                 orderAbroad.setPayStatus(3);
                 tOrderAbroadService.updateById(orderAbroad);
@@ -136,7 +147,7 @@ public class WebhookController {
         String signature = request.getHeader("x-signature");
 
 // Get your secret
-        String secret = getSecret();
+        String secret = getSecretPaymentInent();
 
         if (HmacUtils.hmacSha256Hex(secret, valueToDigest.toString()).equals(signature)) {
 
@@ -146,15 +157,40 @@ public class WebhookController {
             responseBody = "payment intent ok";
 
             // 如果用户支付成功,将订单支付状态改成 1已支付。
-            JSONObject jsonObject = JSON.parseObject(payload);
-            String data = jsonObject.getString("data");
-            JSONObject jsonObject1 = JSON.parseObject(data);
-            String dataObject = jsonObject1.getString("object");
-            JSONObject jsonObject2 = JSON.parseObject(dataObject);
-            String requestId = jsonObject2.getString("request_id");
-            QueryWrapper<TOrderAbroad> tOrderAbroadQueryWrapper = new QueryWrapper<>();
-            tOrderAbroadQueryWrapper.eq("request_id",requestId);
-            TOrderAbroad orderAbroad = tOrderAbroadService.getOne(tOrderAbroadQueryWrapper);
+//            JSONObject jsonObj = JSON.parseObject(payload);
+//            String data = jsonObj.getString("data");
+//            JSONObject jsonObject1 = JSON.parseObject(data);
+//            String dataObject = jsonObject1.getString("object");
+//            JSONObject jsonObject2 = JSON.parseObject(dataObject);
+//            String paymentIntentId = jsonObject2.getString("id");
+//            JSONObject data1 = jsonObj.getJSONObject("data");
+//            JSONObject object = data1.getJSONObject("object");
+//            String paymentIntentId = object.getString("id");
+//            QueryWrapper<TOrderAbroad> tOrderAbroadQueryWrapper = new QueryWrapper<>();
+//            tOrderAbroadQueryWrapper.eq("payment_intent_id",paymentIntentId);
+            String paymentIntentId = JSON.parseObject(payload).getJSONObject("data").getJSONObject("object").getString("id");
+//            JSONObject jsonObj = Optional.ofNullable(jsonObject)
+//                    .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("data")))
+//                    .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("object")))
+//                    .flatMap(jsonObject1 -> Optional.ofNullable(jsonObject1.getJSONObject("id")))
+//                    .orElse(null);
+//            JSONObject idJson = Optional.ofNullable(jsonObj)
+//                    .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("data")))
+//                    .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("object")))
+//                    .flatMap(jsonObject -> Optional.ofNullable(jsonObject.getJSONObject("id")))
+//                    .orElse(null);
+//            JSONObject idJson = Optional.ofNullable(jsonObj)
+//                    .map(jsonObject -> jsonObject.getJSONObject("data"))
+//                    .map(jsonObject -> jsonObject.getJSONObject("object"))
+//                    .map(jsonObject -> jsonObject.getJSONObject("id"))
+//                    .orElse(null);
+//            String paymentIntentId = JSON.toJSONString(idJson);
+            LambdaQueryWrapper<TOrderAbroad> lambdaQueryWrapper = Wrappers.lambdaQuery();
+            lambdaQueryWrapper.eq(TOrderAbroad::getPaymentIntentId, paymentIntentId);
+//            QueryWrapper<TOrderAbroad> lambdaQueryWrapper = new QueryWrapper<>();
+//            lambdaQueryWrapper.eq("payment_intent_id", paymentIntentId);
+            TOrderAbroad orderAbroad = tOrderAbroadService.getOne(lambdaQueryWrapper);
+
             System.out.println(orderAbroad);
 
             orderAbroad.setPayStatus(1);
@@ -173,15 +209,17 @@ public class WebhookController {
 
             // TODO: 验签失败,先retrieve手动获取订单信息,如果成功,走上面那一套,如果失败不做处理
 
-
-
         }
-        System.out.println(response);
-        System.out.println(responseBody);
+//        System.out.println(response);
+//        System.out.println(responseBody);
         return responseBody;
     }
 
-    private String getSecret() {
-        return WEBHOOKS_KEY;
+    private String getSecretPaymentInent() {
+        return WEBHOOKS_KEY_PAYMENT_INTENT;
+    }
+
+    private String getSecretRefund() {
+        return WEBHOOKS_KEY_REFUND;
     }
 }

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

@@ -13,7 +13,8 @@ public class PaymentIntentRequestBody {
 
     private String merchantOrderId;
 
-    private String requestId;
+    // 这个不用前端传递
+//    private String requestId;
 
     private Long productId;
 

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

@@ -1,7 +1,6 @@
 package com.szwl.service.impl;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.szwl.common.AccessTokenCommon;
 import com.szwl.constant.AirwallexConstant;
 import com.szwl.model.bo.R;
@@ -10,7 +9,6 @@ import com.szwl.model.utils.HttpClientSslUtils;
 import com.szwl.service.AirwallexService;
 import com.szwl.service.TOrderAbroadService;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.StringUtils;
 import org.apache.http.entity.ContentType;
 import org.apache.http.message.BasicHeader;
 import org.springframework.stereotype.Service;
@@ -22,8 +20,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import static com.szwl.constant.ResponseCodesEnum.L0006;
-
 /**
  * <p>
  *  服务实现类
@@ -190,6 +186,7 @@ public class AirwallexServiceImpl implements AirwallexService {
 
     /**
      * 获取某笔退款的详情
+     *
      * @param refundId
      * @return
      */