public class PayCommonUtil {

//定义签名,微信根据参数字段的ASCII码值进行排序 加密签名,故使用SortMap进行参数排序

public static String createSign(String characterEncoding,SortedMap parameters){

StringBuffer sb = new StringBuffer();

Set es = parameters.entrySet();

Iterator it = es.iterator();

while(it.hasNext()) {

Map.Entry entry = (Map.Entry)it.next();

String k = (String)entry.getKey();

Object v = entry.getValue();

if(null != v && !"".equals(v)

&& !"sign".equals(k) && !"key".equals(k)) {

sb.append(k + "=" + v + "&");

}

}

sb.append("key=" + ConstantUtil.PARTNER_KEY);//最后加密时添加商户密钥,由于key值放在最后,所以不用添加到SortMap里面去,单独处理,编码方式采用UTF-8

String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();

return sign;

}

//将封装好的参数转换成Xml格式类型的字符串

public static String getRequestXml(SortedMap parameters){

StringBuffer sb = new StringBuffer();

sb.append("");

Set es = parameters.entrySet();

Iterator it = es.iterator();

while(it.hasNext()) {

Map.Entry entry = (Map.Entry)it.next();

String k = (String)entry.getKey();

String v = (String)entry.getValue();

if("sign".equalsIgnoreCase(k)){

}

else if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)) {

sb.append(""+""+k+">");

}

else {

sb.append(""+v+""+k+">");

}

}

sb.append(""+""+"sign"+">");

sb.append("");

return sb.toString();

}

}

//微信Md5加密工具

public class MD5Util {

private static String byteArrayToHexString(byte b[]) {

StringBuffer resultSb = new StringBuffer();

for (int i = 0; i < b.length; i++)

resultSb.append(byteToHexString(b[i]));

return resultSb.toString();

}

private static String byteToHexString(byte b) {

int n = b;

if (n < 0)

n += 256;

int d1 = n / 16;

int d2 = n % 16;

return hexDigits[d1] + hexDigits[d2];

}

public static String MD5Encode(String origin, String charsetname) {

String resultString = null;

try {

resultString = new String(origin);

MessageDigest md = MessageDigest.getInstance("MD5");

if (charsetname == null || "".equals(charsetname))

resultString = byteArrayToHexString(md.digest(resultString

.getBytes()));

else

resultString = byteArrayToHexString(md.digest(resultString

.getBytes(charsetname)));

} catch (Exception exception) {

}

return resultString;

}

private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",

"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

}

//微信返回的结果为Xml格式的字符串,XmlUtil主要用于解析结果

public class XMLUtil {

/**

* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。

* @param strxml

* @return

* @throws JDOMException

* @throws IOException

*/

public static Map doXMLParse(String strxml) throws JDOMException, IOException {

strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

if(null == strxml || "".equals(strxml)) {

return null;

}

Map m = new HashMap();

InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));

SAXBuilder builder = new SAXBuilder();

Document doc = builder.build(in);

Element root = doc.getRootElement();

List list = root.getChildren();

Iterator it = list.iterator();

while(it.hasNext()) {

Element e = (Element) it.next();

String k = e.getName();

String v = "";

List children = e.getChildren();

if(children.isEmpty()) {

v = e.getTextNormalize();

} else {

v = XMLUtil.getChildrenText(children);

}

m.put(k, v);

}

//关闭流

in.close();

return m;

}

/**

* 获取子结点的xml

* @param children

* @return String

*/

public static String getChildrenText(List children) {

StringBuffer sb = new StringBuffer();

if(!children.isEmpty()) {

Iterator it = children.iterator();

while(it.hasNext()) {

Element e = (Element) it.next();

String name = e.getName();

String value = e.getTextNormalize();

List list = e.getChildren();

sb.append("");

if(!list.isEmpty()) {

sb.append(XMLUtil.getChildrenText(list));

}

sb.append(value);

sb.append("" + name + ">");

}

}

return sb.toString();

}

/**

* 获取xml编码字符集

* @param strxml

* @return

* @throws IOException

* @throws JDOMException

*/

public static String getXMLEncoding(String strxml) throws JDOMException, IOException {

InputStream in = HttpClientUtil.String2Inputstream(strxml);

SAXBuilder builder = new SAXBuilder();

Document doc = builder.build(in);

in.close();

return (String)doc.getProperty("encoding");

}

}

//发送https

public class CommonUtil {

private static Logger log = LoggerFactory.getLogger(CommonUtil.class);

/**

* 发送https请求

* @param requestUrl 请求地址

* @param requestMethod 请求方式(GET、POST)

* @param outputStr 提交的数据

* @return 返回微信服务器响应的信息

*/

public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {

try {

// 创建SSLContext对象,并使用我们指定的信任管理器初始化

MyX509TrustManager[] tm = { new MyX509TrustManager() };

SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");

sslContext.init(null, tm, new java.security.SecureRandom());

// 从上述SSLContext对象中得到SSLSocketFactory对象

SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

conn.setSSLSocketFactory(ssf);

conn.setDoOutput(true);

conn.setDoInput(true);

conn.setUseCaches(false);

// 设置请求方式(GET/POST)

conn.setRequestMethod(requestMethod);

conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");

// 当outputStr不为null时向输出流写数据

if (null != outputStr) {

OutputStream outputStream = conn.getOutputStream();

// 注意编码格式

outputStream.write(outputStr.getBytes("UTF-8"));

outputStream.close();

}

// 从输入流读取返回内容

InputStream inputStream = conn.getInputStream();

InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str = null;

StringBuffer buffer = new StringBuffer();

while ((str = bufferedReader.readLine()) != null) {

buffer.append(str);

}

// 释放资源

bufferedReader.close();

inputStreamReader.close();

inputStream.close();

inputStream = null;

conn.disconnect();

return buffer.toString();

} catch (ConnectException ce) {

log.error("连接超时:{}", ce);

} catch (Exception e) {

log.error("https请求异常:{}", e);

}

return null;

}

/**

* 获取接口访问凭证

*

* @param appid 凭证

* @param appsecret 密钥

* @return

*//*

public static Token getToken(String appid, String appsecret) {

Token token = null;

String requestUrl = ConfigUtil.TOKEN_URL.replace("APPID", appid).replace("APPSECRET", appsecret);

// 发起GET请求获取凭证

JSONObject jsonObject = JSONObject.fromObject(httpsRequest(requestUrl, "GET", null));

if (null != jsonObject) {

try {

token = new Token();

token.setAccessToken(jsonObject.getString("access_token"));

token.setExpiresIn(jsonObject.getInt("expires_in"));

} catch (JSONException e) {

token = null;

// 获取token失败

log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));

}

}

return token;

}

public static String urlEncodeUTF8(String source){

String result = source;

try {

result = java.net.URLEncoder.encode(source,"utf-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

return result;

}*/

}

重点:封装参数调用统一下单接口,生成prepay_id(预支付订单Id)

/**

* 微信支付

* @param orderId 订单编号

* @param actualPay 实际支付金额

* @return

*/

private String generateOrderInfoByWeiXinPay(String orderId, float actualPay,HttpServletRequest request,HttpServletResponse response) throws Exception{

String notify_url = propertiesService.WEI_XIN_NOTIFY_URL;//回调地址

String uuid = IdGen.uuid();

System.out.print("uuid" + uuid);

SortedMap signParams = new TreeMap();

signParams.put("appid", ConstantUtil.APP_ID);//app_id

signParams.put("body","测试");//商品参数信息

signParams.put("mch_id", ConstantUtil.PARTNER);//微信商户账号

signParams.put("nonce_str", uuid);//32位不重复的编号

signParams.put("notify_url", notify_url);//回调页面

signParams.put("out_trade_no", orderId);//订单编号

signParams.put("spbill_create_ip",request.getRemoteAddr() );//请求的实际ip地址

signParams.put("total_fee","1");//支付金额 单位为分

signParams.put("trade_type", "APP");付款类型为APP

String sign = PayCommonUtil.createSign("UTF-8", signParams);//生成签名

signParams.put("sign", sign);

signParams.remove("key");//调用统一下单无需key(商户应用密钥)

String requestXml = PayCommonUtil.getRequestXml(signParams);//生成Xml格式的字符串

String result = CommonUtil.httpsRequest (ConstantUtil.UNIFIED_ORDER_URL, "POST", requestXml);//以post请求的方式调用统一下单接口

)

返回的result成功结果取出prepay_id:

Map map = XMLUtil.doXMLParse(result);

String return_code=(String) map.get("return_code");

String prepay_id =null;

String returnSign=null;

String returnNonce_str=null;

if (return_code.contains("SUCCESS")){

prepay_id=(String) map.get("prepay_id");//获取到prepay_id

}

StringBuffer weiXinVo=new StringBuffer();

long currentTimeMillis = System.currentTimeMillis();//生成时间戳

long second = currentTimeMillis / 1000L;(转换成秒)

String seconds = String.valueOf(second).substring(0, 10);(截取前10位)

SortedMap signParam = new TreeMap();

signParam.put("appid", ConstantUtil.APP_ID);//app_id

signParam.put("partnerid", ConstantUtil.PARTNER);//微信商户账号

signParam.put("prepayid", prepay_id);//预付订单id

signParam.put("package", "Sign=WXPay");//默认sign=WXPay

signParam.put("noncestr", uuid);//自定义不重复的长度不长于32位

signParam.put("timestamp",seconds);//北京时间时间戳

String signAgain = PayCommonUtil.createSign("UTF-8", signParam);//再次生成签名

signParams.put("sign", signAgain);

weiXinVo.append("appid=").append(ConstantUtil.APP_ID).append("&partnerid=").append(ConstantUtil.PARTNER).append("&prepayid=").append(prepay_id).append("&package=Sign=WXPay").append("&noncestr=").append(uuid).append("&timestamp=").append(seconds).append("&sign=").append(signAgain);//拼接参数返回给移动端

return weiXinVo.toString();

java微信支付签名生成_微信APP支付(Java后台生成签名具体步骤)相关推荐

  1. 视频教程-微信小程序系统教程Java版[3/3阶段]_微信小程序电商系统-微信开发

    微信小程序系统教程Java版[3/3阶段]_微信小程序电商系统 微信企业号星级会员.10多年软件从业经历,国家级软件项目负责人,主要从事软件研发.软件企业员工技能培训.已经取得计算机技术与软件资格考试 ...

  2. 微信小程序系统教程Java版[3/3阶段]_微信小程序电商系统-翟东平-专题视频课程...

    微信小程序系统教程Java版[3/3阶段]_微信小程序电商系统-2445人已学习 课程介绍         微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识. 微信小 ...

  3. 微信链接修改图片_微信链接修改图标

    自定义链接是什么?微信链接修改图片_微信链接修改图标 自定义微信分享链接是指将一条网页链接通过微信接口生成一张卡片,并且该卡片的标题,内容和图片都可以自己编辑.如下图效果 ● 未自定义的网页链接 ● ...

  4. java微信公众号支付开发平台_微信公众号支付demo,微信公众号支付Java DEMO

    1.5.4微信验证的控制方法: /** * 微信验证 * 请填写接口配置信息,此信息需要你有自己的服务器资源,填写的URL需要正确响应微信发送的Token验证 * 验证服务器地址的有效性 * 开发者提 ...

  5. java 微信支付成功回调_微信支付成功但并未走回调方法(小程序支付)

    问题描述 项目采用: Spring Cloud + Boot + Gateway服务网关 + Consu 注册中心 在小程序发起微信支付后, 调用后台服务的发起微信预支付,通过预支付拿到的返回信息小程 ...

  6. java微信无感支付怎么开通_微信无感支付在哪_微信无感支付如何开通使用

    微信新推出了无感支付,用户们可以在停车的时候使用,但是很多小伙伴都不知道微信无感支付是什么?要如何使用?快啦小编为大家带来微信无感支付的相关资讯,感兴趣的小伙伴赶紧来看看吧! 微信无感支付用法介绍 车 ...

  7. java微信无感支付怎么开通_微信无感支付是什么 微信无感支付怎么开通

    微信v6.6.1 官方最新版(for iOS11) 类型:ios社交聊天大小:235M语言:中文 评分:6.3 标签: 立即下载 现在已经是到了春运了,开车回家的人也是越来越多.现在开车行走在高速公路 ...

  8. java微信无感支付怎么开通_微信支付之无感支付

    停车免密支付功能的开发  首先我们需要做的是申请微信商户号并开通微信代扣 场景图 前端功能开发: 车辆进场 车辆入场,停车场将用户车牌信息传给小程序.小程序根据车牌信息查询用户是否开通微信免密支付,将 ...

  9. java微信无感支付怎么开通_微信无感支付在哪?怎么使用微信无感支付

    不久前微信启动了高速无感支付,也就是说无需手机,即可付款,不知道大家有没有使用过?其实这一功能已经在山东等多个城市成功试点,现在已经在全国大多数城市覆盖. 那么微信高速无感支付要如何使用呢? 开通微信 ...

最新文章

  1. 未知mysql主机怎么办_Mysql如何巧妙的绕过未知字段名详解
  2. 基于arcgis的python脚本编程视频-面向ArcGIS的Python脚本编程 PDF 高清版
  3. Java开发与技术挑战——关于技术的技术思考
  4. js数组去重的三种常用方法
  5. 为什么程序员发现不了自己的BUG
  6. 从特征分解到协方差矩阵:详细剖析和实现PCA算法
  7. 0 FI配置-FI模块-财务会计-配置清单
  8. 计算机小故障排除方法,常见电脑故障排除方法总汇【详解】
  9. 在Flex中获取一个屏幕截图(Screenshot)并将其传递给ASP.NET
  10. java做h5小游戏服务端_神藏西游H5游戏源码服务端+客户端+搭建教程
  11. js系列:时间格式转成时间戳和比较某个时段是否在另一个时间段内
  12. 翻译:Swift 5编写并发编程,并发解决方案和异步Operation
  13. 马尔科夫 贝叶斯 傅里叶 高斯
  14. 如何解决Word里插入图片会被压缩
  15. jdk卸载,提示Windows Installer安装包有问题,此程序所需要的dll不能运行
  16. Iphone开发(7) 太你妈辛苦了
  17. SonrLint常见解决方案
  18. eCognition9.0安装教程
  19. 交通流的微观模型(Matlab代码实现)
  20. MySQL(数据类型)

热门文章

  1. 清除的文件怎么才能完整准确的恢复呢
  2. Matlab学习 矩阵分解,特征值, 特征向量
  3. 什么是代码,它的作用是什么?
  4. rabbitmq连接异常:An unexpected connection driver error occured处理
  5. Vacations(dp)
  6. html ul代表什么意思,ul在HTML中是什么意思
  7. MySQL面试:left join我要怎优化?
  8. activemq + jaxa +tomcat
  9. pyinstaller打包——将多个py文件+图片打包(最细教程)
  10. 微博上市让新浪又站上“浪尖”