前几天微信弹了一个通知,说是可以一块钱买一个小票机,都一块钱了那也就没有不要的道理,于是买回来了。

请输入图片描述

到货之后才发现,这玩意儿是有内置联通卡的,除了微信小票,其他啥也不能打,那我买回来干〇毛啊,整整5卷纸我又不是真的商户什么时候才能用完。

搜了一下,唯一一个有记载的就是N站的一个帖子 1元买了台微信收款小票机4G版P5 ,但是也并没有什么用,里面没有任何有用的消息。在多方询问下,得知,后台小程序里有一个可以给小票自定义推广位的页面,在那里设置完推广位之后,选择打印,就能打印推广位了。

如果你这个时候不小心打开了抓包软件,就能在里面找到

https://xxxxxxxxxx/smartqr/printerad/printad

从api名称就能看到,这个接口确实是留给打印广告的,里面的内容大致为

{
  "device_sn": "",
  "ad_content": {
    "user_define_template": {
      "root": [
        {
          "text": {
            "column": [
              {
                "value": "123"
              }
            ],
            "column_align": [
              {}
            ]
          }
        }
      ]
    }
  },
  "account_type": ,
  "sid": ""
}

聪明的你一定就知道下一步该做什么了,随后,你就可以用这个小票机打印你想打印的东西了。

但还没完,只知道能打印文字那也太无聊了,这个小票机能做到的上限是什么呢,在和gpt一起捣鼓了两天之后,也算是把目前能做到摸了个大概了。

如果你懒得看下面的内容的话,可以直接下载WeChat Printer进行使用

请输入图片描述

PS:这里的sid是有有效期的,过期之后得重新抓一次

接口结构

所有打印内容都通过:

{
  "ad_content": {
    "user_define_template": {
      "root": []
    }
  }
}

发送。

其中 root 是一个数组。

数组中的元素会按照顺序从上到下依次打印。

目前确认存在三种组件:

  • content(表格/文本)
  • icon(二维码/图片)
  • text(简单文本)

content:最重要的组件

目前绝大多数排版都是通过 content 完成的。

例如:

{
  "content": {
    "column_align": [
      {
        "column_width": 20,
        "style": {
          "justification": 0
        }
      },
      {
        "column_width": 10,
        "style": {
          "justification": 2
        }
      }
    ],
    "lines": {
      "linelist": [
        {
          "column": [
            "可乐",
            "3"
          ]
        }
      ]
    },
    "maxcolumn": 2,
    "style": {
      "height": 0,
      "width": 0
    }
  }
}

列数

目前已经验证:

1列
2列
3列
5列

都可以正常工作。

五列表格测试结果也完全正常。

例如:

#   项目          单价   数量   小计
1   手冲咖啡超大杯  28     2     56

列宽

column_width 不是实际宽度。

而是权重。

例如:

10 : 20

和:

20 : 40

最终效果完全一致。

因此可以理解为类似 CSS 的 flex 权重。


对齐

{
  "style": {
    "justification": 0
  }
}

对应:

0 = 左对齐
1 = 居中
2 = 右对齐

无论是整行还是单列都支持,图片/二维码/表格也都支持用这个设置对齐方式。


字体大小

目前确认:

height = 0
width  = 0

标准字体。

height = 1
width  = 1

双倍字体。

height = 2
width  = 2

也能正常使用。你也可以单独设定height和width的值,例如

height = 1
width  = 0

就可以得到一个窄窄的字,反之则是宽宽的字。在不能换字体的情况下,也算是多了一点可玩性。


自动换行

如果某列文字超出分配宽度:

手冲咖啡超大杯

会自动折行,而且不会影响其它列,例如:

手冲咖啡超
大杯

右边价格列依旧保持正常对齐,排版逻辑比我想象中完善很多。


content 的一个坑

我原本以为

{
  "lines": {
    "linelist": [
      {...},
      {...}
    ]
  }
}

可以实现多行表格,结果直接打印空白。这玩意儿还不能和其他的小票机一样content里面塞完整个小票的内容,一个 content 节点只能渲染一行。如果要实现:

商品A
商品B
商品C

就只能这样写

{
  "root": [
    { "content": {...} },
    { "content": {...} },
    { "content": {...} }
  ]
}

icon:二维码与图片

二维码

在官方小程序中,二维码是这样实现的

{
  "icon": {
    "type": 1,
    "value": "https://example.com"
  }
}

value的值并不是一个图片链接,而是一个链接,在多次测试后得知

type = 1

就是二维码组件,value既可以是 URL,也可以是任意字符串,最后打印的时候会自动转换成二维码打印出来。但是这个小票机的精度很低,这里塞的值太长的话,二维码容易糊在一起,就扫不了了。


图片

依旧是官方小程序,图片就简单多了,是这样实现的

{
  "icon": {
    "type": 3,
    "value": "https://example.com/test.png"
  }
}
type = 3

也就是图片组件了,我刚开始以为图片的url只能用官方的接口,或者只能用腾讯的域名,毕竟那张联通卡很有可能是一个物联卡,可能并不能访问非腾讯的资源,但是我错了,这里的url什么都能填,唯一需要注意的是,url不能太长,太长小票机就会读不到图片了。

以及不管你传入什么尺寸的图片,都只会按照固定大小和固定比例1:1打印出来,而且如果是png图片,透明像素会被填充为黑色。

进阶:灰度图片

这里踩了很久的坑,由于小票机只能打印黑色,所以这里打印图片都会被二值化,根本没法看,唯一的解决办法就是在交给小票机之前,手动将图片抖动处理比如Floyd-Steinberg,Atkinson,Bayer,处理之后,图片中灰色的地方就能用密集度不一样的小点打印出来,视觉上看起来就会有颜色的过渡。

其他 type

其他的type我也试过了,要么打印出来是空白,要么服务器直接拒绝了,摸黑测试过于困难于是就放弃了,交给有缘人吧


text:简单文本组件

除了 content 之外,还存在一个组件

{
  "text": {
    "value": "Hello World"
  }
}

不过目前看比较鸡肋,因为它的样式基本不会生效,字体大小也无法调整,除非你懒得写太多东西进json,否则大多数场景下直接用 content 更方便,能自定义的东西也更多。


特殊控制符

目前发现一个有意思的地方。

{
  "text": {
    "value": "__EOL__"
  }
}

会输出一个空白行,相当于换行符,但

__LINE__
__CUT__

只会被当作普通文字打印出来。

可以打印的特殊字符

特殊符号

∞、。·ˉˇ¨〃々—~‖…‘’“”〔〕〈〉《》「」『』〖〗【】
±×÷∶∧∨∑∏∪∩∈∷√⊥∥∠⌒⊙∫∮≡≌≈∽∝≠≮≯≤≥
∵∴♂♀°′″℃$¤¢£‰§№☆★○●◎◇◆□■△▲※
→←↑↓〓〡〢〣〤〥〦〧〨〩㊣
㎎㎏㎜㎝㎞㎡㏄㏎㏑㏒㏕
︰¬¦℡ˊˋ˙–―‥‵℅℉
↖↗↘↙∕∟∣≒≦≧⊿
═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬
╭╮╯╰╱╲╳
▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▓▔▕
▼▽◢◣◤◥☉⊕〒〝〞

罗马数字

ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ
ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ

带圈、带括号数字

⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛
⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇
①②③④⑤⑥⑦⑧⑨⑩
㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩

拼音字母

āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜü

希腊字母

ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ
αβγδεζηθικλμνξοπρστυφχψω

已确认可打印的上标样式字符

˙  *  ′

已知支持的能力

目前已经确认支持:

  • 普通文本
  • 大字体
  • 超大字体
  • 自动换行
  • 左中右对齐
  • 单列表格
  • 双列表格
  • 三列表格
  • 五列表格
  • 二维码
  • 图片 URL
  • 图文混排
  • 空白行

目前还没搞清楚的部分

虽然已经能正常打印复杂内容了,但还有几个地方没测试:

root 最大节点数

目前还没测试过上限,理论上应该存在服务端限制,但谁能写那么多东西呢,大不了多打几次嘛

是否存在更多组件

目前只发现:

content
icon
text

三个组件,不确定是否存在

barcode
line
table

之类隐藏组件。


icon.type 是否还有其它合法值

目前已知

1 = QRCode
3 = Image

但理论上应该还有其它枚举值,只是暂时没找到。

type:2的话能被服务器接受,但是打出来是空白

总结

折腾了半天发现这玩意儿也没什么好玩的,所以搓了一个小程序让他可以打印聊天记录,找不到我人的时候就可以飞鸽传书了。但每次打印的时候都有一个巨大的语音播报,所以干脆拆机给喇叭拔了。至于他还能做什么呢,我也就不知道了,等其他有缘人来折腾吧。请输入图片描述

最后修改:2026 年 08 月 31 日
如果觉得我的文章对你有用,请随意赞赏