首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C#/JS/PHP 實現小票打印二維碼、掃碼付款完整技術棧指南

     編輯:程式設計綜合問答

需求:POS 系統生成含二維碼的小票,顧客掃碼即可完成付款。涉及二維碼生成、小票排版列印、掃碼支付回調三大核心環節。以下按語言/平台給出成熟方案與關鍵代碼片段。

核心流程架構

1. 後端生成訂單 → 2. 生成支付二維碼(含訂單ID、金額、簽名) → 3. 小票打印機列印二維碼
4. 顧客掃碼 → 5. 支付平台(微信/支付寶)回調通知 → 6. 後端驗證簽名、更新訂單狀態 → 7. 輪詢/WebSocket 推送付款成功給 POS

C# (.NET) 方案:生成與解碼二維碼

推薦庫:QRCoder(純 .NET、無外部依賴)

// NuGet: Install-Package QRCoder
using QRCoder;

public byte[] GenerateQrCode(string payload, int pixelsPerModule = 20) {
    using var qrGenerator = new QRCodeGenerator();
    using var qrCodeData = qrGenerator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q);
    using var qrCode = new PngByteQRCode(qrCodeData);
    return qrCode.GetGraphic(pixelsPerModule); // 返回 PNG 位元組陣列
}

// 列印小票(ESC/POS 指令,適用熱敏打印機)
public void PrintReceipt(byte[] qrPngBytes, OrderInfo order) {
    var printer = new RawPrinterHelper("POS-58"); // 打印機名稱
    printer.PrintBytes(new byte[] { 0x1B, 0x40 }); // 初始化
    printer.PrintText($"訂單號: {order.Id}\n金額: {order.Amount:C}\n時間: {order.Time:yyyy-MM-dd HH:mm}\n");
    printer.PrintBytes(new byte[] { 0x1B, 0x33, 0x18 }); // 設定行距
    printer.PrintImage(qrPngBytes); // 列印二維碼圖片
    printer.PrintBytes(new byte[] { 0x1D, 0x56, 0x00 }); // 切紙
}

JavaScript (Node.js/瀏覽器) 方案:前端生成/掃描

生成:qrcode.js / qrcode.react

<!-- 瀏覽器端 -->
<div id="qrcode"></div>
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
<script>
  new QRCode(document.getElementById("qrcode"), {
    text: "https://pay.example.com/order/12345?amt=100&sign=abc",
    width: 200, height: 200,
    correctLevel: QRCode.CorrectLevel.H
  });
</script>

掃描:html5-qrcode(調用攝像頭)

<div id="reader"></div>
<script src="https://cdn.jsdelivr.net/npm/html5-qrcode@2.3.8/minified/html5-qrcode.min.js"></script>
<script>
  const scanner = new Html5Qrcode("reader");
  scanner.start({ facingMode: "environment" }, { fps: 10, qrbox: 250 },
    (decodedText) => { console.log("掃碼結果:", decodedText); callPayApi(decodedText); },
    (err) => { /* 忽略掃描失敗 */ }
  );
</script>

PHP 方案:微信/支付寶原生支付整合

推薦 SDK:yansongda/pay (Packagist 下載量最高)

// composer require yansongda/pay
use Yansongda\Pay\Pay;

$config = [
    'app_id' => 'wx_app_id',
    'mch_id' => 'mch_id',
    'key' => 'api_key',
    'cert_client' => './cert/apiclient_cert.pem',
    'cert_key' => './cert/apiclient_key.pem',
    'notify_url' => 'https://your.com/pay/notify',
];

$pay = Pay::wechat($config);

// 統一下單,獲取 code_url(二維碼內容)
$result = $pay->driver('native')->pay([
    'out_trade_no' => 'ORDER_12345',
    'total_fee' => 100, // 分
    'body' => '商品名稱',
    'openid' => 'user_openid', // JSAPI 需要,NATIVE 可選
]);

$qrContent = $result['code_url']; // 直接用此字串生成二維碼列印

回調驗證與業務處理


// notify.php
$pay = Pay::wechat($config);
try {
    $data = $pay->verify(); // 自動驗證簽名
    if ($data['return_code'] === 'SUCCESS' && $data['result_code'] === 'SUCCESS') {
        $orderId = $data['out_trade_no'];
        // 更新訂單狀態:已付款
        Order::where('id', $orderId)->update(['status' => 'paid', 'paid_at' => now()]);
        // 推送通知給 POS(WebSocket / 長輪詢 / Server-Sent Events)
        Pusher::trigger('pos-channel', 'order.paid', ['order_id' => $orderId]);
    }
    return $pay->success(); // 返回 SUCCESS 給微信
} catch (\Exception $e) {
    Log::error($e);
    return $pay->fail();
}

關鍵注意事項

環節風險點對策
二維碼內容包含敏感資訊、長度過長導致識別率下降僅放支付連結/訂單ID,簽名驗證在後端;使用高容錯等級 (Q/H)
小票列印熱敏紙褪色、二維碼模糊無法掃描設定較高 DPI、適當放大模組像素、保留足夠靜區
支付回調重複通知、偽造通知、網路中斷未收到冪等處理(訂單狀態機)、驗證簽名、提供主動查單 API 兜底
並發安全同一訂單重複支付資料庫唯一索引 out_trade_no、樂觀鎖、分散式鎖

跨平台整合建議

  • 統一支付網關服務:後端封裝微信/支付寶/銀聯,對外提供 POST /api/pay/qrcode 返回 { qr_code: "data:image/png;base64,..." },POS 端(C#/Java/Node)只需調用並列印。
  • 即時狀態同步:POS 端建立 WebSocket 連線至後端,付款成功後伺服器推送 order.paid 事件,避免輪詢延遲。
  • 測試環境:使用微信/支付寶沙箱環境,完整跑通「下單→生成碼→掃碼→回調→推送」全鏈路。

掌握上述三棧技術要點,即可構建穩定、安全的「小票二維碼掃碼付款」系統。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved