From 4e7189491eab55a3eef06ab751a6978cdb180374 Mon Sep 17 00:00:00 2001 From: duhui Date: Mon, 14 Mar 2022 10:50:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E6=B8=B8=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/DuoYouRechargeController.java | 57 ++++++ .../java/com/jmfy/controller/PayLogic.java | 10 ++ .../java/com/jmfy/paramBean/PaySdkEnum.java | 1 + src/main/java/com/jmfy/util/DuoyouUtils.java | 162 ++++++++++++++++++ 4 files changed, 230 insertions(+) create mode 100644 src/main/java/com/jmfy/controller/DuoYouRechargeController.java create mode 100644 src/main/java/com/jmfy/util/DuoyouUtils.java diff --git a/src/main/java/com/jmfy/controller/DuoYouRechargeController.java b/src/main/java/com/jmfy/controller/DuoYouRechargeController.java new file mode 100644 index 0000000..8ae5839 --- /dev/null +++ b/src/main/java/com/jmfy/controller/DuoYouRechargeController.java @@ -0,0 +1,57 @@ +package com.jmfy.controller; + +import com.jmfy.paramBean.PaySdkEnum; +import com.jmfy.util.DuoyouUtils; +import com.jmfy.util.JsonUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.HashMap; + +/** + * 多游游戏支付 + */ +@RestController +public class DuoYouRechargeController { + + @Resource + private PayLogic payLogic; + + private static final String APP_ID = "531340CB459ACA5BD680DAF51215B56F"; + private static final String APP_KEY = "31cc6cf98488f154d564153ecd93953e"; + + private static final Logger LOGGER = LoggerFactory.getLogger(DuoYouRechargeController.class); + + @RequestMapping(value = "/Web/duoyouCallback") + public String duoyouCallback(HttpServletRequest request) throws Exception { + HashMap parameterMap = JsonUtil.getInstence().getParameterMap2(request); + if (parameterMap.isEmpty()) { + LOGGER.info("duoyouGameCallback data is null"); + return "FAIL"; + } + + String sid = request.getParameter("app_id"); //多游分配的 appId + String transaction_id = request.getParameter("transaction_id"); //多游订单号 + String out_trade_no = request.getParameter("out_trade_no"); //游戏厂商订单号 + String total_fee = request.getParameter("total_fee"); //订单金额(分) + String payType = request.getParameter("payType"); //支付类型, Wx:微信支付 Ali:支付宝 + String extra = request.getParameter("extra"); //额外参数 + String sign = request.getParameter("sign"); //签名 + + HashMap map = new HashMap<>(); + map.put(DuoyouUtils.FIELD_SIGN,sign); + + boolean valid = DuoyouUtils.isSignatureValid(map, APP_ID, APP_KEY); + if (!valid) { + LOGGER.info("callback==>extra={},sin verify fail", extra); + return "FAIL"; + } + + return payLogic.initOrder(extra,out_trade_no,total_fee,new Date(),sid, PaySdkEnum.DUOYOU); + } +} diff --git a/src/main/java/com/jmfy/controller/PayLogic.java b/src/main/java/com/jmfy/controller/PayLogic.java index 336ea6c..aad93e2 100644 --- a/src/main/java/com/jmfy/controller/PayLogic.java +++ b/src/main/java/com/jmfy/controller/PayLogic.java @@ -36,6 +36,16 @@ public class PayLogic { private PayLogic() { } + /** + * + * @param collBackInfo 回调参数 + * @param orderId 自己订单号 + * @param amount 金钱,单位是分 + * @param time 支付时间 + * @param openId 渠道的用户id,目前用不到 + * @param sdk sdk,支付渠道标识 + * @return + */ public String initOrder(String collBackInfo, String orderId, String amount, Date time, String openId, PaySdkEnum sdk){ try { // 角色id_物品id_ccId_平台 diff --git a/src/main/java/com/jmfy/paramBean/PaySdkEnum.java b/src/main/java/com/jmfy/paramBean/PaySdkEnum.java index c5499ca..2feeb16 100644 --- a/src/main/java/com/jmfy/paramBean/PaySdkEnum.java +++ b/src/main/java/com/jmfy/paramBean/PaySdkEnum.java @@ -14,6 +14,7 @@ public enum PaySdkEnum { QUICK(4,"QUICK"), YX(5,"YX"), DY(6,"DY"), + DUOYOU(7,"DUOYOU"), ; private int id; diff --git a/src/main/java/com/jmfy/util/DuoyouUtils.java b/src/main/java/com/jmfy/util/DuoyouUtils.java new file mode 100644 index 0000000..6321189 --- /dev/null +++ b/src/main/java/com/jmfy/util/DuoyouUtils.java @@ -0,0 +1,162 @@ +package com.jmfy.util; + +import com.jmfy.controller.DuoYouRechargeController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.Map; +import java.util.Set; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +public class DuoyouUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(DuoyouUtils.class); + + public static final String FIELD_SIGN = "sign"; + public static final String FIELD_SIGN_TYPE = "sign_type"; + + + public enum SignType { + MD5, HMACSHA256 + } + + + + public static boolean isSignatureValid(Map data, String APP_ID, String APP_KEY) throws Exception { + StringBuffer sb = new StringBuffer(); + sb.append(APP_ID); + sb.append("GAME_MAKERS"); + sb.append(APP_KEY); + // 然后md5生成签名秘钥 + String signKey = DuoyouUtils.MD5Normal(sb.toString()); + return isSignatureValid(data, signKey, SignType.HMACSHA256); + } + + + + /** + * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。 + * + * @param data Map类型数据 + * @param key API密钥 + * @return 签名是否正确 + * @throws Exception + */ + public static boolean isSignatureValid(Map data, String key) throws Exception { + return isSignatureValid(data, key, SignType.MD5); + } + + /** + * 判断签名是否正确,必须包含sign字段,否则返回false。 + * + * @param data Map类型数据 + * @param key API密钥 + * @param signType 签名方式 + * @return 签名是否正确 + * @throws Exception + */ + public static boolean isSignatureValid(Map data, String key, SignType signType) throws Exception { + if (!data.containsKey(FIELD_SIGN) ) { + return false; + } + String sign = data.get(FIELD_SIGN); + LOGGER.info("duoyou sign1:{}",sign); + LOGGER.info("duoyou sign2:{}",generateSignature(data, key, signType)); + return generateSignature(data, key, signType).equals(sign); + } + + + /** + * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。 + * + * @param data 待签名数据 + * @param key API密钥 + * @param signType 签名方式 + * @return 签名 + */ + public static String generateSignature(final Map data, String key, SignType signType) throws Exception { + Set keySet = data.keySet(); + String[] keyArray = keySet.toArray(new String[keySet.size()]); + Arrays.sort(keyArray); + StringBuilder sb = new StringBuilder(); + for (String k : keyArray) { + if (k.equals(FIELD_SIGN)) { + continue; + } + if (data.get(k) != null && data.get(k).trim().length() > 0) // 参数值为空,则不参与签名 + sb.append(k).append("=").append(data.get(k).trim()).append("&"); + } + sb.append("key=").append(key); + if (SignType.MD5.equals(signType)) { + return MD5(sb.toString()).toUpperCase(); + } + else if (SignType.HMACSHA256.equals(signType)) { + return HMACSHA256(sb.toString(), key); + } + else { + throw new Exception(String.format("Invalid sign_type: %s", signType)); + } + } + + + + + /** + * 生成 MD5 + * + * @param data 待处理数据 + * @return MD5结果 + */ + public static String MD5(String data) throws Exception { + java.security.MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] array = md.digest(data.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (byte item : array) { + sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString().toUpperCase(); + } + + + + /** + * 生成 MD5 + * + * @param data 待处理数据 + * @return MD5结果 + */ + public static String MD5Normal(String data) throws Exception { + java.security.MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] array = md.digest(data.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (byte item : array) { + sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString(); + } + + /** + * 生成 HMACSHA256 + * @param data 待处理数据 + * @param key 密钥 + * @return 加密结果 + * @throws Exception + */ + public static String HMACSHA256(String data, String key) throws Exception { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (byte item : array) { + sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString().toUpperCase(); + } + + +}