import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.hqj.wapshop.entity.ShopOrders;
import com.hqj.wapshop.service.ShopOrdersService;
import com.hqj.wechat.util.CommonUtil;
import com.hqj.wechat.util.MD5Util;
import com.hqj.wechat.util.XMLUtil;
import com.hqj.wechat.util.hqjUtil;
/**
* 支付控制controller
*
* @author linwenzhou
* @date 2014-12-08
*/
@Controller
@RequestMapping("pay")
public class PayController {
private static Logger log = LoggerFactory.getLogger(PayController.class);
private static String API_KEY = "你设置的商户支付密匙";
private static String notify_url = "pay/pay.html"; //支付的回调方法
private static String uni_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
@Autowired
private ShopOrdersService orderService;
/**
* 跳转到支付购买页面
*
* @param openId
* 微信粉丝群ID
*
* @return
*/
@RequestMapping(value = "gopay")
public @ResponseBody
String Gopay(String openId,String time, HttpServletRequest request) {
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()+ ":" + request.getServerPort() + path + "/";
log.info("base path=" + basePath);
log.info("go pay come in the openId=" + openId +"==time="+time);
SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
parameters.put("appid", "wxb714cxxxx");
parameters.put("mch_id", "1001xxx");
parameters.put("nonce_str", hqjUtil.generateRandCode(32));
parameters.put("body", "支付测试");//购买支付信息
parameters.put("out_trade_no", hqjUtil.generateRandCode(12));//订单号
parameters.put("total_fee", "1");// 总金额单位为分
parameters.put("spbill_create_ip", hqjUtil.getIpAddr(request));
parameters.put("notify_url", basePath+notify_url);
parameters.put("trade_type", "JSAPI");
parameters.put("openid", openId);
String sign = createSign("UTF-8", parameters);
parameters.put("sign", sign);
String requestXML = getRequestXml(parameters);
// log.info("requestXML" + requestXML);
String result = CommonUtil.httpsRequest2(uni_url, "POST",requestXML);
//log.info("result" + result);
try {
Map<String, String> map = XMLUtil.doXMLParse(result);
log.info("map" + map);
SortedMap<Object, Object> params = new TreeMap<Object, Object>();
params.put("appId", "wxxxxxx");
params.put("timeStamp", "\""+new Date().getTime()+"\"");
params.put("nonceStr", hqjUtil.generateRandCode(32));
params.put("package", "prepay_id=" + map.get("prepay_id"));
params.put("signType", "MD5");
String paySign = createSign("UTF-8", params);
params.put("packageValue", "prepay_id=" + map.get("prepay_id")); // 这里用packageValue是预防package是关键字在js获取值出错
params.put("paySign", paySign); // paySign的生成规则和Sign的生成规则一致
params.put("sendUrl",basePath+"mobile/paysucxx.xhtml?openId="+openId+"&time="+time); // 付款成功后跳转的 方法
String userAgent = request.getHeader("user-agent");
char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger") + 15);
params.put("agent", new String(new char[] { agent }));// 微信版本号,用于前面提到的判断用户手机微信的版本是否是5.0以上版本。
String json = JSONArray.fromObject(params).toString();
return json;
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}// 解析微信返回的信息,以Map形式存储便于取值
return "";
}
/**
* @author lwz
* @date 2014-12-8
* @Description:sign签名
* @param characterEncoding
* 编码格式
* @param parameters
* 请求参数
* @return
*/
public static String createSign(String characterEncoding,SortedMap<Object, 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);
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
/**
* @author 老妖
* @date 2014-12-5下午2:32:05
* @Description:将请求参数转换为xml格式的string
* @param parameters
* 请求参数
* @return
*/
public static String getRequestXml(SortedMap<Object, 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 k = (String) entry.getKey();
String v = (String) entry.getValue();
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k)|| "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
} else {
sb.append("<" + k + ">" + v + "</" + k + ">");
}
}
sb.append("</xml>");
return sb.toString();
}
@RequestMapping(value = "pay")
public @ResponseBody
void success(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
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);
}
log.info("~~~~~~~~~~~~~~~~付款成功~~~~~~~~~");
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
Map<Object, Object> map = XMLUtil.doXMLParse(result);
for (Object keyValue : map.keySet()) {
log.info(keyValue + "=" + map.get(keyValue));
}
if (map.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
// TODO 对数据库的操作
response.getWriter().write(setXML("SUCCESS", "")); // 告诉微信服务器,我收到信息了,不要在调用回调action了
log.info("-------------" + setXML("SUCCESS", ""));
}
}
public static String setXML(String return_code, String return_msg) {
return "<xml><return_code><![CDATA[" + return_code+ "]]></return_code><return_msg><![CDATA[" + return_msg+ "]]></return_msg></xml>";
}
@RequestMapping(value = "paysuc")
public String paysuc(String openId,String time){
ShopOrders order =orderService.findByOpenIdTime(openId, time);
order.setOrderStatus(1);
order.setOuttime(hqjUtil.getTimesmmss());
orderService.updateStatus(order);
return "redirect:/mobile/mallwwew.wwhtml?openId="+openId;
}
}
直接JSP 页面代码
function dopay() {
alert("test");
$.ajax({
type : 'POST',
url : '<%=contextPath%>/pay/gopay.html',
dataType : 'json',
data:{ openId : '<%=openId%>',time:'<%=orderTime%>'},
cache : false,
error : function() {
alert('出错了!');
return false;
},
success : function(data) {
//alert("data"+data[0].agent);
//var obj = eval('(' + data[0] + ')');
//alert("obj"+obj);
if(parseInt(data[0].agent)<5){
alert("您的微信版本低于5.0无法使用微信支付");
return;
}
WeixinJSBridge.invoke('getBrandWCPayRequest',{
"appId" : data[0].appId, //公众号名称,由商户传入
"timeStamp": data[0].timeStamp, //时间戳,自 1970 年以来的秒数
"nonceStr" : data[0].nonceStr, //随机串
"package" : data[0].packageValue, //<span style="font-family:微软雅黑;">商品包信息</span>
"signType" : data[0].signType, //微信签名方式:
"paySign" : data[0].paySign //微信签名
},function(res){
//alert(res.err_msg);
if(res.err_msg == 'get_brand_wcpay_request:ok' ) {
alert("支付成功,按确定跳转页面");
window.location.href=data[0].sendUrl;
}else{
alert("支付失败/取消,从新生成支付链接.");
window.location.href='<%=contextPath%>/mobile/submitOrder.html?openId=<%=openId%>&pay=gopay&type=2&ordertime=<%=orderTime%>';
//<span style="font-family:微软雅黑;">当失败后,继续跳转该支付页面让用户可以继续付款,
//贴别注意不能直接调转jsp,
//</span><span style="font-size:10.5pt">不然会报</span><span style="font-size:12.0pt">
//system:access_denied。</span>
}
});
}
});
}
需要demo案例 请加 laoyao_89 发送 支付案例 获取