更新sql和代码规范修改
This commit is contained in:
@ -37,13 +37,14 @@ public class MerchantPayServiceConfigurer implements PayServiceConfigurer {
|
||||
* @param merchants 商户配置
|
||||
*/
|
||||
@Override
|
||||
public void configure(MerchantDetailsServiceConfigurer merchants) {
|
||||
public void configure(MerchantDetailsServiceConfigurer merchants) {
|
||||
merchants.jdbc()
|
||||
//是否开启缓存,默认不开启,这里开启缓存
|
||||
.cache(false)
|
||||
.template(jdbcTemplate);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户配置
|
||||
*
|
||||
|
@ -15,6 +15,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付宝支付回调处理器
|
||||
*
|
||||
* @author hupeng
|
||||
* @date 2023/7/15
|
||||
*/
|
||||
@ -24,6 +25,7 @@ public class AliPayMessageHandler implements PayMessageHandler<AliPayMessage, Al
|
||||
|
||||
@Resource
|
||||
private PayNoticeProducer payNoticeProducer;
|
||||
|
||||
/**
|
||||
* 处理支付回调消息的处理器接口
|
||||
*
|
||||
|
@ -15,6 +15,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* 微信支付回调处理器
|
||||
*
|
||||
* @author hupeng
|
||||
* @date 2023/7/15
|
||||
*/
|
||||
@ -32,15 +33,15 @@ public class WxPayMessageHandler implements PayMessageHandler<WxPayMessage, PayS
|
||||
log.info("======pay notice ========");
|
||||
|
||||
//交易状态
|
||||
if ("SUCCESS".equals(payMessage.getPayMessage().get("result_code"))){
|
||||
if ("SUCCESS".equals(payMessage.getPayMessage().get("result_code"))) {
|
||||
String orderId = (String) payMessage.getPayMessage().get("out_trade_no");
|
||||
//消息队列处理
|
||||
log.info("微信回调消息处理,发送处理消息orderId={}",orderId);
|
||||
log.info("微信回调消息处理,发送处理消息orderId={}", orderId);
|
||||
payNoticeProducer.sendPayNoticeMessage(orderId, PayTypeEnum.WEIXIN.getType());
|
||||
|
||||
return payService.getPayOutMessage("SUCCESS", "OK");
|
||||
return payService.getPayOutMessage("SUCCESS", "OK");
|
||||
}
|
||||
|
||||
return payService.getPayOutMessage("FAIL", "失败");
|
||||
return payService.getPayOutMessage("FAIL", "失败");
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付宝回调信息拦截器
|
||||
*
|
||||
* @author hupeng
|
||||
* @date 2023/7/15
|
||||
*/
|
||||
@ -21,12 +22,12 @@ public class AliPayMessageInterceptor implements PayMessageInterceptor<AliPayMes
|
||||
/**
|
||||
* 拦截支付消息
|
||||
*
|
||||
* @param payMessage 支付回调消息
|
||||
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
|
||||
* @param payMessage 支付回调消息
|
||||
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
|
||||
* @param payService 支付服务
|
||||
* @return true代表OK,false代表不OK并直接中断对应的支付处理器
|
||||
* @see PayMessageHandler 支付处理器
|
||||
* @throws PayErrorException PayErrorException*
|
||||
* @see PayMessageHandler 支付处理器
|
||||
*/
|
||||
@Override
|
||||
public boolean intercept(AliPayMessage payMessage, Map<String, Object> context, AliPayService payService) throws PayErrorException {
|
||||
@ -36,7 +37,6 @@ public class AliPayMessageInterceptor implements PayMessageInterceptor<AliPayMes
|
||||
// todo
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2022
|
||||
* All rights reserved, Designed By www.yixiang.co
|
||||
|
||||
*/
|
||||
package co.yixiang.yshop.module.pay.enums;
|
||||
|
||||
@ -18,24 +17,24 @@ import java.util.stream.Stream;
|
||||
@AllArgsConstructor
|
||||
public enum PayTypeEnum {
|
||||
|
||||
WEIXIN("weixin","微信支付"),
|
||||
WEIXIN_H5("weixin_h5","微信H5支付"),
|
||||
WEIXIN_APPLET("weixin_applet","微信小程序支付"),
|
||||
WEIXIN_APP("weixin_app","微信app支付"),
|
||||
WEIXIN("weixin", "微信支付"),
|
||||
WEIXIN_H5("weixin_h5", "微信H5支付"),
|
||||
WEIXIN_APPLET("weixin_applet", "微信小程序支付"),
|
||||
WEIXIN_APP("weixin_app", "微信app支付"),
|
||||
|
||||
YUE("yue","余额支付"),
|
||||
INTEGRAL("integral","积分兑换");
|
||||
YUE("yue", "余额支付"),
|
||||
INTEGRAL("integral", "积分兑换");
|
||||
|
||||
|
||||
private String type;
|
||||
private String type;
|
||||
|
||||
private String desc;
|
||||
private String desc;
|
||||
|
||||
public static PayTypeEnum toType(String type) {
|
||||
return Stream.of(PayTypeEnum.values())
|
||||
.filter(p -> p.type.equals(type))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
}
|
||||
public static PayTypeEnum toType(String type) {
|
||||
return Stream.of(PayTypeEnum.values())
|
||||
.filter(p -> p.type.equals(type))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package co.yixiang.yshop.module.pay.mq.message;
|
||||
|
||||
import co.yixiang.yshop.framework.mq.core.stream.AbstractStreamMessage;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
|
@ -15,9 +15,10 @@ public class PayNoticeProducer {
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param orderId 订单编号
|
||||
*/
|
||||
public void sendPayNoticeMessage(String orderId,String payType) {
|
||||
public void sendPayNoticeMessage(String orderId, String payType) {
|
||||
PayNoticeMessage payNoticeMessage = new PayNoticeMessage().setOrderId(orderId).setPayType(payType);
|
||||
redisMQTemplate.send(payNoticeMessage);
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
package co.yixiang.yshop.module.pay;
|
||||
|
||||
import co.yixiang.yshop.module.pay.strategy.PayEnum;
|
||||
|
||||
public class PayClient {
|
||||
public static void main(String[] args) {
|
||||
PayContext payContext = new PayContext();
|
||||
// System.out.println(payContext.selectPayWay(PayEnum.WEIXIN.getCode(), ));
|
||||
}
|
||||
|
||||
}
|
@ -13,7 +13,7 @@ public class PayContext {
|
||||
private Pay pay;
|
||||
|
||||
public Map<String, String> selectPayWay(String payCode, PayParam payParam) throws Exception {
|
||||
pay = PayFactory.getInstance().create(payCode);
|
||||
pay = PayFactory.getInstance().create(payCode);
|
||||
return pay.selectPayWay(payCode, payParam);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
package co.yixiang.yshop.module.pay.controller.admin.merchantdetails;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -15,11 +17,13 @@ import java.io.IOException;
|
||||
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
import co.yixiang.yshop.framework.common.pojo.CommonResult;
|
||||
|
||||
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
|
||||
|
||||
import co.yixiang.yshop.framework.excel.core.util.ExcelUtils;
|
||||
|
||||
import co.yixiang.yshop.framework.operatelog.core.annotations.OperateLog;
|
||||
|
||||
import static co.yixiang.yshop.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
|
||||
@ -91,7 +95,7 @@ public class MerchantDetailsController {
|
||||
@PreAuthorize("@ss.hasPermission('pay:merchant-details:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportMerchantDetailsExcel(@Valid MerchantDetailsExportReqVO exportReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<MerchantDetailsDO> list = merchantDetailsService.getMerchantDetailsList(exportReqVO);
|
||||
// 导出 Excel
|
||||
List<MerchantDetailsExcelVO> datas = MerchantDetailsConvert.INSTANCE.convertList02(list);
|
||||
|
@ -6,9 +6,9 @@ import lombok.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 支付服务商配置 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
* 支付服务商配置 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class MerchantDetailsBaseVO {
|
||||
|
||||
|
@ -49,6 +49,7 @@ import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionU
|
||||
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
|
||||
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.USER_NOT_BINDING_WX;
|
||||
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.USER_NOT_BINDING_WX_APPLET;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
/**
|
||||
@ -122,7 +123,7 @@ public class AppPayController {
|
||||
@RequestMapping("/flush")
|
||||
@Operation(summary = "清空redis")
|
||||
@PermitAll
|
||||
public void flush () throws Exception {
|
||||
public void flush() throws Exception {
|
||||
redisTemplate.execute((RedisCallback<Void>) connection -> {
|
||||
connection.flushDb();
|
||||
return null;
|
||||
|
@ -2,6 +2,7 @@ package co.yixiang.yshop.module.pay.controller.app.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
@ -50,6 +50,7 @@ public class PayOrderProcessorImpl implements PayOrderProcessor {
|
||||
@Resource
|
||||
private MerchantDetailsService merchantDetailsService;
|
||||
|
||||
|
||||
@Override
|
||||
public PayParam getPayParam(String orderId, String payType) {
|
||||
Long userId = getLoginUserId();
|
||||
@ -66,11 +67,11 @@ public class PayOrderProcessorImpl implements PayOrderProcessor {
|
||||
payParam.setPayDesc(PayOrderConstants.PAY_DESC);
|
||||
|
||||
// 判断是否为充值
|
||||
if (StrUtil.startWith(orderId, PayOrderConstants.RECHARGE_ORDER_PREFIX)){
|
||||
if (StrUtil.startWith(orderId, PayOrderConstants.RECHARGE_ORDER_PREFIX)) {
|
||||
RechargeOrderDTO rechargeOrderDTO = rechargeOrderApi.getPayParam(orderId);
|
||||
payParam.setMoney(new BigDecimal(rechargeOrderDTO.getRechargeAmount()));
|
||||
payParam.setRedirectType(PayOrderConstants.RECHARGE_REDIRECT_URL);
|
||||
}else {
|
||||
} else {
|
||||
// 不是充值就是购买
|
||||
ProductOrderDTO productOrderDTO = productOrderApi.getPayParam(orderId);
|
||||
payParam.setMoney(productOrderDTO.getAmount());
|
||||
@ -86,7 +87,7 @@ public class PayOrderProcessorImpl implements PayOrderProcessor {
|
||||
if (StrUtil.startWith(orderId, PayOrderConstants.RECHARGE_ORDER_PREFIX)) {
|
||||
// 充值
|
||||
|
||||
}else {
|
||||
} else {
|
||||
// 不是充值就是购买
|
||||
productOrderApi.handleOrder(orderId, packageParams);
|
||||
}
|
||||
@ -131,12 +132,11 @@ public class PayOrderProcessorImpl implements PayOrderProcessor {
|
||||
if (StrUtil.startWith(orderId, PayOrderConstants.RECHARGE_ORDER_PREFIX)) {
|
||||
// 充值
|
||||
rechargeOrderApi.handleWeChatPayNotify(orderId);
|
||||
}else {
|
||||
} else {
|
||||
// 不是充值就是购买
|
||||
productOrderApi.handleWeChatPayNotify(orderId, resultMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package co.yixiang.yshop.module.pay.service.merchantdetails;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
|
||||
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
|
||||
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
|
@ -1,10 +1,13 @@
|
||||
package co.yixiang.yshop.module.pay.service.merchantdetails;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.*;
|
||||
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
|
||||
import co.yixiang.yshop.framework.common.pojo.PageResult;
|
||||
|
@ -4,6 +4,6 @@ import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.PayParam;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface Pay{
|
||||
Map<String,String> selectPayWay(String payCode, PayParam param) throws Exception;
|
||||
public interface Pay {
|
||||
Map<String, String> selectPayWay(String payCode, PayParam param) throws Exception;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ public interface PayClient {
|
||||
|
||||
/**
|
||||
* 获取支付信息
|
||||
*
|
||||
* @return 支付信息
|
||||
*/
|
||||
Map<String, String> payment(PayParam param) throws Exception;
|
||||
|
@ -7,6 +7,7 @@ public interface PayClientFactory {
|
||||
|
||||
/**
|
||||
* 获取支付客户端
|
||||
*
|
||||
* @param payType 支付类型
|
||||
* @return 支付客户端
|
||||
*/
|
||||
|
@ -5,22 +5,22 @@ import lombok.Getter;
|
||||
@Getter
|
||||
public enum PayEnum {
|
||||
|
||||
ALI("alipay","支付宝支付"),
|
||||
ALI_APP("alipay_app","支付宝APP支付"),
|
||||
ALI_H5("alipay_h5","支付宝H5支付"),
|
||||
WEIXIN("weixin","微信支付"),
|
||||
WEIXIN_H5("weixin_h5","微信H5支付"),
|
||||
WEIXIN_APPLET("weixin_applet","微信小程序支付"),
|
||||
WEIXIN_APP("weixin_app","微信app支付"),
|
||||
YUE("yue","余额支付"),
|
||||
INTEGRAL("integral","积分兑换");
|
||||
ALI("alipay", "支付宝支付"),
|
||||
ALI_APP("alipay_app", "支付宝APP支付"),
|
||||
ALI_H5("alipay_h5", "支付宝H5支付"),
|
||||
WEIXIN("weixin", "微信支付"),
|
||||
WEIXIN_H5("weixin_h5", "微信H5支付"),
|
||||
WEIXIN_APPLET("weixin_applet", "微信小程序支付"),
|
||||
WEIXIN_APP("weixin_app", "微信app支付"),
|
||||
YUE("yue", "余额支付"),
|
||||
INTEGRAL("integral", "积分兑换");
|
||||
|
||||
private String msg;
|
||||
private String code;
|
||||
private String msg;
|
||||
private String code;
|
||||
|
||||
PayEnum( String code,String msg) {
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
PayEnum(String code, String msg) {
|
||||
this.msg = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,20 +11,21 @@ public class PayFactory {
|
||||
|
||||
private static final PayFactory factory = new PayFactory();
|
||||
|
||||
private PayFactory(){}
|
||||
private PayFactory() {
|
||||
}
|
||||
|
||||
private static final Map<Object, Object> PayMap = new HashMap<>(16);
|
||||
|
||||
static {
|
||||
PayMap.put(PayEnum.ALI.getCode(),new AliPay());
|
||||
PayMap.put(PayEnum.WEIXIN.getCode(),new WeChatPay());
|
||||
PayMap.put(PayEnum.ALI.getCode(), new AliPay());
|
||||
PayMap.put(PayEnum.WEIXIN.getCode(), new WeChatPay());
|
||||
}
|
||||
|
||||
public Pay create(String payCode){
|
||||
public Pay create(String payCode) {
|
||||
return (Pay) PayMap.get(payCode);
|
||||
}
|
||||
|
||||
public static PayFactory getInstance(){
|
||||
public static PayFactory getInstance() {
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import java.util.Map;
|
||||
public class AliPay implements PayClient {
|
||||
|
||||
@Override
|
||||
public Map<String,String> payment(PayParam param) throws Exception{
|
||||
public Map<String, String> payment(PayParam param) throws Exception {
|
||||
|
||||
return Collections.emptyMap();
|
||||
|
||||
|
@ -9,7 +9,7 @@ import java.util.Map;
|
||||
public class IntegralPay implements PayClient {
|
||||
|
||||
@Override
|
||||
public Map<String,String> payment(PayParam param) throws Exception{
|
||||
public Map<String, String> payment(PayParam param) throws Exception {
|
||||
//do something
|
||||
|
||||
return Collections.emptyMap();
|
||||
|
@ -15,8 +15,8 @@ public class NowMoneyPay implements PayClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String,String> payment(PayParam param) throws Exception{
|
||||
productOrderApi.yuePay(param.getOrderId(),param.getUid());
|
||||
public Map<String, String> payment(PayParam param) throws Exception {
|
||||
productOrderApi.yuePay(param.getOrderId(), param.getUid());
|
||||
//do something
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
@ -12,10 +12,10 @@ public class WeChatPay implements PayClient {
|
||||
@Resource
|
||||
private WxPayServiceUtils wxPayServiceUtils;
|
||||
|
||||
public WeChatPay(){
|
||||
public WeChatPay() {
|
||||
}
|
||||
|
||||
public WeChatPay(WxPayServiceUtils wxPayServiceUtils){
|
||||
public WeChatPay(WxPayServiceUtils wxPayServiceUtils) {
|
||||
this.wxPayServiceUtils = wxPayServiceUtils;
|
||||
}
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
package co.yixiang.yshop.module.pay.strategy.type;
|
||||
|
||||
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.PayParam;
|
||||
import co.yixiang.yshop.module.pay.strategy.Pay;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class YuePay implements Pay {
|
||||
|
||||
@Override
|
||||
public Map<String,String> selectPayWay(String payCode,PayParam param) throws Exception{
|
||||
//do something
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
@ -10,40 +10,44 @@ public interface WxPayService {
|
||||
|
||||
/**
|
||||
* 微信支付
|
||||
*
|
||||
* @param orderTradeNo 订单编号
|
||||
* @param money 订单金额
|
||||
* @param openid 客户openid
|
||||
* @param ip 服务ip地址
|
||||
* @param type 小程序或app
|
||||
* @param money 订单金额
|
||||
* @param openid 客户openid
|
||||
* @param ip 服务ip地址
|
||||
* @param type 小程序或app
|
||||
*/
|
||||
Map<String,String> gotoPay(String orderTradeNo, BigDecimal money, String openid, String ip, String type, MerchantDetailsDO merchantDetailsDO) throws Exception;
|
||||
Map<String, String> gotoPay(String orderTradeNo, BigDecimal money, String openid, String ip, String type, MerchantDetailsDO merchantDetailsDO) throws Exception;
|
||||
|
||||
/**
|
||||
* 微信退款
|
||||
*
|
||||
* @param transactionId 支付单号
|
||||
* @param outRefundNo 支付生成的退款单号
|
||||
* @param total 订单总金额
|
||||
* @param refund 退款金额
|
||||
* @param outRefundNo 支付生成的退款单号
|
||||
* @param total 订单总金额
|
||||
* @param refund 退款金额
|
||||
* @throws Exception
|
||||
*/
|
||||
public Map<String,String> refund(String transactionId,String outRefundNo,BigDecimal total,BigDecimal refund,MerchantDetailsDO merchantDetailsDO) throws Exception;
|
||||
public Map<String, String> refund(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund, MerchantDetailsDO merchantDetailsDO) throws Exception;
|
||||
|
||||
/**
|
||||
* 保证金退款
|
||||
*
|
||||
* @param transactionId 支付单号
|
||||
* @param outRefundNo 支付生成的退款单号
|
||||
* @param total 订单总金额
|
||||
* @param refund 退款金额
|
||||
* @param outRefundNo 支付生成的退款单号
|
||||
* @param total 订单总金额
|
||||
* @param refund 退款金额
|
||||
*/
|
||||
public Map<String,String> refundBond(String transactionId,String outRefundNo,BigDecimal total,BigDecimal refund) throws Exception;
|
||||
public Map<String, String> refundBond(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* 生成收款码返回
|
||||
*
|
||||
* @param orderFormid 订单编号
|
||||
* @param money 金额
|
||||
* @param ip IP地址
|
||||
* @param tradeType 支付类型
|
||||
* @param money 金额
|
||||
* @param ip IP地址
|
||||
* @param tradeType 支付类型
|
||||
* @throws Exception
|
||||
*/
|
||||
public String getCollectionCode(String orderFormid, BigDecimal money, String ip, String tradeType) throws Exception;
|
||||
|
@ -19,7 +19,7 @@ import java.util.Map;
|
||||
|
||||
@Component
|
||||
@Slf4j(topic = "WxPayServiceUtils")
|
||||
public class WxPayServiceUtils implements InitializingBean {
|
||||
public class WxPayServiceUtils implements InitializingBean {
|
||||
/**
|
||||
* 支付小程序appid
|
||||
*/
|
||||
@ -63,34 +63,34 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
private String key;
|
||||
|
||||
|
||||
public Map<String, String> gotoPay(PayParam param) throws Exception {
|
||||
public Map<String, String> gotoPay(PayParam param) throws Exception {
|
||||
Map<String, String> reqParams = new HashMap<>();
|
||||
//获取商户信息
|
||||
//h5
|
||||
String outTradeNo = "";
|
||||
if(PayTypeEnum.WEIXIN_H5.getType().equals(param.getType())){
|
||||
outTradeNo=param.getOrderId()+"-"+ RandomStringUtil.getRandomCode(3,0)+"H5";
|
||||
if (PayTypeEnum.WEIXIN_H5.getType().equals(param.getType())) {
|
||||
outTradeNo = param.getOrderId() + "-" + RandomStringUtil.getRandomCode(3, 0) + "H5";
|
||||
reqParams.put("appid", param.getMerchantDetailsDO().getAppid());
|
||||
//交易类型
|
||||
reqParams.put("trade_type", "MWEB");
|
||||
}else if(PayTypeEnum.WEIXIN_APP.getType().equals(param.getType())){
|
||||
} else if (PayTypeEnum.WEIXIN_APP.getType().equals(param.getType())) {
|
||||
//微信app分配的APPID
|
||||
//app_appid
|
||||
outTradeNo=param.getOrderId()+"-"+ RandomStringUtil.getRandomCode(3,0)+"APP";
|
||||
outTradeNo = param.getOrderId() + "-" + RandomStringUtil.getRandomCode(3, 0) + "APP";
|
||||
reqParams.put("appid", param.getMerchantDetailsDO().getAppid());
|
||||
//交易类型
|
||||
reqParams.put("trade_type", "APP");
|
||||
}else if(PayTypeEnum.WEIXIN_APPLET.getType().equals(param.getType())){
|
||||
} else if (PayTypeEnum.WEIXIN_APPLET.getType().equals(param.getType())) {
|
||||
//微信app分配的APPID
|
||||
reqParams.put("openid",param.getOpenId());
|
||||
outTradeNo=param.getOrderId()+"-"+ RandomStringUtil.getRandomCode(3,0)+"APPLET";
|
||||
reqParams.put("openid", param.getOpenId());
|
||||
outTradeNo = param.getOrderId() + "-" + RandomStringUtil.getRandomCode(3, 0) + "APPLET";
|
||||
reqParams.put("appid", param.getMerchantDetailsDO().getAppid());
|
||||
//交易类型
|
||||
reqParams.put("trade_type", "JSAPI");
|
||||
}else {
|
||||
} else {
|
||||
//微信app分配的APPID
|
||||
reqParams.put("openid",param.getOpenId());
|
||||
outTradeNo=param.getOrderId()+"-"+ RandomStringUtil.getRandomCode(3,0)+"APPLET";
|
||||
reqParams.put("openid", param.getOpenId());
|
||||
outTradeNo = param.getOrderId() + "-" + RandomStringUtil.getRandomCode(3, 0) + "APPLET";
|
||||
reqParams.put("appid", param.getMerchantDetailsDO().getAppid());
|
||||
//交易类型
|
||||
reqParams.put("trade_type", "JSAPI");
|
||||
@ -104,7 +104,7 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
//签名类型
|
||||
reqParams.put("sign_type", "MD5");
|
||||
//充值订单 商品描述
|
||||
reqParams.put("body", "充值"+param.getPayDesc()+"订单-微信支付");
|
||||
reqParams.put("body", "充值" + param.getPayDesc() + "订单-微信支付");
|
||||
//商户订单编号
|
||||
reqParams.put("out_trade_no", outTradeNo);
|
||||
//订单总金额,单位为分
|
||||
@ -114,7 +114,7 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
//通知地址
|
||||
reqParams.put("notify_url", param.getMerchantDetailsDO().getNotifyUrl());
|
||||
//用户标识
|
||||
// reqParams.put("openid", openid);
|
||||
// reqParams.put("openid", openid);
|
||||
//签名
|
||||
String sign = WXPayUtil.generateSignature(reqParams, param.getMerchantDetailsDO().getKeyPrivate());
|
||||
reqParams.put("sign", sign);
|
||||
@ -122,7 +122,7 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
调用支付定义下单API,返回预付单信息 prepay_id
|
||||
*/
|
||||
String xmlResult = PaymentApi.pushOrder(reqParams);
|
||||
log.info("微信下单信息:{}",xmlResult);
|
||||
log.info("微信下单信息:{}", xmlResult);
|
||||
Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
|
||||
//预付单信息
|
||||
String prepay_id = result.get("prepay_id");
|
||||
@ -143,21 +143,21 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
//将组合后的商户订单号返回
|
||||
packageParams.put("out_trade_no", outTradeNo);
|
||||
packageParams.put("merchant_id", param.getMerchantDetailsDO().getMchId());
|
||||
Map map = PaymentApi.queryByOutTradeNo(param.getMerchantDetailsDO().getAppid(),param.getMerchantDetailsDO().getMchId(),param.getMerchantDetailsDO().getKeyPrivate(),outTradeNo);
|
||||
Map map = PaymentApi.queryByOutTradeNo(param.getMerchantDetailsDO().getAppid(), param.getMerchantDetailsDO().getMchId(), param.getMerchantDetailsDO().getKeyPrivate(), outTradeNo);
|
||||
log.info("查询到微信订单信息:" + map.toString());
|
||||
// payInfo.setTransaction_id(map.get("transaction_id"))
|
||||
// payInfo.setTransaction_id(map.get("transaction_id"))
|
||||
if (PayTypeEnum.WEIXIN_H5.getType().equals(param.getType())) {
|
||||
packageParams.put("mwebUrl", result.get("mweb_url") + "&redirect_url="+ URLEncoder.encode(param.getMerchantDetailsDO().getReturnUrl() + param.getRedirectType(), "GBK"));
|
||||
packageParams.put("mwebUrl", result.get("mweb_url") + "&redirect_url=" + URLEncoder.encode(param.getMerchantDetailsDO().getReturnUrl() + param.getRedirectType(), "GBK"));
|
||||
}
|
||||
return packageParams;
|
||||
}
|
||||
|
||||
public Map<String, String> refund(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund,MerchantDetailsDO merchantDetailsDO) throws Exception {
|
||||
public Map<String, String> refund(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund, MerchantDetailsDO merchantDetailsDO) throws Exception {
|
||||
//退款资金来源-可用余额退款
|
||||
String refundAccount="REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
String refundAccount = "REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("appid", merchantDetailsDO.getAppid());
|
||||
params.put("mch_id",merchantDetailsDO.getMchId());
|
||||
params.put("mch_id", merchantDetailsDO.getMchId());
|
||||
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
|
||||
//商户订单号和微信订单号二选一
|
||||
// params.put("out_trade_no", wxPayLog.getOutTradeNo());
|
||||
@ -167,31 +167,31 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
params.put("refund_fee", refund.multiply(BigDecimal.valueOf(100)).intValue() + "");
|
||||
params.put("refund_account", refundAccount);
|
||||
// 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
|
||||
params.put("refund_desc","退款");
|
||||
params.put("refund_desc", "退款");
|
||||
//退款回调 先不做
|
||||
// params.put("notify_url", pc_refund_notify_url);
|
||||
// params.put("notify_url", pc_refund_notify_url);
|
||||
//签名算法
|
||||
String sign = WXPayUtil.generateSignature(params,merchantDetailsDO.getKeyPrivate());
|
||||
String sign = WXPayUtil.generateSignature(params, merchantDetailsDO.getKeyPrivate());
|
||||
params.put("sign", sign);
|
||||
String xml = PaymentKit.toXml(params);
|
||||
log.info(xml);
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml,cert_url,merchantDetailsDO.getMchId());
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml, cert_url, merchantDetailsDO.getMchId());
|
||||
//加入微信支付日志
|
||||
return PaymentKit.xmlToMap(xmlStr);
|
||||
}
|
||||
|
||||
public Map<String, String> refundBond(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws Exception {
|
||||
public Map<String, String> refundBond(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws Exception {
|
||||
//退款资金来源-可用余额退款
|
||||
String refundAccount="REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
String refundAccount = "REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
Map<String, String> params = new HashMap<>();
|
||||
if(outRefundNo.contains("XCX")){
|
||||
if (outRefundNo.contains("XCX")) {
|
||||
//小程序微信退款
|
||||
params.put("appid", appid);
|
||||
}else if(outRefundNo.contains("APP")){
|
||||
} else if (outRefundNo.contains("APP")) {
|
||||
//APP微信退款
|
||||
params.put("appid", app_appid);
|
||||
}
|
||||
params.put("mch_id",mch_id);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
|
||||
//商户订单号和微信订单号二选一
|
||||
// params.put("out_trade_no", wxPayLog.getOutTradeNo());
|
||||
@ -201,15 +201,15 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
params.put("refund_fee", refund.multiply(BigDecimal.valueOf(100)).intValue() + "");
|
||||
params.put("refund_account", refundAccount);
|
||||
// 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
|
||||
params.put("refund_desc","退款");
|
||||
params.put("refund_desc", "退款");
|
||||
//退款回调
|
||||
// params.put("notify_url", pc_bond_refund_notify_url);
|
||||
// params.put("notify_url", pc_bond_refund_notify_url);
|
||||
//签名算法
|
||||
String sign = WXPayUtil.generateSignature(params,key);
|
||||
String sign = WXPayUtil.generateSignature(params, key);
|
||||
params.put("sign", sign);
|
||||
String xml = PaymentKit.toXml(params);
|
||||
log.info(xml);
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml,cert_url,mch_id);
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml, cert_url, mch_id);
|
||||
log.info(xmlStr);
|
||||
//加入微信支付日志
|
||||
Map map = PaymentKit.xmlToMap(xmlStr);
|
||||
@ -220,15 +220,15 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
public String getCollectionCode(String orderTradeNo, BigDecimal money, String ip, String tradeType) throws Exception {
|
||||
Map<String, String> reqParams = new HashMap<>();
|
||||
//微信分配的小程序ID
|
||||
reqParams.put("appid",appid);
|
||||
reqParams.put("appid", appid);
|
||||
//微信支付分配的商户号
|
||||
reqParams.put("mch_id",mch_id);
|
||||
reqParams.put("mch_id", mch_id);
|
||||
//随机字符串
|
||||
reqParams.put("nonce_str", System.currentTimeMillis() / 1000 + "");
|
||||
//签名类型
|
||||
reqParams.put("sign_type", "MD5");
|
||||
//充值订单 商品描述
|
||||
reqParams.put("body", "充值"+orderTradeNo+"订单-微信小程序");
|
||||
reqParams.put("body", "充值" + orderTradeNo + "订单-微信小程序");
|
||||
|
||||
//商户订单编号
|
||||
reqParams.put("out_trade_no", orderTradeNo);
|
||||
@ -238,13 +238,13 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
// reqParams.put("spbill_create_ip", "127.0.0.1");
|
||||
reqParams.put("spbill_create_ip", ip);
|
||||
//支付回调地址
|
||||
// reqParams.put("notify_url", pc_notify_url);
|
||||
// reqParams.put("notify_url", pc_notify_url);
|
||||
//交易类型
|
||||
reqParams.put("trade_type", tradeType);
|
||||
//用户标识
|
||||
// reqParams.put("openid", openid);
|
||||
//签名
|
||||
String sign = WXPayUtil.generateSignature(reqParams,key);
|
||||
String sign = WXPayUtil.generateSignature(reqParams, key);
|
||||
reqParams.put("sign", sign);
|
||||
/*
|
||||
调用支付定义下单API,返回预付单信息 prepay_id
|
||||
@ -255,12 +255,12 @@ public class WxPayServiceUtils implements InitializingBean {
|
||||
return result.get("code_url");
|
||||
}
|
||||
|
||||
public boolean verifyNotify(Map<String, String> params){
|
||||
return PaymentKit.verifyNotify(params,key);
|
||||
public boolean verifyNotify(Map<String, String> params) {
|
||||
return PaymentKit.verifyNotify(params, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
log.info("微信支付配置读取Bean初始化成功");
|
||||
log.info("微信支付配置读取Bean初始化成功");
|
||||
}
|
||||
}
|
||||
|
@ -63,27 +63,27 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, String> gotoPay(String orderId, BigDecimal money, String openid, String ip, String type, MerchantDetailsDO merchantDetailsDO) throws Exception {
|
||||
public Map<String, String> gotoPay(String orderId, BigDecimal money, String openid, String ip, String type, MerchantDetailsDO merchantDetailsDO) throws Exception {
|
||||
Map<String, String> reqParams = new HashMap<>();
|
||||
//获取商户信息
|
||||
//h5
|
||||
String outTradeNo = "";
|
||||
if(PayTypeEnum.WEIXIN_H5.getType().equals(type)){
|
||||
outTradeNo=orderId+"-"+ RandomStringUtil.getRandomCode(3,0)+"H5";
|
||||
if (PayTypeEnum.WEIXIN_H5.getType().equals(type)) {
|
||||
outTradeNo = orderId + "-" + RandomStringUtil.getRandomCode(3, 0) + "H5";
|
||||
reqParams.put("appid", merchantDetailsDO.getAppid());
|
||||
//交易类型
|
||||
reqParams.put("trade_type", "MWEB");
|
||||
}else if(PayTypeEnum.WEIXIN_APP.getType().equals(type)){
|
||||
} else if (PayTypeEnum.WEIXIN_APP.getType().equals(type)) {
|
||||
//微信app分配的APPID
|
||||
//app_appid
|
||||
outTradeNo=orderId+"-"+ RandomStringUtil.getRandomCode(3,0)+"APP";
|
||||
outTradeNo = orderId + "-" + RandomStringUtil.getRandomCode(3, 0) + "APP";
|
||||
reqParams.put("appid", merchantDetailsDO.getAppid());
|
||||
//交易类型
|
||||
reqParams.put("trade_type", "APP");
|
||||
}else if(PayTypeEnum.WEIXIN_APPLET.getType().equals(type)){
|
||||
} else if (PayTypeEnum.WEIXIN_APPLET.getType().equals(type)) {
|
||||
//微信app分配的APPID
|
||||
//app_appid
|
||||
outTradeNo=orderId+"-"+ RandomStringUtil.getRandomCode(3,0)+"APPLET";
|
||||
outTradeNo = orderId + "-" + RandomStringUtil.getRandomCode(3, 0) + "APPLET";
|
||||
reqParams.put("appid", appid);
|
||||
//交易类型
|
||||
reqParams.put("trade_type", "JSAPI");
|
||||
@ -97,7 +97,7 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
//签名类型
|
||||
reqParams.put("sign_type", "MD5");
|
||||
//充值订单 商品描述
|
||||
reqParams.put("body", "充值"+outTradeNo+"订单-微信支付");
|
||||
reqParams.put("body", "充值" + outTradeNo + "订单-微信支付");
|
||||
//商户订单编号
|
||||
reqParams.put("out_trade_no", outTradeNo);
|
||||
//订单总金额,单位为分
|
||||
@ -107,7 +107,7 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
//通知地址
|
||||
reqParams.put("notify_url", merchantDetailsDO.getNotifyUrl());
|
||||
//用户标识
|
||||
// reqParams.put("openid", openid);
|
||||
// reqParams.put("openid", openid);
|
||||
//签名
|
||||
String sign = WXPayUtil.generateSignature(reqParams, merchantDetailsDO.getKeyPrivate());
|
||||
reqParams.put("sign", sign);
|
||||
@ -136,31 +136,31 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
packageParams.put("out_trade_no", outTradeNo);
|
||||
packageParams.put("orderId", orderId);
|
||||
packageParams.put("merchant_id", merchantDetailsDO.getMchId());
|
||||
Map map = PaymentApi.queryByOutTradeNo(merchantDetailsDO.getAppid(),merchantDetailsDO.getMchId(),merchantDetailsDO.getKeyPrivate(),outTradeNo);
|
||||
Map map = PaymentApi.queryByOutTradeNo(merchantDetailsDO.getAppid(), merchantDetailsDO.getMchId(), merchantDetailsDO.getKeyPrivate(), outTradeNo);
|
||||
log.info("查询到微信订单信息:" + map.toString());
|
||||
// payInfo.setTransaction_id(map.get("transaction_id"))
|
||||
// payInfo.setTransaction_id(map.get("transaction_id"))
|
||||
if (PayTypeEnum.WEIXIN_H5.getType().equals(type)) {
|
||||
packageParams.put("mwebUrl", result.get("mweb_url") + "&redirect_url="+ URLEncoder.encode(merchantDetailsDO.getReturnUrl(), "GBK"));
|
||||
packageParams.put("mwebUrl", result.get("mweb_url") + "&redirect_url=" + URLEncoder.encode(merchantDetailsDO.getReturnUrl(), "GBK"));
|
||||
}
|
||||
return packageParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> refund(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund,MerchantDetailsDO merchantDetailsDO) throws Exception {
|
||||
public Map<String, String> refund(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund, MerchantDetailsDO merchantDetailsDO) throws Exception {
|
||||
//退款资金来源-可用余额退款
|
||||
String refundAccount="REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
String refundAccount = "REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
Map<String, String> params = new HashMap<>();
|
||||
if(outRefundNo.contains("APPLET")){
|
||||
if (outRefundNo.contains("APPLET")) {
|
||||
//小程序微信退款
|
||||
params.put("appid", appid);
|
||||
}else if(outRefundNo.contains("APP")){
|
||||
} else if (outRefundNo.contains("APP")) {
|
||||
//APP微信退款
|
||||
params.put("appid", app_appid);
|
||||
}else if(outRefundNo.contains("H5")){
|
||||
} else if (outRefundNo.contains("H5")) {
|
||||
//H5
|
||||
params.put("appid", app_appid);
|
||||
}
|
||||
params.put("mch_id",mch_id);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
|
||||
//商户订单号和微信订单号二选一
|
||||
// params.put("out_trade_no", wxPayLog.getOutTradeNo());
|
||||
@ -170,35 +170,35 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
params.put("refund_fee", refund.multiply(BigDecimal.valueOf(100)).intValue() + "");
|
||||
params.put("refund_account", refundAccount);
|
||||
// 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
|
||||
params.put("refund_desc","退款");
|
||||
params.put("refund_desc", "退款");
|
||||
//退款回调 先不做
|
||||
// params.put("notify_url", pc_refund_notify_url);
|
||||
// params.put("notify_url", pc_refund_notify_url);
|
||||
//签名算法
|
||||
String sign = WXPayUtil.generateSignature(params,key);
|
||||
String sign = WXPayUtil.generateSignature(params, key);
|
||||
params.put("sign", sign);
|
||||
String xml = PaymentKit.toXml(params);
|
||||
log.info(xml);
|
||||
String cert_url = "/yshop-server/apiclient_cert.p12";
|
||||
log.info("certUrl:{}",cert_url);
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml,cert_url,mch_id);
|
||||
log.info("certUrl:{}", cert_url);
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml, cert_url, mch_id);
|
||||
log.info(xmlStr);
|
||||
//加入微信支付日志
|
||||
return PaymentKit.xmlToMap(xmlStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> refundBond(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws Exception {
|
||||
public Map<String, String> refundBond(String transactionId, String outRefundNo, BigDecimal total, BigDecimal refund) throws Exception {
|
||||
//退款资金来源-可用余额退款
|
||||
String refundAccount="REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
String refundAccount = "REFUND_SOURCE_RECHARGE_FUNDS";
|
||||
Map<String, String> params = new HashMap<>();
|
||||
if(outRefundNo.contains("XCX")){
|
||||
if (outRefundNo.contains("XCX")) {
|
||||
//小程序微信退款
|
||||
params.put("appid", appid);
|
||||
}else if(outRefundNo.contains("APP")){
|
||||
} else if (outRefundNo.contains("APP")) {
|
||||
//APP微信退款
|
||||
params.put("appid", app_appid);
|
||||
}
|
||||
params.put("mch_id",mch_id);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
|
||||
//商户订单号和微信订单号二选一
|
||||
// params.put("out_trade_no", wxPayLog.getOutTradeNo());
|
||||
@ -208,15 +208,15 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
params.put("refund_fee", refund.multiply(BigDecimal.valueOf(100)).intValue() + "");
|
||||
params.put("refund_account", refundAccount);
|
||||
// 退款原因,若商户传入,会在下发给用户的退款消息中体现退款原因
|
||||
params.put("refund_desc","退款");
|
||||
params.put("refund_desc", "退款");
|
||||
//退款回调
|
||||
// params.put("notify_url", pc_bond_refund_notify_url);
|
||||
// params.put("notify_url", pc_bond_refund_notify_url);
|
||||
//签名算法
|
||||
String sign = WXPayUtil.generateSignature(params,key);
|
||||
String sign = WXPayUtil.generateSignature(params, key);
|
||||
params.put("sign", sign);
|
||||
String xml = PaymentKit.toXml(params);
|
||||
log.info(xml);
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml,cert_url,mch_id);
|
||||
String xmlStr = WXPayUtil.doRefund("https://api.mch.weixin.qq.com/secapi/pay/refund", xml, cert_url, mch_id);
|
||||
log.info(xmlStr);
|
||||
//加入微信支付日志
|
||||
Map map = PaymentKit.xmlToMap(xmlStr);
|
||||
@ -227,15 +227,15 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
public String getCollectionCode(String orderTradeNo, BigDecimal money, String ip, String tradeType) throws Exception {
|
||||
Map<String, String> reqParams = new HashMap<>();
|
||||
//微信分配的小程序ID
|
||||
reqParams.put("appid",appid);
|
||||
reqParams.put("appid", appid);
|
||||
//微信支付分配的商户号
|
||||
reqParams.put("mch_id",mch_id);
|
||||
reqParams.put("mch_id", mch_id);
|
||||
//随机字符串
|
||||
reqParams.put("nonce_str", System.currentTimeMillis() / 1000 + "");
|
||||
//签名类型
|
||||
reqParams.put("sign_type", "MD5");
|
||||
//充值订单 商品描述
|
||||
reqParams.put("body", "充值"+orderTradeNo+"订单-微信小程序");
|
||||
reqParams.put("body", "充值" + orderTradeNo + "订单-微信小程序");
|
||||
|
||||
//商户订单编号
|
||||
reqParams.put("out_trade_no", orderTradeNo);
|
||||
@ -245,13 +245,13 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
// reqParams.put("spbill_create_ip", "127.0.0.1");
|
||||
reqParams.put("spbill_create_ip", ip);
|
||||
//支付回调地址
|
||||
// reqParams.put("notify_url", pc_notify_url);
|
||||
// reqParams.put("notify_url", pc_notify_url);
|
||||
//交易类型
|
||||
reqParams.put("trade_type", tradeType);
|
||||
//用户标识
|
||||
// reqParams.put("openid", openid);
|
||||
//签名
|
||||
String sign = WXPayUtil.generateSignature(reqParams,key);
|
||||
String sign = WXPayUtil.generateSignature(reqParams, key);
|
||||
reqParams.put("sign", sign);
|
||||
/*
|
||||
调用支付定义下单API,返回预付单信息 prepay_id
|
||||
@ -263,7 +263,7 @@ public class WxPayServiceImpl implements WxPayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyNotify(Map<String, String> params){
|
||||
return PaymentKit.verifyNotify(params,key);
|
||||
public boolean verifyNotify(Map<String, String> params) {
|
||||
return PaymentKit.verifyNotify(params, key);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class HttpKit {
|
||||
try {
|
||||
TrustManager[] e = new TrustManager[]{new HttpKit().new TrustAnyTrustManager()};
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init((KeyManager[])null, e, new SecureRandom());
|
||||
sslContext.init((KeyManager[]) null, e, new SecureRandom());
|
||||
return sslContext.getSocketFactory();
|
||||
} catch (Exception var2) {
|
||||
throw new RuntimeException(var2);
|
||||
@ -39,7 +39,7 @@ public class HttpKit {
|
||||
}
|
||||
|
||||
public static void setCharSet(String charSet) {
|
||||
if(charSet!=null && !charSet.equals("")) {
|
||||
if (charSet != null && !charSet.equals("")) {
|
||||
throw new IllegalArgumentException("charSet can not be blank.");
|
||||
} else {
|
||||
CHARSET = charSet;
|
||||
@ -48,10 +48,10 @@ public class HttpKit {
|
||||
|
||||
private static HttpURLConnection getHttpConnection(String url, String method, Map<String, String> headers) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
|
||||
URL _url = new URL(url);
|
||||
HttpURLConnection conn = (HttpURLConnection)_url.openConnection();
|
||||
if(conn instanceof HttpsURLConnection) {
|
||||
((HttpsURLConnection)conn).setSSLSocketFactory(sslSocketFactory);
|
||||
((HttpsURLConnection)conn).setHostnameVerifier(trustAnyHostnameVerifier);
|
||||
HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
|
||||
if (conn instanceof HttpsURLConnection) {
|
||||
((HttpsURLConnection) conn).setSSLSocketFactory(sslSocketFactory);
|
||||
((HttpsURLConnection) conn).setHostnameVerifier(trustAnyHostnameVerifier);
|
||||
}
|
||||
|
||||
conn.setRequestMethod(method);
|
||||
@ -61,12 +61,12 @@ public class HttpKit {
|
||||
conn.setReadTimeout(19000);
|
||||
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
conn.setRequestProperty("AuthUser-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
|
||||
if(headers != null && !headers.isEmpty()) {
|
||||
if (headers != null && !headers.isEmpty()) {
|
||||
Iterator i$ = headers.entrySet().iterator();
|
||||
|
||||
while(i$.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)i$.next();
|
||||
conn.setRequestProperty((String)entry.getKey(), (String)entry.getValue());
|
||||
while (i$.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry) i$.next();
|
||||
conn.setRequestProperty((String) entry.getKey(), (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ public class HttpKit {
|
||||
} catch (Exception var8) {
|
||||
throw new RuntimeException(var8);
|
||||
} finally {
|
||||
if(conn != null) {
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
@ -91,11 +91,11 @@ public class HttpKit {
|
||||
}
|
||||
|
||||
public static String get(String url, Map<String, String> queryParas) {
|
||||
return get(url, queryParas, (Map)null);
|
||||
return get(url, queryParas, (Map) null);
|
||||
}
|
||||
|
||||
public static String get(String url) {
|
||||
return get(url, (Map)null, (Map)null);
|
||||
return get(url, (Map) null, (Map) null);
|
||||
}
|
||||
|
||||
public static String post(String url, Map<String, String> queryParas, String data, Map<String, String> headers) {
|
||||
@ -113,7 +113,7 @@ public class HttpKit {
|
||||
} catch (Exception var10) {
|
||||
throw new RuntimeException(var10);
|
||||
} finally {
|
||||
if(conn != null) {
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
@ -121,15 +121,15 @@ public class HttpKit {
|
||||
}
|
||||
|
||||
public static String post(String url, Map<String, String> queryParas, String data) {
|
||||
return post(url, queryParas, data, (Map)null);
|
||||
return post(url, queryParas, data, (Map) null);
|
||||
}
|
||||
|
||||
public static String post(String url, String data, Map<String, String> headers) {
|
||||
return post(url, (Map)null, data, headers);
|
||||
return post(url, (Map) null, data, headers);
|
||||
}
|
||||
|
||||
public static String post(String url, String data) {
|
||||
return post(url, (Map)null, data, (Map)null);
|
||||
return post(url, (Map) null, data, (Map) null);
|
||||
}
|
||||
|
||||
private static String readResponseString(HttpURLConnection conn) {
|
||||
@ -141,7 +141,7 @@ public class HttpKit {
|
||||
BufferedReader e = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
|
||||
String line = null;
|
||||
|
||||
while((line = e.readLine()) != null) {
|
||||
while ((line = e.readLine()) != null) {
|
||||
sb.append(line).append("\n");
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ public class HttpKit {
|
||||
} catch (Exception var14) {
|
||||
throw new RuntimeException(var14);
|
||||
} finally {
|
||||
if(inputStream != null) {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException var13) {
|
||||
@ -161,10 +161,10 @@ public class HttpKit {
|
||||
}
|
||||
|
||||
private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) {
|
||||
if(queryParas != null && !queryParas.isEmpty()) {
|
||||
if (queryParas != null && !queryParas.isEmpty()) {
|
||||
StringBuilder sb = new StringBuilder(url);
|
||||
boolean isFirst;
|
||||
if(url.indexOf("?") == -1) {
|
||||
if (url.indexOf("?") == -1) {
|
||||
isFirst = true;
|
||||
sb.append("?");
|
||||
} else {
|
||||
@ -173,17 +173,17 @@ public class HttpKit {
|
||||
|
||||
String key;
|
||||
String value;
|
||||
for(Iterator i$ = queryParas.entrySet().iterator(); i$.hasNext(); sb.append(key).append("=").append(value)) {
|
||||
Map.Entry entry = (Map.Entry)i$.next();
|
||||
if(isFirst) {
|
||||
for (Iterator i$ = queryParas.entrySet().iterator(); i$.hasNext(); sb.append(key).append("=").append(value)) {
|
||||
Map.Entry entry = (Map.Entry) i$.next();
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
|
||||
key = (String)entry.getKey();
|
||||
value = (String)entry.getValue();
|
||||
if(value!=null && !value.equals("")) {
|
||||
key = (String) entry.getKey();
|
||||
value = (String) entry.getValue();
|
||||
if (value != null && !value.equals("")) {
|
||||
try {
|
||||
value = URLEncoder.encode(value, CHARSET);
|
||||
} catch (UnsupportedEncodingException var9) {
|
||||
@ -206,7 +206,7 @@ public class HttpKit {
|
||||
br = request.getReader();
|
||||
String line = null;
|
||||
|
||||
while((line = br.readLine()) != null) {
|
||||
while ((line = br.readLine()) != null) {
|
||||
e.append(line).append("\n");
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ public class HttpKit {
|
||||
} catch (IOException var12) {
|
||||
throw new RuntimeException(var12);
|
||||
} finally {
|
||||
if(br != null) {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException var11) {
|
||||
@ -225,7 +225,9 @@ public class HttpKit {
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public static String readIncommingRequestData(HttpServletRequest request) {
|
||||
return readData(request);
|
||||
|
@ -7,6 +7,7 @@ import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* IOUtils
|
||||
*
|
||||
* @author majker
|
||||
*/
|
||||
public abstract class IOUtils {
|
||||
@ -14,6 +15,7 @@ public abstract class IOUtils {
|
||||
|
||||
/**
|
||||
* closeQuietly
|
||||
*
|
||||
* @param closeable 自动关闭
|
||||
*/
|
||||
public static void closeQuietly(Closeable closeable) {
|
||||
@ -29,10 +31,10 @@ public abstract class IOUtils {
|
||||
/**
|
||||
* InputStream to String utf-8
|
||||
*
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @return the requested String
|
||||
* @throws NullPointerException if the input is null
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public static String toString(InputStream input) throws IOException {
|
||||
return toString(input, Charsets.UTF_8);
|
||||
@ -41,17 +43,17 @@ public abstract class IOUtils {
|
||||
/**
|
||||
* InputStream to String
|
||||
*
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @param charset the <code>Charset</code>
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @param charset the <code>Charset</code>
|
||||
* @return the requested String
|
||||
* @throws NullPointerException if the input is null
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public static String toString(InputStream input, Charset charset) throws IOException {
|
||||
InputStreamReader in = new InputStreamReader(input, charset);
|
||||
StringBuffer out = new StringBuffer();
|
||||
char[] c = new char[DEFAULT_BUFFER_SIZE];
|
||||
for (int n; (n = in.read(c)) != -1;) {
|
||||
for (int n; (n = in.read(c)) != -1; ) {
|
||||
out.append(new String(c, 0, n));
|
||||
}
|
||||
IOUtils.closeQuietly(in);
|
||||
@ -61,8 +63,9 @@ public abstract class IOUtils {
|
||||
|
||||
/**
|
||||
* InputStream to File
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @param file the File to write
|
||||
*
|
||||
* @param input the <code>InputStream</code> to read from
|
||||
* @param file the File to write
|
||||
* @throws IOException id异常
|
||||
*/
|
||||
public static void toFile(InputStream input, File file) throws IOException {
|
||||
|
@ -13,264 +13,280 @@ import java.util.Map;
|
||||
**************************************************/
|
||||
public class PaymentApi {
|
||||
|
||||
private PaymentApi() {}
|
||||
private PaymentApi() {
|
||||
}
|
||||
|
||||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
|
||||
private static String unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
|
||||
private static String unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||
|
||||
/**
|
||||
* 交易类型枚举
|
||||
* WAP的文档:https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1
|
||||
* @author L.cm
|
||||
* <pre>
|
||||
* email: 596392912@qq.com
|
||||
* site: http://www.dreamlu.net
|
||||
* date: 2015年10月27日 下午9:46:27
|
||||
* </pre>
|
||||
*/
|
||||
public enum TradeType {
|
||||
JSAPI, NATIVE, APP, WAP, MWEB
|
||||
}
|
||||
/**
|
||||
* 交易类型枚举
|
||||
* WAP的文档:https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1
|
||||
*
|
||||
* @author L.cm
|
||||
* <pre>
|
||||
* email: 596392912@qq.com
|
||||
* site: http://www.dreamlu.net
|
||||
* date: 2015年10月27日 下午9:46:27
|
||||
* </pre>
|
||||
*/
|
||||
public enum TradeType {
|
||||
JSAPI, NATIVE, APP, WAP, MWEB
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一下单
|
||||
* @param params 参数map
|
||||
* @return String
|
||||
*/
|
||||
public static String pushOrder(Map<String, String> params) {
|
||||
return HttpKit.post(unifiedOrderUrl, PaymentKit.toXml(params));
|
||||
}
|
||||
/**
|
||||
* 统一下单
|
||||
*
|
||||
* @param params 参数map
|
||||
* @return String
|
||||
*/
|
||||
public static String pushOrder(Map<String, String> params) {
|
||||
return HttpKit.post(unifiedOrderUrl, PaymentKit.toXml(params));
|
||||
}
|
||||
|
||||
private static Map<String, String> request(String url, Map<String, String> params, String paternerKey) {
|
||||
params.put("nonce_str", System.currentTimeMillis() + "");
|
||||
String sign = PaymentKit.createSign(params, paternerKey);
|
||||
params.put("sign", sign);
|
||||
String xmlStr = HttpKit.post(url, PaymentKit.toXml(params));
|
||||
return PaymentKit.xmlToMap(xmlStr);
|
||||
}
|
||||
private static Map<String, String> request(String url, Map<String, String> params, String paternerKey) {
|
||||
params.put("nonce_str", System.currentTimeMillis() + "");
|
||||
String sign = PaymentKit.createSign(params, paternerKey);
|
||||
params.put("sign", sign);
|
||||
String xmlStr = HttpKit.post(url, PaymentKit.toXml(params));
|
||||
return PaymentKit.xmlToMap(xmlStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文档说明:https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_4
|
||||
* <pre>
|
||||
* @param appId 公众账号ID 是 String(32) wx8888888888888888 微信分配的公众账号ID
|
||||
* 随机字符串 noncestr 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
|
||||
* 订单详情扩展字符串 package 是 String(32) WAP 扩展字段,固定填写WAP
|
||||
* @param prepayId 预支付交易会话标识 是 String(64) wx201410272009395522657a690389285100 微信统一下单接口返回的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
|
||||
* 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
|
||||
* 时间戳 timestamp 是 String(32) 1414561699 当前的时间,其他详见时间戳规则
|
||||
* @param paternerKey 签名密匙
|
||||
* </pre>
|
||||
* @return {String}
|
||||
*/
|
||||
public static String getDeepLink(String appId, String prepayId, String paternerKey) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appId);
|
||||
params.put("noncestr", System.currentTimeMillis() + "");
|
||||
params.put("package", "WAP");
|
||||
params.put("prepayid", prepayId);
|
||||
params.put("timestamp", System.currentTimeMillis() / 1000 + "");
|
||||
String sign = PaymentKit.createSign(params, paternerKey);
|
||||
params.put("sign", sign);
|
||||
/**
|
||||
* 文档说明:https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_4
|
||||
* <pre>
|
||||
* @param appId 公众账号ID 是 String(32) wx8888888888888888 微信分配的公众账号ID
|
||||
* 随机字符串 noncestr 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
|
||||
* 订单详情扩展字符串 package 是 String(32) WAP 扩展字段,固定填写WAP
|
||||
* @param prepayId 预支付交易会话标识 是 String(64) wx201410272009395522657a690389285100 微信统一下单接口返回的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
|
||||
* 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
|
||||
* 时间戳 timestamp 是 String(32) 1414561699 当前的时间,其他详见时间戳规则
|
||||
* @param paternerKey 签名密匙
|
||||
* </pre>
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
public static String getDeepLink(String appId, String prepayId, String paternerKey) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appId);
|
||||
params.put("noncestr", System.currentTimeMillis() + "");
|
||||
params.put("package", "WAP");
|
||||
params.put("prepayid", prepayId);
|
||||
params.put("timestamp", System.currentTimeMillis() / 1000 + "");
|
||||
String sign = PaymentKit.createSign(params, paternerKey);
|
||||
params.put("sign", sign);
|
||||
|
||||
String string1 = PaymentKit.packageSign(params, true);
|
||||
String string1 = PaymentKit.packageSign(params, true);
|
||||
|
||||
String string2 = "";
|
||||
try { string2 = PaymentKit.urlEncode(string1); } catch (UnsupportedEncodingException e) {}
|
||||
String string2 = "";
|
||||
try {
|
||||
string2 = PaymentKit.urlEncode(string1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
}
|
||||
|
||||
return "wechat://wap/pay?" + string2;
|
||||
}
|
||||
return "wechat://wap/pay?" + string2;
|
||||
}
|
||||
|
||||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
|
||||
private static String orderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
|
||||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
|
||||
private static String orderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
|
||||
|
||||
/**
|
||||
* 根据商户订单号查询信息
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param transaction_id 微信订单号
|
||||
* @return 回调信息
|
||||
*/
|
||||
public static Map<String, String> queryByTransactionId(String appid, String mch_id, String paternerKey, String transaction_id) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("transaction_id", transaction_id);
|
||||
return request(orderQueryUrl, params, paternerKey);
|
||||
}
|
||||
/**
|
||||
* 根据商户订单号查询信息
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param transaction_id 微信订单号
|
||||
* @return 回调信息
|
||||
*/
|
||||
public static Map<String, String> queryByTransactionId(String appid, String mch_id, String paternerKey, String transaction_id) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("transaction_id", transaction_id);
|
||||
return request(orderQueryUrl, params, paternerKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户订单号查询信息
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_trade_no 商户订单号
|
||||
* @return 回调信息
|
||||
*/
|
||||
public static Map<String, String> queryByOutTradeNo(String appid, String mch_id, String paternerKey, String out_trade_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("out_trade_no", out_trade_no);
|
||||
return request(orderQueryUrl, params, paternerKey);
|
||||
}
|
||||
/**
|
||||
* 根据商户订单号查询信息
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_trade_no 商户订单号
|
||||
* @return 回调信息
|
||||
*/
|
||||
public static Map<String, String> queryByOutTradeNo(String appid, String mch_id, String paternerKey, String out_trade_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("out_trade_no", out_trade_no);
|
||||
return request(orderQueryUrl, params, paternerKey);
|
||||
}
|
||||
|
||||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
|
||||
private static String closeOrderUrl = "https://api.mch.weixin.qq.com/pay/closeorder";
|
||||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
|
||||
private static String closeOrderUrl = "https://api.mch.weixin.qq.com/pay/closeorder";
|
||||
|
||||
/**
|
||||
* 关闭订单
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_trade_no 商户订单号
|
||||
* @return 回调信息
|
||||
*/
|
||||
public static Map<String, String> closeOrder(String appid, String mch_id, String paternerKey, String out_trade_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("out_trade_no", out_trade_no);
|
||||
return request(closeOrderUrl, params, paternerKey);
|
||||
}
|
||||
/**
|
||||
* 关闭订单
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_trade_no 商户订单号
|
||||
* @return 回调信息
|
||||
*/
|
||||
public static Map<String, String> closeOrder(String appid, String mch_id, String paternerKey, String out_trade_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("out_trade_no", out_trade_no);
|
||||
return request(closeOrderUrl, params, paternerKey);
|
||||
}
|
||||
|
||||
// 申请退款文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
|
||||
public static String refundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
|
||||
// 申请退款文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
|
||||
public static String refundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
|
||||
|
||||
|
||||
// 查询退款文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
|
||||
private static String refundQueryUrl = "https://api.mch.weixin.qq.com/pay/refundquery";
|
||||
// 查询退款文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
|
||||
private static String refundQueryUrl = "https://api.mch.weixin.qq.com/pay/refundquery";
|
||||
|
||||
private static Map<String, String> baseRefundQuery(Map<String, String> params, String appid, String mch_id, String paternerKey) {
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
return request(refundQueryUrl, params, paternerKey);
|
||||
}
|
||||
private static Map<String, String> baseRefundQuery(Map<String, String> params, String appid, String mch_id, String paternerKey) {
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
return request(refundQueryUrl, params, paternerKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据微信订单号查询退款
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param transaction_id 微信订单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByTransactionId(String appid, String mch_id, String paternerKey, String transaction_id) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("transaction_id", transaction_id);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
/**
|
||||
* 根据微信订单号查询退款
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param transaction_id 微信订单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByTransactionId(String appid, String mch_id, String paternerKey, String transaction_id) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("transaction_id", transaction_id);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户订单号查询退款
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_trade_no 商户订单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByOutTradeNo(String appid, String mch_id, String paternerKey, String out_trade_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("out_trade_no", out_trade_no);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
/**
|
||||
* 根据商户订单号查询退款
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_trade_no 商户订单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByOutTradeNo(String appid, String mch_id, String paternerKey, String out_trade_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("out_trade_no", out_trade_no);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据微信订单号查询退款
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_refund_no 商户退款单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByOutRefundNo(String appid, String mch_id, String paternerKey, String out_refund_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("out_refund_no", out_refund_no);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
/**
|
||||
* 根据微信订单号查询退款
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param out_refund_no 商户退款单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByOutRefundNo(String appid, String mch_id, String paternerKey, String out_refund_no) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("out_refund_no", out_refund_no);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据微信订单号查询退款
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param refund_id 微信退款单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByRefundId(String appid, String mch_id, String paternerKey, String refund_id) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("refund_id", refund_id);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
/**
|
||||
* 根据微信订单号查询退款
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 商户密钥
|
||||
* @param refund_id 微信退款单号
|
||||
* @return map
|
||||
*/
|
||||
public static Map<String, String> refundQueryByRefundId(String appid, String mch_id, String paternerKey, String refund_id) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("refund_id", refund_id);
|
||||
return baseRefundQuery(params, appid, mch_id, paternerKey);
|
||||
}
|
||||
|
||||
private static String downloadBillUrl = "https://api.mch.weixin.qq.com/pay/downloadbill";
|
||||
private static String downloadBillUrl = "https://api.mch.weixin.qq.com/pay/downloadbill";
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* ALL,返回当日所有订单信息,默认值
|
||||
* SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* REVOKED,已撤销的订单
|
||||
* </pre>
|
||||
*/
|
||||
public static enum BillType {
|
||||
ALL, SUCCESS, REFUND, REVOKED
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* ALL,返回当日所有订单信息,默认值
|
||||
* SUCCESS,返回当日成功支付的订单
|
||||
* REFUND,返回当日退款订单
|
||||
* REVOKED,已撤销的订单
|
||||
* </pre>
|
||||
*/
|
||||
public static enum BillType {
|
||||
ALL, SUCCESS, REFUND, REVOKED
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单
|
||||
* <pre>
|
||||
* 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID(企业号corpid即为此appId)
|
||||
* 商户号 mch_id 是 String(32) 1900000109 微信支付分配的商户号
|
||||
* 设备号 device_info 否 String(32) 013467007045764 微信支付分配的终端设备号
|
||||
* 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
|
||||
* 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
|
||||
* 对账单日期 bill_date 是 String(8) 20140603 下载对账单的日期,格式:20140603
|
||||
* 账单类型 bill_type 否 String(8)
|
||||
* </pre>
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 签名密匙
|
||||
* @param billDate 对账单日期
|
||||
* @return String
|
||||
*/
|
||||
public static String downloadBill(String appid, String mch_id, String paternerKey, String billDate) {
|
||||
return downloadBill(appid, mch_id, paternerKey, billDate, null);
|
||||
}
|
||||
/**
|
||||
* 下载对账单
|
||||
* <pre>
|
||||
* 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID(企业号corpid即为此appId)
|
||||
* 商户号 mch_id 是 String(32) 1900000109 微信支付分配的商户号
|
||||
* 设备号 device_info 否 String(32) 013467007045764 微信支付分配的终端设备号
|
||||
* 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
|
||||
* 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
|
||||
* 对账单日期 bill_date 是 String(8) 20140603 下载对账单的日期,格式:20140603
|
||||
* 账单类型 bill_type 否 String(8)
|
||||
* </pre>
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 签名密匙
|
||||
* @param billDate 对账单日期
|
||||
* @return String
|
||||
*/
|
||||
public static String downloadBill(String appid, String mch_id, String paternerKey, String billDate) {
|
||||
return downloadBill(appid, mch_id, paternerKey, billDate, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载对账单
|
||||
* <pre>
|
||||
* 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID(企业号corpid即为此appId)
|
||||
* 商户号 mch_id 是 String(32) 1900000109 微信支付分配的商户号
|
||||
* 设备号 device_info 否 String(32) 013467007045764 微信支付分配的终端设备号
|
||||
* 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
|
||||
* 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
|
||||
* 对账单日期 bill_date 是 String(8) 20140603 下载对账单的日期,格式:20140603
|
||||
* 账单类型 bill_type 否 String(8)
|
||||
* </pre>
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 签名密匙
|
||||
* @param billDate 对账单日期
|
||||
* @param billType 账单类型
|
||||
* @return String
|
||||
*/
|
||||
public static String downloadBill(String appid, String mch_id, String paternerKey, String billDate, BillType billType) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("nonce_str", System.currentTimeMillis() + "");
|
||||
params.put("bill_date", billDate);
|
||||
if (null != billType) {
|
||||
params.put("bill_type", billType.name());
|
||||
} else {
|
||||
params.put("bill_type", BillType.ALL.name());
|
||||
}
|
||||
String sign = PaymentKit.createSign(params, paternerKey);
|
||||
params.put("sign", sign);
|
||||
return HttpKit.post(downloadBillUrl, PaymentKit.toXml(params));
|
||||
}
|
||||
/**
|
||||
* 下载对账单
|
||||
* <pre>
|
||||
* 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID(企业号corpid即为此appId)
|
||||
* 商户号 mch_id 是 String(32) 1900000109 微信支付分配的商户号
|
||||
* 设备号 device_info 否 String(32) 013467007045764 微信支付分配的终端设备号
|
||||
* 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法
|
||||
* 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法
|
||||
* 对账单日期 bill_date 是 String(8) 20140603 下载对账单的日期,格式:20140603
|
||||
* 账单类型 bill_type 否 String(8)
|
||||
* </pre>
|
||||
*
|
||||
* @param appid 公众账号ID
|
||||
* @param mch_id 商户号
|
||||
* @param paternerKey 签名密匙
|
||||
* @param billDate 对账单日期
|
||||
* @param billType 账单类型
|
||||
* @return String
|
||||
*/
|
||||
public static String downloadBill(String appid, String mch_id, String paternerKey, String billDate, BillType billType) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("appid", appid);
|
||||
params.put("mch_id", mch_id);
|
||||
params.put("nonce_str", System.currentTimeMillis() + "");
|
||||
params.put("bill_date", billDate);
|
||||
if (null != billType) {
|
||||
params.put("bill_type", billType.name());
|
||||
} else {
|
||||
params.put("bill_type", BillType.ALL.name());
|
||||
}
|
||||
String sign = PaymentKit.createSign(params, paternerKey);
|
||||
params.put("sign", sign);
|
||||
return HttpKit.post(downloadBillUrl, PaymentKit.toXml(params));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -19,102 +19,111 @@ import java.util.TreeMap;
|
||||
**************************************************/
|
||||
public class PaymentKit {
|
||||
|
||||
/**
|
||||
* 组装签名的字段
|
||||
* @param params 参数
|
||||
* @param urlEncoder 是否urlEncoder
|
||||
* @return String
|
||||
*/
|
||||
public static String packageSign(Map<String, String> params, boolean urlEncoder) {
|
||||
// 先将参数以其参数名的字典序升序进行排序
|
||||
TreeMap<String, String> sortedParams = new TreeMap<String, String>(params);
|
||||
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Entry<String, String> param : sortedParams.entrySet()) {
|
||||
String value = param.getValue();
|
||||
if (Tools.isEmpty(value)) {
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(param.getKey()).append("=");
|
||||
if (urlEncoder) {
|
||||
try { value = urlEncode(value); } catch (UnsupportedEncodingException e) {}
|
||||
}
|
||||
sb.append(value);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* 组装签名的字段
|
||||
*
|
||||
* @param params 参数
|
||||
* @param urlEncoder 是否urlEncoder
|
||||
* @return String
|
||||
*/
|
||||
public static String packageSign(Map<String, String> params, boolean urlEncoder) {
|
||||
// 先将参数以其参数名的字典序升序进行排序
|
||||
TreeMap<String, String> sortedParams = new TreeMap<String, String>(params);
|
||||
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Entry<String, String> param : sortedParams.entrySet()) {
|
||||
String value = param.getValue();
|
||||
if (Tools.isEmpty(value)) {
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(param.getKey()).append("=");
|
||||
if (urlEncoder) {
|
||||
try {
|
||||
value = urlEncode(value);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
}
|
||||
}
|
||||
sb.append(value);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* urlEncode
|
||||
* @param src 微信参数
|
||||
* @return String
|
||||
* @throws UnsupportedEncodingException 编码错误
|
||||
*/
|
||||
public static String urlEncode(String src) throws UnsupportedEncodingException {
|
||||
return URLEncoder.encode(src, Charsets.UTF_8.name()).replace("+", "%20");
|
||||
}
|
||||
/**
|
||||
* urlEncode
|
||||
*
|
||||
* @param src 微信参数
|
||||
* @return String
|
||||
* @throws UnsupportedEncodingException 编码错误
|
||||
*/
|
||||
public static String urlEncode(String src) throws UnsupportedEncodingException {
|
||||
return URLEncoder.encode(src, Charsets.UTF_8.name()).replace("+", "%20");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
* @param params 参数
|
||||
* @param paternerKey 支付密钥
|
||||
* @return sign
|
||||
*/
|
||||
public static String createSign(Map<String, String> params, String paternerKey) {
|
||||
// 生成签名前先去除sign
|
||||
params.remove("sign");
|
||||
String stringA = packageSign(params, false);
|
||||
String stringSignTemp = stringA + "&key=" + paternerKey;
|
||||
return Tools.md5(stringSignTemp).toUpperCase();
|
||||
}
|
||||
/**
|
||||
* 生成签名
|
||||
*
|
||||
* @param params 参数
|
||||
* @param paternerKey 支付密钥
|
||||
* @return sign
|
||||
*/
|
||||
public static String createSign(Map<String, String> params, String paternerKey) {
|
||||
// 生成签名前先去除sign
|
||||
params.remove("sign");
|
||||
String stringA = packageSign(params, false);
|
||||
String stringSignTemp = stringA + "&key=" + paternerKey;
|
||||
return Tools.md5(stringSignTemp).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付异步通知时校验sign
|
||||
* @param params 参数
|
||||
* @param paternerKey 支付密钥
|
||||
* @return {boolean}
|
||||
*/
|
||||
public static boolean verifyNotify(Map<String, String> params, String paternerKey){
|
||||
String sign = params.get("sign");
|
||||
String localSign = PaymentKit.createSign(params, paternerKey);
|
||||
return sign.equals(localSign);
|
||||
}
|
||||
/**
|
||||
* 支付异步通知时校验sign
|
||||
*
|
||||
* @param params 参数
|
||||
* @param paternerKey 支付密钥
|
||||
* @return {boolean}
|
||||
*/
|
||||
public static boolean verifyNotify(Map<String, String> params, String paternerKey) {
|
||||
String sign = params.get("sign");
|
||||
String localSign = PaymentKit.createSign(params, paternerKey);
|
||||
return sign.equals(localSign);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信下单,map to xml
|
||||
* @param params 参数
|
||||
* @return String
|
||||
*/
|
||||
public static String toXml(Map<String, String> params) {
|
||||
StringBuilder xml = new StringBuilder();
|
||||
xml.append("<xml>");
|
||||
for (Entry<String, String> entry : params.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
// 略过空值
|
||||
if (Tools.isEmpty(value)) continue;
|
||||
xml.append("<").append(key).append(">");
|
||||
xml.append(entry.getValue());
|
||||
xml.append("</").append(key).append(">");
|
||||
}
|
||||
xml.append("</xml>");
|
||||
return xml.toString();
|
||||
}
|
||||
/**
|
||||
* 微信下单,map to xml
|
||||
*
|
||||
* @param params 参数
|
||||
* @return String
|
||||
*/
|
||||
public static String toXml(Map<String, String> params) {
|
||||
StringBuilder xml = new StringBuilder();
|
||||
xml.append("<xml>");
|
||||
for (Entry<String, String> entry : params.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
// 略过空值
|
||||
if (Tools.isEmpty(value)) continue;
|
||||
xml.append("<").append(key).append(">");
|
||||
xml.append(entry.getValue());
|
||||
xml.append("</").append(key).append(">");
|
||||
}
|
||||
xml.append("</xml>");
|
||||
return xml.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对支付的xml,没有嵌套节点的简单处理
|
||||
* @param xmlStr xml字符串
|
||||
* @return map集合
|
||||
*/
|
||||
public static Map<String, String> xmlToMap(String xmlStr) {
|
||||
XmlHelper xmlHelper = XmlHelper.of(xmlStr);
|
||||
return xmlHelper.toMap();
|
||||
}
|
||||
/**
|
||||
* 针对支付的xml,没有嵌套节点的简单处理
|
||||
*
|
||||
* @param xmlStr xml字符串
|
||||
* @return map集合
|
||||
*/
|
||||
public static Map<String, String> xmlToMap(String xmlStr) {
|
||||
XmlHelper xmlHelper = XmlHelper.of(xmlStr);
|
||||
return xmlHelper.toMap();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,22 +5,20 @@ import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author lnexin@aliyun.com
|
||||
* @Name RandomStringUtil
|
||||
* @Descr 生成随机字符串
|
||||
* @author lnexin@aliyun.com
|
||||
* @date 2015年10月15日下午2:36:05
|
||||
*/
|
||||
public class RandomStringUtil {
|
||||
/**
|
||||
* @param passLength
|
||||
* : 要生成多少长度的字符串
|
||||
* @param type
|
||||
* : 需要哪种类型
|
||||
* @param passLength : 要生成多少长度的字符串
|
||||
* @param type : 需要哪种类型
|
||||
* @return 根据传入的type来判定
|
||||
*/
|
||||
|
||||
|
||||
// 可以根据自己需求来删减下面的代码,不要要的类型可以删掉
|
||||
|
||||
|
||||
// type=0:纯数字(0-9)
|
||||
// type=1:全小写字母(a-z)
|
||||
// type=2:全大写字母(A-Z)
|
||||
@ -29,39 +27,38 @@ public class RandomStringUtil {
|
||||
// type=5:大写字母+小写字母
|
||||
// type=6:数字+大写字母+小写字母
|
||||
// type=7:固定长度33位:根据UUID拿到的随机字符串,去掉了四个"-"(相当于长度33位的小写字母加数字)
|
||||
|
||||
public static String getRandomCode(int passLength, int type) {
|
||||
StringBuffer buffer = null;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Random r = new Random();
|
||||
r.setSeed(new Date().getTime());
|
||||
switch (type) {
|
||||
case 0:
|
||||
buffer = new StringBuffer("123456789");
|
||||
break;
|
||||
case 1:
|
||||
buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
|
||||
break;
|
||||
case 2:
|
||||
buffer = new StringBuffer("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
break;
|
||||
case 3:
|
||||
buffer = new StringBuffer("0123456789abcdefghijklmnopqrstuvwxyz");
|
||||
break;
|
||||
case 4:
|
||||
buffer = new StringBuffer("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
break;
|
||||
case 5:
|
||||
buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
break;
|
||||
case 6:
|
||||
buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
sb.append(buffer.charAt(r.nextInt(buffer.length() - 10)));
|
||||
passLength -= 1;
|
||||
break;
|
||||
case 7:
|
||||
String s = UUID.randomUUID().toString();
|
||||
sb.append(s.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23) + s.substring(24));
|
||||
case 0:
|
||||
buffer = new StringBuffer("123456789");
|
||||
break;
|
||||
case 1:
|
||||
buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyz");
|
||||
break;
|
||||
case 2:
|
||||
buffer = new StringBuffer("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
break;
|
||||
case 3:
|
||||
buffer = new StringBuffer("0123456789abcdefghijklmnopqrstuvwxyz");
|
||||
break;
|
||||
case 4:
|
||||
buffer = new StringBuffer("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
break;
|
||||
case 5:
|
||||
buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
break;
|
||||
case 6:
|
||||
buffer = new StringBuffer("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
sb.append(buffer.charAt(r.nextInt(buffer.length() - 10)));
|
||||
passLength -= 1;
|
||||
break;
|
||||
case 7:
|
||||
String s = UUID.randomUUID().toString();
|
||||
sb.append(s.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23) + s.substring(24));
|
||||
}
|
||||
|
||||
if (type != 7) {
|
||||
|
@ -16,158 +16,169 @@ import java.util.regex.Pattern;
|
||||
**************************************************/
|
||||
public class Tools {
|
||||
|
||||
/**
|
||||
* 随机生成六位数验证码
|
||||
* @return
|
||||
*/
|
||||
public static int getRandomNum(){
|
||||
/**
|
||||
* 随机生成六位数验证码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int getRandomNum() {
|
||||
Random r = new Random();
|
||||
return r.nextInt(900000)+100000;//(Math.random()*(999999-100000)+100000)
|
||||
}
|
||||
return r.nextInt(900000) + 100000;//(Math.random()*(999999-100000)+100000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测字符串是否不为空(null,"","null")
|
||||
* @param s
|
||||
* @return 不为空则返回true,否则返回false
|
||||
*/
|
||||
public static boolean notEmpty(String s){
|
||||
return s!=null && !"".equals(s) && !"null".equals(s);
|
||||
}
|
||||
/**
|
||||
* 检测字符串是否不为空(null,"","null")
|
||||
*
|
||||
* @param s
|
||||
* @return 不为空则返回true,否则返回false
|
||||
*/
|
||||
public static boolean notEmpty(String s) {
|
||||
return s != null && !"".equals(s) && !"null".equals(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测字符串是否为空(null,"","null")
|
||||
* @param s
|
||||
* @return 为空则返回true,不否则返回false
|
||||
*/
|
||||
public static boolean isEmpty(String s){
|
||||
return s==null || "".equals(s) || "null".equals(s);
|
||||
}
|
||||
/**
|
||||
* 检测字符串是否为空(null,"","null")
|
||||
*
|
||||
* @param s
|
||||
* @return 为空则返回true,不否则返回false
|
||||
*/
|
||||
public static boolean isEmpty(String s) {
|
||||
return s == null || "".equals(s) || "null".equals(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转换为字符串数组
|
||||
* @param str 字符串
|
||||
* @param splitRegex 分隔符
|
||||
* @return
|
||||
*/
|
||||
public static String[] str2StrArray(String str,String splitRegex){
|
||||
if(isEmpty(str)){
|
||||
return null;
|
||||
}
|
||||
return str.split(splitRegex);
|
||||
}
|
||||
/**
|
||||
* 字符串转换为字符串数组
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param splitRegex 分隔符
|
||||
* @return
|
||||
*/
|
||||
public static String[] str2StrArray(String str, String splitRegex) {
|
||||
if (isEmpty(str)) {
|
||||
return null;
|
||||
}
|
||||
return str.split(splitRegex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用默认的分隔符(,)将字符串转换为字符串数组
|
||||
* @param str 字符串
|
||||
* @return
|
||||
*/
|
||||
public static String[] str2StrArray(String str){
|
||||
return str2StrArray(str,",\\s*");
|
||||
}
|
||||
/**
|
||||
* 用默认的分隔符(,)将字符串转换为字符串数组
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return
|
||||
*/
|
||||
public static String[] str2StrArray(String str) {
|
||||
return str2StrArray(str, ",\\s*");
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照yyyy-MM-dd HH:mm:ss的格式,日期转字符串
|
||||
* @param date
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String date2Str(Date date){
|
||||
return date2Str(date,"yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
/**
|
||||
* 按照yyyy-MM-dd HH:mm:ss的格式,日期转字符串
|
||||
*
|
||||
* @param date
|
||||
* @return yyyy-MM-dd HH:mm:ss
|
||||
*/
|
||||
public static String date2Str(Date date) {
|
||||
return date2Str(date, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照yyyy-MM-dd HH:mm:ss的格式,字符串转日期
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Date str2Date(String date){
|
||||
if(notEmpty(date)){
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
return sdf.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Date();
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 按照yyyy-MM-dd HH:mm:ss的格式,字符串转日期
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Date str2Date(String date) {
|
||||
if (notEmpty(date)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
return sdf.parse(date);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new Date();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照参数format的格式,日期转字符串
|
||||
* @param date
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String date2Str(Date date,String format){
|
||||
if(date!=null){
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
return sdf.format(date);
|
||||
}else{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 按照参数format的格式,日期转字符串
|
||||
*
|
||||
* @param date
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String date2Str(Date date, String format) {
|
||||
if (date != null) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
return sdf.format(date);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 把时间根据时、分、秒转换为时间段
|
||||
* @param StrDate
|
||||
*/
|
||||
public static String getTimes(String StrDate){
|
||||
String resultTimes = "";
|
||||
/**
|
||||
* 把时间根据时、分、秒转换为时间段
|
||||
*
|
||||
* @param StrDate
|
||||
*/
|
||||
public static String getTimes(String StrDate) {
|
||||
String resultTimes = "";
|
||||
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date now;
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date now;
|
||||
|
||||
try {
|
||||
now = new Date();
|
||||
Date date=df.parse(StrDate);
|
||||
long times = now.getTime()-date.getTime();
|
||||
long day = times/(24*60*60*1000);
|
||||
long hour = (times/(60*60*1000)-day*24);
|
||||
long min = ((times/(60*1000))-day*24*60-hour*60);
|
||||
long sec = (times/1000-day*24*60*60-hour*60*60-min*60);
|
||||
try {
|
||||
now = new Date();
|
||||
Date date = df.parse(StrDate);
|
||||
long times = now.getTime() - date.getTime();
|
||||
long day = times / (24 * 60 * 60 * 1000);
|
||||
long hour = (times / (60 * 60 * 1000) - day * 24);
|
||||
long min = ((times / (60 * 1000)) - day * 24 * 60 - hour * 60);
|
||||
long sec = (times / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
//sb.append("发表于:");
|
||||
if(hour>0 ){
|
||||
sb.append(hour+"小时前");
|
||||
} else if(min>0){
|
||||
sb.append(min+"分钟前");
|
||||
} else{
|
||||
sb.append(sec+"秒前");
|
||||
}
|
||||
StringBuffer sb = new StringBuffer();
|
||||
//sb.append("发表于:");
|
||||
if (hour > 0) {
|
||||
sb.append(hour + "小时前");
|
||||
} else if (min > 0) {
|
||||
sb.append(min + "分钟前");
|
||||
} else {
|
||||
sb.append(sec + "秒前");
|
||||
}
|
||||
|
||||
resultTimes = sb.toString();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
resultTimes = sb.toString();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return resultTimes;
|
||||
}
|
||||
return resultTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 验证邮箱
|
||||
*
|
||||
* @param email
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkEmail(String email){
|
||||
boolean flag = false;
|
||||
try{
|
||||
String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
|
||||
Pattern regex = Pattern.compile(check);
|
||||
Matcher matcher = regex.matcher(email);
|
||||
flag = matcher.matches();
|
||||
}catch(Exception e){
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
public static boolean checkEmail(String email) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
|
||||
Pattern regex = Pattern.compile(check);
|
||||
Matcher matcher = regex.matcher(email);
|
||||
flag = matcher.matches();
|
||||
} catch (Exception e) {
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证手机号码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkMobileNumber(String mobileNumber){
|
||||
public static boolean checkMobileNumber(String mobileNumber) {
|
||||
Pattern p = null;
|
||||
Matcher m = null;
|
||||
boolean b = false;
|
||||
@ -177,133 +188,136 @@ public class Tools {
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将驼峰转下划线
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static String camelToUnderline(String param){
|
||||
if (param==null||"".equals(param.trim())){
|
||||
return "";
|
||||
}
|
||||
int len=param.length();
|
||||
StringBuilder sb=new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c=param.charAt(i);
|
||||
if (Character.isUpperCase(c)){
|
||||
sb.append("_");
|
||||
sb.append(Character.toLowerCase(c));
|
||||
}else{
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* 将驼峰转下划线
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
public static String camelToUnderline(String param) {
|
||||
if (param == null || "".equals(param.trim())) {
|
||||
return "";
|
||||
}
|
||||
int len = param.length();
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
char c = param.charAt(i);
|
||||
if (Character.isUpperCase(c)) {
|
||||
sb.append("_");
|
||||
sb.append(Character.toLowerCase(c));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉下划线并将下划线后的首字母转为大写
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String transformStr(String str){
|
||||
//去掉数据库字段的下划线
|
||||
if(str.contains("_")) {
|
||||
String[] names = str.split("_");
|
||||
String firstPart = names[0];
|
||||
String otherPart = "";
|
||||
for (int i = 1; i < names.length; i++) {
|
||||
String word = names[i].replaceFirst(names[i].substring(0, 1), names[i].substring(0, 1).toUpperCase());
|
||||
otherPart += word;
|
||||
}
|
||||
str = firstPart + otherPart;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
/**
|
||||
* 去掉下划线并将下划线后的首字母转为大写
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String transformStr(String str) {
|
||||
//去掉数据库字段的下划线
|
||||
if (str.contains("_")) {
|
||||
String[] names = str.split("_");
|
||||
String firstPart = names[0];
|
||||
String otherPart = "";
|
||||
for (int i = 1; i < names.length; i++) {
|
||||
String word = names[i].replaceFirst(names[i].substring(0, 1), names[i].substring(0, 1).toUpperCase());
|
||||
otherPart += word;
|
||||
}
|
||||
str = firstPart + otherPart;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为map
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static List<Map<String,Object>> transformMap(List<Map<String,Object>> list){
|
||||
List<Map<String,Object>> resultMapList = new ArrayList<>();
|
||||
/**
|
||||
* 转换为map
|
||||
*
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static List<Map<String, Object>> transformMap(List<Map<String, Object>> list) {
|
||||
List<Map<String, Object>> resultMapList = new ArrayList<>();
|
||||
|
||||
for (Map<String, Object> map : list) {
|
||||
Map<String,Object> tempMap = new HashMap<>();
|
||||
for (String s : map.keySet()) {
|
||||
tempMap.put(transformStr(s),map.get(s));
|
||||
}
|
||||
resultMapList.add(tempMap);
|
||||
}
|
||||
return resultMapList;
|
||||
}
|
||||
for (Map<String, Object> map : list) {
|
||||
Map<String, Object> tempMap = new HashMap<>();
|
||||
for (String s : map.keySet()) {
|
||||
tempMap.put(transformStr(s), map.get(s));
|
||||
}
|
||||
resultMapList.add(tempMap);
|
||||
}
|
||||
return resultMapList;
|
||||
}
|
||||
|
||||
public static String clearHtml(String content,int p) {
|
||||
if(null==content) return "";
|
||||
if(0==p) return "";
|
||||
public static String clearHtml(String content, int p) {
|
||||
if (null == content) return "";
|
||||
if (0 == p) return "";
|
||||
|
||||
Pattern p_script;
|
||||
Matcher m_script;
|
||||
Pattern p_style;
|
||||
Matcher m_style;
|
||||
Pattern p_html;
|
||||
Matcher m_html;
|
||||
Pattern p_script;
|
||||
Matcher m_script;
|
||||
Pattern p_style;
|
||||
Matcher m_style;
|
||||
Pattern p_html;
|
||||
Matcher m_html;
|
||||
|
||||
try {
|
||||
String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
|
||||
//定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script> }
|
||||
String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
|
||||
//定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style> }
|
||||
String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
|
||||
try {
|
||||
String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
|
||||
//定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script> }
|
||||
String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
|
||||
//定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style> }
|
||||
String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
|
||||
|
||||
p_script = Pattern.compile(regEx_script,Pattern.CASE_INSENSITIVE);
|
||||
m_script = p_script.matcher(content);
|
||||
content = m_script.replaceAll(""); //过滤script标签
|
||||
p_style = Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE);
|
||||
m_style = p_style.matcher(content);
|
||||
content = m_style.replaceAll(""); //过滤style标签
|
||||
p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
|
||||
m_script = p_script.matcher(content);
|
||||
content = m_script.replaceAll(""); //过滤script标签
|
||||
p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
|
||||
m_style = p_style.matcher(content);
|
||||
content = m_style.replaceAll(""); //过滤style标签
|
||||
|
||||
p_html = Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);
|
||||
m_html = p_html.matcher(content);
|
||||
p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
|
||||
m_html = p_html.matcher(content);
|
||||
|
||||
content = m_html.replaceAll(""); //过滤html标签
|
||||
}catch(Exception e) {
|
||||
return "";
|
||||
}
|
||||
content = m_html.replaceAll(""); //过滤html标签
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if(content.length()>p){
|
||||
content = content.substring(0, p)+"...";
|
||||
}else{
|
||||
content = content + "...";
|
||||
}
|
||||
if (content.length() > p) {
|
||||
content = content.substring(0, p) + "...";
|
||||
} else {
|
||||
content = content + "...";
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
public static String md5(String str) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(str.getBytes());
|
||||
byte b[] = md.digest();
|
||||
public static String md5(String str) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(str.getBytes());
|
||||
byte b[] = md.digest();
|
||||
|
||||
int i;
|
||||
int i;
|
||||
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
for (int offset = 0; offset < b.length; offset++) {
|
||||
i = b[offset];
|
||||
if (i < 0)
|
||||
i += 256;
|
||||
if (i < 16)
|
||||
buf.append("0");
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
str = buf.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
for (int offset = 0; offset < b.length; offset++) {
|
||||
i = b[offset];
|
||||
if (i < 0)
|
||||
i += 256;
|
||||
if (i < 16)
|
||||
buf.append("0");
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
str = buf.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -15,37 +15,37 @@ public class WXPayConstants {
|
||||
public static final String DOMAIN_APIUS = "apius.mch.wechat.qq.com";
|
||||
|
||||
|
||||
public static final String FAIL = "FAIL";
|
||||
public static final String SUCCESS = "SUCCESS";
|
||||
public static final String FAIL = "FAIL";
|
||||
public static final String SUCCESS = "SUCCESS";
|
||||
public static final String HMACSHA256 = "HMAC-SHA256";
|
||||
public static final String MD5 = "MD5";
|
||||
|
||||
public static final String FIELD_SIGN = "sign";
|
||||
public static final String FIELD_SIGN_TYPE = "sign_type";
|
||||
|
||||
public static final String MICROPAY_URL_SUFFIX = "/pay/micropay";
|
||||
public static final String MICROPAY_URL_SUFFIX = "/pay/micropay";
|
||||
public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder";
|
||||
public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery";
|
||||
public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse";
|
||||
public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder";
|
||||
public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund";
|
||||
public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery";
|
||||
public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery";
|
||||
public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse";
|
||||
public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder";
|
||||
public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund";
|
||||
public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery";
|
||||
public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill";
|
||||
public static final String REPORT_URL_SUFFIX = "/payitil/report";
|
||||
public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl";
|
||||
public static final String REPORT_URL_SUFFIX = "/payitil/report";
|
||||
public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl";
|
||||
public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid";
|
||||
|
||||
// sandbox
|
||||
public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay";
|
||||
public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay";
|
||||
public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder";
|
||||
public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery";
|
||||
public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse";
|
||||
public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder";
|
||||
public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund";
|
||||
public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery";
|
||||
public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery";
|
||||
public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse";
|
||||
public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder";
|
||||
public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund";
|
||||
public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery";
|
||||
public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill";
|
||||
public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report";
|
||||
public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl";
|
||||
public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report";
|
||||
public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl";
|
||||
public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid";
|
||||
|
||||
}
|
||||
|
@ -43,282 +43,284 @@ import java.util.*;
|
||||
@Slf4j
|
||||
public class WXPayUtil {
|
||||
|
||||
/**
|
||||
* XML格式字符串转换为Map
|
||||
*
|
||||
* @param strXML XML字符串
|
||||
* @return XML数据转换后的Map
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Map<String, String> xmlToMap(String strXML) throws Exception {
|
||||
try {
|
||||
Map<String, String> data = new HashMap<String, String>();
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
InputStream 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());
|
||||
}
|
||||
}
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Exception ex) {
|
||||
// do nothing
|
||||
}
|
||||
return data;
|
||||
} catch (Exception ex) {
|
||||
WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
|
||||
throw ex;
|
||||
}
|
||||
/**
|
||||
* XML格式字符串转换为Map
|
||||
*
|
||||
* @param strXML XML字符串
|
||||
* @return XML数据转换后的Map
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Map<String, String> xmlToMap(String strXML) throws Exception {
|
||||
try {
|
||||
Map<String, String> data = new HashMap<String, String>();
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
InputStream 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());
|
||||
}
|
||||
}
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Exception ex) {
|
||||
// do nothing
|
||||
}
|
||||
return data;
|
||||
} catch (Exception ex) {
|
||||
WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Map转换为XML格式的字符串
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @return XML格式的字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String mapToXml(Map<String, String> data) throws Exception {
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
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) {
|
||||
}
|
||||
return output;
|
||||
}
|
||||
/**
|
||||
* 将Map转换为XML格式的字符串
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @return XML格式的字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String mapToXml(Map<String, String> data) throws Exception {
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
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) {
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成带有 sign 的 XML 格式字符串
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @return 含有sign字段的XML
|
||||
*/
|
||||
public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
|
||||
return generateSignedXml(data, key, WXPayConstants.SignType.MD5);
|
||||
}
|
||||
/**
|
||||
* 生成带有 sign 的 XML 格式字符串
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @return 含有sign字段的XML
|
||||
*/
|
||||
public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
|
||||
return generateSignedXml(data, key, WXPayConstants.SignType.MD5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成带有 sign 的 XML 格式字符串
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @param signType 签名类型
|
||||
* @return 含有sign字段的XML
|
||||
*/
|
||||
public static String generateSignedXml(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
|
||||
String sign = generateSignature(data, key, signType);
|
||||
data.put(WXPayConstants.FIELD_SIGN, sign);
|
||||
return mapToXml(data);
|
||||
}
|
||||
/**
|
||||
* 生成带有 sign 的 XML 格式字符串
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @param signType 签名类型
|
||||
* @return 含有sign字段的XML
|
||||
*/
|
||||
public static String generateSignedXml(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
|
||||
String sign = generateSignature(data, key, signType);
|
||||
data.put(WXPayConstants.FIELD_SIGN, sign);
|
||||
return mapToXml(data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断签名是否正确
|
||||
*
|
||||
* @param xmlStr XML格式数据
|
||||
* @param key API密钥
|
||||
* @return 签名是否正确
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
|
||||
Map<String, String> data = xmlToMap(xmlStr);
|
||||
if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
|
||||
return false;
|
||||
}
|
||||
String sign = data.get(WXPayConstants.FIELD_SIGN);
|
||||
return generateSignature(data, key).equals(sign);
|
||||
}
|
||||
/**
|
||||
* 判断签名是否正确
|
||||
*
|
||||
* @param xmlStr XML格式数据
|
||||
* @param key API密钥
|
||||
* @return 签名是否正确
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
|
||||
Map<String, String> data = xmlToMap(xmlStr);
|
||||
if (!data.containsKey(WXPayConstants.FIELD_SIGN)) {
|
||||
return false;
|
||||
}
|
||||
String sign = data.get(WXPayConstants.FIELD_SIGN);
|
||||
return generateSignature(data, key).equals(sign);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @return 签名是否正确
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
|
||||
return isSignatureValid(data, key, WXPayConstants.SignType.MD5);
|
||||
}
|
||||
/**
|
||||
* 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @return 签名是否正确
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
|
||||
return isSignatureValid(data, key, WXPayConstants.SignType.MD5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断签名是否正确,必须包含sign字段,否则返回false。
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @param signType 签名方式
|
||||
* @return 签名是否正确
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isSignatureValid(Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
|
||||
if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
|
||||
return false;
|
||||
}
|
||||
String sign = data.get(WXPayConstants.FIELD_SIGN);
|
||||
return generateSignature(data, key, signType).equals(sign);
|
||||
}
|
||||
/**
|
||||
* 判断签名是否正确,必须包含sign字段,否则返回false。
|
||||
*
|
||||
* @param data Map类型数据
|
||||
* @param key API密钥
|
||||
* @param signType 签名方式
|
||||
* @return 签名是否正确
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isSignatureValid(Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
|
||||
if (!data.containsKey(WXPayConstants.FIELD_SIGN)) {
|
||||
return false;
|
||||
}
|
||||
String sign = data.get(WXPayConstants.FIELD_SIGN);
|
||||
return generateSignature(data, key, signType).equals(sign);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名
|
||||
*
|
||||
* @param data 待签名数据
|
||||
* @param key API密钥
|
||||
* @return 签名
|
||||
*/
|
||||
public static String generateSignature(final Map<String, String> data, String key) throws Exception {
|
||||
return generateSignature(data, key, WXPayConstants.SignType.MD5);
|
||||
}
|
||||
/**
|
||||
* 生成签名
|
||||
*
|
||||
* @param data 待签名数据
|
||||
* @param key API密钥
|
||||
* @return 签名
|
||||
*/
|
||||
public static String generateSignature(final Map<String, String> data, String key) throws Exception {
|
||||
return generateSignature(data, key, WXPayConstants.SignType.MD5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
|
||||
*
|
||||
* @param data 待签名数据
|
||||
* @param key API密钥
|
||||
* @param signType 签名方式
|
||||
* @return 签名
|
||||
*/
|
||||
public static String generateSignature(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
|
||||
Set<String> keySet = data.keySet();
|
||||
String[] keyArray = keySet.toArray(new String[0]);
|
||||
Arrays.sort(keyArray);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String k : keyArray) {
|
||||
if (k.equals(WXPayConstants.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 (WXPayConstants.SignType.MD5.equals(signType)) {
|
||||
return MD5(sb.toString()).toUpperCase();
|
||||
}
|
||||
else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {
|
||||
return HMACSHA256(sb.toString(), key);
|
||||
}
|
||||
else {
|
||||
throw new Exception(String.format("Invalid sign_type: %s", signType));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
|
||||
*
|
||||
* @param data 待签名数据
|
||||
* @param key API密钥
|
||||
* @param signType 签名方式
|
||||
* @return 签名
|
||||
*/
|
||||
public static String generateSignature(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
|
||||
Set<String> keySet = data.keySet();
|
||||
String[] keyArray = keySet.toArray(new String[0]);
|
||||
Arrays.sort(keyArray);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String k : keyArray) {
|
||||
if (k.equals(WXPayConstants.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 (WXPayConstants.SignType.MD5.equals(signType)) {
|
||||
return MD5(sb.toString()).toUpperCase();
|
||||
} else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {
|
||||
return HMACSHA256(sb.toString(), key);
|
||||
} else {
|
||||
throw new Exception(String.format("Invalid sign_type: %s", signType));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取随机字符串 Nonce Str
|
||||
*
|
||||
* @return String 随机字符串
|
||||
*/
|
||||
public static String generateNonceStr() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
|
||||
}
|
||||
/**
|
||||
* 获取随机字符串 Nonce Str
|
||||
*
|
||||
* @return String 随机字符串
|
||||
*/
|
||||
public static String generateNonceStr() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成 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();
|
||||
}
|
||||
/**
|
||||
* 生成 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();
|
||||
}
|
||||
/**
|
||||
* 生成 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 Logger getLogger() {
|
||||
Logger logger = LoggerFactory.getLogger("wxpay java sdk");
|
||||
return logger;
|
||||
}
|
||||
/**
|
||||
* 日志
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Logger getLogger() {
|
||||
Logger logger = LoggerFactory.getLogger("wxpay java sdk");
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间戳,单位秒
|
||||
* @return
|
||||
*/
|
||||
public static long getCurrentTimestamp() {
|
||||
return System.currentTimeMillis()/1000;
|
||||
}
|
||||
/**
|
||||
* 获取当前时间戳,单位秒
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static long getCurrentTimestamp() {
|
||||
return System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间戳,单位毫秒
|
||||
* @return
|
||||
*/
|
||||
public static long getCurrentTimestampMs() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
/**
|
||||
* 获取当前时间戳,单位毫秒
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static long getCurrentTimestampMs() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 uuid, 即用来标识一笔单,也用做 nonce_str
|
||||
* @return
|
||||
*/
|
||||
public static String generateUUID() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
|
||||
}
|
||||
/**
|
||||
* 生成 uuid, 即用来标识一笔单,也用做 nonce_str
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String generateUUID() {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请退款
|
||||
*/
|
||||
public static String doRefund(String url, String data,String cert_url,String mch_id) throws Exception {
|
||||
public static String doRefund(String url, String data, String cert_url, String mch_id) throws Exception {
|
||||
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||
File file = ResourceUtils.getFile(cert_url);
|
||||
// FileInputStream is = new FileInputStream(file);
|
||||
@ -327,13 +329,13 @@ public class WXPayUtil {
|
||||
}
|
||||
// Trust own CA and all self-signed certs
|
||||
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(
|
||||
keyStore,
|
||||
mch_id.toCharArray())
|
||||
keyStore,
|
||||
mch_id.toCharArray())
|
||||
.build();
|
||||
// Allow TLSv1 protocol only
|
||||
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
|
||||
sslcontext,
|
||||
// new String[]{"TLSv1"},
|
||||
// new String[]{"TLSv1"},
|
||||
null,
|
||||
null,
|
||||
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
|
||||
|
@ -40,23 +40,24 @@ public class WechatUtil {
|
||||
private static String secret;
|
||||
|
||||
@Value("${weixin.appid}")
|
||||
public void setAppId(String appId){
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
@Value("${weixin.secret}")
|
||||
public void setSecret(String secret){
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小程序codeid换取openid
|
||||
*
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public static JSONObject getOpenId(String code) {
|
||||
String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+ appId +"&secret=" +
|
||||
secret +"&js_code="+code+"&grant_type=authorization_code";
|
||||
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" +
|
||||
secret + "&js_code=" + code + "&grant_type=authorization_code";
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
String line;
|
||||
@ -110,12 +111,13 @@ public class WechatUtil {
|
||||
|
||||
/**
|
||||
* 获取小程序token和openid
|
||||
*
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public static JSONObject getAccessTokenOrOpenid(String code) {
|
||||
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
|
||||
"appid="+ appId +"&secret="+ secret +"&code="+code+"&grant_type=authorization_code";
|
||||
"appid=" + appId + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
String line;
|
||||
@ -169,10 +171,11 @@ public class WechatUtil {
|
||||
|
||||
/**
|
||||
* 获取小程序unionId
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getUnionId(String accessToken,String openid) {
|
||||
String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openid;
|
||||
public static String getUnionId(String accessToken, String openid) {
|
||||
String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid;
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
String line;
|
||||
|
@ -27,6 +27,7 @@ import java.util.Map;
|
||||
* 文档地址:
|
||||
* http://www.w3school.com.cn/xpath/index.asp
|
||||
* </pre>
|
||||
*
|
||||
* @author majker
|
||||
*/
|
||||
public class XmlHelper {
|
||||
@ -76,6 +77,7 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取String
|
||||
*
|
||||
* @param expression 路径
|
||||
* @return String
|
||||
*/
|
||||
@ -85,6 +87,7 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取Boolean
|
||||
*
|
||||
* @param expression 路径
|
||||
* @return String
|
||||
*/
|
||||
@ -94,6 +97,7 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取Number
|
||||
*
|
||||
* @param expression 路径
|
||||
* @return {Number}
|
||||
*/
|
||||
@ -103,6 +107,7 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取某个节点
|
||||
*
|
||||
* @param expression 路径
|
||||
* @return {Node}
|
||||
*/
|
||||
@ -112,6 +117,7 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取子节点
|
||||
*
|
||||
* @param expression 路径
|
||||
* @return NodeList
|
||||
*/
|
||||
@ -122,7 +128,8 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取String
|
||||
* @param node 节点
|
||||
*
|
||||
* @param node 节点
|
||||
* @param expression 相对于node的路径
|
||||
* @return String
|
||||
*/
|
||||
@ -132,7 +139,8 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @param node 节点
|
||||
*
|
||||
* @param node 节点
|
||||
* @param expression 相对于node的路径
|
||||
* @return String
|
||||
*/
|
||||
@ -142,7 +150,8 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @param node 节点
|
||||
*
|
||||
* @param node 节点
|
||||
* @param expression 相对于node的路径
|
||||
* @return {Number}
|
||||
*/
|
||||
@ -152,7 +161,8 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取某个节点
|
||||
* @param node 节点
|
||||
*
|
||||
* @param node 节点
|
||||
* @param expression 路径
|
||||
* @return {Node}
|
||||
*/
|
||||
@ -162,7 +172,8 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 获取子节点
|
||||
* @param node 节点
|
||||
*
|
||||
* @param node 节点
|
||||
* @param expression 相对于node的路径
|
||||
* @return NodeList
|
||||
*/
|
||||
@ -172,6 +183,7 @@ public class XmlHelper {
|
||||
|
||||
/**
|
||||
* 针对没有嵌套节点的简单处理
|
||||
*
|
||||
* @return map集合
|
||||
*/
|
||||
public Map<String, String> toMap() {
|
||||
@ -189,12 +201,12 @@ public class XmlHelper {
|
||||
return params;
|
||||
}
|
||||
|
||||
private static DocumentBuilderFactory getDocumentBuilderFactory(){
|
||||
private static DocumentBuilderFactory getDocumentBuilderFactory() {
|
||||
return XmlHelperHolder.documentBuilderFactory;
|
||||
}
|
||||
|
||||
private static XPathFactory getXPathFactory() {
|
||||
return XmlHelperHolder.xPathFactory;
|
||||
return XmlHelperHolder.xPathFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user