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

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

hadoop开启回收站配置

开启回收站功能,可以将删除的文件在不超时的情况下,恢复原数据,起到防止误删除、备份等作用。 开启回收站功能参数说明 (1)默认值fs.trash.interval = 0,0表示禁用回收站;其他值表示设置文件的存活时间。 (2)默认值fs.trash.checkpoint.interval = 0,检查回收站的间隔时间。如果该值为0,则该值设置和fs.trash.interval的参数值相等。

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

如何更优雅地对接第三方API

如何更优雅地对接第三方API 本文所有示例完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/third 我们在日常开发过程中,有不少场景会对接第三方的API,例如第三方账号登录,第三方服务等等。第三方服务会提供API或者SDK,我依稀记得早些年Maven还没那么广泛使用,通常要对接第三方

uniapp设置微信小程序的交互反馈

链接:uni.showToast(OBJECT) | uni-app官网 (dcloud.net.cn) 设置操作成功的弹窗: title是我们弹窗提示的文字 showToast是我们在加载的时候进入就会弹出的提示。 2.设置失败的提示窗口和标签 icon:'error'是设置我们失败的logo 设置的文字上限是7个文字,如果需要设置的提示文字过长就需要设置icon并给

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

H5漂流瓶社交系统源码

一个非常有创意的H5漂流瓶社交系统源码,带完整前端h5和后台管理系统。 环境:Nginx 1.20.1-MySQL 5.6.50-PHP-7.3 代码下载

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a