package com.nova.sankuai.domain.api.yinsheng;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.parser.Feature;
|
import com.nova.sankuai.domain.entity.VipCardOrder;
|
import com.nova.sankuai.domain.vo.vipcard.VipCardVo;
|
import com.nova.sankuai.infra.config.CommonException;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.tomcat.util.codec.binary.Base64;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Component;
|
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* @author weikangdi
|
* @create 2022/3/2
|
*/
|
@Component
|
@Slf4j
|
public class YinShengUtil {
|
@Value("${yinsheng.notify_url}")
|
private String notify_url;
|
|
@Value("${yinsheng.h5.partner_id}")
|
private String partner_id;
|
|
@Value("${yinsheng.h5.seller_id}")
|
private String seller_id;
|
|
@Value("${yinsheng.h5.seller_name}")
|
private String seller_name;
|
|
@Value("${yinsheng.h5.business_code}")
|
private String business_code;
|
|
@Value("${yinsheng.h5.password}")
|
private String password;
|
|
@Value("${yinsheng.h5.private_key_path}")
|
private String privateKeyPath;
|
|
@Value("${yinsheng.h5.public_key_path}")
|
private String publicKeyPath;
|
|
/**
|
* wap支付,手机收银台
|
*/
|
public final static String WAP_METHOD = "ysepay.online.wap.directpay.createbyuser";
|
|
|
public Map<String, String> generateParam(VipCardVo cardVo, String orderNo) {
|
Map<String, String> mapData = new HashMap<>();
|
//组装请求参数报文
|
mapData.put("method", WAP_METHOD);
|
mapData.put("partner_id", partner_id);
|
mapData.put("timestamp", DateUtil.getDateNow());
|
mapData.put("charset", "utf-8");
|
mapData.put("sign_type", "SM");
|
mapData.put("notify_url", notify_url + "/api/v1/vipCardOrder/notifyByYinSheng");
|
//银盛支付处理完请求后,当前页面自动跳转到商户网站里指定页面的http路径。若不想回调,则需传入银盛指定地址
|
mapData.put("return_url", cardVo.getUrl());
|
mapData.put("version", "3.0");
|
|
mapData.put("out_trade_no", orderNo);
|
mapData.put("shopdate", DateUtil.getDateNowYmd());
|
mapData.put("subject", cardVo.getName());
|
mapData.put("total_amount", cardVo.parseSellingPrice());
|
mapData.put("currency", "CNY");
|
mapData.put("seller_id", seller_id);
|
mapData.put("seller_name", seller_name);
|
mapData.put("timeout_express", "30m");
|
mapData.put("business_code", business_code);
|
// mapData.put("pay_mode", "native");
|
// mapData.put("bank_type", "1903000");
|
try {
|
log.info("待验签数据:" + CommonUtil.mapToString(mapData));
|
String sign = sign(mapData);
|
mapData.put("sign", sign);
|
} catch (Exception e) {
|
log.error("签名异常:", e);
|
throw new CommonException("参数异常");
|
}
|
return mapData;
|
}
|
|
/**
|
* 异步通知参数验签
|
*/
|
public boolean asynVerifyYs(Map<String, String> reqMap) throws Exception {
|
//获取银盛公钥
|
GMCertInfo verifyCertInfo = GMSignUtils.getVerifyCertInfo(publicKeyPath);
|
//验签
|
String sign = reqMap.get("sign");
|
System.out.println("签名原文:" + reqMap);
|
String content = StringUtil.createLinkString(CommonUtil.paraFilter(reqMap));
|
System.out.println("验签数据" + content + "," + sign);
|
byte[] srcData = content.getBytes("utf-8");
|
boolean validateSignResult = GMSignUtils.verifyMsgSignSM2(verifyCertInfo, Base64.decodeBase64(sign.getBytes("utf-8")), srcData);
|
return validateSignResult;
|
}
|
|
/**
|
* 同步请求参数签名
|
*/
|
public String sign(Map<String, String> mapData) throws Exception {
|
//商户私钥地址
|
//将所有外层报文参数(sign除外)进行字典排序,组成字符串得到待签名内容
|
String signContent = CommonUtil.mapToString(mapData);
|
log.info("待签名内容:{}", signContent);
|
//执行签名
|
String sign = GMSignUtils.signMsgSM2(privateKeyPath, password, signContent);
|
return sign;
|
}
|
|
public JSONObject getOrderStatus(VipCardOrder order) {
|
Map<String, String> mapData = new HashMap<>();
|
//组装请求参数报文
|
mapData.put("method", "ysepay.online.trade.order.query");
|
mapData.put("partner_id", partner_id);
|
mapData.put("timestamp", DateUtil.getDateNow());
|
mapData.put("charset", "utf-8");
|
mapData.put("sign_type", "SM");
|
mapData.put("version", "3.0");
|
JSONObject biz_content = new JSONObject();
|
biz_content.put("out_trade_no", order.getPartnerThirdOrderId());
|
biz_content.put("shopdate", cn.hutool.core.date.DateUtil.format(order.getCreationDate(), "yyyyMMdd"));
|
mapData.put("biz_content", biz_content.toJSONString());
|
try {
|
log.info("待验签数据:" + CommonUtil.mapToString(mapData));
|
String sign = sign(mapData);
|
mapData.put("sign", sign);
|
} catch (Exception e) {
|
log.error("签名异常:", e);
|
throw new CommonException("参数异常");
|
}
|
//调用银盛接口查询状态
|
String result = HttpRequest.sendPost("https://search.ysepay.com/gateway.do", CommonUtil.mapToString(mapData));
|
try {
|
JSONObject jsonObject = JSON.parseObject(result, Feature.OrderedField);
|
log.info("银盛查询明细返回原始参数:jsonObject:" + jsonObject);
|
JSONObject response = jsonObject.getJSONObject("ysepay_online_trade_order_query_response");
|
String content = response.toString();
|
String sign = jsonObject.get("sign").toString();
|
log.info("sign:" + sign);
|
log.info("content:" + content);
|
boolean verify = resultVerify(sign, content);
|
log.info("同步请求验签结果:{}", verify);
|
if (verify && "Success".equals(response.getString("msg"))) {
|
return response;
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
log.error("同步请求验签异常" + result);
|
throw new CommonException("同步请求验签异常");
|
}
|
return null;
|
}
|
|
public boolean resultVerify(String sign, String content) throws Exception {
|
//获取银盛公钥
|
GMCertInfo verifyCertInfo = GMSignUtils.getVerifyCertInfo(publicKeyPath);
|
//验签
|
byte[] srcData = content.getBytes("utf-8");
|
boolean validateSignResult = GMSignUtils.verifyMsgSignSM2(verifyCertInfo, Base64.decodeBase64(sign.getBytes("utf-8")), srcData);
|
return validateSignResult;
|
}
|
|
}
|