以下为微信app和JSAPI支付
package cn.xizhi.until.pay;
import cn.xizhi.until.GetIp;
import cn.xizhi.until.MD5Utils;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
public class AppPay {
private static final String appid = "填写自己的"; //微信开放平台appid
private static final String publicAppid = "填写自己的";//微信公众号appid
private static final String mch_id = "填写自己的"; //商户号
private static final String nonceStr = WXPayUtil.generateNonceStr();
private static final long timestamp = System.currentTimeMillis()/ 1000;
@SneakyThrows
public static void main(String[] args){
String s = queryOrderResult("210525051242354");
if (s.equals("1")){
System.out.println("支付成功");
}else {
System.out.println("订单不存在");
}
}
// 将map的key全部转换为小写
public static Map transformLowerCase(Map orgMap) {
Map resultMap = new HashMap<>();
if (orgMap == null || orgMap.isEmpty()) {
return resultMap;
}
Set keySet = orgMap.keySet();
for (String key : keySet) {
String newKey = key.toLowerCase();
resultMap.put(newKey, orgMap.get(key));
}
return resultMap;
}
//将map的key按升序排序 拼接value+密钥 进行MD5加密生成密钥
public static String createSign(Map params, String privateKey){
StringBuilder sb = new StringBuilder();
// 将参数以参数名的字典升序排序
Map sortParams = new TreeMap(params);
// 遍历排序的字典,并拼接"key=value"格式
for (Map.Entry entry : sortParams.entrySet()) {
String key = entry.getKey();
String value = entry.getValue().trim();
if (StringUtils.isNotEmpty(value)) {
sb.append(value);
}
}
System.out.println(sb);
String stringSignTemp = sb+privateKey;
System.out.println("待签名原文:"+stringSignTemp);
String signValue = MD5Utils.encrypByMd5(stringSignTemp);
System.out.println(signValue);
return signValue;
}
/**
* 调用统一下单,并获取支付跳转链接
* @param price 总价格
* @param description 商品描述
* @param out_trade_no 商户订单号
* @return
*/
// 支付
public static Map appPay(BigDecimal price, String description, String out_trade_no, HttpServletRequest request){
String total = String.valueOf(price.multiply(new BigDecimal("100"))).substring(0,String.valueOf(price.multiply(new BigDecimal("100"))).length()-3);
String ip = GetIp.getIpAddr(request);
// 封装需要的信息
Map payMap = new HashMap();
try {
// 1. 拼接下单地址参数
Map param = new HashMap();
param.put("appid", appid); // 公总号ID
param.put("mch_id", mch_id); // 商户号ID
param.put("nonce_str",nonceStr); // 随机字符串
param.put("body", description) ;// 商品描述
param.put("out_trade_no", out_trade_no); // 商户订单号
System.out.println("out_trade_no"+out_trade_no);
param.put("total_fee", total);//金额(分)
param.put("spbill_create_ip", ip); // 商户终端ip
param.put("notify_url","填写自己的"); // H5微信异步通知回调地址
param.put("trade_type", "APP"); // H5支付类型
// 生成签名,官方默认MD5+商户秘钥+参数信息
String sign = WXPayUtil.generateSignature(param, "LYtbqfDAZiekNQemSc2NIu4uhQqPnitn");
param.put("sign", sign);
// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(param);
// 2. 发送请求
HttpClient1 httpClient1 = new HttpClient1("https://api.mch.weixin.qq.com/pay/unifiedorder");
httpClient1.setHttps(true);// https协议
httpClient1.setXmlParam(xmlParam);
httpClient1.post();
// 获取结果
String xmlResult = httpClient1.getContent();
System.out.println("xmlResult:"+xmlResult);
//以下内容是返回前端页面的json数据
String prepay_id="";//prepay_id
if (xmlResult.indexOf("SUCCESS") != -1) { // 只要执行了下单接口,都会包含SUCCESS的
Map map = WXPayUtil.xmlToMap(xmlResult);
prepay_id=(String) map.get("prepay_id");
System.out.println("结果:"+xmlResult);
// 公众号ID
payMap.put("appid", appid);
//预支付交易会话ID
payMap.put("prepayid",prepay_id);
//商户号
payMap.put("partnerid",mch_id);
//随机字符串
payMap.put("noncestr",nonceStr);
//扩展字段
payMap.put("package","Sign=WXPay");
//时间戳
payMap.put("timestamp",String.valueOf(timestamp));
//生成签名
String sign1 = WXPayUtil.generateSignature(payMap, "LYtbqfDAZiekNQemSc2NIu4uhQqPnitn");
//将签名字符串放入map中
payMap.put("sign",sign1);
} else {
payMap.put("msg", "支付失败");
return payMap;
}
} catch (Exception e) {
e.printStackTrace();
payMap.put("msg", "系统支付错误");
return payMap;
}
//添加微信支付记录日志等操作
payMap.put("msg", "success");
payMap.put("out_trade_no", out_trade_no);
return payMap;
}
/**
* 调用统一下单,并获取支付跳转链接
* @param openid
* @param price 总价格
* @param description 商品描述
* @param out_trade_no 商户订单号
* @param request
* @return
*/
public static Map payH5(String openid, BigDecimal price, String description, String out_trade_no, HttpServletRequest request){
String ip = GetIp.getIpAddr(request);
String total = String.valueOf(price.multiply(new BigDecimal("100"))).substring(0,String.valueOf(price.multiply(new BigDecimal("100"))).length()-3);
// 封装需要的信息
Map payMap = new HashMap();
String nonceStr= WXPayUtil.generateNonceStr();
long timestamp = System.currentTimeMillis()/ 1000;
//定义 两个String 字段类型
String result_code = null;
String myRremark = null;
try {
// 1. 拼接下单地址参数
Map param = new HashMap();
param.put("appid", String.valueOf(publicAppid)); // 公总号ID
param.put("mch_id", String.valueOf(mch_id)); // 商户号ID
param.put("nonce_str",nonceStr); // 随机字符串
param.put("body", description) ;// 商品描述
param.put("out_trade_no", out_trade_no); // 商户订单号
param.put("total_fee", total);//金额(分)
param.put("spbill_create_ip", ip); // 商户终端ip
param.put("notify_url", "填写自己的"); // H5微信异步通知回调地址
param.put("trade_type", "JSAPI"); // H5支付类型
param.put("openid", openid);
// 生成签名,官方默认MD5+商户秘钥+参数信息
// String sign =createSign(param);
String sign = WXPayUtil.generateSignature(param, "LYtbqfDAZiekNQemSc2NIu4uhQqPnitn");
param.put("sign", sign);
// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(param);
System.out.println("setXmlParam:"+xmlParam);
System.out.println("ip"+ip);
// 2. 发送请求
// String xmlStr = HttpRequest.sendPost(unifiedorder_url, xml);//发送post请求"统一下单接口"
HttpClient1 httpClient1 = new HttpClient1("https://api.mch.weixin.qq.com/pay/unifiedorder");
httpClient1.setHttps(true);// https协议
httpClient1.setXmlParam(xmlParam);
httpClient1.post();
// 获取结果
String xmlResult = httpClient1.getContent();
//以下内容是返回前端页面的json数据
String mweb_url = "";//跳转链接
String prepay_id="";//prepay_id
if (xmlResult.indexOf("SUCCESS") != -1) { // 只要执行了下发接口,都会包含SUCCESS的
Map map = WXPayUtil.xmlToMap(xmlResult);
//mweb_url为拉起微信支付收银台的中间页面,可通过访问该url来拉起微信客户端,完成支付,mweb_url的有效期为5分钟。
mweb_url = (String) map.get("mweb_url");
prepay_id=(String) map.get("prepay_id");
//判断调起支付是否成功
if (map.get("result_code").equals("SUCCESS")){
result_code = "true";
}else {
result_code = "false";
myRremark = map.get("err_code_des");
}
System.out.println("结果:"+xmlResult);
//支付完返回浏览器跳转的地址,如跳到查看订单页面
String redirect_url = "填写自己的";
String redirect_urlEncode = URLEncoder.encode(redirect_url,"utf-8");//对上面地址urlencode
mweb_url = mweb_url + "&redirect_url=" + redirect_urlEncode;//拼接返回地址
System.out.println("成功的payMap:"+payMap);
} else {
payMap.put("msg", "支付失败");
System.out.println("失败的payMap:"+payMap);
return payMap;
}
payMap.put("appId", String.valueOf(publicAppid)); // 公众号ID
payMap.put("package","prepay_id="+prepay_id);
payMap.put("nonceStr",nonceStr);
payMap.put("signType","MD5");
payMap.put("timeStamp",String.valueOf(timestamp));
String sign1 = WXPayUtil.generateSignature(payMap, "LYtbqfDAZiekNQemSc2NIu4uhQqPnitn");
payMap.put("paySign",sign1);
payMap.put("out_trade_no",out_trade_no);
System.out.println("payMap:"+payMap);
} catch (Exception e) {
e.printStackTrace();
payMap.put("msg", "系统支付错误");
System.out.println("系统支付错误的payMap:"+payMap);
return payMap;
}
//添加微信支付记录日志等操作
payMap.put("result_code",result_code);
payMap.put("myRremark",myRremark);
payMap.put("msg", "success");
System.out.println("支付成功的payMap:"+payMap);
return payMap;
}
/**
* 下载交易账单(获取数据流形式)
* @return
*/
public static String downloadbill(String bill_date,String bill_type){
// 封装需要的信息
Map payMap = new HashMap();
String nonceStr= WXPayUtil.generateNonceStr();
Date currentTime = new Date();
//新建日期格式
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
//将日期对象格式化成指定格式并以String输出
// String bill_date = simpleDateFormat.format(currentTime);
try {
// 1. 拼接下单地址参数
Map param = new HashMap();
param.put("appid", appid); // 公总号ID
param.put("mch_id", mch_id); // 商户号ID
param.put("nonce_str",nonceStr); // 随机字符串
param.put("bill_type", bill_type); // 账单类型
param.put("sign_type", "MD5"); // 签名类型
param.put("bill_date", bill_date); // 对账单日期
// 生成签名,官方默认MD5+商户秘钥+参数信息
String sign = WXPayUtil.generateSignature(param, "LYtbqfDAZiekNQemSc2NIu4uhQqPnitn");
param.put("sign", sign);
// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(param);
// 2. 发送请求
HttpClient1 httpClient1 = new HttpClient1("https://api.mch.weixin.qq.com/pay/downloadbill");
httpClient1.setHttps(true);// https协议
httpClient1.setXmlParam(xmlParam);
httpClient1.post();
// 获取结果
String xmlResult = httpClient1.getContent();
return xmlResult;
} catch (Exception e) {
e.printStackTrace();
payMap.put("msg", "系统下载账单错误");
return "系统下载账单错误";
}
}
/**
* 下载交易账单(获取Gzip形式)
* 生成签名的xml
* @return
*/
public static String bill(String bill_date,String bill_type){
// 封装需要的信息
Map payMap = new HashMap();
String nonceStr= WXPayUtil.generateNonceStr();
// Date currentTime = new Date();
// //新建日期格式
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
// //将日期对象格式化成指定格式并以String输出
// String bill_date = simpleDateFormat.format(currentTime);
try {
// 1. 拼接下单地址参数
Map param = new HashMap();
param.put("appid", appid); // 公总号ID
param.put("mch_id", mch_id); // 商户号ID
param.put("nonce_str",nonceStr); // 随机字符串
param.put("bill_type", bill_type); // 账单类型
param.put("sign_type", "MD5"); // 签名类型
param.put("bill_date", bill_date); // 对账单日期
param.put("tar_type","GZIP");
// 生成签名,官方默认MD5+商户秘钥+参数信息
String sign = WXPayUtil.generateSignature(param, "LYtbqfDAZiekNQemSc2NIu4uhQqPnitn");
param.put("sign", sign);
// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(param);
System.out.println("xmlParam"+xmlParam);
return xmlParam;
} catch (Exception e) {
e.printStackTrace();
payMap.put("msg", "签名生成错误");
return "签名生成错误";
}
}
/**
*下载交易账单(下载Gzip)
* @param saveUrl 保存文件地址
* @param data 请求参数
* @return
* @throws IOException
* @throws Exception
*/
public static void downFile(String saveUrl, String data) throws IOException {
Date currentTime = new Date();
//新建日期格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
//将日期对象格式化成指定格式并以String输出
String bill_date = simpleDateFormat.format(currentTime);
// 设置访问地址
URL url = new URL("https://api.mch.weixin.qq.com/pay/downloadbill");
// 连接类的父类,抽象类
URLConnection urlConnection = url.openConnection();
// http的连接类 得到网络访问对象
HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
// 设置请求参数(访问方式,超时时间,输入,输出流,请求头信息),以流的形式进行连接
// 设定请求的方法,默认是GET
httpURLConnection.setRequestMethod("POST");
// 超时时间
httpURLConnection.setConnectTimeout(3000);
// 设置是否向HttpURLConnection输出
httpURLConnection.setDoOutput(true);
// 设置是否从httpUrlConnection读入
httpURLConnection.setDoInput(true);
// 设置使用编码格式参数的名-值对
httpURLConnection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
// 简历连接
httpURLConnection.connect();
// 写入参数到请求中
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8"));
// 传递参数
writer.write(data.toString());
writer.flush();
writer.close();
// 获取响应code 200成功
int code = httpURLConnection.getResponseCode();
if (code == 200) {
InputStream inputStream = httpURLConnection.getInputStream();
// 判断字节大小
if (inputStream.available() != 0) {
System.out.println("结果大小:" + inputStream.available());
File file = new File(saveUrl+"\\"+bill_date+".zip");
if (!file.getParentFile().exists()) {
boolean result = file.getParentFile().mkdirs();
if (!result) {
System.out.println("创建失败");
}
}
OutputStream out = new FileOutputStream(file);
int size = 0;
int len = 0;
byte[] buf = new byte[1024];
while ((size = inputStream.read(buf)) != -1) {
len += size;
out.write(buf, 0, size);
}
System.out.println("最终写入字节数大小:" + len);
inputStream.close();
out.close();
}
}
// 关闭 http连接,释放资源
httpURLConnection.disconnect();
}
/**
* 订单结果查询
* 生成签名的xml
* @return
*/
public static String queryOrderResult(String out_trade_no){
// 封装需要的信息
Map payMap = new HashMap();
String nonceStr= WXPayUtil.generateNonceStr();
try {
// 1. 拼接下单地址参数
Map param = new HashMap();
param.put("appid", appid); // 公总号ID
param.put("mch_id", mch_id); // 商户号ID
param.put("out_trade_no",out_trade_no); // 随机字符串
param.put("nonce_str", nonceStr); // 账单类型
param.put("sign_type", "MD5"); // 签名类型
// 生成签名,官方默认MD5+商户秘钥+参数信息
String sign = WXPayUtil.generateSignature(param, "LYtbqfDAZiekNQemSc2NIu4uhQqPnitn");
param.put("sign", sign);
// 将所有参数转换为xml形式
String xmlParam = WXPayUtil.mapToXml(param);
// 2. 发送请求
HttpClient1 httpClient1 = new HttpClient1("https://api.mch.weixin.qq.com/pay/orderquery");
httpClient1.setHttps(true);// https协议
httpClient1.setXmlParam(xmlParam);
httpClient1.post();
// 获取结果
String xmlResult = httpClient1.getContent();
if (xmlResult.indexOf("SUCCESS") != -1) { // 只要执行了下单接口,都会包含SUCCESS的
Map map = WXPayUtil.xmlToMap(xmlResult);
String trade_state_desc=(String) map.get("trade_state_desc");
if (trade_state_desc==null){
return "2";
}else if (trade_state_desc.equals("支付成功")){
return "1";
}
}
return "3";
} catch (Exception e) {
e.printStackTrace();
payMap.put("msg", "签名生成错误");
return "签名生成错误";
}
}
}
附赠http请求工具类
package cn.xizhi.until.pay;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* http请求客户端
*
* @author Administrator
*
*/
public class HttpClient1 {
private String url;
private Map param;
private int statusCode;
private String content;
private String xmlParam;
private boolean isHttps;
public boolean isHttps() {
return isHttps;
}
public void setHttps(boolean isHttps) {
this.isHttps = isHttps;
}
public String getXmlParam() {
return xmlParam;
}
public void setXmlParam(String xmlParam) {
this.xmlParam = xmlParam;
}
public HttpClient1(String url, Map param) {
this.url = url;
this.param = param;
}
public HttpClient1(String url) {
this.url = url;
}
public void setParameter(Map map) {
param = map;
}
public void addParameter(String key, String value) {
if (param == null)
param = new HashMap();
param.put(key, value);
}
public void post() throws ClientProtocolException, IOException {
HttpPost http = new HttpPost(url);
setEntity(http);
execute(http);
}
public void put() throws ClientProtocolException, IOException {
HttpPut http = new HttpPut(url);
setEntity(http);
execute(http);
}
public void get() throws ClientProtocolException, IOException {
if (param != null) {
StringBuilder url = new StringBuilder(this.url);
boolean isFirst = true;
for (String key : param.keySet()) {
if (isFirst)
url.append("?");
else
url.append("&");
url.append(key).append("=").append(param.get(key));
}
this.url = url.toString();
}
HttpGet http = new HttpGet(url);
execute(http);
}
/**
* set http post,put param
*/
private void setEntity(HttpEntityEnclosingRequestBase http) {
if (param != null) {
List nvps = new LinkedList();
for (String key : param.keySet())
nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
}
if (xmlParam != null) {
http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
}
}
private void execute(HttpUriRequest http) throws ClientProtocolException,
IOException {
CloseableHttpClient httpClient = null;
try {
if (isHttps) {
SSLContext sslContext = new org.apache.http.ssl.SSLContextBuilder()
.loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.build();
} else {
httpClient = HttpClients.createDefault();
}
CloseableHttpResponse response = httpClient.execute(http);
try {
if (response != null) {
if (response.getStatusLine() != null)
statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
// 响应内容
content = EntityUtils.toString(entity, Consts.UTF_8);
}
} finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
httpClient.close();
}
}
public int getStatusCode() {
return statusCode;
}
public String getContent() throws ParseException, IOException {
return content;
}
/**
* 获取用户实际ip
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
//根据网卡取本机配置的IP
InetAddress inet=null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress= inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
return ipAddress;
}
public static void main(String[] args) throws SocketException {
System.out.println("IP"+getOutIPV4());
}
public static String getV4IP(){
String ip = "";
String chinaz = "http://ip.chinaz.com";
StringBuilder inputLine = new StringBuilder();
String read = "";
URL url = null;
HttpURLConnection urlConnection = null;
BufferedReader in = null;
try {
url = new URL(chinaz);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedReader( new InputStreamReader(urlConnection.getInputStream(),"UTF-8"));
while((read=in.readLine())!=null){
inputLine.append(read+"\r\n");
}
//System.out.println(inputLine.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(in!=null){
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Pattern p = Pattern.compile("\\(.*?)\\<\\/dd>");
Matcher m = p.matcher(inputLine.toString());
if(m.find()){
String ipstr = m.group(1);
ip = ipstr;
//System.out.println(ipstr);
}
return ip;
}
public static String getOutIPV4() {
String ip = "";
String chinaz = "http://ip.chinaz.com";
StringBuilder inputLine = new StringBuilder();
String read = "";
URL url = null;
HttpURLConnection urlConnection = null;
BufferedReader in = null;
try {
url = new URL(chinaz);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
while ((read = in.readLine()) != null) {
inputLine.append(read + "\r\n");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pattern p = Pattern.compile("\\(.*?)\\<\\/dd>");
Matcher m = p.matcher(inputLine.toString());
if (m.find()) {
String ipstr = m.group(1);
ip = ipstr;
}
return ip;
}
}
亲测可用,复制粘贴即可