h5对接微信支付分jssdk支付分并调用开启支付分页面

2023-11-03 12:40

本文主要是介绍h5对接微信支付分jssdk支付分并调用开启支付分页面,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、ws.config签名   调用ticket等获取ws.config的签名,下面会调用方法再调用方法时需要再次按照调用方法的签名

wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});

jsapi_ticket

生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

1、获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appID&secret=appsecret

2、用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,api 调用次数非常有限,频繁刷新api_ticket 会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回如下JSON:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
1
2
3
4
5
6


https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=27_1JoR00pdKD26t0IbR_kPzC5FbCChBLVmoRTkJPQ6b3SbHO2D-IfeaCe1-iBI-kFCjZ58QCSffv9IEVhv0PfmfCsT4ZAEDNcwfO8zYEtB05SOM-mY8pspfKJsz_V8LJnqhMWJO-R9ymZhBj00UWRdACAIKF&type=jsapi


获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx954f1899ef15d2ea&secret=9af198bddb8db015e9113ed7379cbcdf

微信 JS 接口签名校验工具:

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

微信支付接口签名校验工具

https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.5.0.js"></script>
<script src="jquery-3.4.1.min.js"></script>
<script src="vconsole.min.js"></script>
<script type="text/javascript">
var vConsole = new VConsole();
window.vConsole = new window.VConsole();
var appidG = "";
var timestampG = "";
var nonceStrG = "";
var signatureG = "";
$(function () {
var signUrl = window.location.href.split('#')[0];
console.log("signUrl:" + signUrl);
$.ajax({
url: "/index/test",
method: "post",
data: {
signUrl: signUrl
},
success: function (data) {
console.log("data:" + data);
var dataJson = JSON.parse(data);
// console.log("dataJson.appid:"+dataJson.appid);
console.log("wx.config() ---> 接收后台返回的参数");
appidG = dataJson.appid;
timestampG = dataJson.timestamp;
nonceStrG = dataJson.nonceStr;
signatureG = dataJson.signature;
wx.config({
debug: true,
appId: dataJson.appid,
timestamp: dataJson.timestamp,
nonceStr: dataJson.nonceStr,
signature: dataJson.signature,
jsApiList: ['onMenuShareAppMessage', 'openBusinessView']
})
}
});
});
function getLocation() {
wx.ready(function () {
wx.getLocation({
type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
alert('纬度:' + latitude + '------经度:' + longitude)
},
fail: function (res) {
console.log('未开启定位功能');
},
cancel: function (res) {
console.log('用户拒绝授权获取地理位置');
}
});
});
}
/**
* 跳转微信支付分
*/
function goToWXScore() {
console.log("appidG:" + appidG);
console.log("timestampG:" + timestampG);
console.log("nonceStrG:" + nonceStrG);
console.log("signatureG:" + signatureG);
$.ajax({
url: "/index/generateSignature",
method: "post",
data: {
timestamp: timestampG,
nonce_str:nonceStrG
},
success: function (sign) {
console.log("sign:" + sign);
wx.ready(function () {
wx.checkJsApi({
jsApiList: ['openBusinessView'], // 需要检测的JS接口列表
success: function (res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"openBusinessView":true},"errMsg":"checkJsApi:ok"}
if (res.checkResult.openBusinessView) {
wx.invoke(
'openBusinessView', {
businessType: 'wxpayScoreEnable',
queryString: "mch_id=1518750531&service_id=00004000000000704283351234894845&out_request_no=1234323JKHDFE1243259&timestamp=" + timestampG + "" +
"&nonce_str=" + nonceStrG + "&sign_type=HMAC-SHA256&sign=" + sign + ""
},
function (res) {
// 从微信侧小程序返回时会执行这个回调函数
if (parseInt(res.err_code) === 0) {
s
// 返回成功
} else {
// 返回失败
}
});
}
}
});
});
}
});
}
</script>
</head>
<body>
<div>
<!--<button id="snap1" onclick="goToWXScore()">goToWXScore</button>-->
<button id="pay" onclick="goToWXScore()" value="跳转支付分">跳转支付分</button>
<button id="snap2" onclick="getLocation()" value="获取地区">获取地区</button>
<!--<button id="snap3" onclick="onBridgeReady()">支付</button>-->
</div>
</body>
</html>

后端接口

@ResponseBody
@RequestMapping("/test")
@Login(required = false)
public String test(String signUrl) {
System.out.println("signUrl:"+signUrl);
//String res = HttpGetMethod.doGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx954f1899ef15d2ea&secret=acb8ad2a46765766c7881ea37237c1c7", "utf8", null);
String jsapi_ticket = "HoagFKDcsGMVCIY2vOjf9kjcHCRqLoF8k77O2dyyZiMTaOwxLTQ9nHU3fa4jfiEj2XW4NsvQG53gZZgVMkQdJA";
//String url = "http://localhost/h5/weixinexer.html";
Map<String, String> ret = com.jd.mrd.m.nc.web.utils.Sign.sign(jsapi_ticket, signUrl);
ret.put("appid","wx954f1899ef15d2ea");
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
return JSON.toJSONString(ret);
}
/**
* 获取签名
* @param timestamp
* @param nonce_str
* @return
* @throws Exception
*/
@ResponseBody
@RequestMapping("/generateSignature")
@Login(required = false)
public String generateSignature(String timestamp,String nonce_str) throws Exception {
HashMap<String, String> stringStringHashMap = new HashMap<String, String>();
stringStringHashMap.put("mch_id","1518750531");
stringStringHashMap.put("service_id","00004000000000704283351234894845");
stringStringHashMap.put("out_request_no","1234323JKHDFE1243259");
stringStringHashMap.put("timestamp",timestamp);
stringStringHashMap.put("nonce_str",nonce_str);
stringStringHashMap.put("sign_type","HMAC-SHA256");
String signature = WeChatUtils.generateSignature(stringStringHashMap, "acb8ad2a46765766c7881ea37237c1c7", WeChatConstant.SignType.HMACSHA256);
return signature;
}
@RequestMapping(value = "generateImage")
@ResponseBody
@Login(required = false)
public String generateImage(HttpServletRequest request, String base64) throws IOException {
//String base64=request.getParameter("base64");;
File directory = new File("");//设定为当前文件夹
URL resource = IndexController.class.getResource("/");
String clasFilePath = resource.getPath();
System.out.println(clasFilePath);//获取标准的路径
File file = new File(clasFilePath);
String strParentDirectory = file.getParent();
System.out.println(strParentDirectory);
file = new File(strParentDirectory);
strParentDirectory = file.getParent();
System.out.println(strParentDirectory);
strParentDirectory = strParentDirectory + "/h5/img";
System.out.println(strParentDirectory);
String fileName = CommonUtils.generateUUID() + ".jpg";
String fileUrl = strParentDirectory + "/" + fileName;
String imgStr = base64.split(",")[1];
Base64Utils.GenerateImage(imgStr, fileUrl);
System.out.println(fileUrl);
System.out.println(request.getServerName() + "/h5/img/" + fileName);
return request.getServerName() + "/h5/img/" + fileName;
//        JSONObject json =new JSONObject();
//        json.put("result",fileUrl);
//        response.setCharacterEncoding("utf-8");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter out = null;
//        out = response.getWriter();
//        out.write(json.toString());
//        return json.toJSONString();
}
@RequestMapping(value = "testPost")
@ResponseBody
@Login(required = false)
public String testPost(HttpServletRequest request, String base64) {
return "";
}
package com.jd.lestore.payment.common.utils;
import com.jd.lestore.payment.common.constant.WeChatConstant;
import com.jd.lestore.payment.common.constant.WeChatConstant.SignType;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class WeChatUtils {
/**
* 生成新的请求序列号
*
* @return
*/
public static Integer getNewRequestSerial() {
String timestamp = String.valueOf( System.currentTimeMillis()/1000 );
return Integer.valueOf(timestamp).intValue();
}
public static String generateSignature(final Map<String, String> data, String key) throws Exception {
return generateSignature(data, key, SignType.MD5);
}
public static String generateHMACSHA256Signature(final Map<String, String> data, String key) throws Exception {
return generateSignature(data, key, SignType.HMACSHA256);
}
/**
* 生成签名
*
* @param data
* @param key
* @return
* @throws Exception 规则
*                   第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
*                   <p>
*                   特别注意以下重要规则:
*                   <p>
*                   ◆ 参数名ASCII码从小到大排序(字典序);
*                   ◆ 如果参数的值为空不参与签名;
*                   ◆ 参数名区分大小写;
*                   ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
*                   ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
*                   <p>
*                   第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
*/
public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
Set<String> keySet = data.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (k.equals(WeChatConstant.FIELD_SIGN)) {
continue;
}
if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
sb.append(k).append("=").append(data.get(k).trim()).append("&");
}
sb.append("key=").append(key);
if (SignType.MD5.equals(signType)) {
return MD5(sb.toString()).toUpperCase();
} else if (SignType.HMACSHA256.equals(signType)) {
System.out.println("HMACSHA256 original text: " + sb.toString());
return HMACSHA256(sb.toString(), key);
} else {
throw new Exception(String.format("Invalid sign_type: %s", signType));
}
}
/**
* 生成 MD5
*
* @param data 待处理数据
* @return MD5结果
*/
public static String MD5(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] array = md.digest(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
/**
* 生成 HMACSHA256
*
* @param data 待处理数据
* @param key  密钥
* @return 加密结果
* @throws Exception
*/
public static String HMACSHA256(String data, String key) throws Exception {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString().toUpperCase();
}
/**
* 获取当前时间戳,单位秒
*
* @return
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis() / 1000;
}
/**
* 获取当前时间戳,单位毫秒
*
* @return
*/
public static long getCurrentTimestampMs() {
return System.currentTimeMillis();
}
/**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlToMap(String strXML) throws Exception {
InputStream stream = null;
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
data.put(element.getNodeName(), element.getTextContent());
}
}
return data;
} finally {
try {
stream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private static DocumentBuilderFactory setWechatPaySafeCode( ) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 禁 用 DOCTYPE
try{
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
//该 feature 的作用是配置是否包含外部的参数,包括外部 DTD 子集,设置false 禁用参数实体
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
//该 feature 的功能指是否包含外部生成的实体,设置 false 禁用外部实体
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
}catch ( Exception e ){
e.printStackTrace();
}
return dbf;
}
/**
* XML格式字符串转换为Map
*
* @param strXML XML字符串
* @return XML数据转换后的Map
* @throws Exception
*/
public static Map<String, String> xmlClildToMap(String strXML) throws Exception {
InputStream stream = null;
try {
Map<String, String> data = new HashMap<String, String>();
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Document doc = documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int idx = 0; idx < nodeList.getLength(); ++idx) {
Node node = nodeList.item(idx);
if (node.getNodeType() == Node.ELEMENT_NODE) {
org.w3c.dom.Element element = (org.w3c.dom.Element) node;
if(element.hasChildNodes()){//对于三级子项处理
for(int i = 0 ; i < element.getChildNodes().getLength();i++){
Node nodeChild = element.getChildNodes().item(i);
data.put(nodeChild.getNodeName(),nodeChild.getTextContent());
}
}else {
data.put(element.getNodeName(), element.getTextContent());
}
}
}
return data;
} finally {
try {
stream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXml(Map<String, String> data) throws Exception {
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
org.w3c.dom.Document document = documentBuilder.newDocument();
org.w3c.dom.Element root = document.createElement("xml");
document.appendChild(root);
for (String key : data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
try {
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return output;
}
/**
* 将Map转换为XML格式的字符串
*
* @param data Map类型数据
* @return XML格式的字符串
* @throws Exception
*/
public static String mapToXmlROOT(Map<String, String> data,String xmlRoot) throws Exception {
DocumentBuilderFactory documentBuilderFactory = setWechatPaySafeCode();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
org.w3c.dom.Document document = documentBuilder.newDocument();
document.setXmlStandalone(true);
org.w3c.dom.Element root = document.createElement(xmlRoot);
document.appendChild(root);
for (String key : data.keySet()) {
String value = data.get(key);
if (value == null) {
value = "";
}
value = value.trim();
org.w3c.dom.Element filed = document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
try {
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return output;
}
}

这篇关于h5对接微信支付分jssdk支付分并调用开启支付分页面的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/338244

相关文章

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

如何用java对接微信小程序下单后的发货接口

《如何用java对接微信小程序下单后的发货接口》:本文主要介绍在微信小程序后台实现发货通知的步骤,包括获取Access_token、使用RestTemplate调用发货接口、处理AccessTok... 目录配置参数 调用代码获取Access_token调用发货的接口类注意点总结配置参数 首先需要获取Ac

讯飞webapi语音识别接口调用示例代码(python)

《讯飞webapi语音识别接口调用示例代码(python)》:本文主要介绍如何使用Python3调用讯飞WebAPI语音识别接口,重点解决了在处理语音识别结果时判断是否为最后一帧的问题,通过运行代... 目录前言一、环境二、引入库三、代码实例四、运行结果五、总结前言基于python3 讯飞webAPI语音

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

一文详解kafka开启kerberos认证的完整步骤

《一文详解kafka开启kerberos认证的完整步骤》这篇文章主要为大家详细介绍了kafka开启kerberos认证的完整步骤,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、kerberos安装部署二、准备机器三、Kerberos Server 安装1、配置krb5.con

SpringBoot基于沙箱环境实现支付宝支付教程

《SpringBoot基于沙箱环境实现支付宝支付教程》本文介绍了如何使用支付宝沙箱环境进行开发测试,包括沙箱环境的介绍、准备步骤、在SpringBoot项目中结合支付宝沙箱进行支付接口的实现与测试... 目录一、支付宝沙箱环境介绍二、沙箱环境准备2.1 注册入驻支付宝开放平台2.2 配置沙箱环境2.3 沙箱