Dokumentasi Reseller & Developer API

Panduan Lengkap Reseller
& Panduan Bangun Website Toko Sendiri

Dokumentasi terpadu untuk reseller perorangan, pemilik konter, hingga developer yang ingin membangun website / bot topup sendiri dengan mengambil produk & harga modal dari NexShop via REST API dan Webhook Relay.

Download Dokumentasi PDF
Daftar Isi Panduan Lengkap
  1. Apa itu Program Reseller?
  2. Keuntungan Reseller NexShop
  3. Cara Mendaftar Reseller
  4. Tingkatan Tier & Diskon
  5. Alur Membangun Website Toko Sendiri
  6. Autentikasi API Reseller
  7. API Get Produk & Harga Modal Reseller
  8. API Transaksi, Validasi ID & Status
  9. Konsep Webhook Reseller
  10. Format Header & Payload JSON
  11. Verifikasi Signature HMAC SHA-256
  12. Contoh Skrip Siap Pakai (Full Flow)
  13. Pertanyaan Umum (FAQ)
  14. Kontak Admin & Dukungan
Bab 1

Apa itu Program Reseller NexShop?

Program Reseller NexShop adalah solusi kemitraan terpadu yang dirancang bagi:

  • Reseller Web / Konter: Langsung belanja di NexShop dengan harga diskon otomatis saat login.
  • Pemilik Website Toko Sendiri / Bot: Menghubungkan website/bot Anda ke API NexShop untuk mengambil katalog, harga reseller, dan menerima notifikasi pesanan otomatis.

Konsep Kemitraan

Setelah akun Anda disetujui, harga di seluruh etalase (Marketplace & Topup Diamond Game) otomatis dipotong sesuai tingkatan tier diskon saat Anda login di web maupun saat memanggil Open API dengan API Key dan Secret Key. Anda bebas menentukan harga jual sendiri ke pelanggan untuk mendapatkan margin keuntungan maksimal.

Bab 2

Keuntungan Menjadi Reseller NexShop

Nikmati kemudahan bertransaksi tanpa beban operasional yang rumit.

Harga Otomatis Terpasang

Katalog API dan Web langsung menghasilkan harga modal reseller berdasarkan tier diskon akun Anda.

Pendaftaran Tanpa Biaya

Tidak ada biaya pendaftaran. Belanja langsung di web dapat dibayar per transaksi; penggunaan Open API memotong saldo reseller yang Anda isi melalui Partner Portal.

API Lengkap & Stabil

Endpoint katalog, validasi Player ID Game, pembuatan order idempoten, cek status, saldo, dan webhook transaksi.

Jalur Dukungan Prioritas

Konsultasi, penanganan kendala transaksi, dan integrasi teknis ditangani langsung via WhatsApp khusus.

Bab 3

Cara Mendaftar Menjadi Reseller NexShop

Pendaftaran mitra dilakukan langsung di Partner Portal dan tidak dipungut biaya. Ikuti urutan berikut agar akun, KYC, dan akses API terbentuk dengan benar.

Penting: akun portal benar-benar terpisah

Akun belanja/storefront NexShop tidak dapat dipakai untuk masuk ke Partner Portal dan tidak otomatis menjadi akun reseller. Gunakan email khusus Portal Reseller yang belum pernah dipakai untuk akun NexShop, lalu buat password portal tersendiri. Jangan memasukkan password akun belanja pada formulir portal.

1

Buka tab “Daftar Baru & KYC”

Buka Partner Portal NexShop. Tautan tersebut langsung membuka tab Daftar Baru & KYC; Anda tidak perlu membuat atau login ke akun belanja NexShop lebih dahulu.

2

Siapkan identitas portal dan data KYC

Isi data sesuai dokumen dan kondisi usaha yang sebenarnya:

  • Wajib: email Portal Reseller khusus, password portal minimal 8 karakter, Nama Lengkap sesuai KTP, nomor WhatsApp aktif, NIK 16 digit, dan Foto KTP asli yang jelas.
  • Profil usaha: Nama Usaha/Toko, Kanal Penjualan, Estimasi Transaksi Bulanan, serta Catatan Tambahan bila diperlukan.
  • Berkas KTP: JPG atau PNG, maksimal 5 MB, tidak buram, tidak terpotong, dan seluruh data utama dapat dibaca.

KTP diproses melalui penyimpanan privat dan dienkripsi untuk pemeriksaan admin terautentikasi; berkas KYC bukan dokumen publik.

3

Selesaikan verifikasi keamanan dan kirim formulir

Selesaikan verifikasi keamanan/Turnstile (“bukan robot”), periksa kembali email, NIK, nomor WhatsApp, serta Foto KTP, lalu tekan Daftar Akun Portal Reseller & Kirim Berkas KYC satu kali.

Satu pengiriman membuat tiga hal sekaligus: identity Portal Reseller terpisah, pengajuan reseller, dan berkas KYC. Jangan mengulang formulir atau mendaftar lewat login storefront.

4

Akun terbentuk dengan status “Menunggu Verifikasi”

Setelah pengiriman berhasil, sistem memasukkan Anda ke Partner Portal dengan status pending/menunggu verifikasi. Anda dapat membuka dashboard, membaca panduan, melihat katalog, dan menekan Cek Status Verifikasi Terkini tanpa membuat akun baru.

Selama masih pending, akun belum dapat melakukan transaksi reseller atau memakai API. Jangan melakukan deposit atau mengandalkan API Key sebelum status disetujui.

5

Admin meninjau identitas dan KYC

Tim NexShop memeriksa kecocokan identitas, kelengkapan KYC, profil usaha, dan kelayakan pengajuan. Waktu peninjauan maksimal 3×24 jam kerja. Pantau status di dashboard dan pastikan nomor WhatsApp yang didaftarkan tetap aktif bila tim memerlukan klarifikasi.

  • Approved: akses transaksi reseller dibuka dan tier awal ditetapkan admin.
  • Rejected: baca catatan peninjauan atau hubungi Customer Service sebelum memperbaiki data.
  • Suspended: akses dibekukan; penyelesaiannya wajib melalui admin NexShop.
6

Mulai memakai saldo, harga reseller, dan integrasi API

Setelah disetujui, login memakai email dan password Portal Reseller yang dibuat pada langkah 2. Harga modal mengikuti tier aktif. Pasangan API Key dan Secret Key tersedia untuk integrasi server; simpan Secret Key hanya di environment backend dan jangan menaruhnya di browser atau source publik.

7

Aktifkan 2FA opsional untuk memperkuat login

Di menu Pengaturan → Two-Factor Authentication, Anda dapat mengaktifkan 2FA opsional menggunakan aplikasi authenticator. Konfirmasi setup dengan kode 6 digit, kemudian simpan seluruh recovery code di tempat aman.

Setelah 2FA aktif, login memerlukan kode authenticator atau satu recovery code yang belum pernah dipakai. Recovery code bersifat sekali pakai dan tidak dapat diminta kembali dalam bentuk plaintext.

Bab 4

Tingkatan Tier & Diskon Reseller

Diskon reseller dihitung otomatis oleh server NexShop di setiap produk berdasarkan tier tingkatan akun Anda.

Rumus Perhitungan Diskon

Harga Reseller = Harga Normal × (1 − Diskon%)

Contoh: Jika harga normal produk adalah Rp100.000 dan tier akun Anda memiliki diskon 5%, maka harga modal yang Anda bayar ke NexShop adalah Rp95.000. Anda bebas menjual di website Anda misalnya seharga Rp99.000 atau Rp100.000.

Tingkatan Tier Persentase Diskon Deskripsi & Fasilitas
Memuat data tier reseller aktif...
Bab 5 (Developer)

Alur Membangun Website Toko Reseller Sendiri

Jika Anda ingin membangun website toko topup atau bot jualan sendiri, berikut adalah arsitektur integrasi standar yang direkomendasikan:

Siklus Alur Transaksi Toko Anda

1

Tarik Katalog Produk dari NexShop

Backend toko Anda memanggil GET /api/v1/reseller/products memakai API Key dan Secret Key. Respons berisi seluruh produk aktif beserta harga_reseller sesuai tier akun. Simpan atau cache katalog di server Anda; jangan membuka kredensial ini di browser.

2

Pelanggan Memilih Produk & Memasukkan Data

Pelanggan memasukkan User ID Game / No HP / nomor tujuan. Untuk game yang didukung, backend toko Anda dapat memanggil POST /api/v1/reseller/check-nickname sebelum membuat order.

3

Teruskan Pesanan ke API NexShop

Setelah pelanggan membayar ke toko Anda, backend memanggil POST /api/v1/reseller/orders. Harga reseller dipotong otomatis dari saldo Partner Portal. Kirim ref_id unik dan gunakan nilai yang sama saat retry agar saldo tidak terpotong dua kali.

4

Terima Callback Webhook Real-time

NexShop mengirim HTTP POST bertanda tangan HMAC ke Webhook URL milik akun Anda saat status berubah. Verifikasi signature, balas HTTP 200, lalu perbarui pesanan menggunakan reference_id, status, dan Serial Number. Jika callback terlambat, cek dengan GET /api/v1/reseller/orders/:id.

Bab 6 (Developer)

Autentikasi Open API Reseller

Seluruh endpoint /api/v1/reseller/* diautentikasi memakai pasangan API Key dan Secret Key yang bisa Anda lihat di Partner Portal › API & Integrasi. Keduanya dikirim sebagai HTTP header pada setiap permintaan — tidak ada langkah login terpisah dan tidak ada token yang kedaluwarsa.

Perubahan penting bagi integrasi lama. Sebelumnya Secret Key hanya diperiksa apabila kebetulan dikirim, sehingga API Key saja sudah cukup untuk memesan atas nama akun Anda — artinya satu kunci yang bocor langsung bisa dipakai menghabiskan saldo deposit. Header X-NexShop-Secret kini wajib. Permintaan tanpa header tersebut dijawab 401 SECRET_KEY_REQUIRED.

Header Wajib

HTTP Request Headers semua endpoint /api/v1/reseller
X-NexShop-Api-Key: nx_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-NexShop-Secret:  nx_sec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type:      application/json

API Key juga boleh dikirim lewat Authorization: Bearer nx_live_..., tetapi X-NexShop-Secret tetap harus disertakan.

Aturan Keamanan yang Ditegakkan Server

  • Secret Key wajib & dibandingkan secara timing-safe. Server tidak membocorkan berapa banyak karakter awal yang sudah benar lewat selisih waktu respons.
  • IP Whitelist (opsional, sangat disarankan). Isi dengan alamat IP publik server toko Anda di Partner Portal. Selama daftar itu terisi, permintaan dari IP lain ditolak 403 IP_NOT_WHITELISTED. Alamat pemanggil ditentukan server dari koneksi yang sebenarnya — header X-Forwarded-For yang Anda kirim sendiri tidak dipercaya dan tidak bisa dipakai menyamar.
  • Batas laju 120 permintaan per menit per API Key. Melebihi itu dijawab 429 RATE_LIMITED. Beri jeda antar permintaan, jangan mengulang seketika.
  • Status akun diperiksa di setiap permintaan. Akun yang belum disetujui, sedang disuspend, atau diblokir dijawab 403 walau kuncinya benar.
  • Secret Key tidak pernah dikirim balik utuh oleh endpoint mana pun kecuali saat Anda menekan "Tampilkan" di Partner Portal. Simpan sebagai environment variable di server, jangan pernah ditaruh di kode frontend/aplikasi yang bisa dibaca pengguna.

Uji Koneksi Pertama

Endpoint teringan untuk memastikan kredensial sudah benar adalah cek saldo:

cURL GET /api/v1/reseller/balance
curl https://nexshop.cloud/api/v1/reseller/balance \
  -H "X-NexShop-Api-Key: $NEXSHOP_API_KEY" \
  -H "X-NexShop-Secret: $NEXSHOP_SECRET_KEY"
Response 200 OK
{
  "success": true,
  "data": {
    "balance": 1250000,
    "currency": "IDR",
    "tier": "Gold",
    "tier_code": "gold",
    "discount_percent": 5,
    "reseller_status": "approved"
  }
}
tier dan discount_percent berisi nilai akun Anda yang sebenarnya. Bila akun belum diberi tingkatan, tier bernilai null dan diskonnya 0 — bukan nilai contoh. Jangan mengasumsikan ada diskon default.

Daftar Kode Error Autentikasi

HTTP code Artinya & tindakan
401 INVALID_API_KEY API Key tidak dikenal atau dinonaktifkan. Cek ulang di Partner Portal.
401 SECRET_KEY_REQUIRED Header X-NexShop-Secret tidak dikirim.
401 INVALID_SECRET_KEY Secret Key tidak cocok dengan API Key tersebut.
403 IP_NOT_WHITELISTED IP server Anda belum terdaftar. Respons menyertakan client_ip yang terbaca server — salin nilai itu ke pengaturan whitelist.
403 RESELLER_NOT_APPROVED Akun belum diverifikasi admin atau sedang disuspend.
403 ACCOUNT_BLOCKED Akun diblokir. Hubungi dukungan NexShop.
429 RATE_LIMITED Melebihi 120 permintaan per menit. Tunggu, lalu coba lagi dengan jeda.

Kode Error Validasi Nickname

HTTP code Artinya & tindakan
400 UNSUPPORTED_GAME kode_game belum didukung oleh provider validasi nickname.
422 INVALID_GAME_ACCOUNT User ID atau Zone ID tidak valid. Jangan lanjutkan order.
503 NICKNAME_PROVIDER_UNAVAILABLE Provider sedang tidak tersedia atau belum dikonfigurasi. Retry terbatas, jangan menganggap akun valid.
Bab 7 (Developer)

API Get Produk & Harga Modal Reseller

Open API menyediakan satu endpoint katalog resmi untuk seluruh produk aktif—Topup Game, Pulsa, Paket Data, E-Wallet, PLN, dan produk Marketplace lain. Harga pada respons dihitung dengan tier akun yang terautentikasi.

GET /api/v1/reseller/products

Wajib mengirim X-NexShop-Api-Key dan X-NexShop-Secret. Gunakan harga_reseller sebagai modal saat menghitung harga jual toko Anda.

Contoh Response Open API (JSON) 200 OK
{
  "success": true,
  "total": 245,
  "data": [{
    "kode_produk": "ML86",
    "nama": "Mobile Legends 86 Diamond",
    "kategori": "Topup Game",
    "operator": "Mobile Legends",
    "harga_normal": 22000,
    "harga_reseller": 21340,
    "diskon_persen": 3,
    "hemat": 660,
    "butuh_server_id": true,
    "status": "ACTIVE"
  }]
}
Bab 8 (Developer)

API Transaksi, Validasi ID & Status

Seluruh endpoint berikut memakai pasangan API Key + Secret Key dan dijalankan dari backend toko Anda:

POST /api/v1/reseller/check-nickname

Mengecek username / nickname akun game pemain sebelum transaksi dibuat. Endpoint ini memakai provider validasi game NexShop (bukan endpoint TokoVoucher), sehingga hasilnya hanya tersedia untuk kode game yang didukung dan ketika provider sedang aktif.

Request Body (JSON) application/json
{
  "kode_game": "mobile-legends",
  "user_id": "12345678",
  "zone_id": "2123"
}
Response Berhasil (JSON) 200 OK
{
  "success": true,
  "data": {
    "kode_game": "mobile-legends",
    "username": "SkyWalker_99",
    "user_id": "12345678",
    "zone_id": "2123"
  }
}
POST /api/v1/reseller/orders

Membuat pesanan produk digital dan memotong saldo reseller secara atomik. ref_id wajib unik untuk satu pesanan dan harus digunakan kembali ketika retry karena timeout.

Format Parameter Tujuan per Kategori Kamus Data
// 1. Topup Game (Misal: Mobile Legends)
{ "kode_produk": "ML86", "tujuan": "12345678", "server_id": "2123", "ref_id": "TOKO-10001" }

// 2. E-Wallet / Pulsa / Paket Data (Misal: DANA)
{ "kode_produk": "DANA50", "tujuan": "08123456789", "ref_id": "TOKO-10002" }

// 3. Token PLN Prabayar
{ "kode_produk": "PLN50", "tujuan": "51234567890", "ref_id": "TOKO-10003" }

// 4. Transfer Antar Bank (tujuan = No Rekening, server_id = Kode Bank 3 digit misal 014 BCA)
{ "kode_produk": "TFBANK", "tujuan": "1234567890", "server_id": "014", "ref_id": "TOKO-10004" }
Response Pembuatan Order (JSON) 201 Created
{
  "success": true,
  "data": {
    "order_id": "NXA1B2C3D4E5F6",
    "ref_id": "TOKO-10001",
    "status": "PROCESSING",
    "kode_produk": "ML86",
    "nama_produk": "Mobile Legends 86 Diamond",
    "target": "12345678",
    "price": 21340,
    "serial_number": null,
    "balance_remaining": 478660
  }
}
GET /api/v1/reseller/orders/:id

Mengecek status memakai order_id NexShop atau ref_id milik toko Anda. Nilai status adalah PROCESSING, SUCCESS, atau FAILED. Gunakan endpoint ini setelah timeout dan sebagai fallback jika webhook terlambat.

Bab 9 (Webhook)

Konsep & Alur Webhook Reseller

Webhook Reseller NexShop mengirim perubahan status order Open API (PROCESSING, SUCCESS, FAILED, dan SN resmi) ke URL HTTPS yang Anda simpan sendiri di Partner Portal › API & Integrasi.

Hubungkan Callback dengan ref_id

Setiap order harus memakai ref_id unik dari sistem toko Anda (misalnya MYSTORE-10293). Nilai yang sama dikembalikan sebagai reference_id pada webhook, sehingga callback dapat dipasangkan ke pesanan lokal dan diproses secara idempoten.

Bab 10 (Webhook)

Format Header & Payload JSON Webhook

Setiap kali status transaksi berubah, server NexShop mengirimkan HTTP POST ke endpoint Anda:

HTTP Request Headers

Content-Type: application/json
User-Agent: NexShop-Webhook-Relay/1.0
X-NexShop-Event: transaction.updated
X-NexShop-Signature: a1b2c3d4e5f6... (hex HMAC SHA-256)

Payload JSON Body

{
  "event": "transaction.updated",
  "reference_id": "MYSTORE-984210",
  "order_id": "NX260823102938",
  "status": "SUCCESS",
  "product_code": "ML86",
  "product_name": "Mobile Legends 86 Diamond",
  "target": "12345678",
  "server_id": "2123",
  "amount": 21340,
  "serial_number": "MP26082300019283",
  "message": "Transaksi Berhasil",
  "timestamp": "2026-08-23T20:30:00.000Z"
}
Bab 11 (Webhook)

Verifikasi Signature Kriptografis (HMAC SHA-256)

Rumus yang dipakai Partner Portal: signature = HEX(HMAC_SHA256(webhook_secret, raw_body)). Hitung dari byte body mentah sebelum JSON di-parse.

webhook-handler.js (Node.js Express) JavaScript
const express = require("express");
const crypto = require("crypto");

const app = express();
const WEBHOOK_SECRET = "whsec_secret_toko_anda";

app.post("/api/webhook/nexshop", express.raw({ type: "application/json" }), (req, res) => {
    const signatureHeader = req.headers["x-nexshop-signature"];
    const rawBody = req.body.toString("utf8");

    if (!signatureHeader) {
        return res.status(400).send("Missing signature");
    }

    const expectedSignature = crypto
        .createHmac("sha256", WEBHOOK_SECRET)
        .update(rawBody)
        .digest("hex");

    const actual = Buffer.from(signatureHeader);
    const expected = Buffer.from(expectedSignature);
    if (actual.length !== expected.length || !crypto.timingSafeEqual(actual, expected)) {
        return res.status(401).send("Invalid signature");
    }

    const payload = JSON.parse(rawBody);
    console.log("Status Transaksi:", payload.reference_id, payload.status, "SN:", payload.serial_number);

    // Update status pesanan di database toko Anda & kirim SN ke pembeli
    // ...

    res.status(200).json({ received: true });
});

app.listen(8000, () => console.log("Webhook server running on port 8000"));
callback.php (PHP) PHP
<?php
$secret = "whsec_secret_toko_anda";
$rawBody = file_get_contents("php://input");
$signature = $_SERVER['HTTP_X_NEXSHOP_SIGNATURE'] ?? '';

if (empty($signature)) {
    http_response_code(400);
    exit("Missing signature");
}

$expected = hash_hmac("sha256", $rawBody, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit("Invalid signature");
}

$payload = json_decode($rawBody, true);
// Update pesanan di database toko Anda
http_response_code(200);
echo json_encode(["received" => true]);
main.py (FastAPI) Python 3
from fastapi import FastAPI, Request, HTTPException, Header
import hmac, hashlib

app = FastAPI()
WEBHOOK_SECRET = "whsec_secret_toko_anda"

@app.post("/api/webhook/nexshop")
async def receive_webhook(
    request: Request,
    x_nexshop_signature: str = Header(None)
):
    if not x_nexshop_signature:
        raise HTTPException(status_code=400, detail="Missing signature")
    
    raw_body = (await request.body()).decode("utf-8")
    expected_sig = hmac.new(
        WEBHOOK_SECRET.encode("utf-8"),
        raw_body.encode("utf-8"),
        hashlib.sha256
    ).hexdigest()
    
    if not hmac.compare_digest(x_nexshop_signature, expected_sig):
        raise HTTPException(status_code=401, detail="Invalid signature")
    
    payload = await request.json()
    print("Trx update:", payload["reference_id"], payload["status"])
    return {"received": True}
Bab 12 (Full Example)

Contoh Skrip Integrasi Lengkap (Node.js)

Klien siap pakai untuk backend toko Anda. Perhatikan bahwa kredensial dibaca dari environment variable — API Key dan Secret Key tidak boleh ditulis langsung di dalam kode yang ikut masuk ke repositori.

Panggil API NexShop hanya dari server toko Anda, tidak pernah dari browser atau aplikasi mobile. Kredensial yang dikirim dari sisi klien bisa dibaca siapa pun yang membuka DevTools, dan saldo deposit Anda yang akan terpakai.
nexshop-client.js Node.js
const axios = require("axios");
const crypto = require("crypto");

// Kredensial dari environment, BUKAN ditulis di dalam kode.
const client = axios.create({
    baseURL: "https://nexshop.cloud/api/v1/reseller",
    timeout: 15000,
    headers: {
        "X-NexShop-Api-Key": process.env.NEXSHOP_API_KEY,
        "X-NexShop-Secret": process.env.NEXSHOP_SECRET_KEY,
        "Content-Type": "application/json"
    }
});

// 1. Katalog + harga modal sesuai tingkatan akun Anda.
//    Simpan/cache hasilnya; jangan panggil per pengunjung toko.
async function getKatalog() {
    const res = await client.get("/products");
    return res.data.data; // [{ kode_produk, harga_normal, harga_reseller, ... }]
}

// 2. Validasi ID game pelanggan SEBELUM order dibuat.
//    Order ke tujuan yang salah tidak bisa dibatalkan.
async function cekNickname(kodeGame, userId, zoneId) {
    const res = await client.post("/check-nickname", {
        kode_game: kodeGame,
        user_id: userId,
        zone_id: zoneId
    });
    return res.data.data; // { username: "..." }
}

// 3. Buat pesanan.
//    ref_id WAJIB unik per pesanan DAN stabil: kalau permintaan ini
//    perlu diulang karena timeout jaringan, kirim ref_id yang SAMA.
//    NexShop akan mengembalikan pesanan yang sudah ada alih-alih
//    memotong saldo dua kali (idempotency).
async function buatPesanan({ kodeProduk, tujuan, serverId, refId }) {
    try {
        const res = await client.post("/orders", {
            kode_produk: kodeProduk,
            tujuan: tujuan,
            server_id: serverId,
            ref_id: refId
        });
        return res.data.data;
    } catch (err) {
        // Timeout BUKAN berarti pesanan gagal -- bisa jadi sudah
        // terbuat di sisi NexShop tapi responsnya tidak sampai.
        // Jangan langsung menandai gagal; cek statusnya dulu.
        if (!err.response) {
            return await cekStatus(refId);
        }
        throw err;
    }
}

// 4. Cek status pesanan (pakai order_id ATAU ref_id Anda sendiri).
async function cekStatus(idAtauRef) {
    const res = await client.get(`/orders/${encodeURIComponent(idAtauRef)}`);
    return res.data.data; // status: SUCCESS | PROCESSING | FAILED
}

// 5. Sisa saldo deposit.
async function cekSaldo() {
    const res = await client.get("/balance");
    return res.data.data.balance;
}

module.exports = { getKatalog, cekNickname, buatPesanan, cekStatus, cekSaldo };

Penerima Webhook (Express)

Endpoint ini menerima pemberitahuan status dari NexShop. Yang paling penting: verifikasi signature sebelum mempercayai isinya, dan balas 200 secepat mungkin.

webhook.js Express
// PENTING: pakai raw body. Signature dihitung atas byte mentah;
// JSON.stringify hasil parse bisa berbeda susunannya dan bikin
// verifikasi selalu gagal.
app.post("/webhook/nexshop",
    express.raw({ type: "application/json" }),
    (req, res) => {
        const signature = req.headers["x-nexshop-signature"] || "";
        const harusnya = crypto
            .createHmac("sha256", process.env.NEXSHOP_WEBHOOK_SECRET)
            .update(req.body)
            .digest("hex");

        // timingSafeEqual, bukan !== : perbandingan biasa membocorkan
        // berapa karakter awal yang sudah benar lewat selisih waktu.
        const a = Buffer.from(signature);
        const b = Buffer.from(harusnya);
        if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
            return res.status(401).send("signature tidak valid");
        }

        const event = JSON.parse(req.body.toString());

        // Balas 200 DULU, proses belakangan. NexShop menganggap
        // respons lambat sebagai gagal dan akan mengirim ulang.
        res.status(200).json({ received: true });

        // Webhook bisa datang lebih dari sekali untuk pesanan yang
        // sama (retry). Pastikan pemrosesannya idempoten -- kunci
        // pada reference_id, jangan menambah saldo/mengirim barang
        // dua kali untuk satu reference_id.
        prosesStatusPesanan(event.reference_id, event.status);
    }
);
Panduan Bertahap

Menjalankan Partner Portal: Tahap demi Tahap

Urutan di bawah adalah jalur terpendek dari akun baru sampai transaksi pertama berhasil. Kerjakan berurutan — tiap tahap bergantung pada tahap sebelumnya.

1

Daftar & unggah KTP

Buka Partner Portal › tab Daftar Baru & KYC. Buat email dan password khusus Portal Reseller yang berbeda dari akun belanja NexShop, isi data usaha, lalu unggah foto KTP yang jelas dan tidak terpotong.

Foto KTP dienkripsi (AES-256-GCM) sebelum disimpan dan hanya bisa dibuka admin lewat halaman peninjauan yang terautentikasi. Berkasnya tidak punya URL publik, jadi tidak bisa dibuka siapa pun yang kebetulan menerima tautannya.

Akun belanja NexShop tidak otomatis menjadi akun portal dan password akun belanja tidak berlaku di sini. Jika sudah punya akun belanja, tetap buat akun Portal Reseller terpisah dengan email dan password baru.

2

Tunggu verifikasi admin

Peninjauan memakan waktu maksimal 3×24 jam kerja. Selama menunggu, Anda tetap bisa masuk portal untuk membaca dokumentasi dan melihat katalog.

Tombol Cek Status Verifikasi Terkini di banner dashboard memuat ulang status akun tanpa perlu logout.

3

Isi saldo deposit

Menu Deposit → pilih nominal → bayar via QRIS atau Virtual Account. Saldo masuk otomatis setelah pembayaran terverifikasi ke gateway — tidak perlu konfirmasi manual. Nominal deposit minimal Rp 10.000.

Setiap transaksi API memotong saldo ini. Pesanan yang ditolak provider dikembalikan otomatis ke saldo, tercatat di menu Mutasi.

4

Ambil kredensial API

Menu API & Integrasi berisi API Key (nx_live_…) dan Secret Key (nx_sec_…). Keduanya wajib dikirim di setiap permintaan — lihat Bab 6.

Simpan Secret Key sebagai environment variable di server toko Anda. Menekan Buat Ulang Kunci membatalkan pasangan lama seketika; integrasi yang masih memakai kunci lama akan langsung berhenti bekerja.

5

Kunci akses ke IP server Anda

Masih di menu yang sama, isi IP Whitelist dengan alamat IP publik server toko Anda (pisahkan dengan koma bila lebih dari satu). Setelah terisi, kunci yang bocor pun tidak bisa dipakai dari mesin lain.

Belum tahu IP servernya? Panggil API tanpa whitelist sekali; bila ditolak, respons 403 menyertakan client_ip berisi alamat yang terbaca server.

6

Pasang Webhook URL

Isi Webhook URL dengan endpoint HTTPS milik toko Anda, lalu tekan Tes Webhook untuk memastikan server Anda membalas 200.

Syarat URL yang diterima:

  • HTTPS wajib. Endpoint HTTP polos ditolak karena data transaksi lewat di sana.
  • Port 80 atau 443 saja.
  • Domain publik. Alamat internal (localhost, 10.x, 192.168.x, 169.254.x) ditolak.
  • Tanpa username/password di URL dan tanpa redirect — berikan alamat akhirnya langsung.
7

Transaksi uji, lalu go-live

Lakukan satu order bernominal terkecil ke ID milik Anda sendiri. Pastikan tiga hal terjadi: saldo terpotong sesuai harga tier, webhook diterima dengan signature valid, dan status akhir tercatat benar di menu Transaksi.

Mengunduh Rincian Harga Semua Level

Di menu Produk tersedia tombol Rincian Harga Semua Level. Berkas yang diunduh memuat satu kolom harga untuk setiap tingkatan reseller beserta nominal hematnya — berguna untuk menyusun harga jual dan membandingkan keuntungan antar tingkatan.

  • CSV — langsung bisa dibuka di Excel/Google Sheets.
  • JSON — untuk diproses otomatis oleh sistem toko Anda.

Seluruh angkanya dihitung di server memakai rumus yang sama persis dengan checkout, sehingga harga di berkas tidak akan pernah berbeda dari yang benar-benar ditagih. Kolom hemat bisa lebih kecil daripada persentase tingkatan bila harga menyentuh batas margin minimum NexShop — itu perilaku yang disengaja, bukan kesalahan hitung.

Ambil lewat API GET /api/reseller/portal/price-list
curl "https://nexshop.cloud/api/reseller/portal/price-list?format=json" \
  -H "Authorization: Bearer <token_portal>"

Checklist Sebelum Go-Live

  • Kredensial disimpan di environment variable, tidak di dalam kode atau di sisi browser.
  • IP Whitelist terisi alamat server produksi.
  • Webhook memverifikasi signature dengan perbandingan timing-safe, dan memproses ulang kiriman yang sama secara idempoten.
  • ref_id dibuat unik per pesanan dan dipakai ulang saat mengulang permintaan yang timeout.
  • Timeout jaringan ditangani dengan mengecek status, bukan langsung menandai pesanan gagal.
  • Harga jual di toko Anda dihitung ulang dari respons API, bukan dari angka yang disalin manual.
  • Ada pemantauan saldo agar transaksi tidak berhenti mendadak karena deposit habis.
Bab 13

Pertanyaan Umum (FAQ Reseller & Developer)

Jawaban atas pertanyaan seputar akun reseller dan integrasi teknis.

Apakah saya bisa menghubungkan website toko / bot Telegram saya ke NexShop?

Bisa! Anda dapat menggunakan API NexShop untuk mengambil katalog harga modal reseller Anda, mengeksekusi order, dan menerima Webhook Callback status transaksi secara real-time.

Bagaimana cara mendaftarkan URL Webhook Callback toko saya?

Buka Partner Portal › API & Integrasi, isi Webhook URL HTTPS toko Anda, simpan, lalu tekan Tes Webhook. Webhook Secret tersedia pada akun yang sudah disetujui dan dipakai untuk memverifikasi header X-NexShop-Signature.

Apakah ada batas request (Rate Limit) pada API?

API publik dilindungi rate limiter yang wajar untuk mencegah serangan abuse. Untuk endpoint inquiry tagihan, pastikan memanggil hanya saat pelanggan meminta cek tagihan.

Apakah ada kewajiban deposit saldo minimum?

Tidak ada biaya pendaftaran atau saldo mengendap wajib untuk berbelanja langsung di web. Namun, transaksi melalui Open API dipotong dari saldo reseller; isi saldo minimal Rp 10.000 melalui Partner Portal sebelum membuat order API.

Bab 14

Kontak Dukungan & Integrasi Reseller

Butuh bantuan integrasi webhook, pembuatan akun reseller, atau konsultasi API toko Anda?

Pusat Dukungan Teknis & Reseller NexShop

Tim Admin dan Developer NexShop siap membantu integrasi toko Anda.
Jam Layanan: Setiap Hari, 08.00 − 22.00 WIB.

Kembali ke atas