首页 新闻 赞助 找找看

易宝代扣充值接口,提交报文返回“验证签名失败”

0
悬赏园豆:40 [已解决问题] 解决于 2014-08-28 14:10

 /* 附
 * 发送报文的完整步骤:
 *  1. 拿到Grp标签的内容(包括Grp标签本身)
 *  2. 调用DigitSignUtils.getSignInfo方法进行签名
 *  3. 将生成的签名进行Base64编码并放入Sign标签内
 *  4. 将报文整个再进行Base64编码进行Post
 *
 * 接收报文的完整步骤:
 *  1. 将整个接收到的字符串进行Base64解码
 *  2. 拿到Grp标签明文(包括Grp标签本身)和Sign标签内容(Sign标签内容要进行Base64解码)
 *  3. 调用DigitSignUtils.verify方法进行签名校验
 *  4. 若校验通过,说明报文正确
 */

  

 

 

  /**
     * 在线充值
     * @throws Exception
     */
    public PayReturnData recharge(PayReCharge charge) throws Exception{
        PayReturnData payReturn = new PayReturnData();
        //明文数据(Grp标签的内容)
        String data = PayUtil.recharge(charge);
        //生成签名
        String sign = PayUtil.signInfo(data);
        //完整报文
        String dataComplete = PayUtil.reChargeComplete(data, sign);
        System.out.println(dataComplete);
        //String dataComplete = "<MsgTes><Grp><GrpHead><Version>2.0.0</Version><BusCd>1023</BusCd><MctCd>10040010535</MctCd><SendDate>20121207</SendDate><SendTime>153030</SendTime><SendSeq>1234567890</SendSeq><remark1>remark1</remark1><remark2>remark2</remark2></GrpHead><GrpBody><OdrNo>20130705181836</OdrNo><OdrAmt>100</OdrAmt><OdrTime>20130705181836</OdrTime><CommName>futuresrading</CommName><CertType>010</CertType><CertCode>610111199006252073</CertCode><CstName>www</CstName><CstCard>6222023700016065783</CstCard><BankNo>102</BankNo><bakAccType>pu</bakAccType></GrpBody></Grp><Sign>mtUal1+AJMrWpmcT2mcm6ptAu2SU7C88Y7yal8ToFPAVYaF3elLCyku+peL2+RXyfG1v6mM2zhP01mRgJmT4lypxRgWhBOIhDfDmclap+THTIjxQcMJQnflOAxU6ubMnMCjQ9KcTQIlrHGQO+Jt2Q7z+pq6sVk58g/5so5Isn34=</Sign></MsgTes>";
        if(dataComplete != null && !"".equals(dataComplete)){
            //机构端完整报文加密
            dataComplete = Base64Utils.encrypt(dataComplete);
            //post提交,获取返回值
            String returnData = PayUtil.postData(dataComplete);
            System.out.println(returnData);
            if(returnData != null && !"".equals(returnData)){
                //易宝返回信息解密
                returnData = Base64Utils.decrypt(returnData);
                //签名校验
                if(PayUtil.signVerify(returnData)){
                    //返回信息解析成对象集合
                    payReturn = PayUtil.returnData(returnData);
                }
                
            }
        }
        return  payReturn;
    }

public class PayUtil {
    
    private static final String CONTEXT_PATH = ServletActionContext.getServletContext().getRealPath("");
    private static final String certPath = "E:/public.cer";
    
    private static final String keyStorePath = "E:/private.pfx";
    private static final String privateKeyPassword = "111111";
    
    private static final String charset = "UTF-8";
    
    private static final String mctCd = "10040003895";
    private static final String sendSeq = java.util.UUID.randomUUID().toString();
    
    private static final String url = "http://ishanghu.yeepay.com/fund/ng/fanYaServlet";// 正式的测试环境地址
    
    /**
     * 身份验证
     * @param CstName
     * @param CertType
     * @param CertCode
     * @param BankNo
     * @param CstCard
     * @return
     */
    @SuppressWarnings("unused")
    public static String validate(String CstName,String CertType,String CertCode,String BankNo,String CstCard){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");      //发送日期    
        SimpleDateFormat format = new SimpleDateFormat("HHmmss");     //发送时间
        SimpleDateFormat sdm = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        StringBuffer str = new StringBuffer();
        String SendSeq = sdm.format(new Date());
        String MctCd = "10040003895";
        str.append("<Grp><GrpHead><Version>2.0.0</Version><BusCd>1006</BusCd><MctCd>");
        str.append(MctCd);
        str.append("</MctCd><SendDate>");
        str.append(sdf.format(new Date()));
        str.append("</SendDate><SendTime>");
        str.append(format.format(new Date()));
        str.append("</SendTime><SendSeq>");
        str.append(SendSeq);
        str.append("</SendSeq><remark1></remark1><remark2></remark2></GrpHead><GrpBody><TraderCode>0123456789</TraderCode>");
        str.append("<CstName>");
        str.append(CstName);
        str.append("</CstName><CertType>"+CertType+"</CertType><CertCode>");
        str.append(CertCode);
        str.append("</CertCode><BankNo>");
        str.append(BankNo);
        str.append("</BankNo><CstCard>");
        str.append(CstCard);
        str.append("</CstCard></GrpBody></Grp>");
        return str.toString();
    }
    
    /**
     * 易宝返回 身份验证 结果信息
     * @param data
     * @return
     */
    public static String reValidate(String data){
        String status = "00";
        SAXReader saxReader = new SAXReader();
        Document document = null;  
        try{  
           document = saxReader.read(new StringReader(data));  
        }catch(DocumentException e){  
           e.printStackTrace();  
           return status;  
        }
        Element root = document.getRootElement();
        List nodes = root.selectNodes("/MsgTes/Grp/GrpBody");
        for(Iterator i = nodes.iterator();i.hasNext();){
            Element datas = (Element)i.next();
            status = datas.elementText("status");
            if(null == status || "".equals(status)){
                status ="00";
            }
            return status;
        }
        return status;
    }
    
    /**
     * 充值报文部分信息
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unused")
    public static String recharge(PayReCharge charge) throws Exception{
        System.out.println(CONTEXT_PATH);
        StringBuffer str = new StringBuffer();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat format = new SimpleDateFormat("HHmmss");
        SimpleDateFormat sdm = new SimpleDateFormat("yyyyMMddHHmmss");
        //str.append("<?xml version='1.0' encoding='UTF-8'?>");
        //str.append("<MsgTes xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='1023_200.xsd'>");
        str.append("<Grp><GrpHead><Version>2.0.0</Version><BusCd>1023</BusCd><MctCd>");
        str.append(mctCd);
        str.append("</MctCd><SendDate>");
        str.append(sdf.format(new Date()));
        str.append("</SendDate><SendTime>");
        str.append(format.format(new Date()));
        str.append("</SendTime><SendSeq>");
        str.append(sdm.format(new Date()));
        str.append("</SendSeq><remark1>remark1</remark1><remark2>remark2</remark2></GrpHead><GrpBody><OdrNo>");
        str.append(sdm.format(new Date()));
        str.append("</OdrNo><OdrAmt>");
        str.append(charge.getOdrAmt());
        str.append("</OdrAmt>");
        str.append("<OdrTime>");
        str.append(sdm.format(new Date()));
        str.append("</OdrTime><commName>");
        str.append(charge.getCommName());
        str.append("</commName><CertType>"+charge.getCertType()+"</CertType><CertCode>");
        str.append(charge.getCertCode());
        str.append("</CertCode><CstName>");
        str.append(charge.getCstName());
        str.append("</CstName><CstCard>");
        str.append(charge.getCstCard());
        str.append("</CstCard><BankNo>"+charge.getBankNo()+"</BankNo><bakAccTyp>0101");
        str.append("</bakAccTyp></GrpBody></Grp>");
        //str.append("<Sign>"+sign+"</Sign></MsgTes>");
        return str.toString();
    }
    
    /**
     * 充值报文完整xml信息
     */
    public static String reChargeComplete(String data,String sign){
        StringBuffer str = new StringBuffer();
        //str.append("<?xml version='1.0' encoding='UTF-8'?>");
        //str.append("<MsgTes xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='1023_200.xsd'>");
        str.append("<MsgTes>");
        str.append(data);
        str.append("<Sign>"+sign+"</Sign></MsgTes>");
        return str.toString();
    }
    
    /**
     * 生成签名
     * @param data
     * @return
     * @throws UnsupportedEncodingException
     * @throws Exception
     */
    public static String signInfo(String data) throws UnsupportedEncodingException, Exception{
        String sign = null;
        if(data!=null && !"".equals(data)){
            System.out.println(DigitSignUtils.getSignInfo(keyStorePath,privateKeyPassword, data.getBytes(charset)).toString());
            sign = Base64Utils.encrypt(DigitSignUtils.getSignInfo(keyStorePath,privateKeyPassword, data.getBytes(charset)).toString());
            System.out.println(sign);
        }
        return sign;
    }
    
    /**
     * 签名校验
     * @throws Exception
     * @throws UnsupportedEncodingException
     */
    public static boolean signVerify(String returnData) throws UnsupportedEncodingException, Exception{
        boolean bool = false;
        if(returnData != null && !"".equals(returnData)){
            //获取明文数据
            System.out.println("回调报文:"+returnData);
            Integer startGrp = returnData.indexOf("<Grp>");
            Integer endGrp = returnData.indexOf("</Grp>");
            String subStrGrp = null;
            if(startGrp != -1 && endGrp != -1){
                subStrGrp = returnData.substring(startGrp, endGrp+6);
                System.out.println("明文数据:"+subStrGrp);
            }
            //获取数字签名
            Integer startSign = returnData.indexOf("<Sign>");
            Integer endSign = returnData.indexOf("</Sign>");
            String subStrSign = null;
            if(startSign != -1 && endSign != -1){
                subStrSign = returnData.substring(startSign+6, endSign);
                if(subStrSign != null && !"".equals(subStrSign)){
                    System.out.println("数字签名解密前:"+subStrSign);
                    subStrSign = Base64Utils.decrypt(subStrSign);
                    System.out.println("数字签名解密后:"+subStrSign);
                }
            }
            
            if(subStrGrp != null && !"".equals(subStrGrp) && subStrSign != null && !"".equals(subStrSign)){
                bool = DigitSignUtils.verify(certPath, subStrGrp.getBytes(charset), subStrSign.getBytes(charset));
            }
            
        }
        return bool;
    }
    
    /**
     * 机构端提交报文信息
     * @param data
     * @return
     * @throws Exception
     */
    public static String postData(String dataComplete) throws Exception{
        // 新建自定义客户端
        MyHttpClient client = new MyHttpClient();
        
        // 将post的数据放入map
        Map<String, String> map = new HashMap<String, String>();
        map.put("data", dataComplete);// key必须为data
        
        // 执行请求
        PostMethod post = client.postRequest(url, map, null, MyHttpClient.CHARSET_UTF8);
        if (post.getStatusCode() == HttpStatus.SC_OK){// 判断请求是否成功
            // 若请求成功则获取返回体(httpclient建议使用getResponseBodyAsStream)
            // 为了方便查看返回体用stream2String将流转为字符串
            return MyHttpClient.stream2String(post.getResponseBodyAsStream());
        }
        return null;
    }
    
    /**
     * 解析易宝的充值返回信息
     * @param returnData
     * @return
     */
    public static PayReturnData returnData(String returnData){
        SAXReader saxReader = new SAXReader();
        Document document = null;  
        try{  
           document = saxReader.read(new StringReader(returnData));  
        }catch(DocumentException e){  
           e.printStackTrace();  
           return null;  
        }
        Element root = document.getRootElement();  
        PayReturnData payReturn = new PayReturnData();
        //获取客户的返回信息
        List nodes = root.selectNodes("/MsgTes/Grp/GrpBody");
        for(Iterator i = nodes.iterator();i.hasNext();){
            Element datas = (Element)i.next();
            
            String odrNo = datas.elementText("OdrNo");
            //订单号
            if(odrNo != null && !"".equals(odrNo)){
                payReturn.setOdrNo(odrNo);
            }
            
            String ypOdrNo = datas.elementText("YpOdrNo");
            //易宝交易号
            if(ypOdrNo != null && !"".equals(ypOdrNo)){
                payReturn.setYpOdrNo(ypOdrNo);
            }
            
            String odrAmt = datas.elementText("OdrAmt");
            //订单金额
            if(odrAmt != null && !"".equals(odrAmt)){
                payReturn.setOdrAmt(odrAmt);
            }
            
            String payTime = datas.elementText("PayTime");
            //支付时间
            if(payTime != null && !"".equals(payTime)){
                payReturn.setPayTime(payTime);
            }
            
            String bankNo = datas.elementText("BankNo");
            //银行机构号
            if(bankNo != null && !"".equals(bankNo)){
                payReturn.setBankNo(bankNo);
            }
            
            String payTime1 = datas.elementText("payTime");
            //授权号
            if(payTime1 != null && "".equals(payTime1)){
                payReturn.setPayTime1(payTime1);
            }
            
            String status = datas.elementText("status");
            //返回标示
            if(status != null && !"".equals(status)){
                payReturn.setStatus(status);
            }
            
            String info = datas.elementText("info");
            //标示信息
            if(info != null && !"".equals(info)){
                payReturn.setInfo(info);
            }
            
        }
        return payReturn;
    }
    
    /**
     * 生产32位唯一序列
     * @return
     */
//    public static String getUUid(){
//        return java.util.UUID.randomUUID().toString();
//    }
    public static String getUUid(){
        String uuid = java.util.UUID.randomUUID().toString();
        uuid = uuid.replace("-", "");
        return uuid;
    }
}

 

以上是我的源码,望懂行的同事指点一下。

人间烟火的主页 人间烟火 | 初学一级 | 园豆:20
提问于:2013-07-08 22:10
< >
分享
最佳答案
0

字符流让我用String给转换了

人间烟火 | 初学一级 |园豆:20 | 2013-07-18 19:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册