1. xml相关jar包引入(微信接口要求以xml格式传参)
<dependencies>
<!-- xml -->
<dependency>
<groupId>net.sf.kxml</groupId>
<artifactId>kxml2</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>xmlpull</groupId>
<artifactId>xmlpull</artifactId>
<version>1.1.3.1</version>
</dependency>
</dependencies>
2. maven过滤证书插件引入
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>UTF-8</encoding>
<!-- 过滤后缀为p12、crt的证书文件 -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>p12</nonFilteredFileExtension>
<nonFilteredFileExtension>crt</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
3. maven证书资源引入 (注意: 1.将下载好的证书放在src/main/resources下,2.按如下配置pom)
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.p12</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
1. TransferController(提现相关接口)
package com.zero.jimu.controller;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.util.StringUtil;
import com.zero.jimu.entity.WithdrawalRecord;
import com.zero.jimu.service.WithdrawalRecord.WithdrawalRecordService;
import com.zero.jimu.service.appUser.AppUserService;
import com.zero.jimu.service.sysUser.SysUserService;
import com.zero.jimu.utils.CheckParamsUtil;
import com.zero.jimu.utils.DateUtil;
import com.zero.jimu.utils.IpAddrUtil;
import com.zero.jimu.utils.exception.ErrorEnum;
import com.zero.jimu.utils.exception.Result;
import com.zero.jimu.utils.exception.ResultUtil;
import com.zero.jimu.utils.withdrawal.CollectionUtil;
import com.zero.jimu.utils.withdrawal.HttpUtils;
import com.zero.jimu.utils.withdrawal.PayUtil;
import com.zero.jimu.utils.withdrawal.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* 提现相关接口
*/
@RestController
@RequestMapping("/transfer")
public class TransferController {
@Autowired
SysUserService sysUserService;
@Autowired
AppUserService appUserService;
@Autowired
WithdrawalRecordService withdrawalRecordService;
private static final Logger logger = LoggerFactory.getLogger(TransferController.class);
private static final String TRANSFERS_PAY = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款API
private static final String TRANSFERS_PAY_QUERY = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo"; // 企业付款查询API
private static final String APP_ID = "wx100000001000" ;//公众账号appid
private static final String MCH_ID = "14000000000";//商户号
private static final String API_SECRET = "85565656565656565656565";//API密钥
/**
* 企业向个人支付转账
* @param request
* @param params
*/
@PostMapping(value = "/pay")
@ResponseBody
@Transactional
public Result transferPay(@RequestBody String params,HttpServletRequest request) {
/** =============================================接口参数校验================================================*/
JSONObject jsonObject = JSONObject.parseObject(params);//解析json
//校验参数是否为空
if(CheckParamsUtil.isBlank(jsonObject,"userId","amount","userType")){
return ResultUtil.fail(ErrorEnum.ERROR_PARAM_ISBLANK);
}
/**==============================================设置局部变量=================================================*/
String userId = jsonObject.getString("userId");//用户id
String openid = "";//用户openid
Float applyMoney = jsonObject.getFloat("amount");//用户申请提现金额 0.3-5000
int userType = jsonObject.getInteger("userType");//用户类型
String amount;//企业付款金额
Float poundage = 0f;//手续费
String desc;//企业付款描述信息
String id = UUID.randomUUID().toString().replaceAll("-", "");//提现记录表id
if(applyMoney<0.3||applyMoney>5000){
return ResultUtil.fail("00000001","申请提现金额不符:低于最小金额0.30元或高于5000.00元");
}
/** ======================================业务判断 1.userId是否有收款资格=====================================*/
if(userType == 1){
openid = sysUserService.getOpenidBySysUserId(userId);
}
if(userType == 2){
openid = appUserService.getOpenidByAppUserId(userId);
}
if(openid==null||openid.equals("")){
return ResultUtil.fail("00000001","该用户不可提现");
}
/** ======================================业务判断 2.openid可提现金额校验=====================================*/
/** userType==1 商家身份*/
if(userType == 1){
//校验用户提现金额
//1.提现金额<=可提现金额 15%的抽成
}
Float account = 0f;
/** userType==2 用户身份*/
if(userType == 2){
//校验用户提现金额
//1.提现金额<=可提现金额
account = appUserService.getAccount(userId);
if(applyMoney>account){
return ResultUtil.fail("00000001","非法操作:申请提现金额大于可提现金额");
}
}
/** =================================业务判断 3.userId当天提现次数及当天提现金额限制==================================*/
//当日提现次数 首次免手续费
List<WithdrawalRecord> withdrawalRecords = withdrawalRecordService.selectWithdrawalRecordOfToday(userId,openid,userType);
//当日非初次提现
if(withdrawalRecords.size()>0&&withdrawalRecords.size()<=10){
poundage = 2f;//当日非初次提现,手续费为2元
desc = "申请提现金额:"+applyMoney+"元,当天已提现"+withdrawalRecords.size()+"次,需扣除2元手续费";
//此处对用户当天累计提现金额可做限制
// Float withdrawalAmountRequested = 0f;//用户今日累计已申请的提现额度
// for(int i = 0;i < withdrawalRecords.size();i++){
// withdrawalAmountRequested = (withdrawalAmountRequested*1000+withdrawalRecords.get(i).getActualMoney()*1000)/1000;
// }
}else if(withdrawalRecords.size()>10){
return ResultUtil.fail("00000001","该用户当天提现次数上限:微信企业付款每天最多可向同一个用户付款10次");
}else{
desc = "申请提现金额:"+applyMoney+"元,当天首次提现免手续费";
}
/** =================================业务判断 4.一个商户同一日付款总额限额10万元==================================*/
Float amountWithdrawn = withdrawalRecordService.selectAllWithdrawalRecordNumOfToday();//商户同一日付款总额
if(amountWithdrawn>100000){
return ResultUtil.fail("00000001","今日商户付款总额限额,请明天再试");
}
/** ========================校验实际提现金额是否在微信企业付款实际允许的提现(0.3-5000)范围内=========================*/
Float actualMoney = (applyMoney*1000-poundage*1000)/1000;//实际提现金额
if(actualMoney<0.3||actualMoney>5000){
return ResultUtil.fail("00000001","扣除手续费后的实际提现金额不符:"+actualMoney+"元:低于最小金额0.30元或高于5000.00元");
}
amount = Integer.parseInt((int)((actualMoney)*10)+"")*10+"";//微信企业付款金额 30-500000
/** ==================================================================================================================*/
/** ==================================================封装提现所需参数================================================*/
/** ==================================================================================================================*/
Map<String, String> restmap = null;
try {
Map<String, String> parm = new HashMap<String, String>();
parm.put("mch_appid", APP_ID); //公众账号appid
parm.put("mchid", MCH_ID); //商户号
parm.put("nonce_str", PayUtil.getNonceStr()); //随机字符串
parm.put("partner_trade_no", PayUtil.getTransferNo()); //商户订单号
parm.put("openid", openid); //用户openid oCVr20N2YLH9VQztnkZTaCj2aYYY
parm.put("check_name", "NO_CHECK"); //校验用户姓名选项 OPTION_CHECK
//parm.put("re_user_name", "安迪"); //check_name设置为FORCE_CHECK或OPTION_CHECK,则必填
parm.put("amount",amount); //转账金额
parm.put("desc", desc); //企业付款描述信息
parm.put("spbill_create_ip", IpAddrUtil.getIpAddr(request)); //Ip地址
parm.put("sign", PayUtil.getSign(parm, API_SECRET));
String restxml = HttpUtils.posts(TRANSFERS_PAY, XmlUtil.xmlFormat(parm, false));
restmap = XmlUtil.xmlParse(restxml);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return ResultUtil.fail("00000001","转账发生异常");
}
/** ========================================================提现结果处理===================================================*/
/** ===================================================生成提现及流水记录,改变余额==================================================*/
if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
logger.info("转账成功");
Map<String, String> transferMap = new HashMap<>();
transferMap.put("partnerTradeNo", restmap.get("partner_trade_no"));//商户转账订单号
transferMap.put("paymentNo", restmap.get("payment_no")); //微信订单号
transferMap.put("paymentTime", restmap.get("payment_time")); //微信支付成功时间
//生成提现记录
withdrawalRecordService.insert(new WithdrawalRecord(id,userType,userId,applyMoney,poundage,actualMoney,1,restmap.get("partner_trade_no"),restmap.get("payment_no"),
restmap.get("payment_time")==null?null:DateUtil.strToDate(restmap.get("payment_time"),"yyyy-MM-dd HH:mm:ss"),openid,desc,restmap.get("spbill_create_ip"),"0"));
//生成流水表
String waterId = UUID.randomUUID().toString().replaceAll("-", "");
Map<String,Object> map = new HashMap<>();
map.put("id",waterId);//编号
map.put("userId",userId);//用户id
map.put("title","提现");//该流水的标题
map.put("waterType",2);//商家流水类型1.场地收入 2.提现 用户流水类型1.分销收入 2.提现 3.预订场地
map.put("incomeExpense",1);//收入还是支出 0.收入 1.支出
map.put("applyMoney",applyMoney);//申请提现金额
map.put("poundage",poundage);//手续费
map.put("actualMoney",actualMoney);//实际金额
map.put("whetherToAccount",1);//是否到账0.未到账1.已到账
if(userType==1){
sysUserService.insertUserWater(map);
//改变用户可提现余额
}
if(userType==2){
appUserService.insertUserWater1(map);
//改变用户可提现余额
appUserService.updateUserAccount(userId,(account*1000-applyMoney*1000)/1000);//float精度问题
}
return ResultUtil.success(transferMap);
}
/** =================================================3.转账失败========================================================*/
else {
if (CollectionUtil.isNotEmpty(restmap)) {
logger.info("转账失败:" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
}
return ResultUtil.fail("00000001","转账失败"+restmap.get("err_code_des"));
}
}
/**
* 企业向个人转账查询
* @param request
* @param response
* @param tradeno 商户转账订单号
* @param callback
*/
@PostMapping(value = "/pay/query")
public Result orderPayQuery(HttpServletRequest request, HttpServletResponse response, String tradeno,
String callback) {
if (StringUtil.isEmpty(tradeno)) {
return ResultUtil.fail("00000001","转账订单号不能为空");
}
Map<String, String> restmap = null;
try {
Map<String, String> parm = new HashMap<String, String>();
parm.put("appid", APP_ID);
parm.put("mch_id", MCH_ID);
parm.put("partner_trade_no", tradeno);
parm.put("nonce_str", PayUtil.getNonceStr());
parm.put("sign", PayUtil.getSign(parm, API_SECRET));
String restxml = HttpUtils.posts(TRANSFERS_PAY_QUERY, XmlUtil.xmlFormat(parm, true));
restmap = XmlUtil.xmlParse(restxml);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
// 订单查询成功 处理业务逻辑
logger.info("订单查询:订单" + restmap.get("partner_trade_no") + "支付成功");
Map<String, String> transferMap = new HashMap<>();
transferMap.put("partnerTradeNo", restmap.get("partner_trade_no"));//商户转账订单号
transferMap.put("openid", restmap.get("openid")); //收款微信号
transferMap.put("paymentAmount", restmap.get("payment_amount")); //转账金额
transferMap.put("transferTime", restmap.get("transfer_time")); //转账时间
transferMap.put("desc", restmap.get("desc")); //转账描述
return ResultUtil.success(transferMap);
}else {
if (CollectionUtil.isNotEmpty(restmap)) {
logger.info("订单转账失败:" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
}
return ResultUtil.fail("00000001","订单转账失败");
}
}
}
2. HttpUtils(企业付款http请求工具)
package com.zero.jimu.utils.withdrawal;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* 企业付款http请求工具
*/
public class HttpUtils {
private static final String DEFAULT_CHARSET = "UTF-8";
private static final int CONNECT_TIME_OUT = 5000; //链接超时时间3秒
private static final RequestConfig REQUEST_CONFIG = RequestConfig.custom().setConnectTimeout(CONNECT_TIME_OUT).build();
private static SSLContext wx_ssl_context = null; //微信支付ssl证书
private static final String MCH_ID = "1000000000";//证书密码默认是商户号
static{
Resource resource = new ClassPathResource("apiclient_cert.p12");//该证书名字最好改为别人猜不到的
try {
KeyStore keystore = KeyStore.getInstance("PKCS12");
char[] keyPassword = MCH_ID.toCharArray(); //证书密码
keystore.load(resource.getInputStream(), keyPassword);
wx_ssl_context = SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @description 功能描述: get 请求
* @param url 请求地址
* @param params 参数
* @param headers headers参数
* @return 请求失败返回null
*/
public static String get(String url, Map<String, String> params, Map<String, String> headers) {
CloseableHttpClient httpClient = null;
if (params != null && !params.isEmpty()) {
StringBuffer param = new StringBuffer();
boolean flag = true; // 是否开始
for (Entry<String, String> entry : params.entrySet()) {
if (flag) {
param.append("?");
flag = false;
} else {
param.append("&");
}
param.append(entry.getKey()).append("=");
try {
param.append(URLEncoder.encode(entry.getValue(), DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {
//编码失败
}
}
url += param.toString();
}
String body = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).build();
HttpGet httpGet = new HttpGet(url);
response = httpClient.execute(httpGet);
body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return body;
}
/**
* @description 功能描述: get 请求
* @param url 请求地址
* @return 请求失败返回null
*/
public static String get(String url) {
return get(url, null);
}
/**
* @description 功能描述: get 请求
* @param url 请求地址
* @param params 参数
* @return 请求失败返回null
*/
public static String get(String url, Map<String, String> params) {
return get(url, params, null);
}
/**
* @description 功能描述: post 请求
* @param url 请求地址
* @param params 参数
* @return 请求失败返回null
*/
public static String post(String url, Map<String, String> params) {
CloseableHttpClient httpClient = null;
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<>();
if (params != null && !params.isEmpty()) {
for (Entry<String, String> entry : params.entrySet()) {
nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
}
String body = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).build();
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));
response = httpClient.execute(httpPost);
body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return body;
}
/**
* @description 功能描述: post 请求
* @param url 请求地址
* @param s 参数xml
* @return 请求失败返回null
*/
public static String post(String url, String s) {
CloseableHttpClient httpClient = null;
HttpPost httpPost = new HttpPost(url);
String body = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).build();
httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET));
response = httpClient.execute(httpPost);
body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return body;
}
/**
* @description 功能描述: post https请求,服务器双向证书验证
* @param url 请求地址
* @param params 参数
* @return 请求失败返回null
*/
public static String posts(String url, Map<String, String> params) {
CloseableHttpClient httpClient = null;
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<>();
if (params != null && !params.isEmpty()) {
for (Entry<String, String> entry : params.entrySet()) {
nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
}
String body = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).setSSLSocketFactory(getSSLConnectionSocket()).build();
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));
response = httpClient.execute(httpPost);
body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return body;
}
/**
* @description 功能描述: post https请求,服务器双向证书验证
* @param url 请求地址
* @param s 参数xml
* @return 请求失败返回null
*/
public static String posts(String url, String s) {
CloseableHttpClient httpClient = null;
HttpPost httpPost = new HttpPost(url);
String body = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.custom().setDefaultRequestConfig(REQUEST_CONFIG).setSSLSocketFactory(getSSLConnectionSocket()).build();
httpPost.setEntity(new StringEntity(s, DEFAULT_CHARSET));
response = httpClient.execute(httpPost);
body = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return body;
}
//获取ssl connection链接
private static SSLConnectionSocketFactory getSSLConnectionSocket() {
return new SSLConnectionSocketFactory(wx_ssl_context, new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
}
}
3. XmlUtil (xml、map转换工具)
package com.zero.jimu.utils.withdrawal;
import com.github.pagehelper.util.StringUtil;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
* xml、map转换工具
*/
public class XmlUtil {
private static final String PREFIX_XML = "" ;
private static final String SUFFIX_XML = "";
private static final String PREFIX_CDATA = ";
private static final String SUFFIX_CDATA = "]]>";
/**
* 转化成xml, 单层无嵌套
*
* @param parm
* @param isAddCDATA
* @return
*/
public static String xmlFormat(Map<String, String> parm, boolean isAddCDATA) {
StringBuffer strbuff = new StringBuffer(PREFIX_XML);
if (CollectionUtil.isNotEmpty(parm)) {
for (Entry<String, String> entry : parm.entrySet()) {
strbuff.append("<").append(entry.getKey()).append(">");
if (isAddCDATA) {
strbuff.append(PREFIX_CDATA);
if (StringUtil.isNotEmpty(entry.getValue())) {
strbuff.append(entry.getValue());
}
strbuff.append(SUFFIX_CDATA);
} else {
if (StringUtil.isNotEmpty(entry.getValue())) {
strbuff.append(entry.getValue());
}
}
strbuff.append("").append(entry.getKey()).append(">");
}
}
return strbuff.append(SUFFIX_XML).toString();
}
/**
* 解析xml
*
* @param xml
* @return
* @throws XmlPullParserException
* @throws IOException
*/
public static Map<String, String> xmlParse(String xml) throws XmlPullParserException, IOException {
Map<String, String> map = null;
if (StringUtil.isNotEmpty(xml)) {
InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser();
pullParser.setInput(inputStream, "UTF-8"); // 为xml设置要解析的xml数据
int eventType = pullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
map = new HashMap<String, String>();
break;
case XmlPullParser.START_TAG:
String key = pullParser.getName();
if (key.equals("xml"))
break;
String value = pullParser.nextText().trim();
map.put(key, value);
break;
case XmlPullParser.END_TAG:
break;
}
eventType = pullParser.next();
}
}
return map;
}
}
4. PayUtil
package com.zero.jimu.utils.withdrawal;
import com.github.pagehelper.util.StringUtil;
import com.zero.jimu.utils.ChineseCharToEnUtil;
import com.zero.jimu.utils.DateUtil;
import com.zero.jimu.utils.Encrypt;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Set;
public class PayUtil {
/**
* 生成订单号
*
* @return
*/
public static String getTradeNo() {
// 自增8位数 00000001
return "TNO" + DateUtil.formatDate(new Date(), DateUtil.TIME_STAMP_PATTERN) + "00000001";
}
/**
* 退款单号
*
* @return
*/
public static String getRefundNo() {
// 自增8位数 00000001
return "RNO" + DateUtil.formatDate(new Date(), DateUtil.TIME_STAMP_PATTERN) + "00000001";
}
/**
* 退款单号
*
* @return
*/
public static String getTransferNo() {
// 自增8位数 00000001
return "TNO" + DateUtil.formatDate(new Date(), DateUtil.TIME_STAMP_PATTERN) + "00000001";
}
/**
* 返回客户端ip
*
* @param request
* @return
*/
public static String getRemoteAddrIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(",");
if (index != -1) {
return ip.substring(0, index);
} else {
return ip;
}
}
ip = request.getHeader("X-Real-IP");
if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
return ip;
}
return request.getRemoteAddr();
}
/**
* 获取服务器的ip地址
*
* @param request
* @return
*/
public static String getLocalIp(HttpServletRequest request) {
return request.getLocalAddr();
}
public static String getSign(Map<String, String> params, String paternerKey) throws UnsupportedEncodingException {
return Encrypt.getMD5(createSign(params, false) + "&key=" + paternerKey).toUpperCase();
}
/**
* 构造签名
*
* @param params
* @param encode
* @return
* @throws UnsupportedEncodingException
*/
public static String createSign(Map<String, String> params, boolean encode) throws UnsupportedEncodingException {
Set<String> keysSet = params.keySet();
Object[] keys = keysSet.toArray();
Arrays.sort(keys);
StringBuffer temp = new StringBuffer();
boolean first = true;
for (Object key : keys) {
if (key == null || StringUtil.isEmpty(params.get(key))) // 参数为空不参与签名
continue;
if (first) {
first = false;
} else {
temp.append("&");
}
temp.append(key).append("=");
Object value = params.get(key);
String valueStr = "";
if (null != value) {
valueStr = value.toString();
}
if (encode) {
temp.append(URLEncoder.encode(valueStr, "UTF-8"));
} else {
temp.append(valueStr);
}
}
return temp.toString();
}
/**
* 创建支付随机字符串
* @return
*/
public static String getNonceStr(){
return ChineseCharToEnUtil.randomString(ChineseCharToEnUtil.LETTER_NUMBER_CHAR, 32);
}
/**
* 支付时间戳
* @return
*/
public static String payTimestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}
5. CollectionUtil
package com.zero.jimu.utils.withdrawal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 集合类工具
*/
public class CollectionUtil {
private CollectionUtil() {
super();
}
// 判断一个集合是否为空
public static <T> boolean isEmpty(Collection<T> col) {
if (col == null || col.isEmpty()) {
return true;
}
return false;
}
// 判断一个集合是否不为空
public static <T> boolean isNotEmpty(Collection<T> col) {
return !isEmpty(col);
}
// 判断Map是否为空
public static <K, V> boolean isEmpty(Map<K, V> map) {
if (map == null || map.isEmpty()) {
return true;
}
return false;
}
// 判断Map是否不为空为空
public static <K, V> boolean isNotEmpty(Map<K, V> map) {
return !isEmpty(map);
}
// 去除list中的重复数据
public static <T> List<T> removeRepeat(List<T> list) {
if (isEmpty(list)) {
return list;
}
List<T> result = new ArrayList<T>();
for (T e : list) {
if (!result.contains(e)) {
result.add(e);
}
}
return result;
}
// 将集合转换为String数组
public static <T> String[] toArray(List<T> list) {
if (isEmpty(list)) {
return null;
}
String[] result = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
result[i] = String.valueOf(list.get(i));
}
return result;
}
}