1.微信配置信息 global.properties

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 map = weixinPrePay(trade_no,totalAmount,description,openId,request);

SortedMap finalpackage = new TreeMap();

//应用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 weixinPrePay(String trade_no,BigDecimal totalAmount,

String description, String openid, HttpServletRequest request) {

SortedMap parameterMap = new TreeMap();

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 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 params = PayCommonUtil.doXMLParse(resultxml);

outSteam.close();

inStream.close();

Map return_data = new HashMap();

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 configMap;

private static ConfigManager m_instance = null;

private static Properties props = null;

private ConfigManager() {

m_props = new Properties();

configMap = new HashMap();

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 getSysConfigMsg(){

Set keyset = m_props.keySet();

Iterator 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 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 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 key = (String)entry.getKey();

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

if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {

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

}else {

sb.append(""+value+""+key+">");

}

}

sb.append("");

return sb.toString();

}

//生成签名

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=" + API_KEY);

System.out.println(sb.toString());

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

return sign;

}

/**

* 验证回调签名

* @return

*/

public static boolean isTenpaySign(Map 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 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("");

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 param){

StringBuffer sb = new StringBuffer();

sb.append("");

for (Map.Entry entry : param.entrySet()) {

sb.append("");

sb.append(entry.getValue());

sb.append(""+ entry.getKey() +">");

}

sb.append("");

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包

com.github.liyiorg

weixin-popular

2.8.5

commons-httpclient

commons-httpclient

3.1

org.jdom

jdom2

2.0.6

以上所述是小编给大家介绍的APP微信支付(java后台_统一下单和回调)详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

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

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

    微信支付Java后台 1.微信配置信息 global.properties 2.方法wxpay用于生成预支付订单信息 方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用 ...

  2. app支付宝支付java后台_支付宝app支付java后台流程demo

    支付宝app支付java后台流程demo 使用ssm框架实现支付宝支付功能. 支付宝测试环境代码测试 源代码 https://github.com/OUYANGSIHAI/sihai-maven-ss ...

  3. 微信统一下单 java_微信支付(java版本)_统一下单

    最近工作接触到微信支付,刚开始解决微信支付很神秘,接触之后发现并没有那么神秘,就是有很多坑,在开发的时候需要注意,整理出来: 1.准备工作 首先需要登录微信支付公众平台阅读接口文档,地址:https: ...

  4. 微信小程序 详解 小程序支付

    1.小程序内调用登录接口,获取到用户的openid,api参见公共api[小程序登录API]  上面已经说过要前后台结合,所以开发小程序的你这时就要做第一步了,文档在:https://mp.weixi ...

  5. 微信小程序详解 php,微信小程序canvas基础详解

    canvas 元素用于在网页上绘制图形.HTML5 的 canvas 元素使用 JavaScript 在网页上绘制2D图像.本文主要和大家分享微信小程序canvas基础详解,希望能帮助到大家. 一.了 ...

  6. 微信小程序详解 php,微信小程序列表开发详解

    本文主要和大家分享微信小程序列表开发详解,主要以代码的形式和大家分享,希望能帮助到大家. 一.知识点 (一).列表渲染 wx:for tip:wx:for="array"可以等于参 ...

  7. 整数反转Java_详解 LeetCode_007_整数反转(Java 实现)

    LeetCode_007_整数反转 题目描述 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: ...

  8. Java对接微信公众平台详解

    Java对接微信公众平台详解 1.公众平台概述 1.1 公众平台概述 1.2 入门指引 2.对接流程 2.1 接入概述 2.2 填写服务器配置 2.3 接口域名说明 2.4 获取Access toke ...

  9. php 微信 群聊,vbot微信机器人微信聊天消息详解(18):群组变动

    <vbot微信机器人微信聊天消息详解(18):群组变动>要点: 本文介绍了vbot微信机器人微信聊天消息详解(18):群组变动,希望对您有用.如果有疑问,可以联系我们. 当微信群新增了成员 ...

最新文章

  1. ETL 工具下载全集 包括 Informatica Datastage Cognos( 持续更新)
  2. matlab apfc,APFC-Boost 带APFC的Boost升压变换器在Matlab中的仿真实现 - 下载 - 搜珍网...
  3. org.gjt.mm.mysql.Driver和com.mysql.jdbc.Driver的概述
  4. 导致集群重启_园区网核心交换机S7706异常重启导致无线网络故障
  5. 小米运维—互联网企业级监控系统实践
  6. 最简单的WebService
  7. 如何使用Hasu USB to USB Controller Converter刷写tmk固件交换Caps和Ctrl
  8. CamOdoCal_2013-IROS_多个普通相机和里程计的内参和外参自动标定
  9. 区块链到底是个什么鬼?一幅漫画让你秒懂!
  10. 腾讯微博android版本,腾讯微博Android V1.2.2版体验
  11. 修改tomcat日志数据路径
  12. 《数据结构》— 数据结构图文解析系列
  13. 常用的免费CMS建站系统推荐
  14. 清理android根目录垃圾,安卓清理君——清除手机垃圾
  15. 网络推广有哪些常见的推广方法?
  16. 【收藏备用】15大超全应用场景总结,进阶主机安全
  17. 平板游戏交互式设计的10大规则
  18. c语言用递归求质因子,使用递归方法求解整数质因子
  19. CSDN“2019 优秀AI、IoT应用案例TOP 30+”正式发布
  20. linux添加网卡设备,Linux添加网卡教程

热门文章

  1. 【Python】enumerate函数
  2. Fusion360学习记录:虎符
  3. python连接CAD,获取坐标,在坐标上插入想要的文字。
  4. 如何把计算机歌曲传给微信好友,如何将手机本地音乐分享到微信朋友圈分享音乐...
  5. max函数(C++)
  6. 计算机怎么游戏教学,《原神》新手怎么玩 新手快速发展技巧教学
  7. c语言定义一个长度为6的数组,定义一个长度为6的数组,从键盘输入6个数据给数组,并显示;然后输出该数组中第三大的数据x....
  8. 最小堆提升每次排序的效率
  9. cesium态势标绘(三角形旗帜)
  10. Java 链表(宠物商店)