html+java做一个完整的JSAPIv3微信支付功能

编程入门 行业动态 更新时间:2024-10-22 09:47:37

html+java<a href=https://www.elefans.com/category/jswz/34/1770767.html style=做一个完整的JSAPIv3微信支付功能"/>

html+java做一个完整的JSAPIv3微信支付功能

使用场景

在微信公众号里面做一个网页链接,带有微信支付的功能。

这里用的是html+springboot

接入前准备

准备好一个公众号,我用的公众号是公司申请的。有商户号的。

然后看官方文档,准备好所需步骤。

准备好所需接入前准备-JSAPI支付 | 微信支付服务商平台文档中心

做了一个简单的前端页面,附源码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><link rel="icon" type="image/png" href="img/logo.ico" sizes="16x16"></head>
<body style="max-width: 400px;min-height:300px;margin: 0 auto;border: 1px solid wheat;">
<button id="payBt">支付5元</button>
<input id="code" value=""><script type="text/javascript" src=".0.0.js"></script>
<script src="js/jquery-3.4.1.min.js"></script>
<script>$(document).ready(function () {// sessionStorage.setItem("openid","oJq4-5vrCjeeMz36PQkCK57Js0bo");if (sessionStorage.getItem("openid") && sessionStorage.getItem("openid") !== "undefined") {return false;}alert("----没有openid----");var code = getUrlParam('code'); // 截取路径中的code,如果没有就去微信授权,如果已经获取到了就直接传code给后台获取openIdvar local = window.location.href;alert(local)var AppId = 'AppId';alert(code);if (code == null || code === '') {alert("-----开始获取code----");$.ajax({type: "POST",url: "http://192.168.2.55/gbmsDev/api/getCodeUrl",data: {reUrl: local.split("?")[0]},dataType: "string",jsonp: 'callback',success(data) {// alert(data);window.location.href = data;}, error() {alert("error");}, complete() {// alert("complete");}});} else {alert("-----已存在code----");$("#code").val(code);getOpenId(code);}});// 去后台获取opendifunction getOpenId(code){alert("-----开始获取openid----");alert("/api/getAccessToken");alert(code);$.ajax({type: "POST",url: "http://192.168.2.55/gbmsDev/api/getAccessToken",data: {code:code},dataType: "json",jsonp: 'callback',success(data) {alert(data);alert(data.openid);if (data.openid!==undefined &&data.openid!=='' ){sessionStorage.setItem("openid",data.openid);alert("设置openid")}}, error() {alert("error");}, complete() {alert("complete");}});}$("#payBt").on("click", function () {if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){alert("addEventListener");document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);}else if (document.attachEvent){alert("attachEvent");document.attachEvent('WeixinJSBridgeReady', onBridgeReady);document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);}}else{onBridgeReady();}});// 微信支付function onBridgeReady(){var openId = sessionStorage.getItem("openid");$("#code").val(openId);if(openId === undefined || openId ===''){return false;}$.ajax({type: "POST",url: "http://192.168.2.55/gbmsDev/api/getPayParam",data: {openId:openId},dataType: "json",jsonp: 'callback',success(data) {WeixinJSBridge.invoke('getBrandWCPayRequest', data,function(res){alert(JSON.stringify(res));if(res.err_msg == "get_brand_wcpay_request:ok" ){alter("支付成功")// 使用以上方式判断前端返回,微信团队郑重提示://res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。}});}, error() {alert("error");}, complete() {// alert("complete");}});}// 获取地址栏参数function getUrlParam(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");var r = window.location.search.substr(1).match(reg);if (r != null) return unescape(r[2]);return null;}</script>
</body>
</html>

 html需要引入:

<script type="text/javascript" src=".0.0.js"></script>

下面的是java的代码:

Controller层:
package com.game.spring.controller;import com.game.spring.utils.WxPayUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/gbmsDev/api")
public class WxController {@RequestMapping(value = "/test")public Object banUser(@RequestParam(value = "state",required = false,defaultValue = "999")Integer state) {System.out.println(state);return "suc";}@RequestMapping(value = "/getCodeUrl")public Object getCodeUrl(@RequestParam(value = "reUrl",required = false,defaultValue = "") String reUrl) {return WxPayUtils.getCodeUrl(reUrl);}
//    获取getAccessToken 里面包含openid@RequestMapping(value = "/getAccessToken")public Object getAccessToken(@RequestParam(value = "code",required = false,defaultValue = "") String code) {return WxPayUtils.getAccessToken(code);}@RequestMapping(value = "/getPayParam")public Object getPayParam(@RequestParam(value = "openId",required = false,defaultValue = "") String openId) {return WxPayUtils.getPayParam(openId);}}

下面是WxPayUtils的代码:

package com.game.spring.utils;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.*;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;public class WxPayUtils {private static Logger logger = LoggerFactory.getLogger(WxPayUtils.class);//appId 微信公众号里创建的AppId,这里的公众号需要关联到微信支付上,// 微信公众平台-基本配置-开发者ID(AppID),这个绑定到微信支付-产品中心-AppID账号管理-关联AppID.这里关联公众号的AppIdpublic static String appId = "wx3crrrrd4ca";//微信支付商户号 微信支付-账户中心-商户信息-微信支付商户号.查看public static String mchId = "1611111996";//    微信下单回调地址,支付成功后会回调这个地址。//对应文档 .shtmlpublic static String callbackUri = "";//APIv3密钥  在微信支付商户平台-账户中心-API安全里设置,如果设置了不知道,就只有修改public static String apiV3Key = "2q5w8e3a6s9d1eeeeee8p5M6N9a09";//  第三方用户唯一凭证密钥,即appsecret  微信公众平台-基本配置-开发者密码(AppSecret) 公众号基本配置里查询public static String appSecret = "39fb76597aeeeeeeed532471";//    JSApi下单url地址public static String JSApiPayUrl = "";// 商户私钥   获取对应的签名需要 在微信支付商户平台-账户中心-API安全里设置 养宠物那边复制的
//    对应文档 .shtmlprivate static String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC3qbz0hDWoilpKR6vYnyi4q+CCjmQUjZVIO9R9QE3OfU4qVIaUYavTL/QReO9QfMZcU3LN8JrfKBRedleBfObXXVTP9e1FZh078LEYOiI9Kdzipf3NvSzjaJqkweMe7gOaGWj60zUBQyIVN9+kQVIcqA/2oNgq3Pz88fRFaOgV91okPTj4yfE5mVZujsuHN1ov1Bbky+cbd77SIA5Vl0dXDVUB+A7ZSpc3GXeXPxbEUvHeeeeeeebOpZzcVYsnR82BfTyKmfKIhvHhQjJpHVwmjw/USxxyblLh7Nc1td7pjoommr9yvBn/knq52mPolurmUTHloOCUyxLFDfUeeeepF9iogaSswxGw6B2qK+Jd1ZOoUHnHS2XrazMwKnG1RuvZ9S6On2/lJBXxjWOcvAeKm0c/Nza3lGxcNFwD6CjiXwo+2cq82L9Y3aBiSJRQKb1";//商户证书序列号 //    对应文档 .shtmlprivate static String mchSerialNo = "23BC1D2F580D5eeeeeeF63D95837CC5";private static CloseableHttpClient httpClient;/*** 第一步:获取code* 获取用户openID第一步,获取下一个接口的code参数* 访问这个url后,页面将跳转至 redirect_uri/?code=CODE&state=STATE。* 跳转的url携带code参数* 官方文档路径* .html* @return url*/public static String getCodeUrl(String reUrl) {String url = "=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";url = url.replace("APPID", appId).replace("REDIRECT_URI",URLEncoder.encode(reUrl));return url;}/***第二部:获取AccessToken,里面包含openId* 根据微信公众号的信息获取微信的accessToken* {"access_token":"61_SiCTd--EFgkIpWZ4MrciAKJN0N_Dv-qdZLnJyh-","expires_in":7870,"refresh_token":"-kpaMn5czZelR87thefNLEC2WK_-","openid":"5vrCjeeMz36PQkCK57bo","scope":"snsapi_base"}* 官方文档路径* .html*/public static String getAccessToken(String code) {String url = "=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";url = url.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE",code);System.out.println(url);String res = HttpRequestsUtils.sendGet(url,"");System.out.println(res);return res;}/***第三步:JSAPI下单* 使用官方开发库请求下单* @param openId openId* @return  {"prepay_id": "wx2611215250487459928b000"}* 官方文档路径* .shtml*/public static String createOrderJSApiV3(String openId) {payLoading();//请求URLHttpPost httpPost = new HttpPost(JSApiPayUrl);// 请求body参数StringEntity entity = new StringEntity(JSONObject.toJSONString(buildWxJsApiV3PayJson(openId,0)), "utf-8");entity.setContentType("application/json");httpPost.setEntity(entity);httpPost.setHeader("Accept", "application/json");//完成签名并执行请求CloseableHttpResponse response = null;try {response = httpClient.execute(httpPost);int statusCode = response.getStatusLine().getStatusCode();if (statusCode == 200) {return EntityUtils.toString(response.getEntity());} else if (statusCode == 204) {return "";} else {System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));throw new IOException("request failed");}} catch (IOException e) {e.printStackTrace();} finally {try {assert response != null;response.close();httpClient.close();} catch (IOException e) {e.printStackTrace();}}return "";}/***第四步:生成支付参数* 生成支付所需的参数* @param prepay_id 下单接口返回的参数 预支付交易会话标识* @return JSONObject* @throws Exception e*/public static JSONObject getTokenWeiXin(String prepay_id){// 获取随机字符串String nonceStr = getNonceStr();// 获取微信小程序支付packageString packagestr = "prepay_id=" + prepay_id;long timestamp = System.currentTimeMillis() / 1000;//签名,使用字段appId、timeStamp、nonceStr、package计算得出的签名值String message = buildMessageTwo(appId, timestamp, nonceStr, packagestr);//获取对应的签名String signature = sign(message.getBytes(StandardCharsets.UTF_8));// 组装返回JSONObject json = new JSONObject(new JSONObject());json.put("appId", appId);json.put("timeStamp", String.valueOf(timestamp));json.put("nonceStr", nonceStr);json.put("package", packagestr);json.put("signType", "RSA");json.put("paySign", signature);return json;}/*** 先调用下单,然后调用生成支付参数* @param openId openId* @return  支付参数*/public static Object  getPayParam(String openId){JSONObject jsonObject = JSON.parseObject(createOrderJSApiV3(openId));return getTokenWeiXin(jsonObject.getString("prepay_id"));}/*** 构造下单的json(第三步需要)* @param description 商品描述* @param amount      订单金额* @param openId      用户ID       onAky51Fojn3NoLrnKwcY* @return JSONObject*/public static JSONObject buildWxJsApiV3PayJson(String description, String amount, String openId) {//订单金额jsonJSONObject amountJson = new JSONObject();amountJson.put("total", Integer.valueOf(amount));amountJson.put("currency", "CNY");//支付者jsonJSONObject payerJson = new JSONObject();payerJson.put("openid", openId);//基础信息jsonJSONObject json = new JSONObject();
//        微信公众号里创建的APPIDjson.put("appid", appId);
//        直连商户号 微信支付-账户中心-商户信息查看json.put("mchid", mchId);json.put("description", description);
//        商户订单号 自己生成json.put("out_trade_no", generateNonceStr());json.put("notify_url", callbackUri);json.put("amount", amountJson);json.put("payer", payerJson);return json;}/*** 根据商品goodsId构造下单的json (第三步需要)* @return JSONObject*/public static JSONObject buildWxJsApiV3PayJson(String openId,Integer goodsId) {return buildWxJsApiV3PayJson("测试商品", "1", openId);}/*** 构造下单的json 无参数* @return JSONObject*/public static JSONObject buildWxJsApiV3PayJson() {return buildWxJsApiV3PayJson("测试商品", "1", "123123123124");}/*** 初始化httpClient的通用方法(第三步:JSAPI下单)* 微信支付官方开发库* 创建加载商户私钥、加载平台证书*/public static void payLoading() {logger.info("----------初始化httpClient-----------");// 加载商户私钥(privateKey:私钥字符串)PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes(StandardCharsets.UTF_8)));// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)), apiV3Key.getBytes(StandardCharsets.UTF_8));// 初始化httpClienthttpClient = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withValidator(new WechatPay2Validator(verifier)).build();}/***看情况调用 ,关闭httpClient客户端* @throws IOException e*/public void after() throws IOException {httpClient.close();logger.info("----------关闭httpClient-----------");}/*** 根据微信公众号的信息获取微信的Token(没有使用)* 官方文档:.html*/public static String getToken() {String url = "=client_credential&appid=APPID&secret=APPSECRET";url = url.replace("APPID", appId).replace("APPSECRET", appSecret);String result = HttpRequestsUtils.sendGet(url,"");System.out.println(result);JSONObject jsonObject = JSON.parseObject(result);return jsonObject.getString("access_token");}public static void main(String[] args) {System.out.println(WxPayUtils.getCodeUrl(""));
//        String str = WxPayUtils.getAccessToken();
//        System.out.println(str);}//    获取随机字符串public static String getNonceStr() {return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);}//    签名连接成一串private static String buildMessageTwo(String appId, long timestamp, String nonceStr, String packag) {return appId + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ packag + "\n";}/*** 生成签名* 官方文档:.shtml* @param message message* @return String*/private static String sign(byte[] message) {Signature sign = null;try {sign = Signature.getInstance("SHA256withRSA");sign.initSign(PemUtil.loadPrivateKey(privateKey));sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {e.printStackTrace();}return null;}/*** 随机字符串 订单号** @return*/public static String generateNonceStr() {return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);}}

pom.xml

         <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--        json--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.2</version></dependency><!--        HttpUtils--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.22</version></dependency><!--        微信SDK--><dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.4.8</version></dependency>
<!--        HttpUrl要用--><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.3</version></dependency><!--        java基础类--><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency>

到这里就差不多了,每个步骤都有具体官方文档,这个必须得看,因为有些要在微信公众号里设置,有些要在微信支付里设置,弄的地方还是挺多的。

代码写的丑,讲究看吧,又不是不能用。。。

如果有什么问题,欢迎大佬指正,最后如果对你有一点点帮助,麻烦支持一下。


全国寄快递4元起,电影票8.8折。更多优惠关注公众号:【折价寄件】

感谢观看!!!!

更多推荐

html+java做一个完整的JSAPIv3微信支付功能

本文发布于:2024-03-08 05:47:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1719973.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:做一个   完整   功能   html   java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!