Dokumentasi API Bayarlink

Dokumen ini ditujukan untuk developer dan agen AI (mis. Claude Code) yang membangun integrasi dengan Bayarlink dari proyek web lain. Isinya diturunkan langsung dari kode API yang berjalan di produksi (versi 25 Oktober 2026).

1. Ringkasan

Bayarlink adalah platform link berbayar: pemilik akun menempel URL tujuan (file, materi kelas, konten digital), menetapkan harga akses, lalu membagikan link pendek. Pembeli yang membuka link pendek membayar lewat QRIS sebelum bisa membuka URL tujuan.

API v1 memungkinkan program lain, atas nama satu akun Bayarlink, untuk:

BisaTidak bisa
Melihat info akun dasar (GET /me)Menghapus link
Melihat daftar link milik akun (GET /links)Mengubah URL tujuan link
Melihat detail satu link (GET /links/{code})Melihat saldo, transaksi, pembeli, atau penarikan
Membuat link berbayar baru (POST /links)Mengakses link milik akun lain
Mengubah harga link (PATCH /links/{code})Membuat akun atau login atas nama user

Base URL

https://bayarlink.com/api/v1
  • Hanya HTTPS. Gunakan host bayarlink.com (tanpa www).
  • Semua respons berformat JSON (Content-Type: application/json; charset=utf-8), tidak di-cache (Cache-Control: no-store).
  • API tidak memakai cookie/sesi. Setiap permintaan wajib membawa token.

2. Autentikasi

2.1 Mendapatkan token

Token dibuat oleh pemilik akun dari situs, bukan lewat API:

  1. Masuk ke https://bayarlink.com/signin
  2. Buka menu API (halaman Dokumentasi API, https://bayarlink.com/dokumentasi-api).
  3. Isi Nama token (mis. toko-saya-produksi), klik Buat token.
  4. Salin token saat itu juga — token hanya ditampilkan sekali. Server hanya menyimpan hash-nya; token yang hilang tidak bisa dilihat lagi, harus dibuat baru.

Aturan token:

  • Format: bl_ diikuti 40 karakter heksadesimal huruf kecil, total 43 karakter. Regex: ^bl_[0-9a-f]{40}$
  • Maksimal 5 token aktif per akun. Cabut salah satu (tombol Cabut) untuk membuat yang baru.
  • Token yang dicabut langsung tidak berlaku.
  • Token tidak bisa dibuat/dikelola saat admin sedang "masuk sebagai pengguna lain" (impersonasi), dan tidak bisa dipakai bila akun diblokir.
  • Saat token dibuat, pemilik akun menerima email notifikasi keamanan.

2.2 Mengirim token

Kirim di header HTTP Authorization dengan skema Bearer:

Authorization: Bearer bl_0123456789abcdef0123456789abcdef01234567

Token tidak diterima lewat query string, cookie, atau body.

2.3 Keamanan token (WAJIB dipatuhi integrasi)

  • Simpan token hanya di server (variabel lingkungan / secret manager), mis. BAYARLINK_API_TOKEN. Jangan commit ke git, jangan tulis ke log, jangan kirim ke browser.
  • Jangan panggil API langsung dari JavaScript di browser. Walau server mengirim Access-Control-Allow-Origin: *, memanggil dari browser berarti token terlihat oleh pengunjung. Selalu lewat backend proyek Anda (proxy/route server-side).
  • Satu token per lingkungan/proyek (mis. produksi, staging) agar mudah dicabut tanpa mengganggu yang lain.
  • Bila token bocor: cabut di halaman Dokumentasi API, buat yang baru.

3. Format respons

3.1 Sukses

{
  "ok": true,
  "data": { ... }
}

Untuk daftar berhalaman, ada tambahan meta (lihat GET /links).

3.2 Gagal

{
  "ok": false,
  "error": {
    "code": "validation_failed",
    "message": "Data tidak valid.",
    "details": {
      "price": "Harga minimal Rp2.000 dan maksimal Rp1.000.000 (bilangan bulat)."
    }
  }
}
  • error.code — kode mesin yang stabil; gunakan ini untuk logika program.
  • error.message — pesan berbahasa Indonesia untuk manusia (boleh berubah).
  • error.details — opsional; peta nama_field → pesan untuk kesalahan validasi.

Semua endpoint link mengembalikan objek dengan bentuk berikut:

{
  "short_code": "aB3xYz",
  "short_url": "https://bayarlink.com/aB3xYz",
  "product_url": "https://drive.google.com/file/d/xxxx/view",
  "price": 15000,
  "clicks": 42,
  "created_at": "2026-10-25 14:30:05"
}
FieldTipeKeterangan
short_codestringKode unik link pendek. Link buatan API: 6 karakter dari abcdefghjkmnpqrstuvwxyzACDEFGHJKLMNPQRSTUVWXYZ23456789. Link lama bisa berbeda panjang (maks 10, alfanumerik).
short_urlstringURL yang dibagikan ke pembeli.
product_urlstringURL tujuan yang terbuka setelah pembeli membayar. Rahasiakan dari pembeli — inilah yang dijual.
priceintegerHarga akses dalam Rupiah (bilangan bulat, tanpa desimal).
clicksintegerJumlah kunjungan ke link pendek.
created_atstringWaktu dibuat, format YYYY-MM-DD HH:MM:SS, zona waktu WIB (UTC+7), tanpa offset.

4. Endpoint

4.1 GET /me — info akun

Memeriksa token dan mengetahui akun pemiliknya.

curl -s https://bayarlink.com/api/v1/me \
  -H "Authorization: Bearer $BAYARLINK_API_TOKEN"

Respons 200:

{ "ok": true, "data": { "id": 1234, "username": "tokosaya" } }

Tidak ada data sensitif (email, saldo, rekening) di endpoint ini.

Mengembalikan link milik akun, terbaru dulu, 20 per halaman.

QueryWajibKeterangan
pagetidakNomor halaman, mulai 1 (default 1).
curl -s "https://bayarlink.com/api/v1/links?page=1" \
  -H "Authorization: Bearer $BAYARLINK_API_TOKEN"

Respons 200:

{
  "ok": true,
  "data": [
    {
      "short_code": "aB3xYz",
      "short_url": "https://bayarlink.com/aB3xYz",
      "product_url": "https://contoh.com/ebook.pdf",
      "price": 15000,
      "clicks": 42,
      "created_at": "2026-10-25 14:30:05"
    }
  ],
  "meta": { "page": 1, "per_page": 20, "total": 57, "total_pages": 3 }
}

Catatan: per_page tetap 20 (tidak bisa diubah). Untuk mengambil semua link, ulangi sampai page == total_pages.

4.3 POST /links — buat link berbayar

Body bisa JSON (disarankan) atau application/x-www-form-urlencoded.

FieldTipeWajibAturan
product_urlstringyaURL valid berawalan http:// atau https://; maks 2000 karakter; tidak boleh mengarah ke bayarlink.com (atau subdomainnya), localhost, 127.0.0.1, 0.0.0.0, ::1, atau alamat jaringan privat (10.*, 192.168.*, 172.16–31.*, 169.254.*).
priceinteger (atau string digit)yaBilangan bulat 2000 sampai 1000000 (Rupiah). Desimal, negatif, "15.000", "Rp15000" → ditolak.
curl -s -X POST https://bayarlink.com/api/v1/links \
  -H "Authorization: Bearer $BAYARLINK_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_url":"https://contoh.com/ebook.pdf","price":15000}'

Respons 201 Created: data berisi objek Link yang baru dibuat (lihat 3.3).

Kemungkinan gagal:

Statuserror.codeSebab
422validation_faileddetails.product_url dan/atau details.price berisi alasannya.
422invalid_jsonContent-Type: application/json tetapi body bukan JSON valid.
429rate_limitedLebih dari 10 link dibuat dalam 5 menit oleh akun ini (dihitung lintas semua token & termasuk link buatan dashboard). Lihat header Retry-After (300 detik).

⚠️ Tidak ada idempotency key. Jika permintaan POST timeout/putus, jangan langsung mengulang — bisa menghasilkan link ganda. Periksa dulu GET /links?page=1 apakah link dengan product_url dan price yang sama baru saja terbuat, baru ulangi bila tidak ada. Duplikat product_url diizinkan oleh sistem (tidak ditolak), jadi pencegahan duplikat adalah tanggung jawab klien.

curl -s https://bayarlink.com/api/v1/links/aB3xYz \
  -H "Authorization: Bearer $BAYARLINK_API_TOKEN"

Respons 200: objek Link. 404 not_found bila kode tidak ada atau milik akun lain (sengaja tidak dibedakan).

short_code di path: alfanumerik 1–10 karakter, peka huruf besar/kecil.

Hanya field price yang bisa diubah. product_url tidak bisa diubah lewat API.

curl -s -X PATCH https://bayarlink.com/api/v1/links/aB3xYz \
  -H "Authorization: Bearer $BAYARLINK_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"price":25000}'

Respons 200: objek Link dengan harga baru.

Statuserror.codeSebab
404not_foundLink tidak ada / bukan milik akun.
422validation_failedprice di luar 2000–1000000 atau bukan bilangan bulat.

Harga baru berlaku untuk pembeli berikutnya. PATCH dengan harga yang sama aman diulang (idempoten).

💰 Harga = uang sungguhan yang ditagih ke pembeli. Integrasi wajib memvalidasi harga di sisi Anda juga, dan sebaiknya meminta konfirmasi manusia sebelum mengubah harga secara massal.

4.6 OPTIONS (preflight)

OPTIONS ke endpoint mana pun membalas 204 tanpa autentikasi, dengan header: Access-Control-Allow-Origin: *, Access-Control-Allow-Headers: Authorization, Content-Type, Access-Control-Allow-Methods: GET, POST, PATCH, OPTIONS. (Tetap ingat 2.3: jangan panggil dari browser.)

5. Batas pemakaian (rate limit)

BatasNilaiLingkupRespons bila lewat
Permintaan umum60 permintaan / 60 detikper akun (semua token akun berbagi kuota)429 rate_limited + Retry-After
Pembuatan link10 link / 5 menitper akun (termasuk via dashboard)429 rate_limited + Retry-After: 300
Autentikasi gagal20 kegagalan / 10 menitper alamat IP429 rate_limited + Retry-After — berlaku juga untuk token yang benar dari IP itu sampai jendela habis

Header pada setiap respons yang lolos autentikasi:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1793012345      (Unix timestamp, detik)

Saran klien:

  • Baca X-RateLimit-Remaining; bila mendekati 0, tunggu sampai X-RateLimit-Reset.
  • Saat 429, tunggu minimal Retry-After detik sebelum mencoba lagi.
  • Jangan mengulang otomatis permintaan yang gagal 401 — token salah yang diulang terus akan memblokir IP server Anda 10 menit.

6. Daftar kode error

HTTPerror.codeArtiTindakan klien
401unauthorizedHeader Authorization tidak ada / format salah.Perbaiki header; jangan ulang otomatis.
401invalid_tokenToken tidak dikenal.Periksa token; jangan ulang otomatis.
401token_revokedToken sudah dicabut.Minta token baru dari pemilik akun.
403account_blockedAkun pemilik token diblokir.Hentikan; hubungi support.
404not_foundEndpoint tidak ada, atau link tidak ada/bukan milik akun.Periksa path/kode.
405method_not_allowedMetode HTTP salah. Header Allow berisi metode yang benar.Perbaiki metode.
422validation_failedData tidak valid; lihat error.details.Perbaiki data; jangan ulang tanpa perubahan.
422invalid_jsonBody JSON rusak.Perbaiki body.
429rate_limitedKena batas pemakaian.Tunggu Retry-After.
500server_errorKesalahan tak terduga di server.Ulangi dengan backoff (kecuali POST, lihat 4.3).
503service_unavailableLayanan sementara tidak tersedia.Ulangi dengan backoff eksponensial (mis. 2s, 4s, 8s, 16s).

7. Contoh klien

7.1 PHP (tanpa library)

<?php
function bayarlink(string $method, string $path, ?array $body = null): array
{
    $token = getenv('BAYARLINK_API_TOKEN');           // simpan di env, bukan di kode
    $ch = curl_init('https://bayarlink.com/api/v1' . $path);
    $headers = ['Authorization: Bearer ' . $token, 'Accept: application/json'];
    if ($body !== null) {
        $headers[] = 'Content-Type: application/json';
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
    }
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 15,
    ]);
    $raw    = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);
    $json = json_decode((string)$raw, true) ?: ['ok' => false, 'error' => ['code' => 'bad_response', 'message' => 'Respons bukan JSON']];
    $json['_status'] = $status;
    return $json;
}

// Buat link
$r = bayarlink('POST', '/links', ['product_url' => 'https://contoh.com/ebook.pdf', 'price' => 15000]);
if ($r['ok']) {
    echo $r['data']['short_url'];
} else {
    error_log('Bayarlink: ' . $r['error']['code'] . ' - ' . $r['error']['message']);
}

7.2 Node.js (18+, fetch bawaan)

const BASE = 'https://bayarlink.com/api/v1';

export async function bayarlink(method, path, body) {
  const res = await fetch(BASE + path, {
    method,
    headers: {
      Authorization: `Bearer ${process.env.BAYARLINK_API_TOKEN}`,
      ...(body ? { 'Content-Type': 'application/json' } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
    signal: AbortSignal.timeout(15000),
  });
  const json = await res.json().catch(() => ({ ok: false, error: { code: 'bad_response' } }));
  if (res.status === 429) {
    const wait = Number(res.headers.get('Retry-After') || 60);
    throw Object.assign(new Error('rate_limited'), { retryAfter: wait });
  }
  return { status: res.status, ...json };
}

// Ubah harga
const r = await bayarlink('PATCH', '/links/aB3xYz', { price: 25000 });

7.3 Python 3 (requests)

import os, requests

BASE = "https://bayarlink.com/api/v1"
S = requests.Session()
S.headers["Authorization"] = f"Bearer {os.environ['BAYARLINK_API_TOKEN']}"

def semua_link():
    page, hasil = 1, []
    while True:
        r = S.get(f"{BASE}/links", params={"page": page}, timeout=15).json()
        if not r["ok"]:
            raise RuntimeError(r["error"])
        hasil += r["data"]
        if page >= r["meta"]["total_pages"]:
            return hasil
        page += 1

8. Panduan untuk agen AI / pengembang integrasi

  1. Mulai dengan GET /me untuk memastikan token benar sebelum fitur lain.
  2. Token hanya di server (BAYARLINK_API_TOKEN di .env yang tidak di-commit). Jangan cetak token ke log/console. Jangan buat endpoint publik yang meneruskan permintaan mentah ke Bayarlink.
  3. Validasi di sisi Anda sebelum memanggil API: harga bilangan bulat 2000–1000000; URL http/https publik; maksimal 10 pembuatan link per 5 menit per akun.
  4. POST /links tidak idempoten — cegah klik ganda di UI Anda, dan jangan retry otomatis setelah timeout tanpa memeriksa GET /links (lihat 4.3).
  5. Hormati 429/Retry-After dan jangan retry 401/403/404/422.
  6. Simpan short_code di database proyek Anda untuk menautkan produk Anda dengan link Bayarlink; ambil detail terbaru dengan GET /links/{short_code} bila perlu.
  7. Jangan tampilkan product_url ke pembeli — itu konten berbayar. Tampilkan hanya short_url.
  8. Waktu created_at adalah WIB tanpa offset — konversikan dengan zona Asia/Jakarta.
  9. Tidak ada webhook dan tidak ada endpoint transaksi/saldo. Status pembayaran pembeli hanya bisa dilihat pemilik akun di dashboard Bayarlink. Jangan merancang fitur yang bergantung pada notifikasi pembayaran dari API ini.
  10. Perubahan harga memengaruhi uang yang dibayar pembeli — mintalah konfirmasi manusia untuk perubahan massal.

9. Cara kerja dari sisi pembeli (konteks bisnis)

  1. Pembeli membuka short_url.
  2. Halaman Bayarlink menampilkan harga dan username penjual, lalu tombol untuk menampilkan kode QRIS (berlaku 1 jam).
  3. Setelah pembayaran diterima, muncul tombol Buka konten menuju product_url.
  4. Akses berlaku 24 jam sejak pembayaran, dari jaringan (alamat IP) yang sama.
  5. Pemilik link menerima hasil penjualan ke saldo setelah dipotong biaya layanan 10% (hanya saat ada penjualan; cek angka terbaru di https://bayarlink.com/about).
  6. Penarikan saldo diajukan pemilik akun dari dashboard (hari kerja Senin–Jumat, 1× per hari; dana dikirim maksimal 24 jam setelah pengajuan dibuat). Tidak tersedia lewat API.

Pastikan konten yang dijual adalah milik sendiri atau berhak dijual — lihat https://bayarlink.com/terms.

10. Bantuan

  • Dokumentasi di dalam akun: https://bayarlink.com/dokumentasi-api (perlu login)
  • Panduan umum: https://bayarlink.com/blog/
  • Kontak: support@bayarlink.com

Siap mencoba? Buat akun, lalu buat token di menu API.

Daftar Bayarlink