更新sql和代码规范修改

This commit is contained in:
moxiangrong
2024-02-18 15:26:45 +08:00
parent 6f5e6e4662
commit c132b68745
1293 changed files with 43935 additions and 18456 deletions

View File

@ -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);
}
/**
* 商户配置
*

View File

@ -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;
/**
* 处理支付回调消息的处理器接口
*

View File

@ -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", "失败");
}
}

View File

@ -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代表OKfalse代表不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;
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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(), ));
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -6,9 +6,9 @@ import lombok.*;
import javax.validation.constraints.*;
/**
* 支付服务商配置 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
* 支付服务商配置 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class MerchantDetailsBaseVO {

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -11,6 +11,7 @@ public interface PayClient {
/**
* 获取支付信息
*
* @return 支付信息
*/
Map<String, String> payment(PayParam param) throws Exception;

View File

@ -7,6 +7,7 @@ public interface PayClientFactory {
/**
* 获取支付客户端
*
* @param payType 支付类型
* @return 支付客户端
*/

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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初始化成功");
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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 {

View File

@ -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));
}
}

View File

@ -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();
}
}

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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";
}

View File

@ -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

View File

@ -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;

View File

@ -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;
}
/**