java版微信支付V3JSAPI 公众号支付

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jidetashuo/article/details/54410875

1. 具体的流程及需要注意的地方见文档  


2.调用的htmljs代码


function weixinPay(){
	var totalprice=$("#totalprice").html();
	totalprice='0.01';
	totalprice=Number(totalprice)*100;
	window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxx&redirect_uri=http%3A%2F%2Fwx.nongyuancui.com%2Fnyc%2Fwap%2Fweixin_openid.action?totalprice="+totalprice+"&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
	//回调地址  注意编码   ':' 用'%3A'代替   '/' 用'%2F'代替
} 



2.java 代码

WeixinController


package xhsoft.yxd.wap.controller;

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 net.sf.json.JSONObject;

import org.apache.log4j.Logger;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import xhsoft.utils.EnvUtils;
import xhsoft.utils.StringUtils;
import xhsoft.web.exp.BusinessExeption;
import xhsoft.yxd.base.model.PayStatus;
import xhsoft.yxd.base.service.IPayStatus;
import xhsoft.yxd.core.constant.WeiXinPayInfo;
import xhsoft.yxd.core.constant.WeiXinPayOrderInfo;
import xhsoft.yxd.core.mv.WapModelAndView;
import xhsoft.yxd.core.uitl.PropertyUtil;
import xhsoft.yxd.core.weixintools.HttpRequest;
import xhsoft.yxd.core.weixintools.Signature;
import xhsoft.yxd.core.weixintools.WeiXinUtils;

/**
 * @author WangMeng
 * @date 2017年1月11日
 */
@Controller
@RequestMapping("/wap")
public class WeixinController
{

	@Autowired
	IPayStatus payStatusService;
	private static Logger logger = Logger.getLogger(WeixinController.class);
	/**
	 * 获取微信用户openId
	 * 
	 * @param request
	 * @param response
	 * @param buyerId
	 * @author WangMeng
	 * @date 2016年6月7日
	 */
	@RequestMapping(value = "/weixin_openid")
	public ModelAndView getOpenId(HttpServletRequest request, HttpServletResponse response)
			throws BusinessExeption

	{

		String code = request.getParameter("code");

		String totalprice = request.getParameter("totalprice");

		String oauth_url = StringUtils.format(
				"{0}?appid={1}&secret={2}&code={3}&grant_type=authorization_code",
				WeiXinPayInfo.OPIDURL, WeiXinPayInfo.APPID, WeiXinPayInfo.SECERT, code);

		JSONObject jsonObject = null;
		try
		{
			jsonObject = HttpRequest.httpsRequestToJsonObject(oauth_url, "POST", null);
		}
		catch (Exception e)
		{
			logger.error("微信支付发送acctoken请求异常");
			throw new BusinessExeption("微信支付发送acctoken请求异常", e);
		}

		Object errorCode = jsonObject.get("errcode");
		String openId = "";
		if (errorCode != null)
		{

			logger.error("微信支付请求openId发送请求返回错误,错误码:" + errorCode);

		}
		else
		{
			openId = jsonObject.getString("openid");

		}
		
		return weixinPay(openId, request, response, Integer.parseInt(totalprice));

	}
	/**
	 * 根据openId进行预支付,获取信息
	 * 
	 * @param openId
	 * @param request
	 * @param response
	 * @return
	 * @author WangMeng
	 * @date 2016年6月8日
	 */
	private ModelAndView weixinPay(String openId, HttpServletRequest request,
			HttpServletResponse response, int totalPrice) throws BusinessExeption
	{

		
		// 预支付请求返回的map集合
		Map<String, String> map = new HashMap<String, String>();
		// 返回给前端页面进行支付的数据
		SortedMap<Object, Object> params = new TreeMap<Object, Object>();

		String out_trade_no = EnvUtils.getHashId();
		try
		{
			String sign = WeiXinUtils.getSign(request, openId, out_trade_no, totalPrice);
			
			map = HttpRequest.httpsRequestToXML(WeiXinPayInfo.PREPARE, "POST", sign);

		}
		catch (java.lang.Exception e)
		{
			logger.error("微信签名异常");
			throw new BusinessExeption("微信支付发送授权请求异常", e);
		}

		params.put("appId", WeiXinPayInfo.APPID);
		params.put("timeStamp", Long.toString(new Date().getTime()));
		params.put("nonceStr", WeiXinUtils.create_nonce_str().replace("-", ""));
		params.put("signType", WeiXinPayOrderInfo.SIGNTYPE);
		String packageValue = StringUtils.format("prepay_id={0}", map.get("prepay_id"));
		params.put("package", packageValue);

		String paySign = Signature.createSign("UTF-8", params);
		params.put("packageValue", packageValue); // 这里用packageValue是预防package是关键字在js获取值出错
		params.put("paySign", paySign); // paySign的生成规则和Sign的生成规则一致
		params.put("sendUrl", WeiXinPayOrderInfo.NOTIFY); // 付款成功后跳转的页面
		params.put("out_trade_no", out_trade_no); // 付款成功后跳转的页面

		ModelAndView mv = new WapModelAndView("wap/weixin.html", request, response);
		mv.addObject("payParams", params);
		return mv;

	}
	/**
	 * 发送微信授权请求 TODO 暂时在前段使用localtion.href发请求,不清楚为什么后台发这个请求不好用
	 * 
	 * @param request
	 * @param response
	 * @param buyerId
	 * @author WangMeng
	 * @date 2016年6月7日
	 */
	@RequestMapping(value = "/weixin_outh")
	public void sendouth(HttpServletRequest request, HttpServletResponse response)
			throws BusinessExeption

	{
		System.out.println("weixin_outh start............");
		String autoCallbackUrl;
		try
		{

			String key = StringUtils
					.format("appid={1}&redirect_uri={2}&response_type=code&scope=snsapi_base&state=123#wechat_redirect",
							WeiXinPayInfo.OAUTHURL, PropertyUtil.getProperty("wxGZpay_appId"),
							PropertyUtil.getProperty("wxGZpay_auth_callurl"));
			// System.out.println("weixin_outh outhUrl............" + outhUrl);
			// HttpRequest.httpsRequest(outhUrl, "GET", null);
			System.out.println("key:" + key);
			// System.out
			// .println(HttpRequest
			// .sendGet("https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx19026bd3a5c42ed2&redirect_uri=http%3A%2F%2Fwx.nongyuancui.com%2Fnyc%2Fwap%2Fweixin_openid.action&response_type=code&scope=snsapi_base&state=123#wechat_redirect"));
			response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx19026bd3a5c42ed2&redirect_uri=http%3A%2F%2Fwx.nongyuancui.com%2Fnyc%2Fwap%2Fweixin_openid.action&response_type=code&scope=snsapi_base&state=123#wechat_redirect");
		}
		catch (Exception e)
		{

			logger.error("微信支付发送授权请求异常", e);
			throw new BusinessExeption("微信支付发送授权请求异常", e);
		}

	}
	/**
	 * 验证是否支付成功
	 * 
	 * @param request
	 * @param response
	 * @author WangMeng
	 * @date 2016年6月8日
	 */
	@ResponseBody
	@RequestMapping(value = "/weixin_validate")
	public String validate(HttpServletRequest request, HttpServletResponse response,
			@RequestParam("outTradeNo") String outTradeNo)

	{

		PayStatus payStatus = payStatusService.getDao().get(outTradeNo);
		String status = payStatus.getStatus();
		JSONObject jObject = new JSONObject();
		jObject.put("flag", false);
		if ("SUCCESS".equals(status))
		{

			jObject.put("flag", true);
			payStatusService.getDao().delete(payStatus);
		}

		return jObject.toString();
	}
}

回调url代码

WeixinNotifyController

package xhsoft.yxd.wap.controller;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import xhsoft.utils.DateTimeUtils;
import xhsoft.web.controller.BaseController;
import xhsoft.web.exp.BusinessExeption;
import xhsoft.yxd.base.model.PayStatus;
import xhsoft.yxd.base.service.IPayStatus;
import xhsoft.yxd.core.weixintools.WeiXinUtils;
import xhsoft.yxd.core.weixintools.XMLUtil;

/**
 * @author WangMeng
 * @date 2016年6月8日
 */
@Controller
@RequestMapping(value = "/wap")
public class WeixinNotifyController extends BaseController
{

	@Autowired
	IPayStatus payStatusService;

	private static Logger logger = Logger.getLogger(WeixinNotifyController.class);
	@RequestMapping(value = "/weixin_notify")
	public void weiixnNotify(HttpServletRequest request, HttpServletResponse response)
			throws BusinessExeption

	{

		try
		{
			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);
			}
			outSteam.close();
			inStream.close();
			String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
			Map<Object, Object> map = XMLUtil.doXMLParse(result);
			String out_trade_no = map.get("out_trade_no").toString();

			if (map.get("result_code").toString().equalsIgnoreCase("SUCCESS"))
			{

				PayStatus payStatus = new PayStatus();
				payStatus.setId(out_trade_no);
				payStatus.setTradeNode(out_trade_no);
				payStatus.setStatus("SUCCESS");
				payStatus.setOpTime(DateTimeUtils.getNowTimeStanderd());
				payStatusService.getDao().saveOrUpdate(payStatus);

				response.getWriter().write(WeiXinUtils.setXML("SUCCESS", "")); // 告诉微信服务器,我收到信息了,不要在调用回调action了

			}
		}
		catch (Exception e)
		{
			logger.error("微信回调异常");
			throw new BusinessExeption("微信回调异常", e);
		}

	}

}

发起支付的html页面

<script>
	$(document).ready(function() {

		var outTradeNo = '${payParams.get("out_trade_no")}';
		function onBridgeReady(){
			
			WeixinJSBridge.invoke('getBrandWCPayRequest', {
				"appId" : '${payParams.get("appId")}', //公众号名称,由商户传入     
				"timeStamp" : '${payParams.get("timeStamp")}', //时间戳,自1970年以来的秒数     
				"nonceStr" : '${payParams.get("nonceStr")}', //随机串     
				"package" : '${payParams.get("packageValue")}',
				"signType" : '${payParams.get("signType")}', //微信签名方式:     
				"paySign" : '${payParams.get("paySign")}'
			//微信签名 
			}, function(res) {
				
				if (res.err_msg == "get_brand_wcpay_request:ok") {

					weixinPayValidate(outTradeNo);
				} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
				else {
					$api.rmStorage('orderData');
					history.back(-1);
				}
			});
		}
		
		if (typeof WeixinJSBridge == "undefined"){
			   if( document.addEventListener ){
			       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
			   }else if (document.attachEvent){
			       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
			       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
			   }
		}else{
		  	 onBridgeReady();
		}
	})

	/**
	 * 验证支付是否成功
	 */
	function weixinPayValidate(outTradeNo) {
	
		var data = {
			outTradeNo : outTradeNo
		}
		extApi.ajax('wap/weixin_validate.action', data, function(data) {
			
			if (JSON.parse(data).flag) {
				newOrder();
			} else {
				//$api.rmStorage('orderData');
				history.back(-1);
			}
		});
	}
	
	
	
	/**
	 * 下单
	 */
	function newOrder() {
		var orderData = $api.getStorage("orderData");
		var key=$api.getStorage("orderDataKey");
		var url;
		if(key=="shopData"){
			url='shop/order_new.action';
		}else{
			url='shop/order_pre_new.action';
		}
		extApi.ajax(url, orderData, newOrerCallback);

	}

	/**
	 *下单回调函数
	 */
	function newOrerCallback(data) {
		//异常
		if (data.flag == false) {
			extApi.toast('下单失败');
			return;
		}
		extApi.toast('订单已经生成');
		var key=$api.getStorage("orderDataKey");
		
		if(key=="shopData"){
		    // 如果用户选择了积分兑换,下单成功后将用户的积分减去
			minUserScore();
		}else{
			ordernewSuccess();
		}
	}
	
	/**
	 *如果用户选择了积分兑换,下单成功后将用户的积分清零
	 */
	function minUserScore() {
		var user = $api.getStorage('user');
		var score=0;
		
		if($("input[type=checkbox]").prop('checked')){
			score=user.store;
		}
		var data = {
				buyerId : user.id,
				score : score
		};
		
		
		extApi.ajax('shop/buyer_score_edit.action', data, function(data) {
			user.store = data.store;
			$api.setStorage('user', user);
			ordernewSuccess();
		});
	}
	


	function ordernewSuccess(){
		
		var key=$api.getStorage("orderDataKey");
		$api.rmStorage(key);
		$api.rmStorage('orderData');
		$api.rmStorage('orderDataKey');
		var count=$api.getStorage("orderDataCount");
		//购物车减去数量监听
		shopcart.minCountTocart(count);
		//清理缓存
		window.history.go(-2);
	}
</script>


代码中涉及到的工具类地址  

展开阅读全文
博主设置当前文章不允许评论。

没有更多推荐了,返回首页