API LAZISNU — Mitra Eksternal

Spesifikasi integrasi API untuk mitra eksternal pada platform NU Care / CMS LAZISNU.

Status: Endpoint /api/v1/partners/* telah diimplementasikan. Dokumen ini menjadi kontrak integrasi resmi untuk mitra eksternal.


1. Ringkasan

AspekKeterangan
Base path/api/v1/partners/*
Identitas mitraAPI Key + X-Partner-Code (kode unik per mitra)
Format body createapplication/json
Response envelope{ meta, data, pagination? }
Create donasi/zakat/kurban1 endpoint unified POST /transactions
List programfilter category_id / sub_category_id
AuthAPI Key + HMAC signature (recommended)

2. Base URL & Versioning

Semua endpoint menggunakan path prefix:

/api/v1/partners
EnvironmentKeterangan
ProductionHost production diberikan saat onboarding integrasi
StagingHost staging diberikan saat onboarding integrasi

Format lengkap: https://{host}/api/v1/partners/{endpoint}

Hostname (base URL) tidak dipublikasikan di dokumentasi publik. Hubungi tim integrasi LAZISNU untuk mendapatkan endpoint environment Anda.

Semua endpoint wajib menggunakan prefix versi (/v1/). Perubahan breaking hanya melalui versi baru (/v2/).


3. Autentikasi & Keamanan

3.1 Header wajib

HeaderWajibContohKeterangan
AuthorizationYaBearer {api_key}API key mitra (diberikan LAZISNU)
X-Partner-CodeYayour_partner_codeKode mitra unik (snake_case, diberikan saat onboarding)
Content-TypeYa (POST/PUT)application/json
AcceptDisarankanapplication/json
X-Request-IdDisarankanUUID v4Trace request
Idempotency-KeyYa (POST transaksi)UUID v4Cegah duplikasi transaksi
X-TimestampYa (HMAC mode)1718000000Unix timestamp (detik)
X-SignatureYa (HMAC mode)sha256=...HMAC-SHA256 body

3.2 Partner code

X-Partner-Code berisi kode unik mitra dalam format snake_case. Nilai kode diberikan secara khusus oleh tim LAZISNU saat onboarding dan bersifat rahasia.

Contoh:

FieldContoh
Header X-Partner-Codeyour_partner_code
Response partner_codeyour_partner_code
Response partner_nameYOUR PARTNER

Daftar lengkap partner code tidak dipublikasikan. Hubungi tim integrasi LAZISNU untuk mendapatkan kode mitra Anda.

signature = HMAC_SHA256(api_secret, timestamp + "." + raw_json_body)
Header: X-Signature: sha256={signature}
  • Timestamp toleransi: ±300 detik
  • Request di luar window → 401 INVALID_SIGNATURE

3.4 Rate limit

TierLimit
Default60 request / menit / API key
Burst create transaction10 request / detik

Response headers:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • Retry-After (saat 429)

4. Format Response Standar

4.1 Success (single resource)

{
  "meta": {
    "code": 200,
    "status": "success",
    "message": null,
    "response_date": "2026-06-03T10:12:07+07:00",
    "request_id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "data": {}
}

4.2 Success (list + pagination)

{
  "meta": {
    "code": 200,
    "status": "success",
    "message": null,
    "response_date": "2026-06-03T10:12:07+07:00",
    "request_id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "data": [],
  "pagination": {
    "current_page": 1,
    "per_page": 20,
    "total": 150,
    "last_page": 8
  }
}

4.3 Error

{
  "meta": {
    "code": 422,
    "status": "error",
    "message": "Validation failed",
    "response_date": "2026-06-03T10:12:07+07:00",
    "request_id": "550e8400-e29b-41d4-a716-446655440000"
  },
  "data": null,
  "errors": {
    "amount": ["Minimal nominal transaksi Rp 5.000"]
  }
}

4.4 HTTP status mapping

HTTPmeta.codeKeterangan
200200OK
201201Created
400400Bad request
401401Unauthorized / invalid signature
403403Partner tidak punya akses resource
404404Resource tidak ditemukan
409409Idempotency conflict
422422Validation error
429429Rate limit
500500Internal server error

5. Data Model (referensi app/Models)

5.1 Transaction (transactions)

FieldTypeRequiredKeterangan
idintegerautoPrimary key internal
trx_idstringautoFormat: LZNU{4digit}{timestamp}
amountintegeryaNominal Rupiah (tanpa desimal)
namestringyaNama donatur/muzakki
emailstringopsional
phonestringopsionalNomor telepon donatur
addressstringopsional
descriptionstringopsionalCatatan transaksi
donation_idintegeryaID program donasi/zakat/qurban
category_idintegerautoDari relasi donation.category_id
organization_idintegerautoDari relasi donation.organization_id
statusenumautoPENDING, SUCCESS, EXPIRED
via_methodenumautoSelalu partner untuk mitra eksternal
payment_methodstringyaDi-set server dari X-Partner-Code (contoh: your_partner_code)
is_anonbooleanopsionalDefault false
is_publishedbooleanopsionalDefault true
meta_dataobjectopsionalData tambahan bebas (JSON)
partner_reference_idstringopsionalID transaksi di sisi mitra (disarankan)
expired_atdatetimeautoISO8601 WIB
created_atdatetimeautoISO8601 WIB
updated_atdatetimeautoISO8601 WIB

5.2 Donation / Campaign (donations)

FieldTypeKeterangan
idintegerID program
titlestringJudul campaign
slugstringURL slug
descriptionsstringDeskripsi HTML/text
targetdecimalTarget nominal
total_collectedintegerAgregat transaksi SUCCESS
category_idintegerLihat tabel kategori
sub_category_idintegerSub-kategori program
organization_idintegerLAZISNU pengelola
statusenumprocessed, approved, rejected
is_activebooleanHanya true yang ditampilkan ke mitra
started_atdatetime
ended_atdatetime

5.3 DonationCategory (donation_categories)

IDKodeNama
1ZNZakat
2DNDonasi
3CNCampaign / Crowdfunding
4QNQurban
5FNFidyah
6KNKoin NU
7WKWakaf

5.4 Organization (organizations)

FieldTypeKeterangan
idinteger
namestring
slugstring
codestringKode unit LAZISNU
phonestringNomor telepon
emailstring
addressstringAlamat lengkap
npwpstring
is_activeboolean

6. Endpoint

6.1 Profil Mitra

GET /me

Response 200

{
  "meta": { "code": 200, "status": "success", "message": null, "response_date": "2026-06-03T10:12:07+07:00", "request_id": "..." },
  "data": {
    "partner_code": "your_partner_code",
    "partner_name": "YOUR PARTNER",
    "organization": {
      "id": 1,
      "name": "LAZISNU Pusat",
      "slug": "lazisnu-pusat",
      "phone": "021-xxxx",
      "email": "[email protected]",
      "address": "Jakarta",
      "npwp": "xx.xxx.xxx.x-xxx.xxx"
    },
    "allowed_category_ids": [1, 2, 3, 4],
    "webhook_url": "https://partner.example.com/webhooks/lazisnu"
  }
}

6.2 Kategori & Sub-kategori

GET /categories

Response 200: list kategori aktif.

GET /categories/{category_id}/sub-categories

Mengembalikan daftar sub-kategori untuk kategori tertentu.


6.3 Campaign / Donasi (Crowdfunding)

GET /campaigns

QueryTypeKeterangan
category_idintegerDefault 3 (Campaign)
sub_category_idintegerFilter sub-kategori
organization_idintegerFilter LAZISNU unit
searchstringCari judul
statusstringDefault hanya approved + is_active=true
pageintegerDefault 1
per_pageintegerDefault 20, max 100

Response 200 (item)

{
  "id": 9,
  "title": "Bantu Pulihkan Pesantren Terdampak Banjir Sultra",
  "slug": "bantu_pulihkan_pesantren_terdampak_banjir_sultra",
  "category": { "id": 3, "name": "Campaign", "slug": "campaign" },
  "sub_category": { "id": 6, "name": "Pendidikan", "slug": "pendidikan" },
  "status": "open",
  "target": 500000000,
  "total_collected": 125000000,
  "organization": { "id": 1, "name": "LAZISNU Pusat", "slug": "lazisnu-pusat" },
  "started_at": "2026-01-01 00:00:00",
  "ended_at": "2026-12-31 23:59:59"
}

GET /campaigns/{id} — detail campaign.

GET /campaigns/slug/{slug} — detail by slug.


6.4 Zakat

GET /zakat

QueryTypeKeterangan
typestringzakat_maal, zakat_profesi, zakat_fitrah, zakat
page, per_pageintegerPagination

Response 200 (item)

{
  "id": 58,
  "title": "Zakat Maal",
  "slug": "zakat_maal",
  "program_type": "zakat",
  "category_id": 1,
  "status": "open",
  "minimum_amount": 10000
}

6.5 Qurban

GET /qurban/products

QueryTypeKeterangan
organization_idintegerOpsional
page, per_pageintegerPagination

Response 200 (item)

{
  "id": 37,
  "title": "Kambing",
  "slug": "kambing",
  "category_id": 4,
  "price": 2900000,
  "status": "open",
  "organization": { "id": 1, "name": "LAZISNU Pusat" }
}

6.6 Transaksi (Unified Create)

POST /transactions

Headers tambahan: Idempotency-Key: {uuid}

Request body

{
  "donation_id": 58,
  "amount": 1000000,
  "name": "Andi Chan",
  "email": "[email protected]",
  "phone": "0853981253678",
  "npwp": "1234567891234567",
  "address": "Jakarta",
  "description": "Donasi via mitra",
  "is_anon": false,
  "partner_reference_id": "PTR-20260603-001",
  "meta_data": {
    "channel": "partner_checkout",
    "order_id": "1234567890"
  }
}
FieldRequiredValidasi
donation_idyaexists, active, whitelisted untuk partner
amountyainteger, min 5000 (qurban: harus match price jika fixed)
nameyamax 255
emailopsionalvalid email
phoneopsional8–15 digit
npwpopsional15–16 digit
partner_reference_iddisarankanunique per partner
meta_dataopsionalobject

payment_method tidak dikirim client — di-set server dari X-Partner-Code.
via_method otomatis partner.

Response 201

{
  "meta": { "code": 201, "status": "success", "message": "Transaction created", "response_date": "...", "request_id": "..." },
  "data": {
    "id": 4,
    "trx_id": "LZNU00011718000000",
    "donation_id": 58,
    "donation": {
      "id": 58,
      "title": "Zakat Maal",
      "slug": "zakat_maal"
    },
    "amount": 1000000,
    "name": "Andi Chan",
    "email": "[email protected]",
    "phone": "0853981253678",
    "status": "SUCCESS",
    "via_method": "partner",
    "payment_method": "your_partner_code",
    "partner_code": "your_partner_code",
    "partner_reference_id": "PTR-20260603-001",
    "created_at": "2026-06-03T10:12:07+07:00"
  }
}

Untuk mitra eksternal, transaksi biasanya langsung SUCCESS (pembayaran sudah terjadi di platform mitra). Jika flow async, status awal PENDING + webhook follow-up.


6.7 Query Transaksi

GET /transactions

QueryTypeKeterangan
statusstringPENDING, SUCCESS, EXPIRED
donation_idinteger
partner_reference_idstring
trx_idstring
date_from, date_todateY-m-d
page, per_pageinteger

GET /transactions/{trx_id}

Detail transaksi by trx_id.

GET /transactions/history

Shortcut: hanya status=SUCCESS, sorted created_at desc.


7. Webhook ke Mitra (Outbound)

LAZISNU dapat mengirim notifikasi ke URL mitra saat status transaksi berubah.

POST {partner_webhook_url}

Headers dari LAZISNU

Content-Type: application/json
X-Lazisnu-Signature: sha256={hmac}
X-Lazisnu-Timestamp: 1718000000
X-Request-Id: uuid

Payload

{
  "event": "transaction.status_updated",
  "data": {
    "trx_id": "LZNU00011718000000",
    "partner_reference_id": "SHP-20260603-001",
    "status": "SUCCESS",
    "amount": 1000000,
    "payment_method": "your_partner_code",
    "paid_at": "2026-06-03T10:15:00+07:00",
    "donation": {
      "id": 58,
      "title": "Zakat Maal",
      "slug": "zakat_maal"
    }
  }
}

Expected response mitra: HTTP 200 dengan body { "received": true }

Retry policy LAZISNU: 3x exponential backoff (1m, 5m, 30m).


8. Idempotency

  • Header Idempotency-Key wajib untuk POST /transactions
  • Key yang sama + payload identik → return transaksi existing (200, bukan 201)
  • Key sama + payload berbeda → 409 Conflict

9. Best Practices Integrasi

  1. Simpan trx_id dan partner_reference_id di database mitra untuk reconciliasi.
  2. Gunakan webhook + polling (GET /transactions/{trx_id}) sebagai fallback.
  3. Validasi amount server-side — jangan percaya nominal dari client tanpa verifikasi di mitra.
  4. Whitelist campaign — mitra hanya bisa create transaksi untuk program yang diizinkan.
  5. Log X-Request-Id di kedua sisi untuk support/debugging.
  6. Rotate API key berkala; dukung 2 key aktif saat rotasi.
  7. Sandbox — uji di staging sebelum production.
  8. Timezone — semua datetime ISO8601 dengan offset +07:00 (WIB).

10. Lampiran


11. Changelog

VersiTanggalPerubahan
1.0.02026-06-03Initial spec mitra eksternal

Dokumen Terkait