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