提交 7807d402 编写于 作者: J Javen205

WxPay

上级 16b027b8
......@@ -20,6 +20,7 @@
<java.version>1.8</java.version>
<ijapy.alipay.version>2.0.0</ijapy.alipay.version>
<ijapy.wxpay.version>2.0.0</ijapy.wxpay.version>
</properties>
<dependencies>
......@@ -48,6 +49,10 @@
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-AliPay</artifactId>
<version>${ijapy.alipay.version}</version>
</dependency><dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-WxPay</artifactId>
<version>${ijapy.wxpay.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
......
package com.ijpay.demo.controller.wxpay;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.ijpay.demo.entity.WxPayBean;
import com.ijpay.demo.kit.IpKit;
import com.ijpay.demo.vo.AjaxResult;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.constant.enums.SignType;
import com.ijpay.wxpay.constant.enums.TradeType;
import com.ijpay.wxpay.kit.WxPayKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @author Javen
*/
@Controller
@RequestMapping("/wxpay")
public class WxPayController {
private Logger log = LoggerFactory.getLogger(this.getClass());
private AjaxResult result = new AjaxResult();
@Autowired
WxPayBean wxPayBean;
@RequestMapping("")
@ResponseBody
public String index() {
log.info("欢迎使用 IJPay 中的微信支付 -By Javen <br/><br> 交流群:723992875");
log.info(wxPayBean.toString());
return ("欢迎使用 IJPay 中的微信支付 -By Javen <br/><br> 交流群:723992875");
}
@GetMapping("/test")
@ResponseBody
public WxPayBean test() {
return wxPayBean;
}
@GetMapping("/getKey")
@ResponseBody
public String getKey() {
return WxPayApi.getSignKey(wxPayBean.getMchId(), wxPayBean.getPartnerKey(), SignType.MD5);
}
/**
* 公众号支付
*/
@RequestMapping(value = "/webPay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult webPay(HttpServletRequest request, @RequestParam("total_fee") String total_fee) {
// openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
String openId = (String) request.getSession().getAttribute("openId");
if (openId == null){
openId = "11111111";
}
if (StrUtil.isEmpty(openId)) {
result.addError("openId is null");
return result;
}
if (StrUtil.isEmpty(total_fee)) {
result.addError("请输入数字金额");
return result;
}
String ip = IpKit.getRealIp(request);
if (StrUtil.isEmpty(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = new HashMap<>();
params.put("appid", wxPayBean.getAppId());
params.put("mch_id", wxPayBean.getMchId());
params.put("body", "IJPay");
params.put("attach", "IJPay");
params.put("out_trade_no", WxPayKit.generateStr());
params.put("total_fee", total_fee);
params.put("spbill_create_ip", ip);
params.put("notify_url", wxPayBean.getDomain().concat("/wxpay/pay_notify"));
params.put("trade_type", TradeType.JSAPI.getTradeType());
String xmlResult = WxPayApi.pushOrder(false,WxPayKit.buildSign(params, wxPayBean.getPartnerKey(), SignType.MD5));
log.info(xmlResult);
Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
String return_code = resultMap.get("return_code");
String return_msg = resultMap.get("return_msg");
if (!WxPayKit.codeIsOK(return_code)) {
result.addError(return_msg);
return result;
}
String result_code = resultMap.get("result_code");
if (!WxPayKit.codeIsOK(result_code)) {
result.addError(return_msg);
return result;
}
// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
String prepay_id = resultMap.get("prepay_id");
Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepay_id, wxPayBean.getAppId(), wxPayBean.getPartnerKey());
String jsonStr = JSON.toJSONString(packageParams);
result.success(jsonStr);
return result;
}
}
......@@ -46,21 +46,20 @@ public class AliPayBean {
this.serverUrl = serverUrl;
}
public String getDomain() {
return domain;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "AliPayBean [appId=" + appId + ", privateKey=" + privateKey + ", publicKey=" + publicKey + ", serverUrl="
+ serverUrl + ", domain=" + domain + "]";
}
@Override
public String toString() {
return "AliPayBean [appId=" + appId + ", privateKey=" + privateKey + ", publicKey=" + publicKey + ", serverUrl="
+ serverUrl + ", domain=" + domain + "]";
}
}
\ No newline at end of file
package com.ijpay.demo.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:/production/wxpay.properties")
@ConfigurationProperties(prefix = "wxpay")
public class WxPayBean {
private String appId;
private String appSecret;
private String mchId;
private String partnerKey;
private String certPath;
private String domain;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getPartnerKey() {
return partnerKey;
}
public void setPartnerKey(String partnerKey) {
this.partnerKey = partnerKey;
}
public String getCertPath() {
return certPath;
}
public void setCertPath(String certPath) {
this.certPath = certPath;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "WxPayBean [appId=" + appId + ", appSecret=" + appSecret + ", mchId=" + mchId + ", partnerKey="
+ partnerKey + ", certPath=" + certPath + ", domain=" + domain + "]";
}
}
\ No newline at end of file
package com.ijpay.demo.kit;
import javax.servlet.http.HttpServletRequest;
public class IpKit {
public static String getRealIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
public static String getRealIpV2(HttpServletRequest request) {
String accessIP = request.getHeader("x-forwarded-for");
if (null == accessIP)
return request.getRemoteAddr();
return accessIP;
}
}
\ No newline at end of file
......@@ -29,7 +29,7 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
* @return {String}
*
*/
public static String getUUID () {
public static String generateStr () {
return UUID.randomUUID().toString().replace("-", "");
}
......
wxpay.appId=wx50037ba14d1ab128
wxpay.appSecret=67a9a24f899ce7b5170d96872f3081a9
wxpay.mchId=1445388302
wxpay.partnerKey=CQtr0JyC4XiTPMXhxED93MsbcPM7zG83
wxpay.certPath=/Users/Javen/Documents/dev/IJPay/wxpay/1444446802_20181219_cert/apiclient_cert.p1
wxpay.domain= https://ijpay.javen.com
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>IJPay</artifactId>
<groupId>com.github.javen205</groupId>
<version>2.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>IJPay-WxPay</artifactId>
</project>
\ No newline at end of file
package com.ijpay.wxpay;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.ssl.SSLSocketFactoryBuilder;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Map;
/**
* Http 代理类
*
* @author Javen
*/
public abstract class HttpDelegate {
protected String get(String url) {
return HttpUtil.get(url);
}
protected String get(String url, Map<String, Object> paramMap) {
return HttpUtil.get(url, paramMap);
}
protected String post(String url, String data) {
return HttpUtil.post(url, data);
}
protected String post(String url, Map<String, Object> paramMap){
return HttpUtil.post(url, paramMap);
}
protected String postSSL(String url, String data, String certPath, String certPass){
try {
return HttpRequest.post(url)
.setSSLSocketFactory(SSLSocketFactoryBuilder
.create()
.setProtocol(SSLSocketFactoryBuilder.TLSv1)
.setKeyManagers(getKeyManager(certPass, certPath, null))
.setSecureRandom(new SecureRandom())
.build()
)
.body(data)
.execute()
.body();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected String postSSL(String url, String data, InputStream certFile, String certPass){
try {
return HttpRequest.post(url)
.setSSLSocketFactory(SSLSocketFactoryBuilder
.create()
.setProtocol(SSLSocketFactoryBuilder.TLSv1)
.setKeyManagers(getKeyManager(certPass, null, certFile))
.setSecureRandom(new SecureRandom())
.build()
)
.body(data)
.execute()
.body();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private KeyManager[] getKeyManager(String certPass, String certPath, InputStream certFile) throws Exception {
KeyStore clientStore = KeyStore.getInstance("PKCS12");
if (certFile != null) clientStore.load(certFile, certPass.toCharArray());
else clientStore.load(new FileInputStream(certPath), certPass.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, certPass.toCharArray());
return kmf.getKeyManagers();
}
}
此差异已折叠。
package com.ijpay.wxpay;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
/**
* xpath解析xml
*
* <pre>
* 文档地址:
* http://www.w3school.com.cn/xpath/index.asp
* </pre>
*/
public class XmlHelper {
private final XPath path;
private final Document doc;
private XmlHelper(InputSource inputSource) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory dbf = getDocumentBuilderFactory();
// This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all
// XML entity attacks are prevented
// Xerces 2 only -
// http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// If you can't completely disable DTDs, then at least do the following:
// Xerces 1 -
// http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 -
// http://xerces.apache.org/xerces2-j/features.html#external-general-entities
// JDK7+ - http://xml.org/sax/features/external-general-entities
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
// Xerces 1 -
// http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 -
// http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
// JDK7+ - http://xml.org/sax/features/external-parameter-entities
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
// Disable external DTDs as well
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and
// Entity Attacks"
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(inputSource);
path = getXPathFactory().newXPath();
}
private static XmlHelper create(InputSource inputSource) {
try {
return new XmlHelper(inputSource);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static XmlHelper of(InputStream is) {
InputSource inputSource = new InputSource(is);
return create(inputSource);
}
public static XmlHelper of(File file) {
InputSource inputSource = new InputSource(file.toURI().toASCIIString());
return create(inputSource);
}
public static XmlHelper of(String xmlStr) {
StringReader sr = new StringReader(xmlStr.trim());
InputSource inputSource = new InputSource(sr);
XmlHelper xmlHelper = create(inputSource);
sr.close();
return xmlHelper;
}
private Object evalXPath(String expression, Object item, QName returnType) {
item = null == item ? doc : item;
try {
return path.evaluate(expression, item, returnType);
} catch (XPathExpressionException e) {
throw new RuntimeException(e);
}
}
/**
* 获取String
*
* @param expression 路径
* @return String
*/
public String getString(String expression) {
return (String) evalXPath(expression, null, XPathConstants.STRING);
}
/**
* 获取Boolean
*
* @param expression 路径
* @return String
*/
public Boolean getBoolean(String expression) {
return (Boolean) evalXPath(expression, null, XPathConstants.BOOLEAN);
}
/**
* 获取Number
*
* @param expression 路径
* @return {Number}
*/
public Number getNumber(String expression) {
return (Number) evalXPath(expression, null, XPathConstants.NUMBER);
}
/**
* 获取某个节点
*
* @param expression 路径
* @return {Node}
*/
public Node getNode(String expression) {
return (Node) evalXPath(expression, null, XPathConstants.NODE);
}
/**
* 获取子节点
*
* @param expression 路径
* @return NodeList
*/
public NodeList getNodeList(String expression) {
return (NodeList) evalXPath(expression, null, XPathConstants.NODESET);
}
/**
* 获取String
*
* @param node 节点
* @param expression 相对于node的路径
* @return String
*/
public String getString(Object node, String expression) {
return (String) evalXPath(expression, node, XPathConstants.STRING);
}
/**
* 获取
*
* @param node 节点
* @param expression 相对于node的路径
* @return String
*/
public Boolean getBoolean(Object node, String expression) {
return (Boolean) evalXPath(expression, node, XPathConstants.BOOLEAN);
}
/**
* 获取
*
* @param node 节点
* @param expression 相对于node的路径
* @return {Number}
*/
public Number getNumber(Object node, String expression) {
return (Number) evalXPath(expression, node, XPathConstants.NUMBER);
}
/**
* 获取某个节点
*
* @param node 节点
* @param expression 路径
* @return {Node}
*/
public Node getNode(Object node, String expression) {
return (Node) evalXPath(expression, node, XPathConstants.NODE);
}
/**
* 获取子节点
*
* @param node 节点
* @param expression 相对于node的路径
* @return NodeList
*/
public NodeList getNodeList(Object node, String expression) {
return (NodeList) evalXPath(expression, node, XPathConstants.NODESET);
}
/**
* 针对没有嵌套节点的简单处理
*
* @return map集合
*/
public Map<String, String> toMap() {
Element root = doc.getDocumentElement();
Map<String, String> params = new HashMap<String, String>();
// 将节点封装成map形式
NodeList list = root.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
params.put(node.getNodeName(), node.getTextContent());
}
// 含有空白符会生成一个#text参数
params.remove("#text");
return params;
}
private static DocumentBuilderFactory getDocumentBuilderFactory() {
return XmlHelper.XmlHelperHolder.documentBuilderFactory;
}
private static XPathFactory getXPathFactory() {
return XmlHelper.XmlHelperHolder.xPathFactory;
}
/**
* 内部类单例
*/
private static class XmlHelperHolder {
private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private static XPathFactory xPathFactory = XPathFactory.newInstance();
}
}
\ No newline at end of file
package com.ijpay.wxpay.constant.enums;
public enum PayModel {
BUSINESS_MODEL("BUSINESS_MODEL","商户模式"),
SERVICE_MODE("SERVICE_MODE","服务商模式");
PayModel(String payModel, String description) {
this.payModel = payModel;
this.description = description;
}
/**
* 商户模式
*/
private final String payModel;
/**
* 描述
*/
private final String description;
public String getPayModel() {
return payModel;
}
public String getDescription() {
return description;
}
}
package com.ijpay.wxpay.constant.enums;
/**
* 签名方式
*
* @author Javen
*/
public enum SignType {
HMACSHA256("HMAC-SHA256"),
MD5("MD5");
SignType(String type) {
this.type = type;
}
private final String type;
public String getType() {
return type;
}
}
package com.ijpay.wxpay.constant.enums;
public enum TradeType {
JSAPI("JSAPI","微信公众号支付或者小程序支付)"),
NATIVE("NATIVE","微信扫码支付"),
APP("APP","微信APP支付"),
MICROPAY("MICROPAY","付款码支付"),
MWEB("MWEB","H5支付");
/**
* 交易类型枚举<br/>
* JSAPI 公众号支付、小程序支付<br/>
* NATIVE 原生扫码支付<br/>
* APP APP支付<br/>
* MWEB WAP支付<br/>
* MICROPAY 刷卡支付<br/>
*/
TradeType(String tradeType, String description) {
this.tradeType = tradeType;
this.description = description;
}
/**
* 交易类型
*/
private final String tradeType;
/**
* 描述
*/
private final String description;
public String getTradeType() {
return tradeType;
}
public String getDescription() {
return description;
}
}
package com.ijpay.wxpay.kit;
import com.ijpay.wxpay.HttpDelegate;
/**
* Http 工具类
*
* @author Javen
*/
public class HttpKit {
private static HttpDelegate delegate = new DefaultHttpKit();
public static HttpDelegate getDelegate() {
return delegate;
}
public static void setDelegate(HttpDelegate delegate) {
HttpKit.delegate = delegate;
}
}
/**
* 使用 hutool 实现的 Http 工具类
*
* @author Javen
*/
class DefaultHttpKit extends HttpDelegate {
}
package com.ijpay.wxpay.kit;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.HmacAlgorithm;
import com.ijpay.wxpay.XmlHelper;
import com.ijpay.wxpay.constant.enums.SignType;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class WxPayKit {
private static final String FIELD_SIGN = "sign";
private static final String FIELD_SIGN_TYPE = "sign_type";
public static String hmacSHA256(String data, String key) {
return SecureUtil.hmac(HmacAlgorithm.HmacSHA256, key).digestHex(data, CharsetUtil.UTF_8);
}
public static String md5(String data) {
return SecureUtil.md5(data);
}
/**
* AES 解密
*
* @param base64Data 需要解密的数据
* @param key 密钥
* @return 解密后的数据
*/
public static String decryptData(String base64Data, String key) {
return SecureUtil.aes(md5(key).toLowerCase().getBytes()).decryptStr(base64Data);
}
/**
* AES 加密
*
* @param data 需要加密的数据
* @param key 密钥
* @return 加密后的数据
*/
public static String encryptData(String data, String key) {
return SecureUtil.aes(md5(key).toLowerCase().getBytes()).encryptBase64(data.getBytes());
}
public static String generateStr() {
return IdUtil.fastSimpleUUID();
}
/**
* 组装签名的字段
*
* @param params 参数
* @param urlEncoder 是否urlEncoder
* @return {String}
*/
public static String packageSign(Map<String, String> params, boolean urlEncoder) {
// 先将参数以其参数名的字典序升序进行排序
TreeMap<String, String> sortedParams = new TreeMap<String, String>(params);
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> param : sortedParams.entrySet()) {
String value = param.getValue();
if (StrUtil.isEmpty(value)) {
continue;
}
if (first) {
first = false;
} else {
sb.append("&");
}
sb.append(param.getKey()).append("=");
if (urlEncoder) {
try {
value = urlEncode(value);
} catch (UnsupportedEncodingException e) {
}
}
sb.append(value);
}
return sb.toString();
}
public static String urlEncode(String src) throws UnsupportedEncodingException {
return URLEncoder.encode(src, CharsetUtil.UTF_8).replace("+", "%20");
}
/**
* 生成签名
*
* @param params 需要签名的参数
* @param partnerKey 密钥
* @param signType 签名类型
* @return 签名后的数据
*/
public static String createSign(Map<String, String> params, String partnerKey, SignType signType) {
if (signType == null) {
signType = SignType.MD5;
}
// 生成签名前先去除sign
params.remove(FIELD_SIGN);
String stringA = packageSign(params, false);
System.out.println("stringA>>>"+stringA);
String stringSignTemp = stringA + "&key=" + partnerKey;
System.out.println("stringSignTemp>>"+stringSignTemp);
if (signType == SignType.MD5) return md5(stringSignTemp).toUpperCase();
else return hmacSHA256(stringSignTemp, partnerKey).toUpperCase();
}
/**
* 构建签名
*
* @param params 需要签名的参数
* @param partnerKey 密钥
* @param signType 签名类型
* @return <@link Map<String, String>> 签名后的
*/
public static Map<String, String> buildSign(Map<String, String> params, String partnerKey, SignType signType) {
if (signType == null) {
signType = SignType.MD5;
}
params.put("nonce_str", WxPayKit.generateStr());
params.put(FIELD_SIGN_TYPE, signType.getType());
String sign = createSign(params, partnerKey, signType);
params.put(FIELD_SIGN, sign);
return params;
}
/**
* 微信下单 map to xml
*
* @param params Map 参数
* @return xml 字符串
*/
public static String toXml(Map<String, String> params) {
StringBuilder xml = new StringBuilder();
xml.append("<xml>");
for (Map.Entry<String, String> entry : params.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// 略过空值
if (StrUtil.isEmpty(value))
continue;
xml.append("<").append(key).append(">");
xml.append(entry.getValue());
xml.append("</").append(key).append(">");
}
xml.append("</xml>");
return xml.toString();
}
/**
* 针对支付的 xml,没有嵌套节点的简单处理
*
* @param xmlStr xml 字符串
* @return <@link Map<String, String>>
*/
public static Map<String, String> xmlToMap(String xmlStr) {
XmlHelper xmlHelper = XmlHelper.of(xmlStr);
return xmlHelper.toMap();
}
/**
* 替换url中的参数
*
* @param str 原始字符串
* @param regex 表达式
* @param args 替换字符串
* @return {String}
*/
public static String replace(String str, String regex, String... args) {
for ( String arg: args) {
str = str.replaceFirst(regex, arg);
}
return str;
}
/**
* 判断接口返回的 code
*
* @param codeValue code 值
* @return 是否是 SUCCESS
*/
public static boolean codeIsOK(String codeValue) {
return StrUtil.isNotEmpty(codeValue) && "SUCCESS".equals(codeValue);
}
/**
* 预付订单再次签名
* @param prepay_id 预付订单号
* @param appId 应用编号
* @param partnerKey API Key
* @return {@link Map<String,String>} 再次签名后的 Map
*/
public static Map<String, String> prepayIdCreateSign(String prepay_id,String appId,String partnerKey) {
Map<String, String> packageParams = new HashMap<String, String>();
packageParams.put("appId", appId);
packageParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
packageParams.put("nonceStr", String.valueOf(System.currentTimeMillis()));
packageParams.put("package", "prepay_id=" + prepay_id);
packageParams.put("signType", "MD5");
String packageSign = WxPayKit.createSign(packageParams, partnerKey,SignType.MD5);
packageParams.put("paySign", packageSign);
return packageParams;
}
}
package com.ijpay.wxpay;
import com.ijpay.wxpay.kit.WxPayKit;
import org.junit.Assert;
import org.junit.Test;
public class WxPayKitTest {
@Test
public void hmacSHA256(){
Assert.assertEquals("9d67ee93641f99f0de85756c1debd8a4e315fbf8fd4ed966ed352bc1a658a8df",
WxPayKit.hmacSHA256("IJPay 让支付触手可及","123"));
}
@Test
public void mad5(){
Assert.assertEquals("42cc1d91bab89b65ff55b19e28fff4f0",
WxPayKit.md5("IJPay 让支付触手可及"));
}
@Test
public void generateStr(){
Assert.assertEquals("42cc1d91bab89b65ff55b19e28fff4f0",WxPayKit.generateStr());
}
@Test
public void encryptData(){
Assert.assertEquals("",WxPayKit.encryptData("IJPay 让支付触手可及","42cc1d91bab89b65ff55b19e28fff4f0"));
}
@Test
public void decryptData(){
Assert.assertEquals("IJPay 让支付触手可及",WxPayKit.decryptData(WxPayKit.encryptData("IJPay 让支付触手可及","42cc1d91bab89b65ff55b19e28fff4f0"),"42cc1d91bab89b65ff55b19e28fff4f0"));
}
}
......@@ -44,11 +44,20 @@
<properties>
<jdk.version>1.6</jdk.version>
<junit.version>4.12</junit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- 全局单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册