微信公众号支付、退费开发

微信公众号支付开发 + springmvc  + jquery

  最近在做一个带有微信公众号支付的项目,由于是新手,其中也遇到了不少问题,想着就写一篇博客,把遇到的问题记录下来,供他人参考,也留着以后回顾。

1:后台支付接口
@Controller
@RequestMapping("/payment")
public class PayController {
	// 日志测试
	Logger log = Logger.getLogger(PayController.class);

	@Autowired AccessTokenService accessTokenService;

	@RequestMapping(value = { "/wxPublicPay" })
	@ResponseBody
	public void wxPublicPay(HttpServletRequest request, HttpServletResponse response) {
		Map<String, String> wxParam = new HashMap<String, String>();
		Map<String, String> returnParam = new HashMap<String, String>();
		// 首先获取用户的openId
		String code = request.getParameter("code");

		AccessToken accessToken = new AccessToken();
		String openId = "";
		accessToken = accessTokenService.getToken(code);

		openId = accessToken.getOpenid(); // 获取用户openid
		log.info("openid是:" + openId);

		// 公众号id
		wxParam.put("appid", WxConstants.APPID);
		// 商户号
		wxParam.put("mch_id", WxConstants.MCH_ID);
		// 随机字符串
		wxParam.put("nonce_str", genNonceStr());
		// 商品描述
		wxParam.put("body", "微信公众号支付测试");
		// 订单号
		wxParam.put("out_trade_no", getOrderID());
		log.info("订单号out_trade_no是:" + wxParam.get("out_trade_no"));

		// 支付金额 单位为分
		wxParam.put("total_fee", "10"); // 0.1元
		// 用户端ip
		wxParam.put("spbill_create_ip", request.getRemoteAddr());
		// 后台回调地址
		wxParam.put("notify_url", "http://wechat/payment/wxPublicNotify");
		// 交易类型
		wxParam.put("trade_type", "JSAPI");

		// openid trade_type=JSAPI时(即公众号支付),此参数必传
		wxParam.put("openid", openId);

		// 生成签名
		String sign = PayUtils.createWeiSign(wxParam);

		wxParam.put("sign", sign);
		// 将map类型数据转换为xml格式
		String entity = PayUtils.toXml(wxParam);
		// 向微信发送请求
		String content = PayUtils.sendPost("https://api.mch.weixin.qq.com/pay/unifiedorder", entity);
		log.info("微信公众号支付返回的结果content为:" + content);

		// 将微信返回的结果转换为XML格式
		wxParam = PayUtils.readStringXmlOut(content);

		if ("SUCCESS".equals(wxParam.get("return_code"))
				&& "SUCCESS".equals(wxParam.get("result_code"))) { // 前端H5调起支付API
			log.info("微信公众号支付请求成功!");
			String paySign = "";
			returnParam.put("appId", WxConstants.APPID); // 公众号id
			returnParam.put("timeStamp", getTimeStamp()); // 时间戳
			returnParam.put("nonceStr", genNonceStr()); // 随机字符串
			// 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
			returnParam.put("package", "prepay_id=" + wxParam.get("prepay_id"));
			log.info("微信公众号支付时, package的值是:" + returnParam.get("package"));

			returnParam.put("signType", "MD5");
			paySign = PayUtils.createWeiSign(returnParam);
			log.info("微信公众号支付时, 第二次签名paySign:" + paySign);

			returnParam.put("paySign", paySign); // 签名

		} else {
			// 获取prepay_id(预支付交易会话标识)失败
			log.info("微信公众号支付请求失败");
		}

		log.info("appId为:" + returnParam.get("appId").toString());
		log.info("timeStamp为:" + returnParam.get("timeStamp").toString());
		log.info("nonceStr为:" + returnParam.get("nonceStr").toString());
		log.info("package为:" + returnParam.get("package").toString());
		log.info("paySign为:" + returnParam.get("paySign").toString());

		String resultJson = "{\"content\":{ "  //content
				+ "\"appId\": " + "\"" + returnParam.get("appId").toString() + "\"" + ","
				+ "\"timeStamp\": " + "\"" + returnParam.get("timeStamp").toString() + "\"" + ","
				+ "\"nonceStr\": " + "\"" + returnParam.get("nonceStr").toString() + "\"" + ","
				+ "\"wx_package\": " + "\"" + returnParam.get("package").toString() + "\"" + ","
				+ "\"paySign\": " + "\"" + returnParam.get("paySign").toString() + "\"" + "}" + "}";

		log.info("返回给前端的resultJson信息是:" + resultJson);

		try {
			response.setContentType("text/json;charset=UTF-8");
			response.getWriter().write(resultJson);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}



2、前台页面

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="format-detection" content="telephone=no,adress=no" />
<title>微信公众号支付测试页面</title>
 <!-- 框架样式 -->
 <link rel="stylesheet" href="../resources/default/css/bootstrap.min.css">
 <!-- 主题样式 -->
 <link rel="stylesheet" href="../resources/default/css/common.css">
 <!-- 用户样式 -->
 <link rel="stylesheet" href="../resources/default/css/module-czx.css">
</head>
<body>
	<h2>微信公众号支付测试页面-pages/index.jsp修改1</h2>
	<pre></pre>
	<button class="btn btn-default base-btn btn-exit" id="payBtn" style="width:94%;margin-left:3%;">点击支付</button>

	<script type="text/javascript" src="../resources/default/js/jquery.min.js"></script>
	<script type="text/javascript" src="../resources/default/js/jquery.tmpl.min.js"></script>
	<script type="text/javascript" src="../resources/default/js/common.js"></script>
	<script type="text/javascript">

		var request = new UrlSearch(); // 实例化
		var code = request.code;
		var appId;
		var timeStamp;
		var nonceStr;
		var wx_package;
		var signType;
		var paySign;
		$.ajax({
			url : 'http://wechat/payment/wxPublicPay?code=' + code,
			type : 'post',
			dataType : 'json',
			contentType : 'application/json; charset=utf-8',
			async : false,
			success : function(data) {
				var data = data;
				appId = data.content.appId;
				timeStamp = data.content.timeStamp;
				nonceStr = data.content.nonceStr;
				wx_package = data.content.wx_package;
				paySign = data.content.paySign;
			}
		});

		function onBridgeReady(){
			   alert("公众号支付测试页面---进入支付方法");
			   WeixinJSBridge.invoke(
			       'getBrandWCPayRequest', {
			           "appId" : appId,     //公众号名称,由商户传入     
			           "timeStamp": timeStamp,          //时间戳,自1970年以来的秒数     
			           "nonceStr" : nonceStr, //随机串     
			           "package" : wx_package,     
			           "signType" : "MD5",         //微信签名方式:     
			           "paySign" : paySign //微信签名 
			       },
			       function (res) {  
			    	   alert(res.err_msg);
			           // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
			    	   if((res.err_msg).indexOf("ok") >= 0) {
			        		alert("支付测试成功!");
			    	   } else {
			    		   alert("支付失败!");
			    	   }
			       }
			   ); 
			}

		// 立即支付按钮事件
		function pay() {
			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();
				}
		}
		
		// 点击支付按钮事件
		$("#payBtn").click(function(){
			pay();
		});
	</script>
</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值