From 7e7f901b2172281dc294dfbc67e6ad00625f09f4 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期一, 04 三月 2024 10:11:21 +0800
Subject: [PATCH] 合并代码

---
 cloud-server-management/src/main/java/com/dsh/course/util/midtrans/MidtransUtil.java |  300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 300 insertions(+), 0 deletions(-)

diff --git a/cloud-server-management/src/main/java/com/dsh/course/util/midtrans/MidtransUtil.java b/cloud-server-management/src/main/java/com/dsh/course/util/midtrans/MidtransUtil.java
new file mode 100644
index 0000000..ed71629
--- /dev/null
+++ b/cloud-server-management/src/main/java/com/dsh/course/util/midtrans/MidtransUtil.java
@@ -0,0 +1,300 @@
+package com.dsh.course.util.midtrans;
+
+import com.alibaba.fastjson.JSON;
+import com.midtrans.Config;
+import com.midtrans.Midtrans;
+import com.midtrans.httpclient.SnapApi;
+import com.midtrans.httpclient.TransactionApi;
+import com.midtrans.httpclient.error.MidtransError;
+import org.json.JSONObject;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* Midtrans支付工具类
+* @author pzb
+* @Date 2022/11/28 14:19
+*/
+public class MidtransUtil {
+
+    private static String sandbox_merchant_id = "G118246934";
+
+    private static String sandbox_serverKey = "SB-Mid-server-qR4Xy4kbpyxND_7f6c1_knb9";
+
+    private static String sandbox_clientKey = "SB-Mid-client-xhRbIV8lsbu7bKCE";
+
+    private static String merchant_id = "G118246934";
+
+    private static String serverKey = "Mid-server-w1ATM2ldDpd0c4Q0s9sNfeNN";
+
+    private static String clientKey = "Mid-client-X22yMA1Wvs0v1vfO";
+
+
+    /**
+     * 获取支付令牌
+     * @param order_id          商户订单id
+     * @param gross_amount      支付金额
+     * @param xOverrideNotification     支付状态通知回调地址
+     * @return
+     */
+    public static TokenResult getPayToken(String order_id, String gross_amount, String xOverrideNotification){
+        //沙箱环境
+        Midtrans.serverKey = sandbox_serverKey;
+        Midtrans.clientKey = sandbox_clientKey;
+        Midtrans.isProduction = false;
+
+        //生产环境
+//        Midtrans.serverKey = serverKey;
+//        Midtrans.clientKey = clientKey;
+//        Midtrans.isProduction = true;
+
+        Midtrans.paymentOverrideNotification(xOverrideNotification);
+        // Create Token and then you can send token variable to FrontEnd,
+        // to initialize Snap JS when customer click pay button
+        //201	成功创建 Snap 令牌。	“令牌”:“66e4fa55-fdac-4ef9-91b5-733b97d1b862”
+        //401	未能创建令牌,因为发送了错误的授权。	“访问被拒绝,请检查客户端或服务器密钥”
+        //4xx	未能创建令牌,因为发送了错误的参数。按照 error_message 并检查您的参数。	“transaction_details.gross_amount 不等于 item_details 的总和”
+        //5xx	由于 Midtrans 内部错误,无法创建令牌。大多数情况下这是暂时的,您可以稍后重试。	“抱歉,我们遇到内部服务器错误。我们会尽快解决这个问题。”
+
+        try {
+            JSONObject transaction = SnapApi.createTransaction(requestBody(order_id, gross_amount), Config.getGlobalConfig());
+            TokenResult tokenResult = new TokenResult();
+            tokenResult.setToken(transaction.getString("token"));
+            tokenResult.setRedirect_url(transaction.getString("redirect_url"));
+            return tokenResult;
+        } catch (MidtransError midtransError) {
+            midtransError.printStackTrace();
+        }
+        return null;
+    }
+
+
+    // Create params JSON Raw Object request
+    public static Map<String, Object> requestBody(String order_id, String gross_amount) {
+        Map<String, Object> params = new HashMap<>();
+        Map<String, String> transactionDetails = new HashMap<>();
+        transactionDetails.put("order_id", order_id);
+        transactionDetails.put("gross_amount", gross_amount);
+        Map<String, String> creditCard = new HashMap<>();
+        creditCard.put("secure", "true");
+        params.put("transaction_details", transactionDetails);
+        params.put("credit_card", creditCard);
+        return params;
+    }
+
+
+    /**
+     * 获取订单支付状态
+     * @param order_id
+     * @return
+     */
+    public static PaymentNotice getPayStatus(String order_id){
+        //沙箱环境
+        Midtrans.serverKey = sandbox_serverKey;
+        Midtrans.clientKey = sandbox_clientKey;
+        Midtrans.isProduction = false;
+
+        //生产环境
+//        Midtrans.serverKey = serverKey;
+//        Midtrans.clientKey = clientKey;
+//        Midtrans.isProduction = true;
+        JSONObject jsonObject = null;
+        try {
+            jsonObject = TransactionApi.checkTransaction(order_id);
+        } catch (MidtransError midtransError) {
+            midtransError.printStackTrace();
+        }
+        PaymentNotice paymentNotice = JSON.parseObject(jsonObject.toString(), PaymentNotice.class);
+        if(null == paymentNotice){
+            System.err.println("回调结果解析失败");
+            return null;
+        }
+        String signature_key = paymentNotice.getSignature_key();
+        order_id = paymentNotice.getOrder_id();
+        String status_code = paymentNotice.getStatus_code();
+        if("400".equals(status_code)){
+            System.err.println("数据丢失或无效");
+            return null;
+        }
+        if("401".equals(status_code)){
+            System.err.println("授权错误");
+            return null;
+        }
+        if("404".equals(status_code)){
+            System.err.println("找不到请求的资源");
+            return null;
+        }
+        String gross_amount = paymentNotice.getGross_amount();
+        String sha_512_securePassword = get_SHA_512_SecurePassword(order_id + status_code + gross_amount + sandbox_serverKey);
+        if(!signature_key.equals(sha_512_securePassword)){
+            System.err.println("签名校验失败");
+            return null;
+        }
+        return paymentNotice;
+    }
+
+
+    /**
+     * 支付回调解析
+     * @param request
+     * @return
+     */
+    public static PaymentNotice payResultNotification(HttpServletRequest request){
+        String param = null;
+        try {
+            param = getParam(request);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        System.err.println("支付回调结果:========》" + param);
+
+        PaymentNotice paymentNotice = JSON.parseObject(param, PaymentNotice.class);
+        if(null == paymentNotice){
+            System.err.println("回调结果解析失败");
+            return null;
+        }
+        String signature_key = paymentNotice.getSignature_key();
+        String order_id = paymentNotice.getOrder_id();
+        String status_code = paymentNotice.getStatus_code();
+        if("400".equals(status_code)){
+            System.err.println("数据丢失或无效");
+            return null;
+        }
+        if("401".equals(status_code)){
+            System.err.println("授权错误");
+            return null;
+        }
+        if("404".equals(status_code)){
+            System.err.println("找不到请求的资源");
+            return null;
+        }
+        String gross_amount = paymentNotice.getGross_amount();
+        String sha_512_securePassword = get_SHA_512_SecurePassword(order_id + status_code + gross_amount + sandbox_serverKey);
+        if(!signature_key.equals(sha_512_securePassword)){
+            System.err.println("签名校验失败");
+            return null;
+        }
+        return paymentNotice;
+    }
+
+
+    /**
+     * 退款交易
+     * @param transaction_id      支付订单id
+     * @param refund_key          商户退款id
+     * @param amount              退款金额
+     * @param reason              退款说明
+     * @return
+     */
+    public static DirectRefundTransaction directRefundTransaction(String transaction_id, String refund_key, String amount, String reason){
+        //沙箱环境
+        Midtrans.serverKey = sandbox_serverKey;
+        Midtrans.clientKey = sandbox_clientKey;
+        Midtrans.isProduction = false;
+
+        //生产环境
+//        Midtrans.serverKey = serverKey;
+//        Midtrans.clientKey = clientKey;
+//        Midtrans.isProduction = true;
+
+        Map<String, String> requestBody = new HashMap<>();
+        requestBody.put("refund_key", refund_key);
+        requestBody.put("amount", amount);
+        requestBody.put("reason", reason);
+
+        JSONObject jsonObject = null;
+        try {
+            jsonObject = TransactionApi.directRefundTransaction(transaction_id, requestBody);
+        } catch (MidtransError midtransError) {
+            midtransError.printStackTrace();
+        }
+        /**
+         * {
+         *   "status_code": "200",
+         *   "status_message": "Success, refund request is approved by the bank",
+         *   "transaction_id": "fddb5889-fd39-46fe-809d-30679fe42434",
+         *   "order_id": "MID-1620622357",
+         *   "gross_amount": "10000.00",
+         *   "payment_type": "credit_card",
+         *   "transaction_time": "2016-06-28 09:42:20",
+         *   "transaction_status": "refund",
+         *   "refund_chargeback_id": 47594,
+         *   "refund_amount": "10000.00",
+         *   "refund_key": "01f1f771-b75c-48ef-b21d-193a79f8aa5b"
+         * }
+         */
+
+        DirectRefundTransaction directRefundTransaction = JSON.parseObject(jsonObject.toString(), DirectRefundTransaction.class);
+        if(null == directRefundTransaction){
+            System.err.println("退款结果解析失败");
+            return null;
+        }
+        String status_code = directRefundTransaction.getStatus_code();
+        if("400".equals(status_code)){
+            System.err.println("数据丢失或无效");
+            return null;
+        }
+        if("401".equals(status_code)){
+            System.err.println("授权错误");
+            return null;
+        }
+        if("404".equals(status_code)){
+            System.err.println("找不到请求的资源");
+            return null;
+        }
+        return directRefundTransaction;
+    }
+
+
+
+
+    /**
+     * 获取请求内容
+     * @param request
+     * @return
+     * @throws IOException
+     */
+    private static String getParam(HttpServletRequest request) throws IOException {
+        // 读取参数
+        InputStream inputStream;
+        StringBuilder sb = new StringBuilder();
+        inputStream = request.getInputStream();
+        String s;
+        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+        while ((s = in.readLine()) != null) {
+            sb.append(s);
+        }
+        in.close();
+        inputStream.close();
+        return sb.toString();
+    }
+
+
+    private static String get_SHA_512_SecurePassword(String passwordToHash){
+        String generatedPassword = null;
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-512");
+            byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
+            StringBuilder sb = new StringBuilder();
+            for(int i=0; i< bytes.length ;i++){
+                sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
+            }
+            generatedPassword = sb.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return generatedPassword;
+    }
+
+
+}

--
Gitblit v1.7.1