【支付平台】java springboot 通过ip获取所在地城市信息

news2024/11/28 14:51:05

         如果只是想知道如何通过ip获取所在地城市信息,可直接看第三步.

        如果搭建自己的支付平台,异地支付限制是必不可少的一环.因为市面上一些非法份子,会使用我们平台生成的付款码进行欺诈行为.这也是我们必须杜绝的一种现象.因此限制异地支付就是其中一种手段.

        在上一篇文章【三方支付】java如何获取请求的来源ip 我们可以获取到用户发起支付时的ip,我们只需要再获取到用户扫码时的ip进行对比,即可知道当前是否为异地支付.当然我们不能直接对比ip,因为用户通常使用pc端发起支付获取付款码,而支付时采用的是移动端.两端未必处于同一个网络,因此ip也是不同的.

  •         第一步,如果我们接入是三方支付,通常三方支付会返回给我们一个二维码地址,或者收银台地址,这时候用户扫码时进入的就是三方支付的支付页面,我们是无法获取到用户ip的,这时候我们需要做的便是生成自己的二维码,用户扫描二维码进入是我们自己的页面(也可以是接口,获取ip之后直接跳转到三方支付,通常是制作一个移动端的页面,展示一些订单信息和风险提示等),只要经过我们的服务就可以拿到用户扫码时的ip了.

  •         第二步,对比ip所在城市的信息.通过上面的步骤,我们拿到发起支付时的ip和扫码时的ip.我们就可以通过ip对应的城市进行对比了.目前市面上通过ip获取城市的开放接口有很多,基本都是收费的,免费的通常ip库不全,有可能查不到地址.类似 百度地图,高德地图 都有响应的接口供大家使用.也可以到阿里云市场进行购买(相对优惠很多).

  •         第三步, 如何通过ip获取这里我们介绍一种免费的,内置在我们自己系统的一种获取ip城市信息的方式,这种方式既省钱又不需要担心网络问题

1. 引入 ip2region ,据ip2region官方给出的数据,ip准确率达到99.9%,而且查询速度也非常客观,可以满足我们的需求

        <dependency>
            <groupId>org.lionsoul</groupId>
            <artifactId>ip2region</artifactId>
            <version>2.7.0</version>
        </dependency>

2. 导入ip2region的数据包

可以到官方进行下载xdb文件,并将文件放置到项目的resources下

3. 编写自己的工具类

 



import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;


@Slf4j
public class Ip2Region {

	protected static Searcher searcher;

	static {
		ClassPathResource resource = new ClassPathResource("ip2region/ip2region.xdb");
		try (InputStream inputStream = resource.getInputStream()) {
			byte[] cBuff = IoUtil.readBytes(inputStream);
			searcher = Searcher.newWithBuffer(cBuff);
		} catch (IOException e) {
			log.error("获取ip文件失败", e);
		}
	}


	/**
	 * 根据ip从 ip2region.db 中获取地理位置
	 *
	 * @param ip
	 * @return 地理位置
	 */
	public static Map<String, String> getCityInfo(String ip) {
		//数据格式: 国家|区域|省份|城市|ISP
		//192.168.31.160 0|0|0|内网IP|内网IP
		//47.52.236.180 中国|0|香港|0|阿里云
		//220.248.12.158 中国|0|上海|上海市|联通
		//164.114.53.60 美国|0|华盛顿|0|0
		HashMap<String, String> cityInfo = new HashMap<>(7);
		try {
			String searchIpInfo = searcher.search(ip);

			log.info("ip查询:{},查询结果:{}", ip, searchIpInfo);
			if (StrUtil.isNotBlank(searchIpInfo)) {
				String[] splitIpInfo = searchIpInfo.split("\\|");
				cityInfo.put("ip", ip);
				cityInfo.put("searchInfo", searchIpInfo);
				cityInfo.put("country", splitIpInfo[0]);
				cityInfo.put("region", splitIpInfo[1]);
				cityInfo.put("province", splitIpInfo[2]);
				cityInfo.put("city", splitIpInfo[3]);
				cityInfo.put("ISP", splitIpInfo[4]);
				return cityInfo;
			}
		} catch (Exception e) {
			log.info("failed to search({}): {}", ip, e);
		}
		return null;
	}

	/**
	 * 根据ip从 ip2region.db 中获取省份
	 *
	 * @param ip
	 * @return 地理位置
	 */
	public static String getProvince(String ip) {
		Map<String, String> cityInfo = getCityInfo(ip);
		if (cityInfo != null) {
			return cityInfo.get("province");
		}
		else {
			return null;
		}
	}

}

4. 使用方式 这里我们获取的是省份,也可以通过实际情况进行调整

    // 获取扫码时的ip
    String clientIp = IpUtil.getClientIp();
    String city1 = Ip2Region.getProvince(clientIp);
    // 获取下单时的ip
    String city2 = Ip2Region.getProvince(order.getClientIp());
    log.info("订单校验ip,订单号:{},下单ip:{},支付ip:{}", id, order.getClientIp(), clientIp);
    if (StrUtil.isNotBlank(city1) && StrUtil.isNotBlank(city2) && !city1.equals(city2)) {
       	return Result.res(ResultEnum.IP_ERROR);
    }

以上就是通过ip对比省份,进行异地支付的限制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/626666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang context 实现原理与源码解读

0 context入门介绍 context是Golang应用开发常用的并发控制技术&#xff0c;主要在异步场景中用于实现并发协调以及对 goroutine 的生命周期控制&#xff0c;它与WaitGroup最大的不同点是context对于派生goroutine有更强的控制力&#xff0c;它可以控制多级的goroutine。 con…

【Android】WMS(一)Window的类型和标志

Window、WindowManager、WMS区别 Window&#xff1a; Window 是 Android 中的一个视图容器&#xff0c;代表整个屏幕或 Activity 的一部分。每个 Window 都有自己的 Surface 对象&#xff0c;Surface 对象具有绘制和渲染功能&#xff0c;可以显示 View 和其他元素。在 Android…

Vue 的基础知识 - 判断, 循环, 事件, 通信

目录 1. 了解 Vue 七大常用属性 2. 文本插值 2.1 v-bind 绑定元素 3. 判断 4. 循环 5. 事件 6. 双向绑定 7. 自定义组件 8. Axios 异步通信 8.1 什么是Axios 8.2 为什么要使用 Axios 8.3 Axios 的简单应用 8.4 Vue 的生命周期 1. 了解 Vue 七大常用属性 1. el 属性…

Qt扫盲-Bar柱状图理论

Bar柱状图理论 一、QAbstractBarSeries1. 常用设置2. 管理 BarSet 二、QBarSerie 和 QHorizontalBarSeries1. 垂直柱状图2. 水平柱状图 二、QPercentBarSeries 和 QHorizontalPercentBarSeries1. 垂直比例图2. 水平比例图 三、QStackedBarSeries 和 QHorizontalStackedBarSerie…

忠诚之源:如何获得铁粉?

文章目录 一、铁粉二、如何吸引和留住铁粉的想法2.1 了解你的目标铁粉2.2 提供有价值的内容2.3 建立良好的关系2.4 持续优化和创新 三、具体可采用的一些方法3.1 提供优质内容3.2 社交媒体互动3.3 创建独特的品牌形象3.4 提供特殊待遇和奖励3.5 参与社区和活动3.6 持续互动和更…

如何把视频语音转换成文字,分享给大家几个免费的方法!

在日常工作和学习中&#xff0c;有时需要将视频中的语音转录为文字&#xff0c;以便整理成文稿或进行其他用途。手动打字效率低下且耗时费力&#xff0c;那么如何快速将语音转换为文字呢&#xff1f;下面介绍几种简单高效的方法&#xff0c;其中之一是使用记灵在线工具。 方法…

PHP的流程控制语句

一.流程控制语句 1.if语句 PHP的if语句格式如下 if(表达式) 语句; 如果表达式的值为真&#xff0c;那么久顺序执行语句&#xff1b;否则&#xff0c;就会跳过该条语句&#xff0c;再往下执行。如果要执行的语句不指一条则用{}&#xff0c;{}被称为语句组&#xff0c;格式如…

Immer编写简洁的更新state逻辑

react官网推荐库use-immer&#xff1a;https://www.npmjs.com/package/use-immer 引入&#xff1a;import { useImmer } from "use-immer"; 优点&#xff1a; 简化代码: 只需要关注需要变动的部分&#xff0c;而 immer 本身将在后台处理其余部分。学习成本和替换代…

双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的实践应用

查看原文>>>双碳目标下DNDC模型建模方法及在土壤碳储量、温室气体排放、农田减排、土地变化、气候变化中的实践应用 目录 第一讲、DNDC模型介绍 第二讲、DNDC初步操作 第三讲、遥感和GIS基础 第四讲、DNDC气象数据 第五讲、DNDC土地数据 第六讲、DNDC土壤数据 …

【C语言】算法学习·Dijkstra算法详解

目录 Dijkstra算法设计 Dijkstra算法简介 Dijkstra算法的基本思想 Dijkstra贪心策略 完美图解 伪代码详解 完整代码 算法解析及优化拓展 ​使用优先队列的完整代码 Dijkstra算法设计 Dijkstra算法简介 Dijkstra算法是解决**单源最短路径**问题的**贪心算法** …

2021年国赛高教杯数学建模C题生产企业原材料的订购与运输解题全过程文档及程序

2021年国赛高教杯数学建模 C题 生产企业原材料的订购与运输 原题再现 某建筑和装饰板材的生产企业所用原材料主要是木质纤维和其他植物素纤维材料,总体可分为 A&#xff0c;B&#xff0c;C 三种类型。该企业每年按 48 周安排生产&#xff0c;需要提前制定 24 周的原材料订购和…

如何在 javascript 中按属性值查找数组中的对象

文章目录 使用 find() 方法按属性值在数组中查找对象使用 filter() 方法按属性值查找数组中的对象使用 JavaScript for 循环按属性值查找数组中的对象使用 JavaScript for...in 循环按属性值查找数组中的对象 数组指的是值的有序列表&#xff0c;每个值称为由索引指定的元素。 …

这所西安的985专硕爆冷,保护一志愿,过线即上岸!

本期为大家整理热门院校“西北工业大学”的择校分析&#xff0c;这个择校分析专题会为大家结合&#xff1a;初试复试占比、复试录取规则&#xff08;是否公平&#xff09;、往年录取录取名单、招生人数、分数线、专业课难度等进行分析。希望能够帮到大家! –所有数据来源于研招…

Plot、Scatter、Subplot函数用法

目 录 一、Plot()函数 二、Scatter()函数 三、Subplot()函数 一、Plot()函数 格式&#xff1a;matplotlib.pyplot.plot(x,y,format_string.**kwargs) 说明&#xff1a; x:x轴数据&#xff0c;列表或数组&#xff0c;可选(注&#xff1a;当绘制多条曲线时&#xff0c;不能省…

IT 系统巡检必须关注的指标总结

1. 系统整体架构 以下内容作为基本 IT 系统信息被首先调查记录&#xff0c;供分析参考使用。 ● 网络设备配置 ---设备型号, IOS 版本, 模块型号和数量,用途 ● 存储系统配置 ---设备型号, IO 带宽, Cache 容量&#xff0c;磁盘数量&#xff0c;接入模式&#xff0c;存储容…

Go项目配置管理工具---Viper

目录 Viper概述前言功能viper配置优先级 从Viper中获取值读取配置文件注册和使用别名 把值写入Viper设置默认值使用Set方法设置值把配置信息写入配置文件从io.Reader中读取配置信息到viper 监控Viper文件 Viper概述 前言 对于现代应用程序&#xff0c;尤其大中型的项目来说&a…

【MySQL】Mycat

文章目录 什么是Mycat为什么要用Mycatmycat能干什么各数据库中间件对比Mycat原理数据库中间件逻辑库逻辑表分片表分片规则全局表ER表非分片表分片节点节点主机mycat安装mycat核心配置schema.xmlserver.xmlrule.xml加密明文密码&#xff08;可选&#xff09; MyCat读写分离垂直拆…

OpenCV中的图像处理3.11(10) OpenCV中的图像变换

目录 3.11 OpenCV中的图像变换3.11.1 傅里叶变换目标理论Numpy中的傅里叶变换OpenCV中的傅立叶变换DFT的性能优化为什么Laplacian是一个高通滤波器&#xff1f;其他资源 翻译及二次校对&#xff1a;cvtutorials.com 编辑者&#xff1a;廿瓶鲸&#xff08;和鲸社区Siby团队成员&…

2.3 YARN伪分布式集群搭建

任务目的 重点掌握 YARN 集群的相关配置学会启动和关闭 YARN 集群的两种方式能够使用 jps 命令查看进程的启动情况能够通过 UI 查看 YARN 集群的运行状态任务清单 任务1:YARN 集群主要配置文件讲解任务2:YARN 集群测试任务步骤 任务1:YARN 集群主要配置文件讲解 1.1 配置环…

基于多尺度图神经网络的流场预测,实现精度与速度的平衡

项目简介 本项目来源于飞桨AI for Science共创计划的论文复现赛题&#xff0c;复现论文为《AMGNET: multi-scale graph neural networks for flow field prediction》。该论文主要采用图神经网络&#xff0c;因为在计算流体力学中计算域被网格离散化&#xff0c;这与图结构天然…