|  |  |  | 
|---|
|  |  |  | import cc.mrbird.febs.pay.service.UnipayService; | 
|---|
|  |  |  | import cc.mrbird.febs.pay.util.*; | 
|---|
|  |  |  | import cn.hutool.core.date.DateUtil; | 
|---|
|  |  |  | import cn.hutool.core.util.ObjectUtil; | 
|---|
|  |  |  | import cn.hutool.core.util.StrUtil; | 
|---|
|  |  |  | import cn.hutool.json.JSONUtil; | 
|---|
|  |  |  | import com.alibaba.fastjson.JSON; | 
|---|
|  |  |  | 
|---|
|  |  |  | "MXm0GwJAZd4Bk8ZYJopIOUyRLibRQIFnI78Q7HAuAUW7QtSX4yh5bMcu+Nt8zIkNAuvBC8Ju7hAmmo1V7n" + | 
|---|
|  |  |  | "cNgAAtydXYWQJALLOFCjCkRgeRVL8YE8bVi4U16b8ltAN1DlbWEzui6VFy2vIga3IryesNVAOOdornyAwf" + | 
|---|
|  |  |  | "1huqB2lYfuQwtrIBKg=="; | 
|---|
|  |  |  | public static final String MD5KEY = "2e95f6a3e11e47fa8a4386d6aefe1735"; | 
|---|
|  |  |  | public static final String notifyUrl = "http://47.111.90.145:8800/api/unipay/unipayCallBack"; | 
|---|
|  |  |  | public static final String agreementPayNotifyUrl = "http://47.111.90.145:8800/api/unipay/agreementPayCallBack"; | 
|---|
|  |  |  | public static final String agreementPayNotifyUrl = "http://47.111.90.145:8800/api/unipay/agreeMentPayCallBack"; | 
|---|
|  |  |  | public static final String singlePayNotifyUrl = "http://47.111.90.145:8800/api/unipay/singlePayCallBack"; | 
|---|
|  |  |  | public static final String p1MerchantNo = "888118000001971";/** 商户编号 */ | 
|---|
|  |  |  | public static final String aesKey = "1234567891234567";/** 商户编号 */ | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | @Transactional | 
|---|
|  |  |  | public String singlePay(SinglePayDto singlePayDto) { | 
|---|
|  |  |  | String singlePay = null; | 
|---|
|  |  |  | String key = MD5KEY; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Map<String, Object> map = new HashMap<>(); | 
|---|
|  |  |  | map.put("userNo", p1MerchantNo);// 商户编号 | 
|---|
|  |  |  | map.put("productCode", "BANK_PAY_DAILY_ORDER");//产品类型 | 
|---|
|  |  |  | map.put("requestTime", DateUtil.now()); // 交易请求时间 | 
|---|
|  |  |  | map.put("merchantOrderNo", singlePayDto.getMerchantOrderNo());//商户订单号 | 
|---|
|  |  |  | map.put("receiverAccountNoEnc", singlePayDto.getReceiverAccountNoEncBankNo()); // 收款账户号 | 
|---|
|  |  |  | map.put("receiverNameEnc", singlePayDto.getReceiverAccountNoEncName()); // 收款人 | 
|---|
|  |  |  | map.put("receiverAccountType", singlePayDto.getReceiverAccountType());//账户类型 | 
|---|
|  |  |  | map.put("paidAmount", singlePayDto.getPaidAmount()); //交易金额 | 
|---|
|  |  |  | map.put("currency", singlePayDto.getCurrency());//币种 | 
|---|
|  |  |  | map.put("isChecked", singlePayDto.getIsChecked());//是否复核 | 
|---|
|  |  |  | map.put("paidDesc", singlePayDto.getPaidDesc());//代付说明 | 
|---|
|  |  |  | map.put("paidUse", singlePayDto.getPaidUse());//代付用途 | 
|---|
|  |  |  | map.put("callbackUrl", singlePayNotifyUrl);//商户通知地址 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String reqSign = getRequestSign(map); | 
|---|
|  |  |  | // 签名 | 
|---|
|  |  |  | String hmac = Md5_Sign.SignByMD5(reqSign, key); | 
|---|
|  |  |  | map.put("hmac", hmac);/** 签名数据 */ | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // Map转json字符串 | 
|---|
|  |  |  | String reqBodyJson = JSON.toJSONString(map); | 
|---|
|  |  |  | System.out.println("reqBodyJson:" + reqBodyJson); | 
|---|
|  |  |  | String httpResponseJson = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | httpResponseJson = HttpClientUtil | 
|---|
|  |  |  | .sendHttpPost("https://www.joinpay.com/payment/pay/singlePay",reqBodyJson); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | System.out.println(httpResponseJson); | 
|---|
|  |  |  | if(StrUtil.isNotBlank(httpResponseJson)){ | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | singlePay = doResponseInfo(httpResponseJson, key); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return singlePay; | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | return "fail"; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 对单笔代付响应信息的处理 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param httpResponseJson 响应信息json字符串 | 
|---|
|  |  |  | * @param key 商户秘钥 | 
|---|
|  |  |  | * @throws Exception 异常实体类 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @SuppressWarnings("unchecked") | 
|---|
|  |  |  | private static String doResponseInfo(String httpResponseJson, String key) throws Exception { | 
|---|
|  |  |  | // 响应信息map集合 | 
|---|
|  |  |  | Map<String, Object> httpResponseMap = (Map<String, Object>) JSONObject.parse(httpResponseJson); | 
|---|
|  |  |  | // 业务数据map集合 | 
|---|
|  |  |  | Map<String, Object> dataMap = (Map<String, Object>) httpResponseMap.get("data"); | 
|---|
|  |  |  | dataMap.put("statusCode", httpResponseMap.get("statusCode")); | 
|---|
|  |  |  | dataMap.put("message", httpResponseMap.get("message")); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 请求签名串 | 
|---|
|  |  |  | String reqSign = getRequestSign(httpResponseMap); | 
|---|
|  |  |  | // 响应签名串 | 
|---|
|  |  |  | String respSign = getResponseSign(dataMap); | 
|---|
|  |  |  | // 请求数据的加密签名 | 
|---|
|  |  |  | String reqHmac = Md5_Sign.SignByMD5(respSign, key); | 
|---|
|  |  |  | // 请求数据的加密签名 | 
|---|
|  |  |  | String respHmac = (String) dataMap.get("hmac"); | 
|---|
|  |  |  | System.out.println("reqHmac:" + reqHmac); | 
|---|
|  |  |  | System.out.println("respSign:" + respHmac); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | reqHmac=reqHmac.toUpperCase(); | 
|---|
|  |  |  | respHmac=respHmac.toUpperCase(); | 
|---|
|  |  |  | boolean isMatch = reqHmac.equals(respHmac); | 
|---|
|  |  |  | if (isMatch) { | 
|---|
|  |  |  | if("2001".equals(httpResponseMap.get("statusCode").toString()) | 
|---|
|  |  |  | && ObjectUtil.isEmpty(dataMap.get("errorCode"))){ | 
|---|
|  |  |  | System.out.println("验签成功"); | 
|---|
|  |  |  | return dataMap.get("merchantOrderNo").toString(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return "fail"; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取响应数据签名串信息 | 
|---|
|  |  |  | * 必须按新代付接口文档应答参数信息顺序来进行字符串的拼接,详情请参考新代付接口文档的应答报文 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param params 响应数据参数 | 
|---|
|  |  |  | * @return 返回响应签名串 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static String getResponseSign(Map<String, Object> params) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | StringBuilder stringBuilder = new StringBuilder(); | 
|---|
|  |  |  | stringBuilder.append(params.get("statusCode")).append(params.get("message")).append(params.get("errorCode")) | 
|---|
|  |  |  | .append(params.get("errorDesc")).append(params.get("userNo")).append(params.get("merchantOrderNo")); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return stringBuilder.toString(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取请求数据签名串信息 | 
|---|
|  |  |  | * 必须按新代付接口文档请求参数信息顺序来进行字符串的拼接,详情请参考新代付接口文档请求报文 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param params 请求数据参数 | 
|---|
|  |  |  | * @return 返回请求签名串 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static String getRequestSign(Map<String, Object> params) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | StringBuilder stringBuilder = new StringBuilder(); | 
|---|
|  |  |  | stringBuilder.append(params.get("userNo")) | 
|---|
|  |  |  | .append(params.get("productCode")) | 
|---|
|  |  |  | .append(params.get("requestTime")) | 
|---|
|  |  |  | .append(params.get("merchantOrderNo")) | 
|---|
|  |  |  | .append(params.get("receiverAccountNoEnc")) | 
|---|
|  |  |  | .append(params.get("receiverNameEnc")) | 
|---|
|  |  |  | .append(params.get("receiverAccountType")) | 
|---|
|  |  |  | .append(params.get("paidAmount")) | 
|---|
|  |  |  | .append(params.get("currency")) | 
|---|
|  |  |  | .append(params.get("isChecked")) | 
|---|
|  |  |  | .append(params.get("paidDesc")) | 
|---|
|  |  |  | .append(params.get("paidUse")) | 
|---|
|  |  |  | .append(params.get("callbackUrl")); | 
|---|
|  |  |  | System.out.println("reqSign:" + stringBuilder.toString()); | 
|---|
|  |  |  | return stringBuilder.toString(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static void main(String[] args) { | 
|---|
|  |  |  | //        BigDecimal value = new BigDecimal("0.10858").setScale(2,BigDecimal.ROUND_HALF_UP); | 
|---|
|  |  |  | BigDecimal value = new BigDecimal("1231.1").setScale(2, BigDecimal.ROUND_DOWN); | 
|---|
|  |  |  | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | System.out.println(httpResponseJson); | 
|---|
|  |  |  | if(StrUtil.isNotBlank(httpResponseJson)){ | 
|---|
|  |  |  | cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(httpResponseJson); | 
|---|
|  |  |  | System.out.println(jsonObject); | 
|---|
|  |  |  | String biz_code = jsonObject.get("biz_code").toString(); | 
|---|
|  |  |  | if("JS000000" == biz_code){ | 
|---|
|  |  |  | return httpResponseJson; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return "fail"; | 
|---|
|  |  |  | cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(httpResponseJson); | 
|---|
|  |  |  | System.out.println(jsonObject); | 
|---|
|  |  |  | String biz_code = jsonObject.get("biz_code").toString(); | 
|---|
|  |  |  | String biz_msg = jsonObject.get("biz_msg").toString(); | 
|---|
|  |  |  | if("JS000000".equals(biz_code)){ | 
|---|
|  |  |  | return biz_code; | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | return "fail"; | 
|---|
|  |  |  | return biz_msg; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|