Satu API.
Semua framework.
Hubungkan aplikasi POS, WMS, atau web Anda ke printer lokal melalui Mrjee Print Bridge.
Installation
- Download installer hanya dari
mrjeeprint.comatau GitHub Release resmi. - Scan file menggunakan Windows Security jika diperlukan.
- Install dan buka aplikasi—Public Beta tidak memerlukan akun atau license key.
- Buka Settings lalu salin Local API Security Token yang dibuat otomatis.
- Buat printer mapping, misalnya
receipt-main. - Tambahkan origin aplikasi web ke CORS allowlist.
- Panggil endpoint lokal dari frontend Anda.
Peringatan Microsoft SmartScreen
Installer Public Beta v1.0.1 belum memiliki sertifikat code signing komersial. Windows dapat menampilkan pesan “Windows protected your PC” atau “Unknown publisher” karena identitas penerbit belum diverifikasi dan file belum memiliki reputasi unduhan yang cukup. Pesan tersebut bukan otomatis merupakan hasil deteksi malware.
- Pastikan installer diunduh dari website atau GitHub resmi.
- Klik kanan file, lalu scan menggunakan Microsoft Defender.
- Jika ingin melanjutkan, pilih More info lalu Run anyway.
- Jangan jalankan file yang diperoleh dari mirror, chat, atau pihak lain.
SHA-256 installer resmi v1.0.1:
B98D452D0F745870039122C2E61094151FA62692D0250D310B20B7DF93CCA5B1Authentication
Endpoint integrasi bebas seperti /api/print membutuhkan bearer token agar website atau program lain tidak dapat mencetak tanpa izin. Public Beta membuat token ini secara otomatis dan menyimpannya terenkripsi di komputer. Token gratis, bukan license key, tidak kedaluwarsa, dan tidak menghubungi server Mrjee. Salin melalui Settings → Local API Security Token, simpan di environment aplikasi, dan jangan commit ke repository publik.
Authorization: Bearer YOUR_SECRET_TOKENMenentukan logical name
logicalName adalah nama tujuan print yang dibuat di aplikasi desktop Mrjee Print Bridge. Nama ini menghubungkan kode aplikasi dengan printer Windows tanpa mengikat kode ke nama hardware tertentu.
- Buka menu printer mapping pada desktop Bridge.
- Pilih printer fisik, misalnya
ZDesigner ZD421. - Isi logical name yang stabil, misalnya
shipping-label. - Pilih format printer seperti PDF, ZPL, SBPL, atau RAW.
- Simpan mapping, lalu gunakan logical name tersebut dari aplikasi web.
shipping-label→ZDesigner ZD421ZPLreceipt-main→EPSON TM-T82RAWinvoice-a4→Canon G2010PDFCheck bridge status
/api/statusPublic health check{
"running": true,
"version": "1.0.0",
"port": 9000,
"license": { "valid": true, "plan": "free" }
}Get available logical names
/api/integration/mappingsBearer token requiredGunakan endpoint ini jika aplikasi perlu menampilkan dropdown tujuan print. Hanya mapping aktif yang dikembalikan.
const response = await fetch(
"http://localhost:9000/api/integration/mappings",
{
headers: {
Authorization: "Bearer YOUR_SECRET_TOKEN"
}
}
);
const { mappings } = await response.json();
// mappings.map(item => item.logicalName){
"success": true,
"mappings": [
{
"logicalName": "shipping-label",
"physicalName": "ZDesigner ZD421",
"type": "zpl",
"enabled": true
}
]
}Get all printers
/api/demo/printersTanpa token · demo-safeMengambil seluruh printer Windows yang terpasang pada komputer pengguna. Hasil mencakup nama, default printer, status, kategori thermal, dan driver type yang terdeteksi.
{
"success": true,
"printers": [
{
"name": "ZDesigner ZD421-203dpi ZPL",
"isDefault": true,
"status": "Normal",
"isThermal": true,
"driverType": "ZPL"
}
]
}Demo test print
/api/demo-printTanpa akun dan bearer tokenEndpoint terbatas untuk halaman demo resmi, request loopback, payload test bawaan, dan maksimal satu job setiap lima detik. Endpoint ini tidak menerima data print bebas dari website.
Print by logical name
/api/printBearer token requiredlogicalNamestring · requiredNama mapping aktif dari endpoint integration/mappings.
datastring · requiredBase64 PDF/image atau raw command.
overridesobject · optionalCopies, size, density, dan opsi job.
Print directly
/api/print-directBearer token requiredGunakan jika aplikasi mengetahui nama printer Windows. Untuk production, logical mapping lebih direkomendasikan.
Framework examples
Seluruh contoh mengirim request langsung dari aplikasi ke bridge lokal.
const response = await fetch("http://localhost:9000/api/print", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_SECRET_TOKEN"
},
body: JSON.stringify({
logicalName: "shipping-label",
data: base64Pdf
})
});function PrintButton({ base64Pdf }) {
const print = async () => {
await fetch("http://localhost:9000/api/print", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${import.meta.env.VITE_PRINT_TOKEN}`
},
body: JSON.stringify({
logicalName: "receipt-main",
data: base64Pdf
})
});
};
return <button onClick={print}>Print receipt</button>;
}"use client";
export async function printLabel(data: string) {
return fetch("http://localhost:9000/api/print", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.NEXT_PUBLIC_PRINT_TOKEN}`
},
body: JSON.stringify({ logicalName: "label-main", data })
});
}<script setup>
const printReceipt = async (data) => {
await fetch("http://localhost:9000/api/print", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${import.meta.env.VITE_PRINT_TOKEN}`
},
body: JSON.stringify({ logicalName: "receipt-main", data })
});
};
</script>import { HttpClient, HttpHeaders } from "@angular/common/http";
printLabel(data: string) {
const headers = new HttpHeaders({
"Content-Type": "application/json",
Authorization: `Bearer ${environment.printBridgeToken}`
});
return this.http.post("http://localhost:9000/api/print", {
logicalName: "label-main",
data
}, { headers });
}const result = await fetch("http://localhost:9000/api/print", {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${process.env.PRINT_BRIDGE_TOKEN}`
},
body: JSON.stringify({
logicalName: "warehouse-label",
data: zplCommand
})
});$payload = json_encode([
"logicalName" => "receipt-main",
"data" => $base64Pdf
]);
$ch = curl_init("http://localhost:9000/api/print");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Authorization: Bearer " . getenv("PRINT_BRIDGE_TOKEN")
],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true
]);
$result = curl_exec($ch);use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.print_bridge.token'))
->post('http://localhost:9000/api/print', [
'logicalName' => 'receipt-main',
'data' => $base64Pdf,
]);
$response->throw();import os, requests
response = requests.post(
"http://localhost:9000/api/print",
headers={
"Authorization": f"Bearer {os.environ['PRINT_BRIDGE_TOKEN']}"
},
json={
"logicalName": "shipping-label",
"data": base64_pdf
},
timeout=30
)
response.raise_for_status()using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", printBridgeToken);
var response = await client.PostAsJsonAsync(
"http://localhost:9000/api/print",
new { logicalName = "shipping-label", data = base64Pdf }
);
response.EnsureSuccessStatusCode();curl -X POST http://localhost:9000/api/print \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_SECRET_TOKEN" \
-d '{
"logicalName": "receipt-main",
"data": "BASE64_OR_RAW_DATA"
}'Error codes
401UNAUTHORIZEDBearer token salah atau tidak ada.
500PRINT_FAILEDMapping atau proses printer gagal.
503TOKEN_NOT_CONFIGUREDSecret token belum diatur.
CORS setup
Tambahkan origin exact aplikasi, misalnya https://pos.example.com. Hindari wildcard * pada production.
Troubleshooting
Windows menampilkan “Unknown publisher”
Versi Public Beta belum ditandatangani dengan sertifikat code signing komersial. Verifikasi sumber download dan SHA-256, scan dengan Microsoft Defender, lalu gunakan More info → Run anyway jika Anda mempercayai file resmi tersebut.
Failed to fetch / bridge offline
Pastikan aplikasi desktop berjalan, port sesuai, dan firewall Windows tidak memblokir localhost.
Origin blocked by CORS
Tambahkan protocol, domain, dan port aplikasi ke CORS allowlist.
Printer mapping not found
Pastikan logicalName sama persis dengan mapping aktif di desktop bridge.