微信小程序支付

开发工具:idea,hbuildx,微信开发工具
微信小程序官方图片
在这里插入图片描述

实现支付操作思路及代码
一、登录
1.uni.login()方法获取用户凭证code
2.uni.getUserProfile()方法返回用的昵称,头像等信息,把用户的code,昵称,头像请求后端接口
3.,后端接口用code,appid,secret等封装成map请求微信获取openid的微信api获取用户的openid
4.查询数据库是否存在该openid,没有的话添加进去,然后根据用户ID生成token,把token和expire返回给小程序,存到storage中,小程序每次请求后端接口都要把token放到请求的header里面

//小程序代码

//login方法获取code,code5分钟有效
uni.login({
					provider:'weixin',
					success:function(res){
						let code = res.code;
						that.code = code;
						console.log("code=>>>"+code)
					}
				}),

//获取微信用户信息
uni.getUserProfile({
					desc:"获取登录用户的信息",
					success(res){
						console.log(res)
						let username = res.userInfo.nickName;
						let photo = res.userInfo.avatarUrl;
						console.log("username====>"+username);
						console.log("photo====>"+photo);
						that.username = username;
						that.photo =photo;
						//请求后台商户系统,返回用户token,存入storage,以后每次请求商户系统都要带有token
						uni.request({
							url:that.url.wxLogin,
							method:"POST",
							data:{
								"nickname":that.username,
								"photo":that.photo,
								"code":that.code,
							},
							success(res){
								let token = res.data.token;
								let expire = res.data.expire;
								console.log("token====>"+token)
								console.log("expire====>"+expire)
								uni.setStorageSync("token",token);
								uni.setStorageSync("expire",expire);
								uni.switchTab({
									url:"../index/index",
								})
							}
						})
					}
				})

//后端代码


@PostMapping("/login")
    @ApiOperation("登录")
    public R login(@RequestBody WxLoginForm form){
        //表单校验
        ValidatorUtils.validateEntity(form);
        Map<String, Object> map = new HashMap<>();
        map.put("appid", wxConfiguration.getAppId());
        map.put("secret", wxConfiguration.getAppSecret());
        map.put("js_code", form.getCode());
        map.put("grant_type", "authorization_code");
        String response = HttpUtil.post(wxConfiguration.getLoginUrl(), map);
        JSONObject jsonObject = JSONUtil.parseObj(response);
        String openid = jsonObject.getStr("openid");
        if (openid == null || StringUtils.isBlank(openid)) {
            return R.error("微信登录凭证不正确!");
        }
        LambdaQueryWrapper<UserEntity> ew = new LambdaQueryWrapper<>();
        ew.eq(UserEntity::getOpenId, openid);
        UserEntity userEntity = userService.getOne(ew);
        String token;
        if (userEntity == null) {
            UserEntity user = new UserEntity();
            user.setNickname(form.getNickname());
            user.setOpenId(openid);
            user.setPhoto(form.getPhoto());
            user.setCreateTime(new Date());
            user.setType(EnumUtil.WX.getCode());
            userService.save(user);
            token = jwtUtils.generateToken(user.getUserId());
        }else{
            token = jwtUtils.generateToken(userEntity.getUserId());
        }
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("expire", jwtUtils.getExpire());
        return R.ok(result);
    }

二、支付
1.小程序带着订单id和用户token请求后端接口,后端先验证用户和订单的有效性,验证通过后封装参数,调用微信统一下单api获得支付订单的id

2.获得支付订单id后封装数据发送给小程序,小程序把数据发送给微信平台验证支付的正确性,如果正确就返回支付的二维码,支付成功之后调用success()函数,在success函数中可以调用后端接口让主动查询微信支付结果api,看该订单是否支付成功,支付订单支付成功的话就修改商品订单的状态为已付款

小程序代码


pay(id){
				let that = this;
				uni.request({
					url:that.url.mircoPayOrder,
					method:"POST",
					data:{
						"orderId":id,
					},
					header:{
						"token":uni.getStorageSync("token"),
					},
					success(res){
						console.log("pay-res=====>"+res.data);
						let timeStamp = res.data.timeStamp;
						let nonceStr = res.data.nonceStr;
						let paySign = res.data.paySign;
						let pk = res.data.package;
						console.log("package:"+pk);
						console.log("nonceStr:"+nonceStr);
						console.log("paySign:"+paySign);
						console.log("timeStamp:"+timeStamp);
						//小程序向微信支付平台发送请求验证支付的正确性,如果正确会返回支付的页面(支付二维码),支付成功后进入success函数
						uni.requestPayment({
							"timeStamp":timeStamp,
							"nonceStr":nonceStr,
							"paySign":paySign,
							"package":pk,
							"signType":"MD5",
							success(res){
								uni.showToast({
									title:"支付成功"
								})
								//用户支付成功之后,小程序向后端商户系统发送请求,让商户系统主动查询支付订单结果
								uni.request({
									url:that.url.activeQueryOrder,
									method:"POST",
									header:{
										"token":uni.getStorageSync("token")
									},
									data:{
										"orderId":id
									},
									//成功之后刷新当前页面
									success(res){
										//getCurrentPages()方法获取所有页面
										let pages = getCurrentPages()
										//当前页面是最后一个
										let page = pages[pages.length - 1]
										page.onShow()
									},
									fail(res){
										console.log("修改订单状态失败=====>"+id)
									}
								})
							},
							fail(res){
								uni.showToast({
									title:"支付失败"
								})
							}
						})
					},
				})
			}

后端代码


@Login
    @PostMapping("/microAppPayOrder")
    @ApiOperation("小程序支付")
    public R microAppPayOrder(@RequestBody PayOrderForm form, @RequestHeader HashMap<String, Object> map) {
        ValidatorUtils.validateEntity(form);
        String token = map.get("token").toString();
        Integer userId = Integer.parseInt(jwtUtils.getClaimByToken(token).getSubject());
        LambdaQueryWrapper<UserEntity> uew = new LambdaQueryWrapper<>();
        uew.eq(UserEntity::getUserId, userId);
        UserEntity user = userService.getOne(uew);
        if (user == null) {
            return R.error("用户不存在!");
        }
        Integer orderId = form.getOrderId();
        LambdaQueryWrapper<Order> oew = new LambdaQueryWrapper<>();
        oew.eq(Order::getId, orderId)
                .eq(Order::getUserId,userId);
        Order order = orderService.getOne(oew);
        if (order == null) {
            return R.error("该用户没有此订单!");
        }
        if (!Objects.equals(order.getStatus(), EnumUtil.PAY_STATUS_NO_PAY.getCode())) {
            return R.error("该订单已支付!");
        }
        //判断优惠券是否过期


        //判断活动是否过期


        //向微信平台发送创建支付订单的请求

        try {
            String openId = user.getOpenId();
            //微信支付的单位是分,要转换一下
            String amount = String.valueOf(order.getAmount().multiply(BigDecimal.valueOf(100)).intValue());
            WXPay wxPay = new WXPay(wxPayConfig);
            Map<String, String> paramMap = new HashMap<>();
            String nonceStr = WXPayUtil.generateNonceStr();
            paramMap.put("nonce_str", nonceStr);    //随机字符串
            paramMap.put("body", "商品备注信息");
            paramMap.put("out_trade_no", order.getCode());   //商品订单流水号,必须为一
            paramMap.put("total_fee", amount);              //订单金额
            paramMap.put("spbill_create_ip", "127.0.0.1");
            paramMap.put("notify_url", "127.0.0.1/notify"); //异步通知url  必须为外网地址
            paramMap.put("trade_type", "JSAPI");            //交易类型
            paramMap.put("openid", openId);
            Map<String, String> result = wxPay.unifiedOrder(paramMap);
            log.info("result:{}",result);
            //支付订单Id
            String prepayId = result.get("prepay_id");
            if (StringUtils.isNotBlank(prepayId)) {
                order.setPrepayId(prepayId);
                orderService.updateById(order);
            }else {
                log.error("微信支付出现异常,订单号:{}",orderId);
                return R.error("微信支付出现异常,订单号:{}" + orderId);
            }
            //发送数据给小程序
            paramMap.clear();
            paramMap.put("appId", wxConfiguration.getAppId());
            String timeStamp = String.valueOf(new Date().getTime());
            paramMap.put("timeStamp", timeStamp);
            paramMap.put("nonceStr", nonceStr);
            paramMap.put("package", "prepay_id=" + prepayId);
            paramMap.put("signType", "MD5");
            //根据组装的map和商户密钥生成签名
            String paySign = WXPayUtil.generateSignature(paramMap, wxConfiguration.getMchKey());
            return R.ok().put("package", "prepay_id=" + prepayId)
                    .put("timeStamp", timeStamp)
                    .put("nonceStr", nonceStr)
                    .put("paySign", paySign);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信支付出现异常,订单号:{}",orderId);
            return R.error("微信支付出现异常,订单号:{}" + orderId);
        }
    }


@PostMapping("/activeQueryOrder")
    @ApiOperation("向微信平台发起请求主动查询支付订单状态")
    public R activeQueryOrder(@RequestBody ActiveQueryOrderForm form,
                              @RequestHeader HashMap<String,Object> header) {
        ValidatorUtils.validateEntity(form);
        //0.先判断该用户下面有没有此订单
        String token = header.get("token").toString();
        Integer userId = Integer.parseInt(jwtUtils.getClaimByToken(token).getSubject());
        String orderId = form.getOrderId();
        LambdaQueryWrapper<Order> ew = new LambdaQueryWrapper<>();
        ew.eq(Order::getUserId, userId)
                .eq(Order::getId, orderId);
        Order order = orderService.getOne(ew);
        if (order == null) {
            return R.error("该用户没有此订单!");
        }
        //1.向微信平台发起请求查询订单是否支付成功
        Map<String, String> map = new HashMap<>();
        map.put("appid", wxConfiguration.getAppId());
        map.put("mch_id", wxConfiguration.getMchId());
        map.put("out_trade_no", order.getCode());
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        try {
            String sign = WXPayUtil.generateSignature(map, wxConfiguration.getMchKey());
            map.put("sign", sign);
            WXPay wxPay = new WXPay(wxPayConfig);
            Map<String, String> result = wxPay.orderQuery(map);
            String returnCode = result.get("return_code");
            String resultCode = result.get("result_code");
            String tradeState = result.get("trade_state");
            if ("SUCCESS".equals(resultCode) && "SUCCESS".equals(returnCode)) {
                if ("SUCCESS".equals(tradeState)) {
                    order.setStatus(EnumUtil.PAY_STATUS_PAIED.getCode());
                    orderService.updateById(order);
                    return R.ok("微信支付成功,订单状态已修改为已支付!");
                }
            }
            log.error("微信支付失败!订单号:{}",orderId);
            return R.error("微信支付失败!");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("微信支付失败!订单号:{}",orderId);
            return R.error("微信支付失败!");
        }
    }

    @ApiOperation("微信异步通知")
    @PostMapping("/receiveWxMsg1")
    public String receiveWxMsg1(@RequestBody String messsge) throws Exception {
        log.info("message:====>{}", messsge);
        Map<String, String> map = WXPayUtil.xmlToMap(messsge);
        String resultCode = map.get("result_code");
        String returnCode = map.get("return_code");
        String outTradeNo = map.get("out_trade_no");
        if ("SUCCESS".equals(resultCode) && "SUCCESS".equals(returnCode)) {
            LambdaQueryWrapper<Order> ew = new LambdaQueryWrapper<>();
            ew.eq(Order::getCode, outTradeNo);
            Order order = new Order();
            order.setStatus(EnumUtil.PAY_STATUS_PAIED.getCode());
            orderService.update(order, ew);
            return "<xml>\n" +
                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                    "</xml>";
        }
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值