您的位置:首页 > 移动开发 > 微信开发

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

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>

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  微信公众号支付