You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET MAUI中基于SPP和Protobuf实现蓝牙经典POS终端打印

解决方案

1. 序列化AcquireReceipt为Protobuf格式

首先完成Protobuf定义补全与C#类生成:

  • 补全终端proto中缺失的common.Money和Receipt定义(需匹配终端实际协议),完整proto示例:
syntax = "proto3";

package com.uaepay.pos.ecr.acquire;

import "common/money.proto";

enum Receipt {
    CUSTOMER_RECEIPT = 0;
    MERCHANT_RECEIPT = 1;
}

message AcquireReceipt {
  common.Money amount = 1;
  optional string subject = 2;
  optional string paymentMethod = 3;
  optional string reserved = 4;
}

message ReceiptsRequest {
  string orderNo = 1;
  repeated Receipt receipts = 2;
  repeated AcquireReceipt acquireReceipts = 3; // 与终端协议匹配的字段,用于携带收据详情
}
  • 安装依赖:通过NuGet安装Google.Protobuf和Google.Protobuf.Tools。
  • 生成C#类:使用protoc命令或Visual Studio Protobuf工具链,将proto文件编译为C#实体类。

序列化代码示例:

// 实例化金额对象(需匹配终端金额格式,比如用整数表示分)
var money = new Common.Money
{
    Currency = "AED",
    Amount = 10000 // 代表100.00 AED
};

// 实例化AcquireReceipt
var acquireReceipt = new Com.Uaepay.Pos.Ecr.Acquire.AcquireReceipt
{
    Amount = money,
    Subject = "Test Purchase",
    PaymentMethod = "CreditCard"
};

2. 结合现有蓝牙代码发送序列化数据

修改现有代码,将AcquireReceipt整合到符合终端要求的ReceiptsRequest中,再序列化发送:

var bluetoothAdapter = BluetoothAdapter.DefaultAdapter;
var device = bluetoothAdapter.BondedDevices.FirstOrDefault(pd => pd.Name == "Pos-terminal") 
             ?? throw new InvalidOperationException("未找到绑定的POS终端");

using var socket = device.CreateRfcommSocketToServiceRecord(UUID.FromString("00001101-0000-1000-8000-00805f9b34fb"))!;
socket.Connect();

// 构建符合终端要求的ReceiptsRequest
var request = new Com.Uaepay.Pos.Ecr.Acquire.ReceiptsRequest
{
    OrderNo = "1234",
    Receipts = { Com.Uaepay.Pos.Ecr.Acquire.Receipt.CustomerReceipt },
    AcquireReceipts = { acquireReceipt }
};

// 序列化为字节数组
var bytes = request.ToByteArray();

// 通过蓝牙发送数据
var outputStream = socket.OutputStream!;
outputStream.Write(bytes, 0, bytes.Length);
outputStream.Flush();

socket.Close();

注意:若终端对消息结构有特殊要求(比如嵌套方式不同),需根据实际proto定义调整对象构建逻辑,确保序列化后的字节完全匹配终端协议。

3. 触发POS终端打印收据

终端接收格式正确的Protobuf数据后,通常会自动触发打印逻辑,需注意以下细节:

  • 确保发送的ReceiptsRequest完全匹配/acquire/refund/receipts/print端点的字段要求,包括枚举值、字段顺序、可选字段的填充规则。
  • 部分终端要求在Protobuf数据后发送结束标识(比如\r\n),可在Flush()后添加:
    var endMarker = Encoding.ASCII.GetBytes("\r\n");
    outputStream.Write(endMarker, 0, endMarker.Length);
    outputStream.Flush();
    
  • 增加异常捕获与重试逻辑,避免蓝牙连接不稳定导致的发送失败:
    try
    {
        // 蓝牙连接与发送代码
    }
    catch (IOException ex)
    {
        // 处理连接异常,比如重试连接或提示用户
    }
    

内容的提问来源于stack exchange,提问作者DPTP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:23:15