微信公众号支付、退费开发
2016-12-15 14:51
357 查看
微信公众号支付开发 + 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>
相关文章推荐
- 微信公众号支付(一):获取用户openId
- 微信公众号支付【Java版】
- 微信公众号支付模块的开发
- 微信公众号、APP微信支付
- 微信公众号对接JSAPI模式的微信支付简介与总结
- 微信支付
- 微信公众号开发中遇到的问题——支付(二)
- JAVA 微信公共号支付
- dcloud中Intent scheme的使用,外部APP唤醒微信公众号支付
- java迷路记-微信支付之公众号支付小结
- Django微信公众号开发(二)公众号内微信支付
- Laravel 微信公众号支付
- 微信公众号之支付验证签名失败
- 微信公众号支付WeixinJSBridge
- ecshop 小京东 微信公众号链接打开,报错appid不能为空,错误码10012
- 微信公众号支付爬坑总结
- 微信支付(网站支付,APP支付,扫码支付)并充值钻石 Java服务端代码 xml解析 map排序
- 微信公众号支付(二)H5调起支付
- php微信支付,退款,企业转账类
- 微信公众号之调起h5支付(代码详解)