微信小程序支付
获取微信参数
支付必须参数
字段名 | 变量名 | 描述 |
---|---|---|
小程序ID | appid | 微信分配的小程序id |
商户号 | mch_id | 微信支付分配的商户号 |
商户秘钥 | paterner_key | 微信支付的秘钥 |
随机字符串 | nonce_str | 随机字符串,长度要求在32位以内。 |
签名 | sign | 通过签名算法计算得出的签名值, |
商品描述 | body | 商品简单描述, |
商户订单号 | out_trade_no | 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_- |
标价金额 | total_fee | 订单总金额,单位为分 |
终端IP | spbill_create_ip | 支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP |
通知地址 | notify_url | 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数,(微信支付完成后调用接口) |
交易类型 | trade_type | JSAPI–JSAPI支付(或小程序支付)、NATIVE–Native支付、APP–app支付,MWEB–H5支付 |
用户标识 | openid | 微信小程序登录后的唯一标识 openid |
获取方式:
小程序ID:
商户号:
商户秘钥:
随机字符串:
nonce_str:WXPayUtil中的generateNonceStr()即可,就是生成UUID的方法;
签名:
sign:用WXPayUtil中的generateSignature(finalMap<String, String> data, String key)方法,data是将除了sign外,其他10个参数放到map中,key是四大配置参数中的API秘钥(paternerKey)
商品描述:
body:所支付的名称
商户订单号:
out_trade_no: 自己后台生成的订单号,只要保证唯一就好
标价金额:
total_fee:订单总金额,单位为分
终端IP:
spbill_create_ip: IP地址
通知地址:
notify_url: 微信支付成功后,微信那边携带参数,请求这个地址,作为业务处理,地址需要公网可以访问
交易类型:
trade_type:JSAPI–JSAPI支付(或小程序支付)、NATIVE–Native支付、APP–app支付,MWEB–H5支付
用户标识:
openid:微信小程序登录后的唯一标识
编码实现
1.maven导入依赖
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
2.导入官方工具类
3.编写Controller
1.预下单:
1.1 controller层
/**
* 预下单
* @param wxPayDto
* @param request
* @return
*/
@PostMapping("/wxPay")
public AjaxResult wxPay(WxPayDto wxPayDto, HttpServletRequest request){
// 传入的值为 前台接收的封装类和IP地址
return AjaxResult.success(wxPayService.wxPay(wxPayDto, IpUtils.getIpAddr(request)));
}
1.2 Service 层(注释都在里面。。写的很详细。一步一步看我操作即可)
@Override
public Map<String,String> wxPay(WxPayDto wxPayDto,String ip) {
//新建一个返回的map
Map<String,String> result = new HashMap<>();
//首先redis 中获取需要用到的参数
Object o = redisUtil.get(RedisConstants.WX_PAY_CONFIG);
//new 一个微信参数map
Map<String,Object> wxPayConfig = new HashMap<>();
if(o == null){
//判断redis中的值是否为空,如果为空的话,就去数据库中查询,然后在放入redis中
QueryWrapper<AppConfigEntity> wrapper = new QueryWrapper<>();
wrapper.select("wx_appid","mch_id","paterner_key");
// 查询所需要的参数
AppConfigEntity appConfigEntity = appConfigMapper.selectOne(wrapper);
if(appConfigEntity == null){
throw new CustomException("参数有误,请联系管理员!",500);
}
//放入map中
wxPayConfig.put("wx_appid",appConfigEntity.getWxAppid());
wxPayConfig.put("mch_id",appConfigEntity.getMchId());
wxPayConfig.put("paternerKey",appConfigEntity.getPaternerKey());
//将map转换为json字符串,并放入到redis中
redisUtil.set(RedisConstants.WX_PAY_CONFIG,GsonUtil.toJson(wxPayConfig));
}else{
// redis中不为空,则将数据转换为map类型的。
wxPayConfig = GsonUtil.toMap(o.toString());
}
// 通过订单ID获取用户ID
OrderEntity orderEntity = orderMapper.selectById(wxPayDto.getOrderId());
if(orderEntity == null){
throw new CustomException("订单异常,请重新下单!",500);
}
// 通过用户ID获取openid(这里需要在小程序登录哪里获取openid),我这里在数据库中,所以通过id来查询出来openid。
UserEntity userEntity = userMapper.selectById(orderEntity.getUserId());
try {
//拼接参数
Map<String,String> param = new HashMap<>();
param.put("appid",wxPayConfig.get("wx_appid").toString());
param.put("body",wxPayDto.getName());
param.put("mch_id",wxPayConfig.get("mch_id").toString());
param.put("nonce_str", WXPayUtil.generateNonceStr());
// 回调接口。此路径为微信服务器调用支付结果通知路径 也就是说,用户支付完成之后,微信服务器会调用此接口,路径必须为公网路径,也就是已经部署到服务器上,我这里调试使用的