pom依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
配置application.properties
server.port=8080
wechat.pay.appId=应用id
wechat.pay.mchId=商户id
wechat.pay.mchKey=商户密钥
wechat.pay.orderUrl=https://api.mch.weixin.qq.com/pay/unifiedorder
wechat.pay.notifyUrl=http://j9kx2p.natappfree.cc/unifidenty
wechat.pay.queryUrl=https://api.mch.weixin.qq.com/pay/orderquery
config.WechantPayConfig
package com.kgc.sbt.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author mjz
* @description:
* @date 2022/1/4 14:24
* @classname WechatPayConfig
*/
@Component
@Data
@ConfigurationProperties(prefix = "wechat.pay")
public class WechatPayConfig {
/**
* @description: 应用id
* @author mjz
* @explain:
*/
private String appId;
/**
* @description:商户id
* @author mjz
* @explain:
*/
private String mchId;
/**
* @description:密钥
* @author mjz
* @explain:
*/
private String mchKey;
/**
* @description:
* @author mjz
* @explain:
*/
private String orderUrl;
/**
* @description:
* @author mjz
* @explain:
*/
private String notifyUrl;
/**
* @description:
* @author mjz
* @explain:
*/
private String queryUrl;
}
constant.CommonConstant
package com.kgc.sbt.constant;
/**
* @author mjz
* @description:
* @date 2021/12/20 19:26
* @classname CommonConstant
*/
public class CommonConstant {
//统一
public static final String UNIFY_RETURN_SUCCESS_CODE="0000";
public static final String UNIFY_RETURN_SUCCESS_MSG="success";
public static final String UNIFY_RETURN_FAIL_CODE="0001";
public static final String UNIFY_RETURN_FAIL_MSG="FAIL";
}
controller
@RestController
@Slf4j
public class WechatPayController {
@Autowired(required = false)
private WechatPayService wechatPayService;
/**
* @description: 统一下单
* @author mjz
* @explain:请求微信官方,进行统一下单,拿到付款的url地址
*/
@PostMapping("/unifiedOrder")
public RequestResult<Map<String, String>> wechatPayUnifiedOrder(@RequestParam String body, @RequestParam Integer totalFee) throws Exception {
//生成到微信官方统一下单的请求xml参数字符串
String unifiedOrderXml = wechatPayService.wechatPayUnifedOrderParamsXml(body, totalFee);
log.info("------ 1、请求微信统一下单参数xml:{} ------", unifiedOrderXml);
//发送请求到微信官方,统一下单
Map<String, String> unifiedOrderReturnMap = wechatPayService.wechatPayUnifedOrder(unifiedOrderXml);
//
Map<String, String> unifiedOrderResultMap = new HashMap<>();
//解析返回结果,获取支付链接
if (WechatPayConstant.WECHAT_PAY_RETURN_CODE_SUCCESS.equals(unifiedOrderReturnMap.get("return_code"))
&& WechatPayConstant.WECHAT_PAY_RETURN_CODE_SUCCESS.equals(unifiedOrderReturnMap.get("result_code"))) {
//支付成功返回
//交易类型
unifiedOrderResultMap.put("trade_type", unifiedOrderReturnMap.get("trade_type"));
unifiedOrderResultMap.put("prepay_id", unifiedOrderReturnMap.get("prepay_id"));
unifiedOrderResultMap.put("code_url", unifiedOrderReturnMap.get("code_url"));
return ResultBulid.success(unifiedOrderResultMap);
}
return ResultBulid.fail(unifiedOrderReturnMap.get("return_code"), unifiedOrderReturnMap.get("result_code"));
}
service
/**
* @author mjz
* @description: 微信支付业务接口
* @explain:
*/
public interface WechatPayService {
/**
* @description: 生成统一下单接口参数
* @author mjz
* @explain:
*/
String wechatPayUnifedOrderParamsXml(String body, Integer totalFee) throws Exception;
/**
* @description:发送请求
* @author mjz
* @explain:
*/
Map<String, String> wechatPayUnifedOrder(String unifedOrderXml) throws Exception;
service.impl
@Service
public class WechatPayServiceImpl implements WechatPayService {
@Autowired
private WechatPayConfig wechatPayConfig;
@Override
public String wechatPayUnifedOrderParamsXml(String body, Integer totalFee) throws Exception {
//要求所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序)
Map<String, String> paramsMap = new TreeMap<>();
//应用id
paramsMap.put("appid", wechatPayConfig.getAppId());
//商户id
paramsMap.put("mch_id", wechatPayConfig.getMchId());
//自定义参数,可以为终端设备号
paramsMap.put("device_info", "WEB");
//随机字符串,长度要求在32位以内
paramsMap.put("nonce_str", WechatPayUtil.generateNonceStrUseRandom());
//商品简单描述,该字段请按照规范传递
paramsMap.put("body", body);
//商户系统内部订单号,要求32个字符内(最少6个字符),只能是数字、大小写字母_-|*且在同一个商户号下唯一。
paramsMap.put("out_trade_no", WechatPayUtil.generateOutTradeUseUUID());
//订单总金额,单位为分
paramsMap.put("total_fee", totalFee.toString());
//终端ip,支持IPV4和IPV6两种格式的IP地址。用户的客户端IP
paramsMap.put("spbill_create_ip", "192.168.1.64");
//通知回调地址,body 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
paramsMap.put("notify_url", wechatPayConfig.getNotifyUrl());
//交易类型
paramsMap.put("trade_type", WechatPayConstant.WECHAT_PAY_TRADE_TYPE_NATIVE);
//商品ID,******trade_type=NATIVE时,此参数必传。*****
paramsMap.put("product_id", WechatPayUtil.generateNonceStrUseUUID(10));
//签名,使用上面所有的参数进行签名,在参数确定后,进行签名操作,自己不参与
//需要传给微信官方,进行微信校验,防止接口交互异常
paramsMap.put("sign", WechatPayUtil.generateSignature(paramsMap, wechatPayConfig.getMchKey()));
return WechatPayUtil.mapToXml(paramsMap);
}
@Override
public Map<String, String> wechatPayUnifedOrder(String unifedOrderXml) throws Exception {
//发送post请求
String unifiedOrderReturnXml = HttpClient4Util.getResponse4PostByString(wechatPayConfig.getOrderUrl(), unifedOrderXml, WechatPayConstant.WECHAT_PAY_ENCODING_UTF8);
//将微信统一下单返回
return WechatPayUtil.xmlToMap(unifiedOrderReturnXml);
}