Java 微信小程序自建平台开发票保存到微信卡包

Java 微信小程序自建平台开发票保存到微信卡包

  • 1 获取Access token
  • 2 获取自身的开票平台识别码
  • 3 设置商户联系方式
  • 4 获取授权页ticket
  • 5 获取授权页链接
  • 6 小程序打开授权页
  • 7 收取授权完成事件推送
  • 8 创建发票卡券模板
  • 9 上传PDF
  • 10 将电子发票卡券插入用户卡包

1 获取Access token

这里的appid和secret是公众号的,不要写小程序的。
获取 Access token

public static JSONObject getAccessToken() {
    String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + gzhAppId + "&secret=" + gzhAppSecret;
    return JSON.parseObject(HttpClientUtil.doGet(url));
}

2 获取自身的开票平台识别码

提前获取开票平台标识s_pappid,因为同一个开票平台的s_pappid都相同,所以获取s_pappid的操作只需要进行一次。只需创建一次,把卡劵s_pappid存起来。
获取自身的开票平台识别码

/**
 * 获取自身的开票平台识别码
 */
public static JSONObject getInvoicePlatformIdentifyCode(String accessToken) {
    String url = String.format("https://api.weixin.qq.com/card/invoice/seturl?access_token=%s", accessToken);
    return JSON.parseObject(HttpClientUtil.doPost(url, new HashMap<>()));
}

3 设置商户联系方式

注意,本步骤不能忽略,否则将造成下一步获取授权页报错。
设置商户联系方式

/**
 * 设置商户联系方式
 */
public static JSONObject setContact(String accessToken, Map<String, Object> params) {
    String url = String.format("https://api.weixin.qq.com/card/invoice/setbizattr?action=set_contact&access_token=%s", accessToken);
    return JSON.parseObject(HttpUtil.post(url, JSONObject.toJSONString(params)));
}

4 获取授权页ticket

获取授权页ticket

/**
 * 获取授权页ticket
 */
public static JSONObject getAuthTicket(String accessToken) {
    String url = String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=wx_card", accessToken);
    return JSON.parseObject(HttpClientUtil.doGet(url));
}

5 获取授权页链接

获取授权页url,上一步获取的授权页ticket将作为参数传入。另外,本环节里面作为参数传入的order_id要注意保留,传递给开票平台作为向用户提供电子发票的依据。这里的授权页type=2(领取发票类型):用于商户发票已开具成功,拉起授权页后让用户将发票归集保存到卡包。
获取授权页链接

/**
 * 获取授权页链接
 */
public static JSONObject getAuthUrl(String accessToken, Map<String, Object> params) {
    String url = String.format("https://api.weixin.qq.com/card/invoice/getauthurl?access_token=%s", accessToken);
    return JSON.parseObject(HttpUtil.post(url, JSONObject.toJSONString(params)));
}

6 小程序打开授权页

获得的授权页url(auth_url)作为传入参数,拉起微信客户端打开授权页。
小程序打开授权页

wx.navigateToMiniProgram({
    appId: '{appid}',
    path: '{auth_url}',
    success(res) {
        console.log('navigateToMiniProgram success:', res)
    },
    fail(error){
        console.log('navigateToMiniProgram fail:', error)
    },
    complete(res){
        console.log('navigateToMiniProgram complete:', res)
    }
})

在这里插入图片描述

7 收取授权完成事件推送

后台等待接收用户的授权完成事件。需要在微信公众平台上配置授权回调地址URL。用户同意授权将发票存入微信卡包后,微信会将发票的order_id通过回调地址URL推送过来,拿到order_id后可以查询具体的开票信息数据,然后上传发票PDF到微信,再将电子发票卡券插入用户卡包。
收取授权完成事件推送
在这里插入图片描述

/**
 * 微信公众号消息回调 get方法用于微信鉴权
 * @param signature 微信的签名,需要与自己生成的签名进行比对,相同则成功
 * @param timestamp 时间戳
 * @param nonce
 * @param echostr
 */
@GetMapping("/callback")
public String validate(@RequestParam(value = "signature", required = false) String signature,
                       @RequestParam(value = "timestamp", required = false) String timestamp,
                       @RequestParam(value = "nonce", required = false) String nonce,
                       @RequestParam(value = "echostr", required = false) String echostr) {
    try {
        log.info("签名开始");
        boolean flag = weChatService.verifyUrl(signature, timestamp, nonce, echostr);
        if (flag) {
            log.info("callbackCheckPass");
            return echostr;
        }
        log.info("callbackCheckFailure");
        return "error";
    } catch (Exception e) {
        log.info("callbackCheckFailure", e);
        return "error";
    }
}
/**
 * 处理具体的回调信息
 */
@PostMapping("/callback")
public String callback(@RequestParam(name = "signature", required = false) String signature,
                       @RequestParam(name = "timestamp", required = false) String timestamp,
                       @RequestParam(name = "nonce", required = false) String nonce,
                       @RequestParam(name = "echostr", required = false) String echostr,
                       @RequestParam(name = "openid", required = false) String openid,
                       @RequestBody String msg) {
    log.info("处理具体的回调信息");
    log.info("======微信回调msg======:" +msg);
    try {
        weChatService.handleWxCallBackMsg(msg, signature, timestamp, nonce, echostr, openid);
        return "success";
    } catch (Exception e) {
        log.info("handleWxCallBackMsg", e);
        return "error";
    }
}

8 创建发票卡券模板

只需创建一次,把卡劵id card_id 存起来。
创建发票卡券模板

9 上传PDF

上传发票PDF文件。此步骤获得的s_media_id起到关联PDF和发票卡券的作用,将作为参数在下一步的插卡接口中传入。
上传PDF

/**
 * 将电子发票PDF文件上传至微信
 */
public static String uploadPdfFile(String accessToken, File file) {
    String url = "https://api.weixin.qq.com/card/invoice/platform/setpdf?access_token=" + accessToken;

    try {
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("pdf", file.getName(), RequestBody.create(MediaType.parse("application/pdf"), file))
                .build();

        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        Response response  = new OkHttpClient().newCall(request).execute();
        if (response.isSuccessful()) {
            JSONObject jsonObject = JSONObject.parseObject(response.body().string());
            if (jsonObject.getInteger("errcode") == 0) {
                return jsonObject.getString("s_media_id");
            }
        }
        return null;

    } catch (Exception e) {
        log.info("调用微信上传PDF接口异常");
        e.printStackTrace();
        return null;
    }
}

10 将电子发票卡券插入用户卡包

将电子发票添加到用户微信卡包。
将电子发票卡券插入用户卡包

 /**
  * 将电子发票卡券插入用户卡包
  */
 public static JSONObject invoiceInsert(String accessToken, Map<String, Object> params) {
     String url = String.format("https://api.weixin.qq.com/card/invoice/insert?access_token=%s", accessToken);
     return JSON.parseObject(PostUtil.postJson(url, JSONObject.toJSONString(params)));
 }

将上面的每一个步骤完成后,具体业务代码自己编写,就可以将发票保存到微信卡包。
在这里插入图片描述

参考博客:
1 小程序自建平台开发票保存到微信卡包(java篇)
2 自建平台模式:小程序开票
3 开票平台接口列表
4 商户接口列表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/766123.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

shopify后台设置为中文

shopify官网&#xff1a;https://link.juejin.cn/?targethttps%3A%2F%2Fshopify.dev%2F 1、点击右上角头像 2、选择个人资料 3、找到Language设置 开发者 1、创建开发商店 2、 3、点击左侧导航在线商店&#xff0c;点击右上角查看你的商店。在线商店链接为https://[商店名…

RK3568驱动指南|第十五篇 I2C-第181章使用GPIO模拟I2C驱动

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

阿里云再次突发故障,高可用形同虚设?

作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验&#xff0c; Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复&#xff0c; 安装迁移&#xff0c;性能优化、故障…

轻松拯救手机数据,数据恢复软件推荐这8款!

在现代生活中&#xff0c;手机已成为我们不可或缺的工具&#xff0c;承载着大量重要的个人和工作数据。然而&#xff0c;意外删除、系统崩溃、设备损坏等情况可能导致数据丢失&#xff0c;给我们带来极大的困扰。幸运的是&#xff0c;随着科技的发展&#xff0c;各种手机数据恢…

文生图功能介绍

Stable Diffusion WebUI&#xff08;SD WebUI&#xff09;及文生图功能介绍 一、引言 随着人工智能技术的飞速发展&#xff0c;AI绘画作为一种新兴的艺术形式&#xff0c;逐渐走入人们的视野。Stable Diffusion WebUI&#xff08;简称SD WebUI&#xff09;作为AI绘画领域的重…

[附源码]最新springboot线上电商|前后端分离|界面简洁

一. 前言 今天小编给大家带来了一款可学习&#xff0c;可商用的&#xff0c;线上电商的网站源码&#xff0c;支持二开&#xff0c;无加密。代码的后端是SpringBoot技术栈&#xff08;非jsp&#xff09;&#xff0c;前端是Angular。如果您需要定制需求请找小编。 文章第六小节…

英灵神殿mac能玩吗 英灵神殿对电脑配置要求《英灵神殿》新手攻略查询 PD虚拟机能玩英灵神殿吗

近年来&#xff0c;随着《英灵神殿》&#xff08;Valheim&#xff09;游戏的火热&#xff0c;越来越多的玩家被其独特的北欧神话题材和丰富的生存挑战所吸引。然而&#xff0c;对于Mac用户来说&#xff0c;如何在Mac平台上运行这款游戏可能是一个问题。此外&#xff0c;作为一名…

编译原理3-自底向上的语法分析

自底向上分析 &#xff0c;就是自左至右扫描输入串&#xff0c;自底向上进 行分析&#xff1b;通过反复查找当前句型的 句柄&#xff0c; 并使 用产生式规则 将找到的句柄归约为相应的非终结符 。逐步进行“ 归约 ”&#xff0c;直到至文法的开始符号&#xff1b; 对于规范推导…

【unity实战】在Unity中使用有限状态机制作一个敌人AI

最终效果 文章目录 最终效果前言有限状态机的主要作用和意义素材下载逻辑图敌人动画配置优雅的代码文件目录状态机代码定义敌人不同状态切换创建敌人效果更多的敌人参考源码完结 前言 有限状态机以前的我嗤之以鼻&#xff0c;现在的我逐帧分析。其实之前我就了解过有限状态机&…

day03-主页模块-修改密码

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.获取用户资料在Vuex中共享登录成功跳转到主页之后&#xff0c;可以获取用户资料&#xff0c;获取的资料在Vuex中共享&#xff0c;这样用户就可以很方便的获取该信…

Leetcode刷题笔记 | 二叉树基本性质 | 一天的题量 | 5道题目 | 深度优先搜索 | 广度优先搜索 | 递归 | 遍历

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;本期毛毛张分享的是LeetCode关于二叉树&#x1f332;的性质的一些基础题&#xff0c;做这些题目的本质还是遍历二叉树&#x1f3c3;‍➡️的过程&#…

计算机组成原理 | 储存子系统(1)概述

三级储存体系 物理与虚拟存储器 &#xff08;抽象逻辑模型&#xff09; 存储器类型 存储器的速度指标

中国民间网络外交组织(CCND)

中国民间网络外交组织Chinese Civil Network Diplomacy简称(CCDN) 是由中国网民建立起来的一个网络外交组织&#xff0c;深度贯彻党的主张和网民意志的统一&#xff0c;为保护中国中华优秀传统文化&#xff0c;民族自信&#xff0c;国家安全&#xff0c;民族利益&#xff0c;社…

昇思MindSpore学习笔记2-04 LLM原理和实践--文本解码原理--以MindNLP为例

摘要&#xff1a; 介绍了昇思MindSpore AI框架采用贪心搜索、集束搜索计算高概率词生成文本的方法、步骤&#xff0c;并为解决重复等问题所作的多种尝试。 这一节完全看不懂&#xff0c;猜测是如何用一定范围的词造句。 一、概念 自回归语言模型 文本序列概率分布 分解为每…

76. UE5 RPG 实现场景阻挡剔除功能

在俯视角游戏中&#xff0c;我们总会碰到一个问题就是&#xff0c;建筑会遮挡住角色的问题。遇到这种问题有多种解决方案&#xff0c;厂商经常使用的一种方案是&#xff0c;如果角色被遮挡&#xff0c;则使用一种纯色或者增加一些菲涅尔的效果来实现 这种效果我之前在unity内实…

SpringBoot 项目整合 MyBatis 框架,附带测试示例

文章目录 一、创建 SpringBoot 项目二、添加 MyBatis 依赖三、项目结构和数据库表结构四、项目代码1、application.yml2、TestController3、TbUser4、TbUserMapper5、TestServiceImpl6、TestService7、TestApplication8、TbUserMapper.xml9、MyBatisTest 五、浏览器测试结果六、…

一文了解什么是车载Tbox

目录 前言一、Tbox是什么呢?二、Tbox架构三、App——TSP——Tbox交互时序图四、汽车混合网关拓扑结构示例五、Tbox功能 前言 强烈建议提前阅读一下这篇文章&#xff1a;车机Tbox介绍 一、Tbox是什么呢? Tbox是汽车上的一个盒子&#xff0c;指的是Telematics BOX&#xff0c…

Michael.W基于Foundry精读Openzeppelin第61期——ERC1967Upgrade.sol

Michael.W基于Foundry精读Openzeppelin第61期——ERC1967Upgrade.sol 0. 版本0.1 ERC1967Upgrade.sol 1. 目标合约2. 代码精读2.1 _getImplementation() internal && _upgradeTo(address newImplementation) internal2.2 _upgradeToAndCall(address newImplementation,…

常见反爬及应对

一&#xff0c;特殊混淆的还原 1.1 还原 AAEncode 与 JJEncode AAEncode是一种JavaScript代码混淆算法&#xff0c;利用它&#xff0c;可以将代码转换成 颜文字 表示的JavaScript代码。 去掉代码最后的 (‘‘)&#xff0c;这是函数的自调用&#xff0c;去除后就是函数的声明…

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验13 静态路由配置错误导致的路由环路问题

一、实验目的 1.验证静态路由配置错误导致的路由环路问题&#xff1b; 二、实验要求 1.使用Cisco Packet Tracer仿真平台&#xff1b; 2.观看B站湖科大教书匠仿真实验视频&#xff0c;完成对应实验。 三、实验内容 1.构建网络拓扑&#xff1b; 2.验证路由环路。 四、实验…