1、获取用户openId

  1. 需要在微信公众平台获取appId,appSecret。
  2. 前端获取code,传入后端调用获取openId
          var fullUrl = window.location.href; // 就是当前页面的url
         const oriCode = urlParams.get('code');
         if (!oriCode) {
            // 第一次访问,后端会重定向到微信获取 code
            var oriRedrictUrl = encodeURIComponent(fullUrl).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
       
            var CodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
                            + "?appid=" + this.merchantSettings.userAppId  //即微信公众平台appId
                            + "&redirect_uri=" + oriRedrictUrl
                            + "&response_type=code"
                            + "&scope=snsapi_base"
                            + "&state=1"
                            + "&connect_redirect=1#wechat_redirect";
            window.location.href = CodeUrl;  
        } else {
            // 已有 code → 请求后端接口直接拿 openid
              const codeData = {
                    userId: this.userId,
                    code: oriCode
                };
                const response = await getUserOpenId(codeData);
                if (response && response.code === 200 && response.data) {
                    // 后端返回的是微信用户的 openid
                    this.openId = response.data;
                }
        }
    public String getOpenId(String userId, String code) throws JsonProcessingException {

        String url = UriComponentsBuilder.fromHttpUrl("https://api.weixin.qq.com/sns/oauth2/access_token?")
                .queryParam("appid",webAppConfig.getAppId() )//微信公众平台appId
                .queryParam("secret", webAppConfig.getAppSecret()) //微信公众平台appSecret
                .queryParam("code", code)
                .queryParam("grant_type", "authorization_code")
                .toUriString();
        // 微信返回的是 JSON
        String responseStr = restTemplate.getForObject(url, String.class);
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> resp = objectMapper.readValue(responseStr, Map.class);
        if (resp != null && resp.get("openid") != null) {
            return resp.get("openid").toString();
        } else {
             return null;
        }
    }

2、正常支付

  1. 使用https://pay.weixin.qq.com/doc/global/v3/zh/4012354174的客户端初始化。
 public void init(String merchantId,PrivateKey merchantPrivateKey,String merchantSerialNumber, String apiV3Key) throws Exception {

        certificatesManager = CertificatesManager.getInstance();
        certificatesManager.putMerchant(
                merchantId,
                new WechatPay2Credentials(
                        merchantId,
                        new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)
                ),
                apiV3Key.getBytes(StandardCharsets.UTF_8)
        );
        verifier = certificatesManager.getVerifier(merchantId);
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier));
        httpClient = builder.build();
    }
  1. 使用https://pay.weixin.qq.com/doc/v3/merchant/4012791856的url进行请求,签名参考https://pay.weixin.qq.com/doc/global/v3/zh/4013014169这里的,转换为对应代码实现方式即可,apiV3和私钥等在https://pay.weixin.qq.com/index.php/core/home/login申请。
   public MarketingPayVo wxH5Pay(String userId, String finalAmount, String openid) throws Exception {

        WechatMarketingSettings queryCondition = new WechatMarketingSettings();
        queryCondition.setUserId(String.valueOf(userId));
        WechatMarketingSettings settings = settingsMapper.selectOne(queryCondition);
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(settings.getPaymentKey());

        init(settings.getMerchantId() ,merchantPrivateKey, settings.getMerchantserialnumber(), settings.getApiv3key());
        Integer totalAmount = Integer.valueOf((int) (Double.valueOf(finalAmount)*100));
        long timestampSeconds = System.currentTimeMillis() / 1000;
        String outTradeNo = userId +  System.currentTimeMillis(); // 用户ID+时间戳

         // 1. 构造请求体
        Map<String, Object> body = new HashMap<>();
        body.put("appid", webAppConfig.getAppId());
        body.put("mchid", settings.getMerchantId());
        body.put("out_trade_no", outTradeNo);
        body.put("description", "Image形象店-深圳腾大-QQ公仔");
        body.put("notify_url", "xxxxxx");

        Map<String, String> payer = new HashMap<>();
        payer.put("openid", openid);
        body.put("payer", payer);

        Map<String, Object> amount = new HashMap<>();
        amount.put("total", totalAmount); // 整数
        amount.put("currency", "CNY");
        body.put("amount", amount);


        String jsonBody = new ObjectMapper().writeValueAsString(body);


        // 2. 构造 POST 请求
            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
            httpPost.addHeader("Accept", "application/json");
            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
            httpPost.setEntity(new StringEntity(jsonBody));
            CloseableHttpResponse response = httpClient.execute(httpPost);

            String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");
            // 4. 解析响应
            JSONObject jsonObject = JSONObject.parseObject(responseString);

            MarketingPayVo marketingPayVo = new MarketingPayVo();
            marketingPayVo.setAppId(webAppConfig.getAppId());
            marketingPayVo.setTimeStamp(String.valueOf(timestampSeconds));
            marketingPayVo.setSignType("RSA");
            marketingPayVo.setNonceStr(getNonceStr());
            marketingPayVo.setPkg("prepay_id="+jsonObject.get("prepay_id"));
            marketingPayVo.setPaySign(generatePaySign(marketingPayVo.getAppId(),String.valueOf(timestampSeconds),marketingPayVo.getNonceStr(),marketingPayVo.getPkg(),merchantPrivateKey));


        return marketingPayVo;
    }

Logo

加入社区!打开量化的大门,首批课程上线啦!

更多推荐