软件编程
位置:首页>> 软件编程>> java编程>> 详解APP微信支付(java后台_统一下单和回调)

详解APP微信支付(java后台_统一下单和回调)

作者:花花世界何必认真  发布时间:2023-11-10 17:26:42 

标签:APP,微信支付,java

1.微信配置信息 global.properties

详解APP微信支付(java后台_统一下单和回调)

2.方法wxpay用于生成预支付订单信息

方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", wxnotify); (见下面代码) 

在局域网是无法进行回调的,必须将你的服务端放在公网上进行测试, 回调函数会被多次调用,如果第一次成功后,你可以将业务数据状态标志为已处理, 对于相同订单的其它回调就不需要再次处理了;


package com.main.controller;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jdom.JDOMException;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.main.model.WeiXinPrePay;
import com.main.util.ConfigManager;
import com.main.util.DateUtil;
import com.main.util.GeneralConstant;
import com.main.util.PayCommonUtil;
import com.main.util.Result;
import com.main.util.StringUtil;
@Controller
@RequestMapping("/pay")
public class PayController {
String randomString = PayCommonUtil.getRandomString(32);
 //支付成功后的回调函数
 public static String wxnotify = "http://com.zhuohuicalss/pay/notifyWeiXinPay";
public PayController() {
System.out.println("MainController构造函数");
}
/**
  * @param totalAmount  支付金额
  * @param description  描述
  * @param request
  * @return
  */
 @RequestMapping(value = "/wxpay", produces = MediaType.APPLICATION_JSON_VALUE)
 @ResponseBody  
 public Result wxpay(HttpServletRequest request) {
 Result result = new Result();
   Long userId = new Long(1);//baseController.getUserId();
BigDecimal totalAmount = new BigDecimal(request.getParameter("totalPrice"));
   String trade_no = "";
   String description="";
try {
trade_no = new String(request.getParameter("orderNum").getBytes("ISO-8859-1"),"UTF-8");
description = request.getParameter("description");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
   String openId = "";
Map<String, String> map = weixinPrePay(trade_no,totalAmount,description,openId,request);
   SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();
   //应用ID
   finalpackage.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID")/*PayCommonUtil.APPID*/);
   //商户号
   finalpackage.put("partnerid", ConfigManager.getInstance().getConfigItem("MCH_ID"));
   Long time = (System.currentTimeMillis() / 1000);
   //时间戳
   finalpackage.put("timestamp", time.toString());
   //随机字符串
   finalpackage.put("noncestr", map.get("nonce_str"));
   //预支付交易会话ID
   finalpackage.put("prepayid", map.get("prepay_id"));
   //扩展字段
   finalpackage.put("package", "Sign=WXPay");
WeiXinPrePay prePay = new WeiXinPrePay();
   prePay.setAppId(ConfigManager.getInstance().getConfigItem("WXAppID"));
   prePay.setMchId(ConfigManager.getInstance().getConfigItem("MCH_ID"));
   prePay.setTimeStamp(time.toString());
   prePay.setNonceStr(map.get("nonce_str"));
   prePay.setPrepayId(map.get("prepay_id"));
   prePay.setSignType("MD5");
   prePay.setPaySign(sign);
   result.setData(prePay);
   result.setStateCode(GeneralConstant.SUCCESS);
   result.setDesc("微信支付加载成功");
return result;
 }
/**
  * 统一下单
  * 应用场景:商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
  * @param trade_no
  * @param totalAmount
  * @param description
  * @param openid
  * @param sym
  * @param request
  * @return
  */
 @SuppressWarnings("unchecked")
 public Map<String, String> weixinPrePay(String trade_no,BigDecimal totalAmount,
     String description, String openid, HttpServletRequest request) {
   SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
   parameterMap.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID")); //应用appid
   parameterMap.put("mch_id", ConfigManager.getInstance().getConfigItem("MCH_ID")/*PayCommonUtil.MCH_ID*/); //商户号
   //parameterMap.put("device_info", "WEB");
   parameterMap.put("nonce_str", randomString);
   parameterMap.put("body", description);
   parameterMap.put("out_trade_no", trade_no);
   parameterMap.put("fee_type", "CNY");
   System.out.println("jiner");
   BigDecimal total = totalAmount.multiply(new BigDecimal(100)); //接口中参数支付金额单位为【分】,参数值不能带小数,所以乘以100
   java.text.DecimalFormat df=new java.text.DecimalFormat("0");
   parameterMap.put("total_fee", df.format(total));
   System.out.println("jiner2");
   parameterMap.put("spbill_create_ip", PayCommonUtil.getRemoteHost(request));
   parameterMap.put("notify_url", wxnotify);
   parameterMap.put("trade_type", "APP");//"JSAPI"
   //trade_type为JSAPI是 openid为必填项
   //parameterMap.put("openid", openid);
   System.out.println("");
   String sign = PayCommonUtil.createSign("UTF-8", parameterMap);
   System.out.println("jiner2");
   parameterMap.put("sign", sign);
   String requestXML = PayCommonUtil.getRequestXml(parameterMap);
   System.out.println(requestXML);
   String result = PayCommonUtil.httpsRequest(
       "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",
       requestXML);
   System.out.println(result);
   Map<String, String> map = null;
   try {
     map = PayCommonUtil.doXMLParse(result);
   } catch (JDOMException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
   return map;    
 }
/**
  * 此函数会被执行多次,如果支付状态已经修改为已支付,则下次再调的时候判断是否已经支付,如果已经支付了,则什么也执行
  * @param request
  * @param response
  * @return
  * @throws IOException
  * @throws JDOMException
  */
 @RequestMapping(value = "notifyWeiXinPay", produces = MediaType.APPLICATION_JSON_VALUE)
 // @RequestDescription("支付回调地址")
 @ResponseBody
 public String notifyWeiXinPay(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
   System.out.println("微信支付回调");
   InputStream inStream = request.getInputStream();
   ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
   byte[] buffer = new byte[1024];
   int len = 0;
   while ((len = inStream.read(buffer)) != -1) {
     outSteam.write(buffer, 0, len);
   }
   String resultxml = new String(outSteam.toByteArray(), "utf-8");
   Map<String, String> params = PayCommonUtil.doXMLParse(resultxml);
   outSteam.close();
   inStream.close();
Map<String,String> return_data = new HashMap<String,String>();
   if (!PayCommonUtil.isTenpaySign(params)) {
     // 支付失败
   return_data.put("return_code", "FAIL");
     return_data.put("return_msg", "return_code不正确");
   return StringUtil.GetMapToXML(return_data);
   } else {
     System.out.println("===============付款成功==============");
     // ------------------------------
     // 处理业务开始
     // ------------------------------
     // 此处处理订单状态,结合自己的订单数据完成订单状态的更新
     // ------------------------------
String total_fee = params.get("total_fee");
     double v = Double.valueOf(total_fee) / 100;
     String out_trade_no = String.valueOf(Long.parseLong(params.get("out_trade_no").split("O")[0]));
Date accountTime = DateUtil.stringtoDate(params.get("time_end"), "yyyyMMddHHmmss");
String ordertime = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
String totalAmount = String.valueOf(v);
String appId = params.get("appid");
String tradeNo = params.get("transaction_id");
return_data.put("return_code", "SUCCESS");
     return_data.put("return_msg", "OK");
return StringUtil.GetMapToXML(return_data);
   }
 }
}

3.用到的一些工具类


import java.io.InputStream;
import java.util.*;
/**
* 读取配置文件的类 单例类
* @author Administrator
*
*/
public class ConfigManager {
// 属性文件命名
private Properties m_props = null;
private static Map<String,String> configMap;
private static ConfigManager m_instance = null;
private static  Properties props = null;
private ConfigManager() {
m_props = new Properties();
configMap = new HashMap<String,String>();
try {
props = System.getProperties(); //获取系统属性
m_props.load(getInputStream());
getSysConfigMsg();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized static ConfigManager getInstance() {
if(m_instance == null){
m_instance = new ConfigManager();
}
return m_instance;
}
public InputStream getInputStream() {
InputStream is = null;
try {
is = getClass().getClassLoader().getResourceAsStream("global.properties");
} catch (Exception e) {
e.printStackTrace();
}
return is;
}
public Map<String,String> getSysConfigMsg(){
Set<Object> keyset = m_props.keySet();
Iterator<Object> it = keyset.iterator();
while(it.hasNext()){
String nextkey = it.next().toString();
configMap.put(nextkey,getConfigItem(nextkey));
}
return configMap;
}
public String getConfigItem(String name) {
String val = m_props.getProperty(name).trim();
if("fileSavePath".equals(name)){
if(props.getProperty("os.name").startsWith("Windows")){
val = val.split("#")[0].toString().trim();
}else{
val = val.split("#")[1].toString().trim();
}
}
return val;
}
public Map<String,String> getConfigMap(){
return configMap;
}
}

import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Pattern;
public class DateUtil {
// 格式:年-月-日 小时:分钟:秒
 public static final String FORMAT_ONE = "yyyy-MM-dd HH:mm:ss";
// 格式:年-月-日 小时:分钟
 public static final String FORMAT_TWO = "yyyy-MM-dd HH:mm";
// 格式:年月日 小时分钟秒
 public static final String FORMAT_THREE = "yyyyMMdd-HHmmss";
// 格式:年月日
 public static final String FORMAT_FOUR = "yyyyMMdd";
// 格式:年-月-日
 public static final String LONG_DATE_FORMAT = "yyyy-MM-dd";
// 格式:月-日
 public static final String SHORT_DATE_FORMAT = "MM-dd";
// 格式:小时:分钟:秒
 public static final String LONG_TIME_FORMAT = "HH:mm:ss";
//格式:年-月
 public static final String MONTG_DATE_FORMAT = "yyyy-MM";
// 年的加减
 public static final int SUB_YEAR = Calendar.YEAR;
// 月加减
 public static final int SUB_MONTH = Calendar.MONTH;
// 天的加减
 public static final int SUB_DAY = Calendar.DATE;
// 小时的加减
 public static final int SUB_HOUR = Calendar.HOUR;
// 分钟的加减
 public static final int SUB_MINUTE = Calendar.MINUTE;
// 秒的加减
 public static final int SUB_SECOND = Calendar.SECOND;
static final String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四",
     "星期五", "星期六" };
public DateUtil() {
 }
/**
  * 把符合日期格式的字符串转换为日期类型
  */
 public static Date stringtoDate(String dateStr, String format) {
   Date d = null;
   SimpleDateFormat formater = new SimpleDateFormat(format);
   try {
     formater.setLenient(false);
     d = formater.parse(dateStr);
   } catch (Exception e) {
     // log.error(e);
     d = null;
   }
   return d;
 }
/**
  * 把符合日期格式的字符串转换为日期类型
  */
 public static Date stringtoDate(String dateStr, String format,
     ParsePosition pos) {
   Date d = null;
   SimpleDateFormat formater = new SimpleDateFormat(format);
   try {
     formater.setLenient(false);
     d = formater.parse(dateStr, pos);
   } catch (Exception e) {
     d = null;
   }
   return d;
 }
/**
  * 把日期转换为字符串
  */
 public static String dateToString(Date date, String format) {
   String result = "";
   SimpleDateFormat formater = new SimpleDateFormat(format);
   try {
     result = formater.format(date);
   } catch (Exception e) {
     // log.error(e);
   }
   return result;
 }
/**
  * 获取当前时间的指定格式
  */
 public static String getCurrDate(String format) {
   return dateToString(new Date(), format);
 }
/**
  *
  * @Title:    dateSub
  * @Date     2014-1-9 上午10:44:02
  * @Description: 得到指定日期前(后)的日期
  * @param:    @param dateKind 例:Calendar.DAY_OF_MONTH
  * @param:    @param dateStr 指定日期
  * @param:    @param amount  增加(减去)的时间量
  * @param:    @return  
  * @return:    String  
  * @throws
  * @author    mtf
  */
 public static String dateSub(int dateKind, String dateStr, int amount) {
   Date date = stringtoDate(dateStr, MONTG_DATE_FORMAT);
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   calendar.add(dateKind, amount);
   return dateToString(calendar.getTime(), FORMAT_ONE);
 }
/**
  * 昨日日期
  * @return
  */
 public static String yearthDate(String dateStr){
 Date date = stringtoDate(dateStr, LONG_DATE_FORMAT);//取时间
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   calendar.add(calendar.DATE,-1);//把日期往后增加一天.整数往后推,负数往前移动
   //date=calendar.getTime();  //这个时间就是日期往后推一天的结果
   return dateToString(calendar.getTime(), LONG_DATE_FORMAT);
 }
/**
  * 两个日期相减
  * @return 相减得到的秒数
  */
 public static long timeSub(String firstTime, String secTime) {
   long first = stringtoDate(firstTime, FORMAT_ONE).getTime();
   long second = stringtoDate(secTime, FORMAT_ONE).getTime();
   return (second - first) / 1000;
 }
 /**
  * 两个日期相减
  * 参数地DATE
  * second 两个日期相差的秒
  * @return 相减得到的秒数
  * 后面时间减去前面时间 再减去 相差秒数  如果大于0 返回 FASLE
  */
 public static boolean timeSub(Date firstTime, Date secTime,long secs) {
   long first = firstTime.getTime();
   long second = secTime.getTime();
   // 判断两个时间 是否间隔那么长 secs。
   return (second - first - secs) > 0 ? false:true;
 }
 /**
  * 两个日期相减
  * 参数地DATE
  * @return 相减得到的秒数
  * 后面时间减去前面时间 如果大于0 返回 false
  */
 public static boolean timeSub(Date firstTime, Date secTime) {
   long first = firstTime.getTime();
   long second = secTime.getTime();
   return (second - first)>0?false:true;
 }
 /**
  * 获得某月的天数
  */
 public static int getDaysOfMonth(String year, String month) {
   int days = 0;
   if (month.equals("1") || month.equals("3") || month.equals("5")
       || month.equals("7") || month.equals("8") || month.equals("10")
       || month.equals("12")) {
     days = 31;
   } else if (month.equals("4") || month.equals("6") || month.equals("9")
       || month.equals("11")) {
     days = 30;
   } else {
     if ((Integer.parseInt(year) % 4 == 0 && Integer.parseInt(year) % 100 != 0)
         || Integer.parseInt(year) % 400 == 0) {
       days = 29;
     } else {
       days = 28;
     }
   }
return days;
 }
/**
  * 获取某年某月的天数
  */
 public static int getDaysOfMonth(int year, int month) {
   Calendar calendar = Calendar.getInstance();
   calendar.set(year, month - 1, 1);
   return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
 }
/**
  * 获得当前日期
  */
 public static int getToday() {
   Calendar calendar = Calendar.getInstance();
   return calendar.get(Calendar.DATE);
 }
/**
  * 获得当前月份
  */
 public static int getToMonth() {
   Calendar calendar = Calendar.getInstance();
   return calendar.get(Calendar.MONTH) + 1;
 }
/**
  * 获得当前年份
  */
 public static int getToYear() {
   Calendar calendar = Calendar.getInstance();
   return calendar.get(Calendar.YEAR);
 }
/**
  * 返回日期的天
  */
 public static int getDay(Date date) {
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   return calendar.get(Calendar.DATE);
 }
/**
  * 返回日期的年
  */
 public static int getYear(Date date) {
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   return calendar.get(Calendar.YEAR);
 }
/**
  * 返回日期的月份,1-12
  */
 public static int getMonth(Date date) {
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   return calendar.get(Calendar.MONTH) + 1;
 }
/**
  * 计算两个日期相差的天数,如果date2 > date1 返回正数,否则返回负数
  */
 public static long dayDiff(Date date1, Date date2) {
   return (date2.getTime() - date1.getTime()) / 86400000;
 }
/**
  * 比较两个日期的年差
  */
 public static int yearDiff(String before, String after) {
   Date beforeDay = stringtoDate(before, LONG_DATE_FORMAT);
   Date afterDay = stringtoDate(after, LONG_DATE_FORMAT);
   return getYear(afterDay) - getYear(beforeDay);
 }
/**
  * 比较指定日期与当前日期的差
  */
 public static int yearDiffCurr(String after) {
   Date beforeDay = new Date();
   Date afterDay = stringtoDate(after, LONG_DATE_FORMAT);
   return getYear(beforeDay) - getYear(afterDay);
 }
/**
  * 获取每月的第一周
  */
 public static int getFirstWeekdayOfMonth(int year, int month) {
   Calendar c = Calendar.getInstance();
   c.setFirstDayOfWeek(Calendar.SATURDAY); // 星期天为第一天
   c.set(year, month - 1, 1);
   return c.get(Calendar.DAY_OF_WEEK);
 }
/**
  * 获取每月的最后一周
  */
 public static int getLastWeekdayOfMonth(int year, int month) {
   Calendar c = Calendar.getInstance();
   c.setFirstDayOfWeek(Calendar.SATURDAY); // 星期天为第一天
   c.set(year, month - 1, getDaysOfMonth(year, month));
   return c.get(Calendar.DAY_OF_WEEK);
 }
/**
  * 获得当前日期字符串,格式"yyyy-MM-dd HH:mm:ss"
  *
  * @return
  */
 public static String getNow() {
   Calendar today = Calendar.getInstance();
   return dateToString(today.getTime(), FORMAT_ONE);
 }
/**
  * 判断日期是否有效,包括闰年的情况
  *
  * @param date
  *     YYYY-mm-dd
  * @return
  */
 public static boolean isDate(String date) {
   StringBuffer reg = new StringBuffer(
       "^((\\d{2}(([02468][048])|([13579][26]))-?((((0?");
   reg.append("[13578])|(1[02]))-?((0?[1-9])|([1-2][0-9])|(3[01])))");
   reg.append("|(((0?[469])|(11))-?((0?[1-9])|([1-2][0-9])|(30)))|");
   reg.append("(0?2-?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][12");
   reg.append("35679])|([13579][01345789]))-?((((0?[13578])|(1[02]))");
   reg.append("-?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))");
   reg.append("-?((0?[1-9])|([1-2][0-9])|(30)))|(0?2-?((0?[");
   reg.append("1-9])|(1[0-9])|(2[0-8]))))))");
   Pattern p = Pattern.compile(reg.toString());
   return p.matcher(date).matches();
 }
/*****
  * 时间 增加、减少 n个小时以后时间
  * @param date
  *     YYYY-mm-dd HH:mm:ss
  * @param num>0 小时    
  * @param type 增加和减少标志
  * **/
 public static Date adjustDateByHour(Date d ,Integer num, int type) {
 Calendar Cal= Calendar.getInstance();
  DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 Cal.setTime(d);
 if(type==0){
   Cal.add(Calendar.MINUTE,-num);
   // System.out.println("date:"+df.format(Cal.getTime()));
}else
 {
 Cal.add(Calendar.MINUTE,num);
   //System.out.println("date:"+df.format(Cal.getTime()));
 }
 return Cal.getTime();
 }
 /*****
  * 时间 增加、减少 n个分钟以后时间
  * @param date
  *     YYYY-mm-dd HH:mm:ss
  * @param num>0 分钟    
  * @param type 增加和减少标志
  * **/
 public static Date adjustDateByMinutes(Date d ,Integer num, int type) {
 Calendar Cal= Calendar.getInstance();
  DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 Cal.setTime(d);
 if(type==0){
   Cal.add(Calendar.MINUTE,-num);
  // System.out.println("date:"+df.format(Cal.getTime()));
}else
 {
 Cal.add(Calendar.MINUTE,num);
  //  System.out.println("date:"+df.format(Cal.getTime()));
 }
 return Cal.getTime();
 }
public static void main(String[] args){
//  String dateStr = DateUtil.yearthDate("2017-05-30");
//  System.out.println(dateStr);
//  long min = DateUtil.timeSub("2017-04-12 00:00:00", "2017-04-13 00:00:00")/60;
//  System.out.println(min);
 String settlementDate = DateUtil.dateToString(new Date(), "yyyy-MM-dd");
 long day = DateUtil.dayDiff(DateUtil.stringtoDate("2017-06-22", "yyyy-MM-dd"),DateUtil.stringtoDate(settlementDate, "yyyy-MM-dd"));
 if(day >= 0){
 System.out.println(day);
 }
String goodsArriveTime = "2017-04-02 17:00-18:00";
 int space_index = goodsArriveTime.indexOf(" ");
 String arrive_date = goodsArriveTime.substring(0, space_index);
String arrive_time = goodsArriveTime.substring(space_index+1, goodsArriveTime.length());
System.out.println(arrive_date);
System.out.println(arrive_time);
String arrive_start_time = arrive_time.substring(0, 2);
String arrive_end_time = arrive_time.substring(6,8);
System.out.println(arrive_start_time);
System.out.println(arrive_end_time);
String Time = DateUtil.getCurrDate("HH");
System.out.println(Time);
String Time2 = DateUtil.getCurrDate("mm");
System.out.println(Time2);
 }
}

import java.security.MessageDigest;
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" };
}
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
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.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyStore;
import java.util.*;
public class PayCommonUtil {
//微信参数配置
 public static String API_KEY = ConfigManager.getInstance().getConfigItem("API_KEY");
//随机字符串生成
 public static String getRandomString(int length) { //length表示生成字符串的长度  
    String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";    
    Random random = new Random();    
    StringBuffer sb = new StringBuffer();    
    for (int i = 0; i < length; i++) {    
      int number = random.nextInt(base.length());    
      sb.append(base.charAt(number));    
    }    
    return sb.toString();    
 }  
//请求xml组装
 public static String getRequestXml(SortedMap<String,Object> parameters){
    StringBuffer sb = new StringBuffer();
    sb.append("<xml>");
    Set es = parameters.entrySet();
    Iterator it = es.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+">"+"<![CDATA["+value+"]]></"+key+">");
      }else {
        sb.append("<"+key+">"+value+"</"+key+">");
      }
    }
    sb.append("</xml>");
    return sb.toString();
 }
//生成签名
 public static String createSign(String characterEncoding,SortedMap<String,Object> 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=" + API_KEY);
    System.out.println(sb.toString());
    String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
    return sign;
 }
/**
  * 验证回调签名
  * @return
  */
 public static boolean isTenpaySign(Map<String, String> map) {
 String characterEncoding="utf-8";
   String charset = "utf-8";
   String signFromAPIResponse = map.get("sign");
   if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {
   System.out.println("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
   return false;
   }
   System.out.println("服务器回包里面的签名是:" + signFromAPIResponse);
  //过滤空 设置 TreeMap
   SortedMap<String,String> packageParams = new TreeMap();
for (String parameter : map.keySet()) {
   String parameterValue = map.get(parameter);
   String v = "";
   if (null != parameterValue) {
   v = parameterValue.trim();
   }
   packageParams.put(parameter, v);
   }
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();
   String v = (String)entry.getValue();
   if(!"sign".equals(k) && null != v && !"".equals(v)) {
   sb.append(k + "=" + v + "&");
   }
   }
   sb.append("key=" + API_KEY);
//将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
  //算出签名
   String resultSign = "";
   String tobesign = sb.toString();
if (null == charset || "".equals(charset)) {
   resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();
   }else{
   try{
   resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();
   }catch (Exception e) {
   resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();
   }
   }
String tenpaySign = ((String)packageParams.get("sign")).toUpperCase();
   return tenpaySign.equals(resultSign);
 }
//请求方法
 public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
    try {
URL url = new URL(requestUrl);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
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) {
      System.out.println("连接超时:{}"+ ce);
    } catch (Exception e) {
      System.out.println("https请求异常:{}"+ e);
    }
    return null;
 }
//退款的请求方法
 public static String httpsRequest2(String requestUrl, String requestMethod, String outputStr) throws Exception {
    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    StringBuilder res = new StringBuilder("");
    FileInputStream instream = new FileInputStream(new File("/home/apiclient_cert.p12"));
    try {
      keyStore.load(instream, "".toCharArray());
    } finally {
      instream.close();
    }
// Trust own CA and all self-signed certs
    SSLContext sslcontext = SSLContexts.custom()
        .loadKeyMaterial(keyStore, "1313329201".toCharArray())
        .build();
    // Allow TLSv1 protocol only
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslcontext,
        new String[] { "TLSv1" },
        null,
        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    CloseableHttpClient httpclient = HttpClients.custom()
        .setSSLSocketFactory(sslsf)
        .build();
    try {
HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
      httpost.addHeader("Connection", "keep-alive");
      httpost.addHeader("Accept", "*/*");
      httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
      httpost.addHeader("Host", "api.mch.weixin.qq.com");
      httpost.addHeader("X-Requested-With", "XMLHttpRequest");
      httpost.addHeader("Cache-Control", "max-age=0");
      httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
       StringEntity entity2 = new StringEntity(outputStr , Consts.UTF_8);
       httpost.setEntity(entity2);
      System.out.println("executing request" + httpost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httpost);
try {
        HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
        System.out.println(response.getStatusLine());
        if (entity != null) {
          System.out.println("Response content length: " + entity.getContentLength());
          BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
          String text = "";
          res.append(text);
          while ((text = bufferedReader.readLine()) != null) {
            res.append(text);
            System.out.println(text);
          }
}
        EntityUtils.consume(entity);
      } finally {
        response.close();
      }
    } finally {
      httpclient.close();
    }
    return res.toString();
 }
//xml解析
 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 = getChildrenText(children);
      }
m.put(k, v);
    }
//关闭流
    in.close();
return m;
 }
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(getChildrenText(list));
       }
       sb.append(value);
       sb.append("</" + name + ">");
     }
   }
return sb.toString();
}
public static String getRemoteHost(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.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
 }
}

package com.lemonjr.api.utils;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringUtil {
/**
* 数值类型前面补零(共13位)
* @param num
* @return
*/
public static String supplementZeroGenerateThirteen(int num){
String str = String.format("%013d", num);
return str;
}
/**
* 数值类型前面补零(共16位)
* @param num
* @return
*/
public static String supplementZeroGenerateSixteen(int num){
String str = String.format("%016d", num);
return str;
}
/**
* 数值类型前面补零(共3位)
* @param num
* @return
*/
public static String supplementZeroGenerateThree(int num){
String str = String.format("%03d", num);
return str;
}
/**
* 判断字符串是不是double型
* @param str
* @return
*/
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]+[.]{0,1}[0-9]*[dD]{0,1}");
Matcher isNum = pattern.matcher(str);
  if( !isNum.matches() ){
 return false;
}
 return true;
}
public static String trim(String str, boolean nullFlag){
  String tempStr = null;
if (str != null)
    {
      tempStr = str.trim();
    }
if (nullFlag)
    {
      if ("".equals(tempStr) || "null".equals(tempStr))
      {
        tempStr = null;
      }
    }
    else
    {
      if (tempStr == null)
      {
        tempStr = "";
      }
    }
return tempStr;
 }
public static String replace(String strSource, String strFrom, String strTo) {
if(strSource==null){
return null;
}
int i = 0;
if ((i = strSource.indexOf(strFrom, i)) >= 0) {
char[] cSrc = strSource.toCharArray();
char[] cTo = strTo.toCharArray();
int len = strFrom.length();
StringBuffer buf = new StringBuffer(cSrc.length);
buf.append(cSrc, 0, i).append(cTo);
i += len;
int j = i;
while ((i = strSource.indexOf(strFrom, i)) > 0) {
buf.append(cSrc, j, i - j).append(cTo);
i += len;
j = i;
}
buf.append(cSrc, j, cSrc.length - j);
return buf.toString();
}
return strSource;
}
public static String deal(String str) {
str = replace(str, "\\", "\\\\");
str = replace(str, "'", "\\'");
str = replace(str, "\r", "\\r");
str = replace(str, "\n", "\\n");
str = replace(str, "\"", "\\\"");
return str;
}
public static String GetMapToXML(Map<String,String> param){
    StringBuffer sb = new StringBuffer();
    sb.append("<xml>");
    for (Map.Entry<String,String> entry : param.entrySet()) {  
       sb.append("<"+ entry.getKey() +">");
       sb.append(entry.getValue());
       sb.append("</"+ entry.getKey() +">");
   }  
    sb.append("</xml>");
    return sb.toString();
  }
public static void main(String[] args){
//String a = StringUtil.supplementZeroGenerateThirteen(1000);
double a = 32.;
System.out.println(StringUtil.isNumeric("32."));
System.out.println(a);
}
}

4.用到的jar包


<!--微信 -->
   <dependency>
     <groupId>com.github.liyiorg</groupId>
     <artifactId>weixin-popular</artifactId>
     <version>2.8.5</version>
   </dependency>
<!--httpclient-->
   <dependency>
     <groupId>commons-httpclient</groupId>
     <artifactId>commons-httpclient</artifactId>
     <version>3.1</version>
   </dependency>
   <dependency>
     <groupId>org.jdom</groupId>
     <artifactId>jdom2</artifactId>
     <version>2.0.6</version>
   </dependency>

以上所述是小编给大家介绍的APP微信支付(java后台_统一下单和回调)详解整合,希望对大家有所帮助。

来源:https://blog.csdn.net/wd0032/article/details/79680215

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com