当前位置: 首页 > news >正文

Java、JSAPI、 ssm架构 微信支付demo

1.前端 index.html

<%@page import="com.tenpay.configure.WxPayConfig"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html><style>#fukuan{font-size: 50px;margin-top: 450px;}.amount{width: 400px;height: 80px;font-size: 50px;text-align: center;}#shouquan {display: inline-block;width: 600px;height: 120px;border-radius: 30px;font-size: 55px;background-color: #00bbff;color: white;line-height: 120px;margin-top: 100px;
}
</style><body><div style="text-align: center;margin-top:50px;"><h3><!-- redirect_uri:是你自己的,主要要url编码 state:可以是任意参数,我一般理解为商品id,你在后台WxPayAction中可以获取到,在到数据库中查询商品详细信息,我写死是1000000scope:  snsapi_userinfo(用户有感知,需用户点击授权)     snsapi_base(默认授权)--><div id="fukuan">付款金额:<input type="text" name="amount"  class="amount">&nbsp;&nbsp;</div><h1><div id="shouquan">授权支付</div></h1></h3></div></body></html>
<script type="text/javascript" src="${pageContext.request.contextPath }/resources/jquery-1.9.0.min.js"></script><script type="text/javascript">$(function(){$(document).on("click","#shouquan",function(){	//获取选中的单选框元素var price = $("input[name='amount']").val();alert("付款金额====="+price);// location="${pageContext.request.contextPath }/alipay_pay_liaotian.html?selectOpenId="+selectOpenId; location="https://open.weixin.qq.com/connect/oauth2/authorize?appid=<%=WxPayConfig.APP_ID %>&redirect_uri=<%=WxPayConfig.REDIRECT_URI %>&response_type=code&scope=snsapi_userinfo&state="+price+"#wechat_redirect";	})})</script>

2.前端 pay.html

<%@ 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="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%String appId = (String)request.getAttribute("appId");String timeStamp = (String)request.getAttribute("timeStamp");String nonceStr = (String)request.getAttribute("nonceStr");String _package = (String)request.getAttribute("package");String signType = (String)request.getAttribute("signType");String paySign = (String)request.getAttribute("paySign");String totalFee = (String)request.getAttribute("totalFee");
%>
<script type="text/javascript">
function callpay()
{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 onBridgeReady() {alert("appId=<%=appId %>,timeStamp=<%=timeStamp %>,nonceStr=<%=nonceStr %>,package=<%=_package %>,signType=<%=signType %>,paySign=<%=paySign %>");WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId" : "<%=appId %>","timeStamp" : "<%=timeStamp %>","nonceStr" : "<%=nonceStr %>","package" : "<%=_package %>","signType" : "<%=signType %>","paySign" : "<%=paySign %>"}, function(res) { // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回  ok,但并不保证它绝对可靠。  //alert(res.err_msg);if (res.err_msg == "get_brand_wcpay_request:ok") {//alert("支付成功");//支付成功,返回首页location="https://www.appbi.com/wechat/"; }if (res.err_msg == "get_brand_wcpay_request:cancel") {alert("交易取消");}if (res.err_msg == "get_brand_wcpay_request:fail") {alert("支付失败");}});}
</script>
</head>
<style>#price{width:100%;font-size: 50px;text-align: center;margin-top: 400px;margin-bottom: 100px;}</style>
<body><div id="price"><span style="font-size: 50px;color:red;font-weight: 900;"><%=totalFee %></span> &nbsp;&nbsp;</div><div style="text-align: center;margin-top: 50px;"><h1><button type="button" style="display:inline-block;width:600px;height:200px;border-radius:30px; background-color: #00bbff;font-size:50px" onclick="callpay()">确认支付</button></h1></div>
</body>
</html>

3. 前端 notify.html

<%@ 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="Content-Type" content="text/html; charset=UTF-8">
<title>恭喜你,支付成功</title>
</head>
<body><div style="text-align:center;"><h1>...恭喜你,支付成功...</h1><h3><a href="https://www.appbi.com/wechat/">跳回首页</a></h3></div>
</body>
</html>

4.后台配置

package com.tenpay.configure;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;public class WxPayConfig {// appidpublic static String APP_ID = "wx9b4ab423461b9";// JSAPI接口中获取APP_SECRET,审核后在公众平台开启开发模式后可查看public static String APP_SECRET = "668d58d15703cf09d3ad8da996";// 受理商ID,身份标识public static String MCH_ID = "16079885";// 商户支付密钥Key,装完整数后,配置得到。public static String KEY = "shanghaishuzikeji123456";// 异步回调地址//public static String NOTIFY_URL = "http://www.appbi.com/wechat/v_3/notify";public static String NOTIFY_URL = "https://www.appbi.com/wechat/v_3/notify.html";// 字符编码public static String CHARTSET = "UTF-8";// 加密方式public static String SIGN_TYPE = "MD5";// redirect_uri,微信授权重定向地址public static String REDIRECT_URI;static {try {REDIRECT_URI = URLEncoder.encode("http://www.appbi.com/wechat/v_3/pay", CHARTSET);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}
}

5.后台业务逻辑

package com.tenpay.action;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.jdom2.JDOMException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;import com.tenpay.RequestHandler;
import com.tenpay.configure.WxPayConfig;
import com.tenpay.service.ServiceUtil;
import com.tenpay.util.MD5Util;
import com.tenpay.util.Sha1Util;
import com.tenpay.util.XMLUtil;import net.sf.json.JSONObject;/******************************************************************************** <b>类名: WxPayAction.java</b> <br/>* 功能:微信支付,调用jsapi<br/>* 日期:2015-12-29<br/>* * @author <a href="mailto:406224709@qq.com">zhongming</a>* @version 1.0* ******************************************************************************/
@Controller
@RequestMapping("/v_3")
public class WxPayAction {/*** 微信客户端授权成功后根据redirect_uri参数调整到pay接口,去准备支付前信息接口* @param request* @param response* @return* @throws Exception*/@RequestMapping("pay")public String order(HttpServletRequest request, HttpServletResponse response,@RequestParam(value="code",required=false) String code,@RequestParam(value="state",required=false) Double state) throws Exception {/*** 第一步:用户同意授权,根据参数,获取code* 授权成功后返回的授权码,参考:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html#.E7.AC.AC.E4.B8.80.E6.AD.A5.EF.BC.9A.E7.94.A8.E6.88.B7.E5.90.8C.E6.84.8F.E6.8E.88.E6.9D.83.EF.BC.8C.E8.8E.B7.E5.8F.96code*///String code = request.getParameter("code");//String state = request.getParameter("state");// state可以为任何含义,根据你前端需求,这里暂时叫商品id// 授权码、商品idSystem.out.println("code=" + code + ",state=" + state);/*** 第二步:通过code换取网页授权access_token* 根据授权码code获取access_token,参考:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html#.E7.AC.AC.E4.BA.8C.E6.AD.A5.EF.BC.9A.E9.80.9A.E8.BF.87code.E6.8D.A2.E5.8F.96.E7.BD.91.E9.A1.B5.E6.8E.88.E6.9D.83access_token*/// 下面就到了获取openid,这个代表用户id.// 获取openIDString openid = ServiceUtil.getOpenId(code);// 生成随机字符串String noncestr = Sha1Util.getNonceStr();// 生成1970年到现在的秒数.String timestamp = Sha1Util.getTimeStamp();// 订单号,自定义生成规则,只要全局唯一就OKString out_trade_no = "NO" + System.currentTimeMillis() + "0001";// 订单金额,应该是根据state(商品id)从数据库中查询出来//String order_price = String.valueOf(1);//state乘100的原因是价格是按分运算   换算成   按元计算BigDecimal a1 = new BigDecimal(String.valueOf(state));BigDecimal b1 = new BigDecimal(String.valueOf(100));Integer resultState = a1.multiply(b1).intValue();// double相乘100的方法String order_price = String.valueOf(resultState);// 商品描述,应该是根据state(商品id)从数据库中查询出来String body = "商品描述,测试....";/*** 第三步:统一下单接口* 需要第二步生成的openid,参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1*/RequestHandler reqHandler = new RequestHandler(request, response);// 初始化 RequestHandler 类可以在微信的文档中找到.还有相关工具类reqHandler.init();// 执行统一下单接口 获得预支付id,一下是必填参数// 微信分配的公众账号ID(企业号corpid即为此appId)reqHandler.setParameter("appid", WxPayConfig.APP_ID); // 微信支付分配的商户号reqHandler.setParameter("mch_id", WxPayConfig.MCH_ID); // 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"reqHandler.setParameter("device_info", "WEB"); // 随机字符串,不长于32位。推荐随机数生成算法reqHandler.setParameter("nonce_str", noncestr); // 商品描述reqHandler.setParameter("body", body); // 商家订单号reqHandler.setParameter("out_trade_no", out_trade_no); // 商品金额,以分为单位reqHandler.setParameter("total_fee", order_price); // APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。reqHandler.setParameter("spbill_create_ip", "123.57.58.123"); // 下面的notify_url是用户支付成功后为微信调用的action 异步回调.reqHandler.setParameter("notify_url", WxPayConfig.NOTIFY_URL);// 交易类型,取值如下:JSAPI,NATIVE,APP,详细说明见参数规定reqHandler.setParameter("trade_type", "JSAPI");// ------------需要进行用户授权获取用户openid-------------reqHandler.setParameter("openid", openid); // 这个必填./** <xml><appid>wx2421b1c4370ec43b</appid><attach>支付测试</attach><body>* JSAPI支付测试</body><mch_id>10000100</mch_id><nonce_str>* 1add1a30ac87aa2db72f57a2375d8fec</nonce_str><notify_url>http://wxpay.* weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url><openid>* oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid><out_trade_no>1415659990</* out_trade_no><spbill_create_ip>14.23.150.211</spbill_create_ip><* total_fee>1</total_fee><trade_type>JSAPI</trade_type><sign>* 0CB01533B8C1EF103065174F50BCA001</sign></xml>*/// 生成签名,并且转为xmlString requestXml = reqHandler.getRequestXml();System.out.println("requestXml:" + requestXml);// 得到的预支付idString prepay_id = ServiceUtil.unifiedorder(requestXml);SortedMap<String, String> params = new TreeMap<String, String>();params.put("appId", WxPayConfig.APP_ID);params.put("timeStamp", timestamp);params.put("nonceStr", noncestr);params.put("package", "prepay_id=" + prepay_id);params.put("signType", "MD5");System.out.println("params:" + JSONObject.fromObject(params).toString());// 生成支付签名,这个签名 给 微信支付的调用使用SortedMap<Object,Object> signMap = new TreeMap<Object,Object>();signMap.put("appId", WxPayConfig.APP_ID); signMap.put("timeStamp", timestamp);signMap.put("nonceStr", noncestr);signMap.put("package", "prepay_id=" + prepay_id);signMap.put("signType", "MD5");// 微信支付签名String paySign = MD5Util.createSign(signMap, WxPayConfig.KEY);System.out.println("PaySIGN:" + paySign);//微信分配的公众账号ID(企业号corpid即为此appId)request.setAttribute("appId", WxPayConfig.APP_ID);// 时间戳request.setAttribute("timeStamp", timestamp); // 随机字符串request.setAttribute("nonceStr", noncestr); // 预支付id ,就这样的格式request.setAttribute("package", "prepay_id=" + prepay_id);// 加密格式request.setAttribute("signType", WxPayConfig.SIGN_TYPE); // 微信支付签名request.setAttribute("paySign", paySign);// 商品金额,以元为单位request.setAttribute("totalFee", state.toString()); return "pay";}/*** 异步返回*/@RequestMapping("notify")public String notify(HttpServletRequest request, HttpServletResponse response) {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 resultStr = new String(outSteam.toByteArray(), WxPayConfig.CHARTSET);Map<String, String> resultMap = XMLUtil.doXMLParse(resultStr);System.out.println("微信回调结果:" + resultMap.toString());String result_code = resultMap.get("result_code");String is_subscribe = resultMap.get("is_subscribe");String out_trade_no = resultMap.get("out_trade_no");String transaction_id = resultMap.get("transaction_id");String sign = resultMap.get("sign");String time_end = resultMap.get("time_end");String bank_type = resultMap.get("bank_type");String return_code = resultMap.get("return_code");// 签名验证
//			GenericValue userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);if (return_code.equals("SUCCESS")) {// 此处就是你的逻辑代码// 修改数据库支付状态}request.setAttribute("out_trade_no", out_trade_no);// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.response.getWriter().write(RequestHandler.setXML("SUCCESS", ""));} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (JDOMException e) {e.printStackTrace();}return "notify";}
}

6. 上述需要源码插件的链接地址

  项目demo参考: https://download.csdn.net/download/qq_39951524/88146803
http://www.lryc.cn/news/106647.html

相关文章:

  • MongoDB文档--基本安装-linux安装(mongodb环境搭建)-docker安装(挂载数据卷)-以及详细版本对比
  • tomcat限制IP访问
  • 互联网宠物医院系统开发:数字化时代下宠物医疗的革新之路
  • docker镜像批量导出导入
  • 宇凡微2.4g遥控船开发方案,采用合封芯片
  • RPC框架引入zookeeper服务注册与服务发现
  • MySQL用通配符过滤数据
  • 低通、高通、带通、阻通滤波器
  • IDEA SpringBoot Maven profiles 配置
  • 微信小程序 背景图片如何占满整个屏幕
  • 邪恶版ChatGPT来了!
  • 一、Postfix[安装与配置、smtp认证、Python发送邮件以及防垃圾邮件方法、使用腾讯云邮件服务]
  • React哲学——官方示例
  • 设计模式之开闭原则
  • Linux中的file命令:查看文件类型
  • 使用WiFi测量仪进行机器人定位的粒子过滤器研究(Matlab代码实现)
  • 【vue】vue 里面使用 v-html 插入的文本带有换行符‘\n‘不换行
  • Java失效算法与应用(FIFO、LRU、LFU)
  • Go语音介绍
  • Vue2与Vue3响应式原理
  • flask中写一个基础的sqlHelper类
  • opencv的Mask操作,选择图片中感兴趣的区域
  • 一次有趣的Webshell分析经历
  • 【NLP概念源和流】 05-引进LSTM网络(第 5/20 部分)
  • Vue没有node_modules怎么办
  • 企业级高负载web服务器-Tomcat小项目
  • 《golang设计模式》第一部分·创建型模式-03-建造者模式(Builder)
  • git 忽略掉不需要的文件
  • 摄像机sd卡格式化怎么恢复数据?简单五步轻松解决
  • 1-4 AUTOSAR方法论--开发流程