Skip to content

Instantly share code, notes, and snippets.

@0xffan
Created April 14, 2017 09:37
Show Gist options
  • Save 0xffan/cb61d548655724fee4f41d9cdd53fe91 to your computer and use it in GitHub Desktop.
Save 0xffan/cb61d548655724fee4f41d9cdd53fe91 to your computer and use it in GitHub Desktop.
package me.ixfan.wechatkit.wxpay;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.TreeMap;
import java.util.stream.Collectors;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* <p>微信支付参数</p>
* @author Fan Weijun
*/
public class WxPayData {
private final TreeMap<String, Object> params = new TreeMap<>();
public WxPayData() {}
/**
* <p>从 XML 构建 WxPayData 对象实例。</p>
* @return
*/
public static WxPayData fromXml(String xml) {
Document document = null;
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setIgnoringElementContentWhitespace(true);
dbFactory.setIgnoringComments(true);
DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
document = docBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WxPayData wxpayData = new WxPayData();
Node xmlNode = document.getFirstChild();
NodeList paramNodes = xmlNode.getChildNodes();
int paramsCount = paramNodes.getLength();
for (int i = 0; i < paramsCount; ++i) {
Node item = paramNodes.item(i);
if (item.getNodeType() == Node.ELEMENT_NODE) {
item.getFirstChild();
wxpayData.setValue(item.getNodeName(), item.getFirstChild().getNodeValue());
}
}
return wxpayData;
}
/**
* <p>设置某个参数的值。</p>
* @param key 参数名,需区分大小写。
* @param value 参数值,只接受 {@link Integer} 和 {@link String} 类型。
*/
public void setValue(String key, Object value) {
params.put(key, value);
}
/**
* <p>获取某个参数的值。</p>
* @param key 参数名,需区分大小写。
* @return 若参数没设值则返回 null。
*/
public Object getValue(String key) {
return params.get(key);
}
/**
* <p>将支付参数转换成 XML。</p>
* @return
*/
public String toXml() {
final StringBuilder xml = new StringBuilder();
xml.append("<xml>");
this.params.forEach((key,value) -> {
if (null == value || key.equals("sign")) {
return;
}
if (value instanceof Integer) {
xml.append(String.format("<%s>%d</%s>", key, value, key));
} else if (value instanceof String) {
xml.append(String.format("<%s><![CDATA[%s]]</%s>", key, value, key));
}
});
xml.append(String.format("<sign>![CDATA[%s]]</sign>", sign("192006250b4c09247ec02edce69f6a2d")));
xml.append("</xml>");
return xml.toString();
}
public String toUrl() {
return this.params.entrySet()
.stream()
.map((entry) -> {
if (entry.getKey().equals("sign") || null == entry.getValue()) {
return "";
}
return String.format("%s=%s", entry.getKey(),entry.getValue().toString());
})
.filter(s -> !s.equals(""))
.collect(Collectors.joining("&"));
}
/**
* <p>生成签名。API密钥(key)不参与签名。</p>
* @return
*/
public String sign() {
return StringUtil.encodeMD5(toUrl()).toUpperCase();
}
/**
* <p>生成签名。API密钥(key)参与签名。</p>
* @param key
* @return
*/
public String sign(String key) {
String paramUrl = toUrl();
paramUrl += String.format("&key=%s", key);
return StringUtil.encodeMD5(paramUrl).toUpperCase();
}
/**
* <p>验证签名是否正确。</p>
* @return
*/
public boolean checkSign() {
if (null == this.params.get("sign")) {
return false;
}
String wxSign = (String) this.params.get("sign");
String mySign = sign("192006250b4c09247ec02edce69f6a2d");
return wxSign.equals(mySign);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment