package com.xzx.gc.util.pay.util;
|
|
|
import com.xzx.gc.model.admin.UserAccountModel;
|
import com.xzx.gc.util.pay.util.entity.ResultEntity;
|
import com.xzx.gc.util.pay.util.entity.TransfersDtoAdmin;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.LogFactory;
|
import org.w3c.dom.Document;
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathFactory;
|
import java.io.ByteArrayInputStream;
|
import java.io.InputStream;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
|
|
@Slf4j
|
public class WechatpayUtil
|
{
|
|
|
public static String queryErrorMessage(String xmlStr){
|
Document document = StringTOXml(xmlStr);
|
String nodePath = "/xml/err_code_des";
|
String msg = getNodeValue(document,nodePath);
|
return msg;
|
}
|
|
/**
|
*
|
* @param
|
* @return Document 对象
|
*/
|
public static Document StringTOXml(String str) {
|
|
StringBuilder sXML = new StringBuilder();
|
sXML.append(str);
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
Document doc = null;
|
try {
|
InputStream is = new ByteArrayInputStream(sXML.toString().getBytes("utf-8"));
|
doc = dbf.newDocumentBuilder().parse(is);
|
is.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return doc;
|
}
|
/**
|
*
|
* @param document
|
* @return 某个节点的值 前提是需要知道xml格式,知道需要取的节点相对根节点所在位置
|
*/
|
public static String getNodeValue(Document document, String nodePaht) {
|
XPathFactory xpfactory = XPathFactory.newInstance();
|
XPath path = xpfactory.newXPath();
|
String servInitrBrch = "";
|
try {
|
servInitrBrch = path.evaluate(nodePaht, document);
|
} catch (XPathExpressionException e) {
|
e.printStackTrace();
|
}
|
return servInitrBrch;
|
}
|
|
public static void main(String[] args) {
|
String xmlStr = "<xml>\n" +
|
"<return_code><![CDATA[SUCCESS]]></return_code>\n" +
|
"<return_msg><![CDATA[支付失败]]></return_msg>\n" +
|
"<mch_appid><![CDATA[wx9c43b2bf3aad415b]]></mch_appid>\n" +
|
"<mchid><![CDATA[1546567611]]></mchid>\n" +
|
"<result_code><![CDATA[FAIL]]></result_code>\n" +
|
"<err_code><![CDATA[V2_ACCOUNT_SIMPLE_BAN]]></err_code>\n" +
|
"<err_code_des><![CDATA[非实名用户账号不可发放]]></err_code_des>\n" +
|
"</xml>";
|
String message = queryErrorMessage(xmlStr);
|
System.out.println(message);
|
}
|
/**
|
* @param model
|
* 微信接口请求参数DTO对象
|
* @return ResultEntity 返回结构体
|
*/
|
public static ResultEntity doTransfers(String url, String path, TransfersDtoAdmin model, UserAccountModel userAccount, String stringBuild)
|
{
|
try
|
{
|
// 3.加载证书请求接口
|
String result = HttpRequestHandler.httpsRequest(url, stringBuild,
|
model, path);
|
log.debug(("response xml = " + result));
|
if(result.contains("CDATA[FAIL]")){
|
String message = queryErrorMessage(result);
|
return new ResultEntity(false, message);
|
}
|
}
|
catch (Exception e)
|
{
|
e.printStackTrace();
|
return new ResultEntity(false, e.getMessage());
|
}
|
return new ResultEntity(true);
|
}
|
|
public static String getStringBuild(TransfersDtoAdmin model){
|
// 1.计算参数签名
|
String paramStr = createLinkString(model);
|
String mysign = paramStr + "&key=" + model.getAppkey();
|
String sign = DigestUtils.md5Hex(mysign).toUpperCase();
|
// 2.封装请求参数
|
StringBuilder reqXmlStr = new StringBuilder();
|
reqXmlStr.append("<xml>");
|
reqXmlStr.append("<mchid>" + model.getMchid() + "</mchid>");
|
reqXmlStr.append("<mch_appid>" + model.getMch_appid() + "</mch_appid>");
|
reqXmlStr.append("<nonce_str>" + model.getNonce_str() + "</nonce_str>");
|
reqXmlStr.append("<check_name>" + model.getCheck_name() + "</check_name>");
|
reqXmlStr.append("<openid>" + model.getOpenid() + "</openid>");
|
reqXmlStr.append("<amount>" + model.getAmount() + "</amount>");
|
reqXmlStr.append("<desc>" + model.getDesc() + "</desc>");
|
reqXmlStr.append("<sign>" + sign + "</sign>");
|
reqXmlStr.append("<partner_trade_no>" + model.getPartner_trade_no() + "</partner_trade_no>");
|
reqXmlStr.append("<spbill_create_ip>" + model.getSpbill_create_ip() + "</spbill_create_ip>");
|
reqXmlStr.append("</xml>");
|
|
log.debug("request xml = " + reqXmlStr);
|
return reqXmlStr.toString();
|
}
|
private static String createLinkString(TransfersDtoAdmin model)
|
{
|
// 微信签名规则 https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=4_3
|
Map<String, Object> paramMap = new HashMap<String, Object>();
|
|
// 订单号默认用商户号+时间戳+4位随机数+可以根据自己的规则进行调整
|
model.setAppkey(model.getAppkey());
|
model.setNonce_str(WechatpayUtil.getNonce_str());
|
model.setPartner_trade_no(model.getMchid()
|
+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
|
+ (int)((Math.random() * 9 + 1) * 1000));
|
|
paramMap.put("mch_appid", model.getMch_appid());
|
paramMap.put("mchid", model.getMchid());
|
paramMap.put("openid", model.getOpenid());
|
paramMap.put("amount", model.getAmount());
|
paramMap.put("check_name", model.getCheck_name());
|
paramMap.put("desc", model.getDesc());
|
paramMap.put("partner_trade_no", model.getPartner_trade_no());
|
paramMap.put("nonce_str", model.getNonce_str());
|
paramMap.put("spbill_create_ip", model.getSpbill_create_ip());
|
|
List<String> keys = new ArrayList(paramMap.keySet());
|
Collections.sort(keys);
|
String prestr = "";
|
for (int i = 0; i < keys.size(); i++ )
|
{
|
String key = keys.get(i);
|
Object value = (Object)paramMap.get(key);
|
if (i == keys.size() - 1)
|
{// 拼接时,不包括最后一个&字符
|
prestr = prestr + key + "=" + value;
|
}
|
else
|
{
|
prestr = prestr + key + "=" + value + "&";
|
}
|
}
|
return prestr;
|
}
|
|
private static String getNonce_str()
|
{
|
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
Random random = new Random();
|
StringBuilder sb = new StringBuilder();
|
for (int i = 0; i < 15; i++ )
|
{
|
int number = random.nextInt(base.length());
|
sb.append(base.charAt(number));
|
}
|
return sb.toString();
|
}
|
|
}
|