文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

微信支付V3 小程序支付API Java版

2023-10-27 13:23

关注

本文目的:快速接通微信支付V3 无需关注细节,实现支付功能,修改配置即可调用

文章目录


接入准备

申请APPID,申请mchid,绑定APPID及mchid,设置APIV3密钥,下载并配置商户证书

微信支付文档


微信支付流程整理(小程序版)

  1. 前端获取登录凭证(wx.login)
  2. 服务端换取用户openId(code2Session)
  3. 创建微信支付订单(/v3/pay/transactions/jsapi)
  4. 回调服务端

提示:以下是本篇文章正文内容,下面案例可供参考

一、导入微信支付扩展包

微信支付扩展包文档

 <!--微信支付-->        <dependency>            <groupId>com.github.wechatpay-apiv3</groupId>            <artifactId>wechatpay-apache-httpclient</artifactId>            <version>0.4.7</version>        </dependency>

二、微信支付工具类

1.签名工具类

代码如下(示例):

@Componentpublic class WxSignUtil {    protected static final SecureRandom RANDOM = new SecureRandom();        public static String WxAppPayTuneUp(String prepayId, String appId, String mch_id, String privateKey) throws Exception {        if (StringUtils.isNotBlank(prepayId)) {            long timestamp = System.currentTimeMillis() / 1000;            String nonceStr = generateNonceStr();            //加载签名            String packageSign = sign(buildMessage(appId, timestamp, nonceStr, prepayId).getBytes(), privateKey);            JSONObject jsonObject = new JSONObject();            jsonObject.put("appId", appId);            jsonObject.put("prepayId", prepayId);            jsonObject.put("timeStamp", timestamp);            jsonObject.put("nonceStr", nonceStr);            jsonObject.put("package", "Sign=WXPay");            jsonObject.put("signType", "RSA");            jsonObject.put("sign", packageSign);            jsonObject.put("partnerId", mch_id);            return jsonObject.toJSONString();        }        return "";    }    public static String sign(byte[] message, String privateKey) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {        //签名方式        Signature sign = Signature.getInstance("SHA256withRSA");        //私钥        sign.initSign(PemUtil                .loadPrivateKey(privateKey));        sign.update(message);        return Base64.getEncoder().encodeToString(sign.sign());    }    //生成随机字符串 微信底层的方法,直接copy出来了    protected static String generateNonceStr() {        char[] nonceChars = new char[32];        for (int index = 0; index < nonceChars.length; ++index) {            nonceChars[index] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(RANDOM.nextInt("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".length()));        }        return new String(nonceChars);    }        public static String buildMessage(String appId, long timestamp, String nonceStr, String prepay_id) {        return appId + "\n"                + timestamp + "\n"                + nonceStr + "\n"                + "prepay_id="+prepay_id + "\n";    }}

2.微信支付工具类

代码如下(示例):

@Slf4j@Componentpublic class WxMiniPayUtils {    public static CloseableHttpClient httpClient;    public static Verifier verifier;        public static void initWXPayClient() throws IOException {        try {            // 加载商户私钥(privateKey:私钥字符串)            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey({{微信支付私钥字符串}});            // 也可使用证书 查询商户证书序列号//            X509Certificate wechatPayCert = PemUtil.loadCertificate(new ByteArrayInputStream(StaticVariable.WX_PAY_CERT.getBytes(StandardCharsets.UTF_8)));//            String serialNo = wechatPayCert.getSerialNumber().toString(16).toUpperCase();            String serialNo ={{微信支付商户证书序列号}};            //merchantId:商户号,serialNo:商户证书序列号            // 获取证书管理器实例            CertificatesManager certificatesManager = CertificatesManager.getInstance();            // 向证书管理器增加需要自动更新平台证书的商户信息            certificatesManager.putMerchant({{微信支付-商户号}}, new WechatPay2Credentials({{微信支付-商户号}},                    new PrivateKeySigner(serialNo, merchantPrivateKey)), {{微信支付-v3 密钥}}.getBytes(StandardCharsets.UTF_8));            // 从证书管理器中获取verifier            //版本>=0.4.0可使用 CertificatesManager.getVerifier(mchId) 得到的验签器替代默认的验签器。            // 它会定时下载和更新商户对应的微信支付平台证书 (默认下载间隔为UPDATE_INTERVAL_MINUTE)。            verifier = certificatesManager.getVerifier({{微信支付-商户号}});            //创建一个httpClient            httpClient = WechatPayHttpClientBuilder.create()                    .withMerchant({{微信支付-商户号}}, serialNo, merchantPrivateKey)                    .withValidator(new WechatPay2Validator(verifier)).build();        } catch (IOException e) {            e.printStackTrace();            log.error("加载秘钥文件失败");        } catch (GeneralSecurityException e) {            e.printStackTrace();            log.error("获取平台证书失败");        } catch (Exception e) {            e.printStackTrace();        }    }        public static void closeWXClient() throws IOException {        if (httpClient != null) {            try {                httpClient.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }        public static String creatOrderJSAPI(String openId,String orderId,Integer amount,String description) throws Exception {        try {            initWXPayClient();            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");            String reqdata = "{"                    + "\"amount\": {"                    + "\"total\": "+amount+","                    + "\"currency\": \"CNY\""                    + "},"                    + "\"mchid\": \""+{{微信支付-商户号}}+"\","                    + "\"description\": \""+description+"\","                    + "\"notify_url\": \""+{{微信支付-回调地址}}+"\","                    + "\"payer\": {"                    + "\"openid\": \""+openId+"\"" + "},"                    + "\"out_trade_no\": \""+orderId+"\","                    + "\"goods_tag\": \"WXG\","                    + "\"appid\": \""+{{微信APPID}}+"\"" + "}";            httpPost.setEntity(new StringEntity(reqdata, "utf-8"));            CloseableHttpResponse response = httpClient.execute(httpPost);            String bodyAsString = EntityUtils.toString(response.getEntity());            return bodyAsString;        }catch (Exception e){            e.printStackTrace();            log.error("创建微信支付订单失败");        }finally {            closeWXClient();        }        return "";    }}

三、创建订单

代码如下(示例):

String response= WxMiniPayUtils.creatOrderJSAPI({{用户openId}}, {{订单id}},{{订单金额}},{{订单描述}});JSONObject jsonObject= JSONObject.fromObject(response);if (jsonObject.containsKey("prepay_id")){}

创建微信支付订单,微信会返回 prepay_id (预下单id)用于前端调起支付


四、调起支付

调起支付文档

前端通过prepay_id调起支付


五、支付回调

Controller代码如下(示例):

@ApiOperation(value = "微信支付回调", notes = "微信支付回调")@PostMapping(value = "wxAppPayNotify.do")public String wxAppPayNotify( @RequestHeader("Wechatpay-Serial") String wechatpaySerial,  @RequestHeader("Wechatpay-Signature") String wechatpaySignature,  @RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp,  @RequestHeader("Wechatpay-Nonce") String wechatpayNonce,  @RequestBody String callback) throws Exception {    return Service.wxAppPayNotify(wechatpaySerial,wechatpaySignature,wechatpayTimestamp,wechatpayNonce,callback);}

验签和解密并返回通知

Servicer代码如下(示例):

@Overridepublic String wxAppPayNotify(String wechatpaySerial, String wechatpaySignature, String wechatpayTimestamp, String wechatpayNonce, String callback) throws Exception {//按照文档要求拼接验签串String verifySignature = wechatpayTimestamp + "\n"+ wechatpayNonce + "\n" + callback + "\n";//使用官方验签工具进行验签boolean verify1 = WxMiniPayUtils.verifier.verify(wechatpaySerial, verifySignature.getBytes(), wechatpaySignature);//判断验签的结果if (!verify1) {//验签失败,应答接口com.alibaba.fastjson.JSONObject jsonResponse = new com.alibaba.fastjson.JSONObject();jsonResponse.put("code", "FAIL");jsonResponse.put("message", "失败");return jsonResponse.toString();}JSONObject parseObject = JSONObject.parseObject(callback);if ("TRANSACTION.SUCCESS".equals(parseObject.getString("event_type"))&& "encrypt-resource".equals(parseObject.getString("resource_type"))) {//通知的类型,支付成功通知的类型为TRANSACTION.SUCCESS//通知的资源数据类型,支付成功通知为encrypt-resourceJSONObject resourceJson = JSONObject.parseObject(parseObject.getString("resource"));String associated_data = resourceJson.getString("associated_data");String nonce = resourceJson.getString("nonce");String ciphertext = resourceJson.getString("ciphertext");//解密,如果这里报错,就一定是APIv3密钥错误AesUtil aesUtil = new AesUtil({{微信支付-v3 密钥}}.getBytes());String resourceData = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);System.out.println("解密后=" + resourceData);//dosomething 处理业务JSONObject resource =JSONObject.fromObject(resourceData);if (resource.containsKey("out_trade_no")){}}JSONObject jsonResponse = new JSONObject();jsonResponse.put("code", "SUCCESS");jsonResponse.put("message", "成功");return jsonResponse.toString();}

总结

微信支付文档

网上的微信支付V3 教程无需看太多 ,专注官方文档

参考文档:https://www.cnblogs.com/cchilei/p/16077207.html

https://blog.csdn.net/m0_59588838/article/details/127204694

来源地址:https://blog.csdn.net/weixin_41476211/article/details/128496850

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯