package com.hbq.teacher_plus.util;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.hbq.teacher_plus.config.AlipayConfig;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.HashMap;
import java.util.Map;
/**
* @author houyu
* @createTime 2019/3/20 8:38
*/
public class AlipayUtil {
/**
* 处理请求参数
* @param requestParams
* @return
*/
public static Map<String, String> handleParams(Map<String, String[]> requestParams){
Map<String, String> handleMap = new HashMap<>(requestParams.size());
for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
String key = entry.getKey();
String[] value = entry.getValue();
handleMap.put(key, join(value, ","));
}
return handleMap;
}
/**
* 数组转字符串 ["1", "2"] ==> "1,2"
* @param os
* @param splitString
* @return
*/
public static String join(Object[] os, String splitString){
String s = "";
if (os != null) {
StringBuilder sBuffer = new StringBuilder();
for (int i = 0; i < os.length; i++) {
sBuffer.append(os[i]).append(splitString);
}
s = sBuffer.deleteCharAt(sBuffer.length() - 1).toString();
}
return s;
}
/**
* 校验是否支付成功
* @param handleParams
* @return
*/
public static boolean rsaCheck(Map<String, String> handleParams) {
boolean checkV1 = false;
try {
checkV1 = AlipaySignature.rsaCheckV1(handleParams, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
} catch (AlipayApiException e) {
e.printStackTrace();
}
return checkV1;
}
/** ---------------------------------------单例模式---------------------------------------*/
private static class SingletonHolder {
private static final AlipayUtil INSTANCE = new AlipayUtil();
}
public static AlipayUtil get() {
return SingletonHolder.INSTANCE;
}
/** ---------------------------------------单例模式---------------------------------------*/
/** 雪花算法生成ID,自带时间排序,一秒可以生成25万个ID左右 */
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
private final static long twepoch = 1288834974657L;
// 机器标识位数
private final static long workerIdBits = 5L;
// 数据中心标识位数
private final static long datacenterIdBits = 5L;
// 机器ID最大值
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
// 数据中心ID最大值
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
// 毫秒内自增位
private final static long sequenceBits = 12L;
// 机器ID偏左移12位
private final static long workerIdShift = sequenceBits;
// 数据中心ID左移17位
private final static long datacenterIdShift = sequenceBits + workerIdBits;
// 时间毫秒左移22位
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
/* 上次生产id时间戳 */
private static long lastTimestamp = -1L;
// 0,并发控制
private long sequence = 0L;
private final long workerId;
// 数据标识id部分
private final long datacenterId;
public AlipayUtil() {
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
* @param workerId 工作机器ID
* @param datacenterId 序列号
*/
public AlipayUtil(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
* 获取下一个ID
*
* @return
*/
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
// 当前毫秒内,则+1
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
// 当前毫秒内计数满了,则等待下一秒
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// ID偏移组合生成最终的ID,并返回ID
long nextId = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift) | sequence;
return nextId;
}
private long tilNextMillis(final long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
/**
* <p>
* 获取 maxWorkerId
* </p>
*/
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuffer mpid = new StringBuffer();
mpid.append(datacenterId);
String name = ManagementFactory.getRuntimeMXBean().getName();
if (!name.isEmpty()) {
/*
* GET jvmPid
*/
mpid.append(name.split("@")[0]);
}
/*
* MAC + PID 的 hashcode 获取16个低位
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
/**
* <p>
* 数据标识id部分
* </p>
*/
protected static long getDatacenterId(long maxDatacenterId) {
long id = 0L;
try {
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
id = 1L;
} else {
byte[] mac = network.getHardwareAddress();
id = ((0x000000FF & (long) mac[mac.length - 1])
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
id = id % (maxDatacenterId + 1);
}
} catch (Exception e) {
System.out.println(" getDatacenterId: " + e.getMessage());
}
return id;
}
/** 雪花算法生成ID,自带时间排序,一秒可以生成25万个ID左右 */
}
config
package com.hbq.teacher_plus.config;
/**
* @author hbq
* @createTime 2020/3/19 23:29
*/
public class AlipayConfig {
// 商户appid
public static String APPID = "";
public static String RSA_PRIVATE_KEY = " ";
// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "";
// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
public static String return_url = "";
// 请求网关地址,沙箱是:https://openapi.alipaydev.com/gateway.do
public static String URL = "https://openapi.alipaydev.com/gateway.do";
// 编码
public static String CHARSET = "UTF-8";
// 返回格式
public static String FORMAT = "json";
// 支付宝公钥(在应用中可以获取)
public static String ALIPAY_PUBLIC_KEY = "";
// RSA2
public static String SIGNTYPE = "RSA2";
}
2. Configuración del entorno de zona de pruebas de Alipay
1. Debido a que nuestros parámetros en la configuración anterior aún no se han configurado, configuremos los parámetros ahora.
2. Abra la ubicación de la zona de pruebas del sitio web oficial de Alipay: https://openhome.alipay.com/platform/appDaily.htm?tab=info
3. En primer lugar, las posiciones de 3 y 4 deben completarse en una URL a la que se pueda acceder desde Internet, como por ejemplo:http://www.baidu.com
4. APPID, cópielo en "1" como se muestra en la figura
5. RSA_PRIVATE_KEY, clave privada de la aplicación
Haga clic directamente para generar la clave secreta, copie la clave pública de la aplicación a continuación y vuelva a la configuración de la zona de pruebas, guarde y copie la clave privada en la configuración del proyecto en la posición "2".
6. ALIPAY_PUBLIC_KEY, clave pública de Alipay
Después de guardar la clave pública en el paso 5, puede ver la clave pública de Alipay:
7. Se completan cinco configuraciones, inicie el proyecto y visite http://localhost:8080/pay/web.
8. Descargue el sandbox Alipay e inicie sesión con la cuenta del sandbox para completar el pago.