Java调用微信支付功能的方法示例代码

Java 使用微信支付

前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用。
因为涉及二维码的前端显示,所以有前端的内容

一. 准备工作

所需微信公众号信息配置

  • APPID:绑定支付的APPID(必须配置)
  • MCHID:商户号(必须配置)
  • KEY:商户支付密钥,参考开户邮件设置(必须配置)
  • APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置)

我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供

二. 构建项目架构

1.新建maven项目

2.导入依赖

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.1.RELEASE</version>
 </parent>
 <dependencies>
  <!--spring boot -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--微信提供的sdk-->
  <dependency>
   <groupId>com.github.wxpay</groupId>
   <artifactId>wxpay-sdk</artifactId>
   <version>0.0.3</version>
  </dependency>
  <!--发送http请求-->
  <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
  </dependency>
  <!--模板引擎-->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-freemarker</artifactId>
  </dependency>
 </dependencies>

依赖中需要注意的是我导入了微信提供的sdk,以及freemarker模板引擎

3.编写配置文件application.properties

# 服务端口
server.port=8081
# 微信开放平台 appid
wx.pay.app_id=
#商户号
wx.pay.partner=
#商户key
wx.pay.partnerkey=
#回调地址
wx.pay.notifyurl:

spring.freemarker.tempalte-loader-path=classpath:/templates
#  关闭缓存,及时刷新,上线生产环境需要修改为true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.suffix=.ftl
spring.mvc.static-path-pattern: /static/**

4.编写启动类

@SpringBootApplication
@ComponentScan(basePackages = {"com.haiyang.wxpay"})
public class Application {

 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }
}

5.创建常用包controller,service,impl,utils

6.创建两个前端需要的文件夹 static和templates

三. 代码实现

1. 创建工具类读取配置文件的参数

@Component
public class WxPayUtils implements InitializingBean {

 @Value("${wx.pay.app_id}")
 private String appId;

 @Value("${wx.pay.partner}")
 private String partner;

 @Value("${wx.pay.partnerkey}")
 private String partnerKey;
 @Value("${wx.pay.notifyurl}")
 private String notifyUrl;

 public static String WX_PAY_APP_ID;
 public static String WX_PAY_PARTNER;
 public static String WX_PAY_PARTNER_KEY;
 public static String WX_OPEN_NOTIFY_URL;

 @Override
 public void afterPropertiesSet() throws Exception {
  WX_PAY_APP_ID = appId;
  WX_PAY_PARTNER = partner;
  WX_PAY_PARTNER_KEY = partnerKey;
  WX_OPEN_NOTIFY_URL = notifyUrl;
 }

}

2. 构建工具类发送http请求

/**
 * http请求客户端
 *
 * @author qy
 *
 */
public class HttpClient {
	private String url;
	private Map<String, String> param;
	private int statusCode;
	private String content;
	private String xmlParam;
	private boolean isHttps;

	public boolean isHttps() {
		return isHttps;
	}

	public void setHttps(boolean isHttps) {
		this.isHttps = isHttps;
	}

	public String getXmlParam() {
		return xmlParam;
	}

	public void setXmlParam(String xmlParam) {
		this.xmlParam = xmlParam;
	}

	public HttpClient(String url, Map<String, String> param) {
		this.url = url;
		this.param = param;
	}

	public HttpClient(String url) {
		this.url = url;
	}

	public void setParameter(Map<String, String> map) {
		param = map;
	}

	public void addParameter(String key, String value) {
		if (param == null)
			param = new HashMap<String, String>();
		param.put(key, value);
	}

	public void post() throws ClientProtocolException, IOException {
		HttpPost http = new HttpPost(url);
		setEntity(http);
		execute(http);
	}

	public void put() throws ClientProtocolException, IOException {
		HttpPut http = new HttpPut(url);
		setEntity(http);
		execute(http);
	}

	public void get() throws ClientProtocolException, IOException {
		if (param != null) {
			StringBuilder url = new StringBuilder(this.url);
			boolean isFirst = true;
			for (String key : param.keySet()) {
				if (isFirst)
					url.append("?");
				else
					url.append("&");
				url.append(key).append("=").append(param.get(key));
			}
			this.url = url.toString();
		}
		HttpGet http = new HttpGet(url);
		execute(http);
	}

	/**
	 * set http post,put param
	 */
	private void setEntity(HttpEntityEnclosingRequestBase http) {
		if (param != null) {
			List<NameValuePair> nvps = new LinkedList<NameValuePair>();
			for (String key : param.keySet())
				nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
			http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
		}
		if (xmlParam != null) {
			http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
		}
	}

	private void execute(HttpUriRequest http) throws ClientProtocolException,
			IOException {
		CloseableHttpClient httpClient = null;
		try {
			if (isHttps) {
				SSLContext sslContext = new SSLContextBuilder()
						.loadTrustMaterial(null, new TrustStrategy() {
							// 信任所有
							public boolean isTrusted(X509Certificate[] chain,
									String authType)
									throws CertificateException {
								return true;
							}
						}).build();
				SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
						sslContext);
				httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
						.build();
			} else {
				httpClient = HttpClients.createDefault();
			}
			CloseableHttpResponse response = httpClient.execute(http);
			try {
				if (response != null) {
					if (response.getStatusLine() != null)
						statusCode = response.getStatusLine().getStatusCode();
					HttpEntity entity = response.getEntity();
					// 响应内容
					content = EntityUtils.toString(entity, Consts.UTF_8);
				}
			} finally {
				response.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			httpClient.close();
		}
	}

	public int getStatusCode() {
		return statusCode;
	}

	public String getContent() throws ParseException, IOException {
		return content;
	}

}

额~有点长就不放图片了 代码都一样

3. 新建controller

@Controller
@RequestMapping("/wxpay")
public class WxPayController {
 @RequestMapping("/pay")
 public String createPayQRcode(Model model) throws Exception{

  String price = "0.01";
  String no = getOrderNo();
  Map m = new HashMap();
  m.put("appid", WxPayUtils.WX_PAY_APP_ID);
  m.put("mch_id", WxPayUtils.WX_PAY_PARTNER);
  m.put("nonce_str", WXPayUtil.generateNonceStr());
  m.put("body","微信支付测试"); //主体信息
  m.put("out_trade_no", no); //订单唯一标识
  m.put("total_fee", getMoney(price));//金额
  m.put("spbill_create_ip", "127.0.0.1");//项目的域名
  m.put("notify_url", WxPayUtils.WX_OPEN_NOTIFY_URL);//回调地址
  m.put("trade_type", "NATIVE");//生成二维码的类型

  //3 发送httpclient请求,传递参数xml格式,微信支付提供的固定的地址
  HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
  //设置xml格式的参数
  //把xml格式的数据加密
  client.setXmlParam(WXPayUtil.generateSignedXml(m, WxPayUtils.WX_PAY_PARTNER_KEY));
  client.setHttps(true);
  //执行post请求发送
  client.post();
  //4 得到发送请求返回结果
  //返回内容,是使用xml格式返回
  String xml = client.getContent();
  //把xml格式转换map集合,把map集合返回
  Map<String,String> resultMap = WXPayUtil.xmlToMap(xml);
  //最终返回数据 的封装
  Map map = new HashMap();
  map.put("no", no);
  map.put("price", price);
  map.put("result_code", resultMap.get("result_code"));
  map.put("code_url", resultMap.get("code_url"));

  model.addAttribute("map",map);
  return "pay";

 }

 @GetMapping("queryorder/{no}")
 @ResponseBody
 public String queryPayStatus(@PathVariable String no) throws Exception{
  //1、封装参数
  Map m = new HashMap<>();
  m.put("appid", WxPayUtils.WX_PAY_APP_ID);
  m.put("mch_id", WxPayUtils.WX_PAY_PARTNER);
  m.put("out_trade_no", no);
  m.put("nonce_str", WXPayUtil.generateNonceStr());

  //2 发送httpclient
  HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
  client.setXmlParam(WXPayUtil.generateSignedXml(m, WxPayUtils.WX_PAY_PARTNER_KEY));
  client.setHttps(true);
  client.post();

  //3.得到订单数据
  String xml = client.getContent();
  Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);

  //4.判断是否支付成功
  if(resultMap.get("trade_state").equals("SUCCESS")) {
   /*
     改变数据库中的数据等操作
    */
   return "支付成功";
  }
  return "支付中";
 }

 @GetMapping("success")
 public String success(){
  return "success";
 }
 @RequestMapping("test")
 public String test(){
  return "pay";
 }
 /**
  * 生成订单号
  * @return
  */
 public static String getOrderNo() {
  SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
  String newDate = sdf.format(new Date());
  String result = "";
  Random random = new Random();
  for (int i = 0; i < 3; i++) {
   result += random.nextInt(10);
  }
  return newDate + result;
 }
 /**
  * 元转换成分
  * @param amount
  * @return
  */
 public static String getMoney(String amount) {
  if(amount==null){
   return "";
  }
  // 金额转化为分为单位
  // 处理包含, ¥ 或者$的金额
  String currency = amount.replaceAll("\\$|\\¥|\\,", "");
  int index = currency.indexOf(".");
  int length = currency.length();
  Long amLong = 0l;
  if(index == -1){
   amLong = Long.valueOf(currency+"00");
  }else if(length - index >= 3){
   amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));
  }else if(length - index == 2){
   amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);
  }else{
   amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");
  }
  return amLong.toString();
 }
}





值得一提的是 这里我们用的是controller而不是restcontroller,因为我们需要展示二维码

4. 在templates文件中新建 订单支付页面(二维码生成的页面)

注意:文件名必须和生成二维码方法中返回的字符串名称一样 我这里叫 pay

先新建html页面,然后再将后缀改成ftl(freemarker模板引擎的后缀名)

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <script src="/static/qrcode.js"></script>
 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<center>
 <div id="qrcode"></div>
</center>
<script type="text/javascript">
 new QRCode(document.getElementById("qrcode"), "${map.code_url}"); // 设置要生成二维码的链接
</script>
<script type="text/javascript">
 var int=self.setInterval("querystatus()",3000);
 function querystatus() {
  $.get("/wxpay/queryorder/${map.no}",function(data,status){
   if (data==="支付中"){
    console.log("支付中");
   } else {
    clearInterval(int)
    window.location.href="/wxpay/success" rel="external nofollow"
   }
  })
 }
</script>
</body>
</html>

再创建支付成功跳转的页面 文件名要与支付成功方法返回的文件名一样

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
<h1>支付成功</h1>
</body>
</html>

引入 qrcode 生成二维码的依赖,放入static文件中
这里我提供下载链接
链接: https://pan.baidu.com/s/15-E3KpRCenAewh0ZaBLnjQ 提取码: xhs9 复制这段内容后打开百度网盘手机App,操作更方便哦

引入完成后

最后 我们启动项目来测试一下

浏览器输入地址
http://localhost:8081/wxpay/pay
发现二维码生成成功,并且定时器也没问题

之后我们扫码支付
成功跳转到支付成功页面 ~nice

四. 总结

  • 首先就是生成二维码,需要的几个主要的参数,订单号,金额,购买的信息(主体信息),其余的参数除了一些可以不写的都是固定的
  • 生成二维码然后展示在页面上,用的qrcode插件,生成
  • 然后设置定时器,来实时查询订单是否支付
  • 查询订单信息的写法和生成二维码的方式差不多 无非就是请求时少了几个参数,必须得带上订单号
  • 微信提供的查询订单接口返回数据中 trade_state 代表支付状态 notpay没有支付,seccess表示已成功
  • 定时器检测到订单支付成功就清除定时器,并且执行支付成功之后的操作

实际项目中远没有这么简单,并且所有的数据都要从数据库中获取,在这里我为了方便把价格固定写死的

到此这篇关于Java调用微信支付功能的方法示例代码的文章就介绍到这了,更多相关Java调用微信支付内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java微信支付接入流程详解

    背景 由于项目是采用java编写的,微信包括微信支付大都是php相关,于是微信支付官方文档对java的支持就不是很友好,在网上找了很多文章,基本上没有一篇是真正跑的通的,经过一番整理,先将java接入微信支付详细流程总结出来以便后续使用. 步骤一 准备阶段:已认证微信号,且通过微信支付认证,这个可以看微信文档,很详细,这里就不再重复. 步骤二 配置授权目录,官方推荐使用https类型的url,不知道http能不能行,个人也推荐使用https的保证不会错. 配置授权域名 步骤三 微信支付二次开发所

  • 使用weixin-java-tools完成微信授权登录、微信支付的示例

    本文为学习记录weixin-java-tools实现公众号微信支付. 码云地址:点我 // 授权登录用到 <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-mp</artifactId> <version>3.1.0</version> </dependency> // 微信支付用到 <depende

  • Java编程调用微信支付功能的方法详解

    本文实例讲述了Java编程调用微信支付功能的方法.分享给大家供大家参考,具体如下: 微信开发文档地址:https://mp.weixin.qq.com/wiki/home/ 从调用处开始 我的流程: 1.点击"支付"按钮,去后台 --> 2.后台生成支付所需数据返回页面 --> 3.页面点击"确认支付"调用微信支付js.完成支付功能. 支付按钮 <div class="button" id="pay" onc

  • 微信支付H5调用支付详解(java版)

    最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一.配置公众号微信支付  需要我们配置微信公众号支付地址和测试白名单. 比如:支付JS页面的地址为 http://www.xxx.com/shop/pay/ 那此处配置www.xxx.com/shop/pay/ 二.开发流程 借用微信公众号支付api(地址 http://pay.weixin.qq.com/wiki/d

  • Java微信支付之公众号支付、扫码支付实例

    微信支付现在已经变得越来越流行了,随之也出现了很多以可以快速接入微信支付为噱头的产品,不过方便之余也使得我们做东西慢慢依赖第三方,丧失了独立思考的能力,这次打算分享下我之前开发过的微信支付. 一 .H5公众号支付 要点:正确获取openId以及统一下单接口,正确处理支付结果通知,正确配置支付授权目录 H5的支付方式是使用较为广泛的方式,这种支付方式主要用于微信内自定义菜单的网页,依赖手机上安装的微信客户端,高版本的微信才支持微信支付,下面按我的流程注意说明 1  编写用于支付的页面,由于是测试用

  • 微信支付之公众号支付(java实现)

    最近两周实现了调用微信接口使用微信进行支付的需求,包含公众号支付及扫码支付两种方式,由于微信文档写的较为简略,现将调用微信接口进行支付流程进行记录及分享. 本文旨在对公众号支付的实现流程进行介绍,即微信用户从公众号中点击链接进入商品h5页面,选择商品后点击支付按钮后弹出微信支付页面.输入支付密码.支付成功后跳转到全部商品页面的整个过程.微信扫码支付请参看后续文章. 1.首先,商户需申请微信公众号.微信商户号及微信支付权限.开发过程中需参照公众号及商户平台提供如下参数: ① appid:公众号id

  • 详解APP微信支付(java后台_统一下单和回调)

    1.微信配置信息 global.properties 2.方法wxpay用于生成预支付订单信息 方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", wxnotify); (见下面代码) 在局域网是无法进行回调的,必须将你的服务端放在公网上进行测试, 回调函数会被多次调用,如果第一次成功后,你可以将业务数据状态标志为已处理, 对于相同订单的

  • java实现微信支付结果通知

    支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答. 对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功. (通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒) 注意:同样的通知可能会多次发送给商户系统.商户系统必须能够正确处理重复的通知. 推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断

  • Java调用微信支付功能的方法示例代码

    Java 使用微信支付 前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用. 因为涉及二维码的前端显示,所以有前端的内容 一. 准备工作 所需微信公众号信息配置 APPID:绑定支付的APPID(必须配置) MCHID:商户号(必须配置) KEY:商户支付密钥,参考开户邮件设置(必须配置) APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) 我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供 二

  • JS通过调用微信API实现微信支付功能的方法示例

    本文实例讲述了JS通过调用微信API实现微信支付功能的方法.分享给大家供大家参考,具体如下: 最近在做微信公众号开发,在微信支付上遇到一些问题,困惑了3天,今天终于搞定.期间要感谢一些大神的帮助,趁热下面分享一下我的经验. 在实现微信支付之前,需要到微信开发平台认证,这些认证和配置信息我就不多说了,这里主要从代码层面实现支付. function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId&quo

  • 小程序微信支付功能配置方法示例详解【基于thinkPHP】

    本文实例讲述了小程序微信支付功能配置方法.分享给大家供大家参考,具体如下: ★ 背景 近期进行小程序的开发,毕竟是商城项目的开发,最后牵扯到的微信支付是必要的 个人开发过程中也是遇到各种问题,在此,我根据自己的实际操作,进行了代码的详细配置,以方便小程序新手的快速操作 -  使用语言:PHP             # PHP世界上最好的语言 HaHahahaaha -  使用框架:ThinkPHP 3.2    # 版本有点低而已,没啥大碍 -  测试工具:微信开发者工具    # 其实还挺好

  • 基于Java的MathML转图片的方法(示例代码)

    Maven依赖: <dependency> <groupId>de.rototor.jeuclid</groupId> <artifactId>jeuclid-core</artifactId> <version>3.1.14</version> </dependency> 示例: @Test public void testMathMlToImg() throws IOException { //MathML

  • java实现微信支付功能

    微信支付的具体实现方法,供大家参考,具体内容如下 工具类(用于在微信支付服务后台生成预支付交易单) package com.fengdi.lianmeng.zhifu.weixin; import com.fengdi.lianmeng.util.MD5; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; /** * * 类说明:除被扫支付场景以外,店铺系统先调用该接口在微信支付服务后台

  • java 遍历MAP的几种方法示例代码

    java中遍历MAP的几种方法 Map<String,String> map=new HashMap<String,String>(); map.put("username", "qq"); map.put("passWord", "123"); map.put("userID", "1"); map.put("email", "qq

  • Java编程调用微信分享功能示例

    本文实例讲述了Java编程调用微信分享功能.分享给大家供大家参考,具体如下: 这篇文章介绍如何使用java开发微信分享功能,因为工作,已经开发完成,可使用. 如果想要自定义微信的分享功能,首先在自己的页面内首先使用AJAX.下面我具体举例. 首先是在页面内写入请求后台的AJAX /** * 调用微信分享接口 * */ public void WXConfig(){ String url = getPara("href"); WXConfigController scan = new W

  • IOS 集成微信支付功能的实现方法

    IOS 集成微信支付功能的实现方法 第一步:集成微信的SDK https://pay.weixin.qq.com/wiki/doc/api/index.html 点击进入 下载对应SDK或示例,最后可以看看示例程序 第二步:在Xcode中填写微信开放平台申请的Appid Xcode>info>URL Types  中新建加入Appid 第三步:在Appdelegate.m 中注册微信支付 和回调 #import "WXApi.h" 添加 代理 WXApiDelegate -

  • java微信支付功能实现源码

    提示:仅微信支付功能模块类,可供参考,可点赞 一.java后台实现源码 package cn.xydx.crowdfunding.controller; import cn.xydx.crowdfunding.util.HttpRequest; import cn.xydx.crowdfunding.util.WXPayUtil; import org.json.JSONObject; import org.springframework.stereotype.Controller; impor

随机推荐