Mulai
Terima pembayaran VA, QRIS, dan GoPay dari website atau aplikasi Anda lewat REST API Skyve.
- Daftar dan buat API key di Portal → API.
- Isi Callback URL di Portal → Profil.
- Buat tagihan dari server Anda, lalu tampilkan nomor VA atau QR ke pembeli.
- Tandai pesanan lunas saat callback masuk dan statusnya sudah terverifikasi.
https://skyve.idAutentikasi
Kirim API key di header X-API-Key atau Authorization: Bearer pada setiap request.
Key lengkap hanya muncul sekali saat dibuat. Kalau hilang atau bocor, buat key baru di portal. Key lama langsung tidak berlaku.
X-API-Key: sk_3f9a1c...
# atau
Authorization: Bearer sk_3f9a1c...Checkout (link bayar)
Cara paling mudah menghubungkan aplikasi Anda. Kirim daftar barang dan nominal, Skyve membalas dengan checkout_url. Arahkan pembeli ke link itu: pembeli memilih metode, membayar, lalu diarahkan kembali ke return_url Anda. Anda tidak perlu membuat halaman bayar sendiri.
POST/api/v1/checkouts
Body
order_idstring · wajib | ID pesanan dari sistem Anda, unik per merchant. Maksimal 24 karakter: huruf, angka, . _ -. |
items[]array · wajib | 1–50 barang, masing-masing name, quantity, dan price (rupiah, bilangan bulat). Total dihitung otomatis, minimal Rp1.000. |
customerobject | name, phone, email. Field yang diisi tampil terkunci dan tidak bisa diubah pembeli. Yang dikosongkan diisi pembeli sendiri. Format phone sama dengan customer_details.phone (nomor luar negeri pakai awalan +). |
return_urlstring | Tujuan tombol "Kembali" setelah bayar. Skyve menambahkan ?order_id=…&status=paid|pending|failed. |
expires_in_hoursnumber | Masa berlaku link. Default 24, maksimal 720. |
Biaya admin
Biaya admin metode pembayaran dibayar oleh pembeli dan ditambahkan di halaman checkout. Di callback, gross_amount adalah total yang dibayar pembeli termasuk fee_amount. Nominal pesanan Anda = gross_amount − fee_amount, sama dengan amount checkout.
Setelah pembeli bayar
Skyve mengirim callback satu kali saat checkout lunas, dengan order_id milik Anda dan checkout_id. Kalau pembeli sempat ganti metode, attempt_order_id bisa berbeda (misalnya TOKO-1001-2).
Verifikasi dengan GET /api/v1/checkouts/{checkout_id} dan pastikan status bernilai paid sebelum menandai pesanan lunas. Status lain: open (belum dibayar) dan expired.
status di query return_url saja, karena pembeli bisa mengubahnya. Selalu verifikasi dari server.curl -X POST https://skyve.id/api/v1/checkouts \
-H "X-API-Key: $SKYVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"order_id": "TOKO-1001",
"items": [
{ "name": "Kopi Susu", "quantity": 2, "price": 18000 },
{ "name": "Croissant", "quantity": 1, "price": 25000 }
],
"customer": { "name": "Budi", "phone": "081234567890" },
"return_url": "https://tokokamu.com/pesanan/TOKO-1001"
}'{
"success": true,
"data": {
"id": "chk_Qm3x9LwZp2Ka",
"checkout_url": "https://skyve.id/c/chk_Qm3x9LwZp2Ka",
"order_id": "TOKO-1001",
"status": "open",
"amount": 61000,
"items": [
{ "name": "Kopi Susu", "quantity": 2, "price": 18000 },
{ "name": "Croissant", "quantity": 1, "price": 25000 }
],
"customer": { "name": "Budi", "phone": "081234567890", "email": null },
"return_url": "https://tokokamu.com/pesanan/TOKO-1001",
"paid_order_id": null,
"paid_at": null,
"expires_at": "2026-10-01T09:00:00.000Z"
}
}{
"tenant_id": "tnt_8c1f2a9d4e7b3c60",
"order_id": "TOKO-1001",
"checkout_id": "chk_Qm3x9LwZp2Ka",
"attempt_order_id": "TOKO-1001",
"transaction_status": "settlement",
"payment_type": "qris",
"gross_amount": "61431.00",
"fee_amount": "431.00",
"transaction_id": "9f1c2e7a-3b0d-4c55-9a1e-7d2f0c6b8e41"
}Buat tagihan
POST/api/v1/charges
Body
order_idstring · wajib | ID pesanan dari sistem Anda. Harus unik per merchant. |
gross_amountnumber · wajib | Nominal dalam rupiah, tanpa desimal. |
payment_methodstring · wajib | Salah satu dari metode pembayaran. |
customer_details.first_namestring · wajib | Minimal 2 karakter. |
customer_details.last_namestring | — |
customer_details.emailstring · wajib | — |
customer_details.phonestring · wajib | Nomor Indonesia: 08… atau 628…. Nomor luar negeri wajib diawali + dan kode negara, mis. +6591234567. |
Response
Tampilkan instruksi bayar ke pembeli sesuai metode. Field yang dipakai ada di tabel metode pembayaran. Status awal selalu pending.
curl -X POST https://skyve.id/api/v1/charges \
-H "X-API-Key: $SKYVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"order_id": "INV-1001",
"gross_amount": 150000,
"payment_method": "bni",
"customer_details": {
"first_name": "Budi",
"email": "budi@mail.com",
"phone": "081234567890"
}
}'{
"success": true,
"data": {
"order_id": "INV-1001",
"transaction_id": "9f1c2e7a-3b0d-4c55-9a1e-7d2f0c6b8e41",
"payment_method": "bni",
"payment_type": "bank_transfer",
"gross_amount": "150000.00",
"transaction_status": "pending",
"va_number": "9881234567890123",
"bank": "bni",
"expiry_time": "2026-10-01 16:51:00"
}
}Cek status
GET/api/v1/charges/{order_id}/status
Mengambil status terbaru langsung dari bank. Pakai untuk memverifikasi callback atau sebagai cadangan kalau callback tidak sampai.
curl https://skyve.id/api/v1/charges/INV-1001/status \
-H "X-API-Key: $SKYVE_API_KEY"{
"success": true,
"data": {
"order_id": "INV-1001",
"transaction_status": "settlement",
"payment_type": "bank_transfer",
"gross_amount": "150000.00",
"fraud_status": "accept"
}
}Callback
Setiap kali status transaksi berubah, Skyve mengirim POST JSON ke Callback URL Anda.
settlement atau capture.- Balas dengan HTTP
200dalam 10 detik. - Skyve tidak mengirim ulang callback yang gagal.
- Callback yang sama bisa datang lebih dari sekali. Abaikan kalau pesanan sudah lunas.
POST https://tokokamu.com/skyve/callback
Content-Type: application/json
{
"tenant_id": "tnt_8c1f2a9d4e7b3c60",
"order_id": "INV-1001",
"transaction_status": "settlement",
"payment_type": "bank_transfer",
"gross_amount": "150000.00",
"fee_amount": "0.00",
"fraud_status": "accept",
"transaction_id": "9f1c2e7a-3b0d-4c55-9a1e-7d2f0c6b8e41"
}app.post('/skyve/callback', express.json(), async (req, res) => {
res.sendStatus(200);
const orderId = req.body.order_id;
const check = await fetch(
`https://skyve.id/api/v1/charges/${encodeURIComponent(orderId)}/status`,
{ headers: { 'X-API-Key': process.env.SKYVE_API_KEY } }
);
const { data } = await check.json();
if (['settlement', 'capture'].includes(data.transaction_status)) {
await markOrderPaid(orderId);
}
});Metode pembayaran
payment_method | Metode | Tampilkan ke pembeli |
|---|---|---|
bni | BNI Virtual Account | va_number |
bri | BRI Virtual Account | va_number |
permata | Permata Virtual Account | va_number |
cimb | CIMB Niaga Virtual Account | va_number |
mandiri | Mandiri Bill Payment | biller_code + bill_key |
qris | QRIS | qr_url (gambar) atau qr_string |
gopay | GoPay | deeplink_url atau qr_url |
manual | Transfer manual | manual_account |
Batas bayar ada di expiry_time.
Transfer manual
Ambil daftar rekening dari GET /api/v1/manual-transfer-accounts, lalu kirim manual_account_id bersama payment_method: "manual". Kalau hanya ada satu rekening, manual_account_id boleh dikosongkan.
Pembeli transfer ke rekening di manual_account, lalu upload bukti ke POST /api/public/{tenant_id}/manual/{order_id}/proof dengan body { "image": "data:image/jpeg;base64,...", "sender_name": "..." }. Status berubah jadi settlement setelah admin Skyve menyetujui bukti.
Status transaksi
transaction_status | Arti |
|---|---|
pending | Menunggu pembayaran |
settlement | Lunas |
capture | Lunas |
expire | Lewat batas bayar |
cancel | Dibatalkan |
deny | Ditolak bank |
Error
Error selalu berformat { success: false, message }.
| HTTP | Penyebab |
|---|---|
400 | Body tidak valid atau metode sedang nonaktif |
401 | API key tidak dikirim |
403 | API key salah |
404 | order_id tidak ditemukan |
409 | order_id sudah pernah dipakai |
502 | Bank atau Midtrans sedang bermasalah, coba lagi |
{
"success": false,
"message": "order_id already exists for this merchant"
}