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("to