๐Ÿ“š Developer Documentation

IMIN Go-Print

Dokumentasi lengkap untuk mengintegrasikan printer thermal IMIN dengan aplikasi web Anda. Pelajari COMMANDS object, cara membuat iframe, dan JavaScript untuk print.

info
Dokumentasi ini untuk GoPrint2
Semua COMMANDS, API, dan contoh kode di halaman ini menggunakan pendekatan GoPrint2 โ€” yaitu konversi manual HTML ke ESC/POS via JavaScript. Jika Anda ingin cetak langsung via window.print() tanpa konversi, lihat GoPrint3 โ†’

rocket_launch Getting Started

Ikuti langkah-langkah berikut untuk mulai menggunakan IMIN Go-Print di aplikasi web Anda.

IMIN Logo

๐Ÿ“ฑ Persyaratan Sistem

Sebelum memulai development

๐Ÿช Install IMIN Go-Print App

Aplikasi IMIN Go-Print harus diunduh dan diinstall terlebih dahulu dari IMIN AppStore yang tersedia di perangkat IMIN Anda.

โœ… Perangkat IMIN Required
โœ… IMIN AppStore Access

โš ๏ธ Penting: IMIN AppStore hanya dapat diakses melalui perangkat IMIN resmi. Jika belum memiliki device IMIN, hubungi Sales IMIN atau email ke sales@imin.sg

  1. Buat Iframe

    Tambahkan iframe tersembunyi sebagai "print sink" untuk menerima dan memproses perintah print.

    HTML
    <!-- Iframe tersembunyi untuk print -->
    <iframe id="printSink" class="iframe-sink" style="display:none;"></iframe>
  2. Susun Command Array

    Gunakan COMMANDS object untuk menyusun perintah thermal printing dalam format array.

    JavaScript
    // Helper function untuk wrap text
    function wrapCommandText(raw) {
      return `'${String(raw).replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n")}'`;
    }
    
    // Contoh: Tiket Antrian
    const currentCode = "A-057";
    const currentDesk = "Loket A";
    const date = new Date().toLocaleString("id-ID");
    
    const commandParts = [
      "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",     // Center alignment
      "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",      // Bold ON
      wrapCommandText("NOMOR ANTRIAN\n"),       // Header text
      "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",     
      "COMMANDS.TEXT_FORMAT.TXT_4SQUARE",      // Double size
      wrapCommandText(currentCode + "\n\n"),    // Nomor antrian besar
      "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",     // Bold OFF
      "COMMANDS.TEXT_FORMAT.TXT_NORMAL",       // Normal size
      wrapCommandText("Nomor : " + currentCode + "\n\n"),
      wrapCommandText("Loket: " + currentDesk + "    Estimasi: 3 menit\n"),
      wrapCommandText("Tanggal: " + date + "\n"),
      wrapCommandText("Terima kasih, harap menunggu panggilan.\n\n\n")
    ];
  3. Kirim ke Print

    Function JavaScript untuk mengirim command ke iframe dan trigger print.

    JavaScript
    function sendToIframe(commandArray) {
      // Gabungkan command array menjadi string
      const commandText = commandArray.join("\n");
      
      // Dapatkan iframe element
      const printSink = document.getElementById("printSink");
      const doc = printSink.contentDocument || printSink.contentWindow.document;
      
      // Tulis command ke iframe
      doc.open("text/plain");
      doc.write(commandText);
      doc.close();
      
      // Focus iframe dan trigger print
      printSink.contentWindow.focus();
      setTimeout(() => {
        try {
          printSink.contentWindow.print();
        } catch (err) {
          console.error("Gagal print:", err);
          alert("Print gagal. Pastikan menggunakan browser Chromium/WebView.");
        }
      }, 120);
    }
    
    // Cara pakai
    const btnPrint = document.getElementById("btnPrint");
    btnPrint.addEventListener("click", () => {
      sendToIframe(commandParts);
    });
  4. Loop Print (v1.5.0) - Print Berulang

    Cara mencetak dokumen yang sama sebanyak beberapa kali dengan validasi input dan delay otomatis. Fitur ini sangat berguna untuk mencetak tiket atau struk dalam jumlah banyak.

    HTML
    <!-- Input untuk jumlah print -->
    <div style="margin: 20px 0;">
      <label>
        <span class="material-symbols-outlined">repeat</span>
        Jumlah Print:
        <input id="printLoopCount" type="number" min="1" max="5" value="1" />
      </label>
    </div>
    
    <button id="btnPrint">Demo Print</button>
    JavaScript
    // Event handler untuk tombol print dengan loop
    btnPrint.addEventListener("click", () => {
      // 1. Ambil nilai input jumlah print
      const loopCountInput = document.getElementById("printLoopCount");
      let loopCount = parseInt(loopCountInput.value) || 1;
    
      // 2. Validasi input (min 1, max 5)
      if (loopCount < 1) {
        loopCount = 1;
        loopCountInput.value = 1;
      } else if (loopCount > 5) {
        // Alert jika melebihi batas maksimal
        alert("โš ๏ธ Maksimal jumlah print adalah 5!\n\nSilakan masukkan angka antara 1-5.");
        loopCountInput.value = 5;
        return; // Stop eksekusi
      }
    
      // 3. Ambil payload/command yang akan dicetak
      const payload = preparePrintPayload(); // Function yang menyiapkan command
      const commandText = payload.commandPartsText;
    
      // 4. Loop print sebanyak loopCount
      for (let i = 0; i < loopCount; i++) {
        // Gunakan setTimeout dengan delay untuk menghindari konflik
        setTimeout(() => {
          sendToIframe(commandText);
        }, i * 150); // Delay 150ms antar print
      }
    });
    
    // Penjelasan:
    // - Delay 150ms mencegah konflik antar print job
    // - Setiap print diberi jeda waktu agar printer bisa proses dengan baik
    // - Max 5 untuk menghindari buffer overflow pada printer
    lightbulb
    ๐Ÿ’ก Kenapa Pakai Delay?
    • Mencegah Konflik: Print job yang terlalu cepat bisa saling bentrok
    • Stabilitas Printer: Memberi waktu printer untuk proses setiap job
    • Avoid Buffer Overflow: Printer punya buffer terbatas, delay mencegah overflow
    • Delay Optimal: 150-200ms adalah sweet spot untuk kebanyakan printer
    JavaScript - Alternative (Promise Based)
    // Alternative: Menggunakan async/await untuk kontrol yang lebih baik
    async function printMultiple(commandText, count) {
      for (let i = 0; i < count; i++) {
        // Print satu per satu dengan await
        await new Promise(resolve => {
          sendToIframe(commandText);
          setTimeout(resolve, 200); // Wait 200ms sebelum print berikutnya
        });
      }
      console.log(`โœ… Selesai print ${count}x`);
    }
    
    // Cara pakai
    btnPrint.addEventListener("click", async () => {
      const loopCount = parseInt(document.getElementById("printLoopCount").value) || 1;
    
      if (loopCount > 5) {
        alert("Maksimal 5!");
        return;
      }
    
      const payload = preparePrintPayload();
      await printMultiple(payload.commandPartsText, loopCount);
    });
  5. Contoh Lengkap - Print dengan Loop dan Loading Indicator

    Implementasi lengkap dengan loading state dan feedback ke user.

    JavaScript - Production Ready
    // Function lengkap dengan loading dan error handling
    async function handlePrintWithLoop() {
      const loopCountInput = document.getElementById("printLoopCount");
      const btnPrint = document.getElementById("btnPrint");
      let loopCount = parseInt(loopCountInput.value) || 1;
    
      // Validasi
      if (loopCount < 1 || loopCount > 5) {
        alert("โš ๏ธ Jumlah print harus antara 1-5");
        return;
      }
    
      try {
        // Disable button saat print
        btnPrint.disabled = true;
        btnPrint.textContent = "Printing...";
    
        // Siapkan command
        const payload = preparePrintPayload();
        const commandText = payload.commandPartsText;
    
        // Print dengan loop
        for (let i = 0; i < loopCount; i++) {
          // Update progress
          btnPrint.textContent = `Printing ${i + 1}/${loopCount}...`;
    
          // Print
          await new Promise((resolve, reject) => {
            try {
              sendToIframe(commandText);
              setTimeout(resolve, 200);
            } catch (err) {
              reject(err);
            }
          });
        }
    
        // Success
        btnPrint.textContent = `โœ“ Printed ${loopCount}x`;
        setTimeout(() => {
          btnPrint.textContent = "Demo Print";
          btnPrint.disabled = false;
        }, 2000);
    
      } catch (error) {
        // Error handling
        console.error("Print error:", error);
        alert("โŒ Print gagal: " + error.message);
        btnPrint.textContent = "Demo Print";
        btnPrint.disabled = false;
      }
    }
    
    // Event listener
    document.getElementById("btnPrint").addEventListener("click", handlePrintWithLoop);
info
๐Ÿ’ก Tips Penting:

Pastikan aplikasi web Anda berjalan di Android dengan WebView yang mendukung window.print(). Untuk testing di desktop, gunakan Chrome atau Chromium-based browser.

terminal COMMANDS Object Reference

COMMANDS object menyediakan set lengkap ESC/POS commands yang terorganisir untuk kontrol printer thermal.

qr_code_2 Cetak QR

Perintah ESC/POS mencetak gambar maupun kode QR dalam bentuk data raster. Pustaka aplikasi sudah menangani konversi bitmap sehingga printer menerima stream ESC/POS siap pakai.

Fitur Cara kerja internal Catatan
Cetak QR Data kode QR dibentuk menjadi bitmap kemudian dikirim sebagai raster. Parameter utama: moduleSize, margin, align.

Tidak ada escape sequence tunggal yang diekspos publik, tetapi printer menerima stream ESC/POS hasil konversi otomatis.

Parameter Tipe Nilai default Deskripsi
moduleSize number 6 (58mm) / 8 (80mm) Lebar satu modul QR dalam dot.
margin number 4 Margin putih di sekeliling QR (satuan modul).
ecc enum "M" Error correction level (L, M, Q, H).

keyboard Basic Control Characters

Karakter kontrol dasar untuk komunikasi dengan printer thermal ESC/POS.

Command
Description
Code
LF
Line Feed
'\x0a'
ESC
Escape
'\x1b'
FS
Field Separator
'\x1c'
GS
Group Separator
'\x1d'
US
Unit Separator
'\x1f'
FF
Form Feed
'\x0c'
DLE
Data Link Escape
'\x10'
DC1
Device Control 1
'\x11'
DC4
Device Control 4
'\x14'
EOT
End of Transmission
'\x04'
NUL
Null
'\x00'
EOL
End of Line
'\n'

horizontal_rule Horizontal Line Commands

Garis horizontal untuk pemisah konten pada printer 58mm dan 80mm.

HR_58MM
=================================
Solid line (58mm)
HR2_58MM
*********************************
Dashed line (58mm)
HR3_58MM
---------------------------------
Dotted line (58mm)
HR_80MM
================================================
Solid line (80mm)
HR2_80MM
************************************************
Dashed line (80mm)
HR3_80MM
------------------------------------------------
Dotted line (80mm)

feed Feed Control Sequences

CTL_LF Print and line feed
CTL_FF Form feed
CTL_CR Carriage return
CTL_HT Horizontal tab
CTL_VT Vertical tab

line_weight Line Spacing

LS_DEFAULT Default line spacing
LS_SET Set line spacing
LS_SET1 Alternative line spacing

settings Hardware Control

HW_INIT Initialize printer dan reset semua mode
HW_SELECT Select printer
HW_RESET Reset printer hardware

point_of_sale Cash Drawer

CD_KICK_2
๐Ÿ’ฐ
Send pulse to pin 2
CD_KICK_5
๐Ÿ’ฐ
Send pulse to pin 5

space_bar Margins

BOTTOM Set bottom margin
LEFT Set left margin
RIGHT Set right margin

content_cut Paper Cutting

PAPER_FULL_CUT
โœ‚๏ธ
Potong kertas penuh
PAPER_PART_CUT
โœ‚๏ธ
Potong kertas partial
PAPER_CUT_A
โœ‚๏ธ
Alternative cut A
PAPER_CUT_B
โœ‚๏ธ
Alternative cut B

format_size Text Formatting

๐Ÿ“ Text Size & Scaling

TXT_NORMAL
Normal
Normal text size
TXT_2HEIGHT
2x Height
Double height
TXT_2WIDTH
2x Width
Double width
TXT_4SQUARE
4x Square
Double height & width

๐ŸŽจ Text Decoration

TXT_UNDERL_ON Underline ON (1-dot)
TXT_UNDERL2_ON Underline ON (2-dot)
TXT_UNDERL_OFF Underline OFF
TXT_BOLD_ON Bold ON
TXT_BOLD_OFF Bold OFF
TXT_ITALIC_ON Italic ON
TXT_ITALIC_OFF Italic OFF

โ†”๏ธ Text Alignment

TXT_ALIGN_LT
โ† Left
Left alignment
TXT_ALIGN_CT
โ†” Center
Center alignment
TXT_ALIGN_RT
Right โ†’
Right alignment

๐Ÿ”ค Font Types

TXT_FONT_A Font Type A (Default)
TXT_FONT_B Font Type B
TXT_FONT_C Font Type C

library_books Panduan Demo Thermal

Ringkasan demo yang aktif beserta potongan kode siap pakai. Tiap kartu mengarah ke halaman demonya sehingga Anda tidak perlu kembali ke playground.

Demo Antrian (Text)

Format dasar tiket antrian. Gunakan Demo Antrian untuk melihat hasil langsung.

const commandParts = [
  "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
  wrap("NOMOR ANTRIAN\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_4SQUARE",
  wrap(code + "\\n\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
  wrap("Loket: " + desk + "\\n"),
  wrap("Tanggal: " + timestamp + "\\n"),
  wrap("Terima kasih, harap menunggu panggilan.\\n\\n\\n")
];

Demo QR Code

Menambahkan COMMANDS.QR() untuk validasi antrian. Lihat hasilnya di Demo QR.

const commandParts = [
  "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
  wrap("SCAN KODE BERIKUT\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
  "COMMANDS.TEXT_FORMAT.TXT_4SQUARE",
  wrap(code + "\\n\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
  `COMMANDS.QR("${code}", { align: "CENTER", moduleSize: 8, margin: 2, ecc: "M" })`,
  wrap("\\nLoket: " + desk + "\\n"),
  wrap("Terima kasih\\n\\n")
];

Demo Struk Cafe

Contoh pesanan dengan subtotal, pajak, dan pemotongan kertas. Jalankan di Demo Struk.

const commandParts = [
  "COMMANDS.HW_INIT",
  "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
  wrap("BoostechLab Coffee\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
  wrap("Jl. Contoh No. 123\\n\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_ALIGN_LT",
  wrap(items.join("\\n")),
  "COMMANDS.HR_58MM",
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
  wrap("TOTAL      Rp " + total + "\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
  wrap("\\nMetode: " + payment + "\\n\\n"),
  "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
  wrap("Terima kasih atas kunjungan Anda\\n\\n"),
  "COMMANDS.PAPER_FULL_CUT"
];

code Contoh Lengkap

Berikut contoh lengkap implementasi cetak struk dengan semua komponen yang dibutuhkan.

HTML + JavaScript
download Download
<!DOCTYPE html>
<html>
<head>
  <title>IMIN Go-Print Example</title>
</head>
<body>
  <h1>Cetak Struk Thermal</h1>
  <button id="btnPrint" type="button">Print Struk</button>

  <!-- Iframe tersembunyi -->
  <iframe id="printSink" style="display:none;"></iframe>

  <script>
    // Helper function
    function wrapCommandText(raw) {
      return `'${String(raw).replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n")}'`;
    }

    // Function kirim ke print
    function sendToIframe(commandArray) {
      const commandText = commandArray.join("\n");
      const printSink = document.getElementById("printSink");
      const doc = printSink.contentDocument || printSink.contentWindow.document;

      doc.open("text/plain");
      doc.write(commandText);
      doc.close();

      printSink.contentWindow.focus();
      setTimeout(() => {
        try {
          printSink.contentWindow.print();
        } catch (err) {
          console.error("Print gagal:", err);
        }
      }, 120);
    }

    // Event listener
    document.getElementById("btnPrint").addEventListener("click", () => {
      const now = new Date().toLocaleString("id-ID");

      const commandParts = [
        "COMMANDS.HW_INIT",                             // Reset printer
        "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",           // Center
        "COMMANDS.TEXT_FORMAT.TXT_2HEIGHT",            // Double height
        "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",            // Bold ON
        wrapCommandText("TOKO SAYA\n"),                // Nama toko
        "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
        "COMMANDS.TEXT_FORMAT.TXT_NORMAL",
        wrapCommandText("Jl. Contoh No. 123\n"),
        wrapCommandText("Telp: 021-12345678\n\n"),
        "COMMANDS.HR_58MM",                             // Garis
        "COMMANDS.TEXT_FORMAT.TXT_ALIGN_LT",           // Left
        wrapCommandText("Tanggal: " + now + "\n\n"),
        wrapCommandText("Item 1          Rp 10.000\n"),
        wrapCommandText("Item 2          Rp 15.000\n"),
        wrapCommandText("Item 3          Rp 20.000\n"),
        "COMMANDS.HR_58MM",
        "COMMANDS.TEXT_FORMAT.TXT_BOLD_ON",
        wrapCommandText("TOTAL           Rp 45.000\n"),
        "COMMANDS.TEXT_FORMAT.TXT_BOLD_OFF",
        wrapCommandText("\n"),
        "COMMANDS.TEXT_FORMAT.TXT_ALIGN_CT",
        wrapCommandText("Terima Kasih\n"),
        wrapCommandText("Selamat Berbelanja Kembali\n\n\n"),
        "COMMANDS.PAPER_FULL_CUT"                       // Cut paper
      ];

      sendToIframe(commandParts);
    });
  </script>
</body>
</html>
play_circle Lihat Demo Langsung home Kembali ke Home