1.申请商户号,设置api密钥.
2.在开发电脑上安装安全控件.
3.我所开发的业务逻辑是前端调用我提供的一个支付前的接口,Java后台先去查询订单相关内容,设置好参数(需要的参数可查看https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1)后调用微信方统一下单接口(注意经常会报签名错误,请检查好自己生成的签名和微信的是否一致 https://pay.weixin.qq.com/wiki/tools/signverify/ 点击这个网址可以校验一下,微信生成的和自己生成的是否一致),统一下单接口返回成功后,用返回的参数再次签名,返回给小程序前端所需要的参数.代码如下:
public String userPay(Object object) {
//开发者的订单信息
OrderListVo orderListVo = new OrderListVo(;)
//调统一下单接口
Map unifiedOrderMap = unifiedOrder(orderListVo);
//再次签名返回前端
return signAgain(unifiedOrderMap);
}
/**
* 统一下单
* @param request
*/
public Map unifiedOrder(OrderListVo orderListVo) {
//统一下单url
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
SortedMap
所需要的工具类
package com.king.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.security.MessageDigest;
import java.util.*;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import com.king.constants.WXPayConstants;
public class PayUtil {
/**
* @Description:创建sign签名
* @param characterEncoding
* 编码格式
* @param map
* 请求参数
* @return
*/
public static String createSign(String characterEncoding, SortedMap packageParams)
{
StringBuffer sb = new StringBuffer();
Set es = packageParams.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=" + WXPayConstants.AppKey);
String sign = md5Password(sb.toString());
sign = sign.toUpperCase();
return sign;
}
/**
* 生成32位md5码
*
* @param key
* @return
*/
public static String md5Password(String key) {
char hexDigits[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
try {
byte[] btInput = key.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
/**
* @Description:将请求参数转换为xml格式的string
* @param map
* 请求参数
* @return
*/
public static String getRequestXml(SortedMap packageParams)
{
StringBuffer sb = new StringBuffer();
sb.append("");
Set es = packageParams.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 ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k))
{
sb.append("<" + k + ">" + "" + k + ">");
} else
{
sb.append("<" + k + ">" + v + "" + k + ">");
}
}
sb.append(" ");
return sb.toString();
}
/**
* 发送https请求
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param data 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static String httpsRequest(String requestUrl, String requestMethod, String data) {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
conn.connect();
// 当data不为null时向输出流写数据
if (null != data) {
// getOutputStream方法隐藏了connect()方法
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(data.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
inputStream = conn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "utf-8");
bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
conn.disconnect();
return buffer.toString();
} catch (Exception e) {
return null;
} finally {
// 释放资源
try {
if(null != inputStream) {
inputStream.close();
}
if(null != inputStreamReader) {
inputStreamReader.close();
}
if(null != bufferedReader) {
bufferedReader.close();
}
} catch (IOException e) {
}
}
}
/**
* 获取访问者IP
* 在一般情况下使用Request.getRemoteAddr()即可,但是经过nginx等反向代理软件后,这个方法会失效
* 本方法先从Header中获取X-Real-IP,如果不存在再从X-Forwarded-For获得第一个IP(用,分割),
* 如果还不存在则调用Request .getRemoteAddr()
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("X-Real-IP");
if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
return ip;
}
ip = request.getHeader("X-Forwarded-For");
if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个IP值,第一个为真实IP。
int index = ip.indexOf(',');
if (index != -1) {
return ip.substring(0, index);
} else {
return ip;
}
} else {
return request.getRemoteAddr();
}
}
public static void main(String[] args) {
SortedMap parameters = new TreeMap();
parameters.put("appid", "");
// 此处传入openid
parameters.put("openid", "");
// 微信支付商户号
parameters.put("mch_id","");
System.out.println(createSign("utf-8", parameters));
String xml = PayCommonUtil.getRequestXml(parameters);
System.out.println(xml);
}
}
解析XML解析工具(需要引入jar包)
pom文件加入
jdom
jdom
1.0
package com.king.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
/**
* 解析微信XML字符穿
*/
public class XMLUtil {
/**
* 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Map doXMLParse(String strxml) {
Map m = new HashMap();
try {
strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
if(null == strxml || "".equals(strxml)) {
return null;
}
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();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return m;
}
/**
* 获取子结点的xml
* @param children
* @return String
*/
@SuppressWarnings("rawtypes")
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("<" + name + ">");
if(!list.isEmpty()) {
sb.append(XMLUtil.getChildrenText(list));
}
sb.append(value);
sb.append("" + name + ">");
}
}
return sb.toString();
}
/**
* 微信支付将请求参数转换为xml格式的String
*
* @param parameters
* @return
*/
@SuppressWarnings("rawtypes")
public static String getRequestXmlQuery(SortedMap paramMap) {
StringBuffer sb = new StringBuffer();
sb.append("");
Set set = paramMap.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
sb.append("<" + key + ">" + "" + key + ">");
}
sb.append(" ");
return sb.toString();
}
/**
* 微信支付将请求参数转换为xml格式的String
*
* @param parameters
* @return
*/
@SuppressWarnings("rawtypes")
public static String getRequestXml(SortedMap paramMap) {
StringBuffer sb = new StringBuffer();
sb.append("");
Set set = paramMap.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if ("attach".equalsIgnoreCase(key) || "body".equalsIgnoreCase(key) || "sign".equalsIgnoreCase(key)) {
sb.append("<" + key + ">" + "" + key + ">");
} else {
sb.append("<" + key + ">" + value + "" + key + ">");
}
}
sb.append(" ");
return sb.toString();
}
}
以上就是支付前的内容,返回给前端需要的五个参数,前端调用微信支付,回调成功后,调用后台接口修改数据库支付状态.
内容可能有所欠缺,后续发现会修改