java微信支付接入流程详解
作者:只要你能好 发布时间:2023-07-28 18:37:46
标签:java,微信支付
背景
由于项目是采用java编写的,微信包括微信支付大都是php相关,于是微信支付官方文档对java的支持就不是很友好,在网上找了很多文章,基本上没有一篇是真正跑的通的,经过一番整理,先将java接入微信支付详细流程总结出来以便后续使用。
步骤一
准备阶段:已认证微信号,且通过微信支付认证,这个可以看微信文档,很详细,这里就不再重复。
步骤二
配置授权目录,官方推荐使用https类型的url,不知道http能不能行,个人也推荐使用https的保证不会错。
配置授权域名
步骤三
微信支付二次开发所需要的参数:
APP_ID,APP_KEY,PARTNER,PARTNER_KEY(AppSecret)
APP_ID和PARTNER_KEY(AppSecret)
PARTNER
APP_KEY(自行设置32位字符)
步骤四
4.1通过页面跳转到确认支付页面,其中的redirect_uri必须是配置授权目录下的
<html>
<head>
<title>支付测试</title>
</head>
<body>
<a href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx619890d997071358&redirect_uri=https%3A%2F%2Fm.yangji.com%2Fpay%2FpayTest.jsp&response_type=code&scope=snsapi_base&state=123#wechat_redirect">支付测试</a>
</body>
</html>
4.2 获取到openid,再经服务器向微信请求获取prepay_id,封装字段并进行签名后通过jsapi调起微信支付
网页端
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no" />
<title>测试支付</title>
<link href="../css/css.css?v=1.0" rel="external nofollow" rel="stylesheet" type="text/css">
</head>
<body>
<div class="index_box">
<div class="apply_name">微信js支付测试</div>
<div class="branch_con">
<ul>
<li><span class="name">测试支付信息[]</span></li>
</ul>
<p class="cz_btn"><a href="javascript:pay();" rel="external nofollow" class="btn_1">立即支付</a></p>
</div>
</div>
<%
String code = request.getParameter("code");
%>
<input type="text" id="code" value="<%out.print(code); %>"/>
<input type="text" id="path" value="${pageContext.request.contextPath}"/>
<div><hr/>
code:<%out.print(code); %>
</div>
<script type="text/javascript">
var appId,timeStamp,nonceStr,pg,signType,paySign;
function onBridgeReady(){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId" : appId, //公众号名称,由商户传入
"timeStamp": timeStamp, //时间戳,自1970年以来的秒数
"nonceStr" : nonceStr, //随机串
"package" : "prepay_id=" + pg,
"signType" : signType, //微信签名方式:
"paySign" : paySign //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
alert("支付成功");
}
}
);
}
function pay(){
var code = document.getElementById("code").value;
var path = document.getElementById("path").value;
send_request(function(value){
var json = eval("(" + value + ")");
if(json.length > 0){
appId = json[0].appId;
timeStamp = json[0].timeStamp;
nonceStr = json[0].nonceStr;
pg = json[0].pg;
signType = json[0].signType;
paySign = json[0].paySign;
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();
}
}
},path+"/pay/payparm.htm?openId="+code, true);
}
function send_request(callback, urladdress,isReturnData){
var xmlhttp = getXMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4) {
try{
if(xmlhttp.status == 200){
if(isReturnData && isReturnData==true){
callback(xmlhttp.responseText);
}
}else{
callback("页面找不到!"+ urladdress +"");
}
} catch(e){
callback("请求发送失败,请重试!" + e);
}
}
}
xmlhttp.open("POST", urladdress, true);
xmlhttp.send(null);
}
function getXMLHttpRequest() {
var xmlhttp;
if (window.XMLHttpRequest) {
try {
xmlhttp = new XMLHttpRequest();
xmlhttp.overrideMimeType("text/html;charset=UTF-8");
} catch (e) {}
} else if (window.ActiveXObject) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHttp");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Msxml3.XMLHttp");
} catch (e) {}
}
}
}
return xmlhttp;
}
</script>
</body>
</html>
服务器端
@RequestMapping("/pay/payparm")
public void payparm(HttpServletRequest request, HttpServletResponse response){
try {
// 获取openid
String openId = (String) request.getSession().getAttribute("openId");
if (openId == null) {
openId = getUserOpenId(request);
}
String appid = WXConfig.APP_ID;
String paternerKey = WXConfig.PERTNER_KEY;
String out_trade_no = getTradeNo();
Map<String, String> paraMap = new HashMap<String, String>();
paraMap.put("appid", appid);
paraMap.put("attach", "测试");
paraMap.put("body", "测试购买支付");
paraMap.put("mch_id", WXConfig.PARTNER);
paraMap.put("nonce_str", create_nonce_str());
paraMap.put("openid", openId);
paraMap.put("out_trade_no", out_trade_no);
paraMap.put("spbill_create_ip", getAddrIp(request));
paraMap.put("total_fee", "1");
paraMap.put("trade_type", "JSAPI");
paraMap.put("notify_url", "http://m.ebiaotong.com/WXPay/notify");// 此路径是微信服务器调用支付结果通知路径
String sign = getSign(paraMap, paternerKey);
paraMap.put("sign", sign);
// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
String xml = ArrayToXml(paraMap);
String xmlStr = HttpKit.post(url, xml);
// 预付商品id
String prepay_id = "";
if (xmlStr.indexOf("SUCCESS") != -1) {
Map<String, String> map = doXMLParse(xmlStr);
prepay_id = (String) map.get("prepay_id");
}
String timeStamp = create_timestamp();
String nonceStr = create_nonce_str();
Map<String, String> payMap = new HashMap<String, String>();
payMap.put("appId", appid);
payMap.put("timeStamp", timeStamp);
payMap.put("nonceStr", nonceStr);
payMap.put("signType", "MD5");
payMap.put("package", "prepay_id=" + prepay_id);
String paySign = getSign(payMap, paternerKey);
payMap.put("pg", prepay_id);
payMap.put("paySign", paySign);
// 拼接并返回json
StringBuilder sBuilder = new StringBuilder("[{");
sBuilder.append("appId:'").append(appid).append("',")
.append("timeStamp:'").append(timeStamp).append("',")
.append("nonceStr:'").append(nonceStr).append("',")
.append("pg:'").append(prepay_id).append("',")
.append("signType:'MD5',")
.append("paySign:'").append(paySign).append("'");
sBuilder.append("}]");
response.getWriter().print(sBuilder.toString());
response.getWriter().close();
} catch (Exception e) {
e.printStackTrace();
}
}
测试结果
来源:https://blog.csdn.net/u012131769/article/details/52669988
0
投稿
猜你喜欢
- java读取resources文件详解及实现代码Java项目中,经常需要将资源文件打包放在项目中,然后在项目中去读取对应的文件。实现代码:S
- Ctrl+1 快速修复Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当
- .NET开发人员首选的方法,通过COM组件调用Office软件本身来实现文件的创建和读写,但是数据量较大的时候异常缓慢;如下代码所示已经做了
- 本文实例为大家分享了Unity键盘WASD实现物体移动的具体代码,供大家参考,具体内容如下1首先在场景中建立一个Capsule,将主摄像机拖
- System.out.print("\b") 会在控制台下往回删掉一个字符,如果你想回删多个字符就打印多个 "
- 这篇文章主要介绍了简单了解Java多态向上转型相关原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 一:前言最近老师布置了给多级菜单的作业,感觉蛮有意思的,可以提升自己的逻辑!下面我写个简易版的多级菜单,本人还是菜鸟,欢迎各位给予宝贵的建议
- 本文实例讲述了Java实现的求逆矩阵算法。分享给大家供大家参考,具体如下:package demo;public class MatrixI
- 当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。导致竞态条件发生的代码区称作临界区。在临界区中使用适当的同步就可以避免
- 在使用SpringSecurity中,大伙都知道默认的登录数据是通过key/value的形式来传递的,默认情况下不支持JSON格式的登录数据
- 上次面试中遇到的一个问题,问到System.out.println()中的out是不是内部类,当时就给问蒙了,直观感觉out应该是Syste
- 目录1.说明2.先来说下@FunctionalInterface3. 下面来讲讲这个 "::"是干嘛的4. 建立一个Pe
- 本文介绍了如何使用Spring Security OAuth2构建一个授权服务器来验证用户身份以提供access_token,并使用这个ac
- 先给大家展示下效果图:1、验证码生成类:import java.util.Random;import java.awt.imag
- Spring Boot产生环形注入***************************APPLICATION FAILED TO STAR
- java web 实现分页功能,分享给大家,具体如下:使用框架:ssm数据库:oracle话说 oracle 的分页查询比 mysql 复杂
- 如何实现首先 * 是属于web这块的,那我们需要引入springboot web模块,具体版本在parent中<dependency&
- 本文实例为大家分享了Java从服务端下载Excel模板文件的具体实现代码,供大家参考,具体内容如下方法一 (2021年01月更新)生成exc
- 把spring-boot项目按照平常的web项目一样发布到tomcat容器下一、修改打包形式在pom.xml里设置 <packagin
- 基于jsr303 通过自定义注解实现,实现思路:存在一些瑕疵,后续补充完善。加入依赖部分版本已不默认自动引入该依赖,选择手动引入<de