新零售支付全家桶


微信账号登陆小程序

我们先要实现这个支付流程,首先必须要做的是,给小程序实现微信登陆的功能。大家回顾一下第一幅时序图,也就是创建支付订单的那副时序图。首先由小程序发起请求给商户系统,让商户系统申请创建支付订单。各位同学你仔细想一想,如果是POSTMAN软件,或者HTTPClient这样的客户端程序,模拟小程序发出请求,他们根本都不是真实的用户,而且也没有登陆小程序,所以商户系统必须要加以判断。

其实想要判断到底是不是真实的用户发来的请求,我们只需要判断两样东西即可。一个是OpenID,另一个是Token字符串。用户在手机上用微信账号登陆小程序的时候,会产生一个唯一的OpenID值,商户系统会记录下这个OpenID值。如果商户系统接收到的请求里面没有OpenID值,或者OpenID值跟数据库里面的对不上,就说明这不是一个合法的用户。那么商户系统就不用理会这个请求。仅仅OpenID能核对上还不行,我还要看看发起请求的用户是不是已经登陆了小程序。只有用户登陆小程序之后,才可以证明是本人下单支付,所以商户系统必须要判断用户到底有没有登陆小程序。因为我们搭建的renren-fast后端项目,整合了Shiro和JWT技术,所以成功登陆小程序的用户,renren-fast后端系统都会返回一个Token字符串。小程序每次发起请求的时候都要带上这个令牌字符串,告诉renren-fast后端系统,我现在已经登陆了。当然了,后端系统也要验证这个Token字符串是否有效,以及过没过期。

UNI-APP登陆接口

uni.login(OBJECT)

App H5 微信小程序 支付宝小程序 百度小程序 字节跳动小程序 QQ小程序
x
uni.login({
    provider: 'weixin',
    success: function (loginRes) {
        console.log(loginRes.authResult);
    }
});

微信小程序代码

uni.getUserInfo({
    success:function(resp){
        // console.log(resp)
        let nickname=resp.userInfo.nickName
        let avatarUrl=resp.userInfo.avatarUrl
        uni.request({
            url:that.url.wx.login,
            method:"POST",
            data:{
                "code":code,
                "nickname":nickname,
                "photo":avatarUrl
            },
            success:function(resp){
                console.log(resp)
                let token=resp.data.token
                let expire=resp.data.expire
                // uni.setStorageSync("token",token)
                // uni.setStorageSync("expire",expire)
                uni.switchTab({
                    url:"../index/index"
                })
            }
        })
    }
})

后端Java代码

  1. 编写application.yml文件
    application:
        wxpay:
        app-id: wx4cb8e*********
        app-secret: 27b1f2997***************
        mch-id: 1526******
        key: qv9Kihy***********
        cert-path: F:/apiclient_cert.p12
  2. 创建WxLoginForm.java

    @Data
    @ApiModel(value = "微信登录表单")
    public class WxLoginForm {
        @ApiModelProperty(value = "临时登陆凭证")
        @NotBlank(message="临时登陆凭证不能为空")
        private String code;
        @ApiModelProperty(value = "昵称")
        @NotBlank(message="昵称不能为空")
        private String nickname;
        @ApiModelProperty(value = "头像URL")
        @NotBlank(message="头像URL不能为空")
        private String photo;
    }
  3. 创建WxCtroller.java

    @RestController
    @RequestMapping("/app/wx")
    @Api("微信业务接口")
    public class WxController {
        @Value("${application.wxpay.app-id}")
        private String appId;
    
        @Value("${application.wxpay.app-secret}")
        private String appSecret;
    
        @Value("${application.wxpay.key}")
        private String key;
    
        @Value("${application.wxpay.mch-id}")
        private String mchId;
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private OrderService orderService;
    
        @Autowired
        private JwtUtils jwtUtils;
    
        @Autowired
        private MyWXPayConfig myWXPayConfig;
    
        @PostMapping("login")
        @ApiOperation("登录")
        public R login(@RequestBody WxLoginForm form) {
            //表单校验
            ValidatorUtils.validateEntity(form);
            String url = "https://api.weixin.qq.com/sns/jscode2session";
            HashMap map = new HashMap();
            map.put("appid", appId);
            map.put("secret", appSecret);
            map.put("js_code", form.getCode());
            map.put("grant_type", "authorization_code");
            String response = HttpUtil.post(url, map);
            JSONObject json = JSONUtil.parseObj(response);
            String openId = json.getStr("openid");
            if (openId == null || openId.length() == 0) {
                return R.error("临时登陆凭证错误");
            }
            UserEntity user = new UserEntity();
            user.setOpenId(openId);
            QueryWrapper wrapper = new QueryWrapper(user);
            int count = userService.count(wrapper);
            if (count == 0) {
                user.setNickname(form.getNickname());
                user.setPhoto(form.getPhoto());
                user.setType(2);
                user.setCreateTime(new Date());
                userService.save(user);
            }
            user = new UserEntity();
            user.setOpenId(openId);
            wrapper = new QueryWrapper(user);
            user = userService.getOne(wrapper);
            long id = user.getUserId();
    
            String token = jwtUtils.generateToken(id);
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("expire", jwtUtils.getExpire());
    
            return R.ok(result);
        }
    }

页面列表

ITEM_HTML