H2H API
Dokumentasi API Pembayaran
API ini digunakan untuk membuat pembayaran, melihat status, serta menerima callback saat pembayaran sukses, gagal, atau expired. Semua request menggunakan API key per merchant.
Ringkasan
- Base URL: https://ocicio.com/api/v1.
- Autentikasi: X-API-Key atau Authorization: Bearer.
- Rate limit default: 120 request/menit per API key.
- Idempotency: gunakan Idempotency-Key atau external_id.
- Callback dipanggil saat payment_paid, payment_failed, payment_expired.
- Currency default: IDR. FX akan dihitung bila channel memakai mata uang berbeda.
Autentikasi
Gunakan salah satu header berikut pada setiap request:
- X-API-Key: ak_xxxxxx_yyyyyyyy
- Authorization: Bearer ak_xxxxxx_yyyyyyyy
curl -H "X-API-Key: ak_xxxxxx_yyyyyyyy" -H "Accept: application/json" https://ocicio.com/api/v1/channels?amount=100000&method=VA
Signature request (opsional)
Jika PAYMENT_API_REQUIRE_SIGNATURE=true, setiap request wajib menyertakan signature HMAC SHA256.
- Header: X-Timestamp (unix atau ISO 8601) dan X-Signature.
- Signature: hash_hmac('sha256', $timestamp.'.'.$rawBody, $callbackSecret).
- Gunakan raw body persis seperti dikirim (GET tanpa body gunakan string kosong).
- Gunakan callback secret dari API key.
- Toleransi waktu mengikuti PAYMENT_WEBHOOK_TOLERANCE (default 300 detik).
X-Timestamp: 1706784000
X-Signature: hash_hmac('sha256', '1706784000.'.'{"amount":100000}', 'callback_secret_xxxxxxxx')
List channel pembayaran
Menampilkan channel yang tersedia, biaya, dan FX (jika berbeda currency).
GET https://ocicio.com/api/v1/channels?amount=100000¤cy=IDR&method=VA
{
"data": [
{
"id": 12,
"name": "BCA",
"method": "VA",
"vendor": "XENDIT",
"currency": "IDR",
"minimum_amount": 100000,
"maximum_amount": null,
"fee": {
"base_amount": 100000,
"fee_amount": 5000,
"total_amount": 105000,
"base_fee_flat": 4000,
"base_fee_pct": 0,
"markup_fee_flat": 1000,
"markup_fee_pct": 0,
"fee_flat": 5000,
"fee_pct": 0
},
"fx": null
}
]
}
Create payment
Endpoint: POST https://ocicio.com/api/v1/payments
- external_id wajib, bisa dipakai untuk idempotency.
- amount wajib (integer).
- method wajib: VA, EWALLET, QRCODE, OUTLET, CARD, PAYLATER.
- absorb_fee opsional (boolean). Jika tidak dikirim, default mengikuti setting API key. Jika true, admin fee ditanggung merchant (total_amount = amount).
- channel_id atau channel_code opsional.
- customer.email wajib, customer.name dan customer.phone opsional.
- item.name wajib, item.description opsional.
- callback_url opsional, override default callback URL API key.
- expires_in opsional (detik), default 120 menit.
curl -X POST https://ocicio.com/api/v1/payments \
-H "X-API-Key: ak_xxxxxx_yyyyyyyy" \
-H "Idempotency-Key: order-2025-0001" \
-H "Content-Type: application/json" \
-d '{
"external_id": "order-2025-0001",
"amount": 100000,
"currency": "IDR",
"method": "VA",
"channel_code": "BCA",
"customer": {
"name": "Dita Saputra",
"email": "dita@example.com",
"phone": "081234567890"
},
"item": {
"name": "Membership Premium",
"description": "Akses 30 hari"
},
"metadata": {
"order_type": "subscription"
},
"callback_url": "https://merchant.example.com/api/payment-callback",
"expires_in": 7200
}'
{
"id": "pi_01hxx6g2k3s",
"external_id": "order-2025-0001",
"status": "pending",
"amount": 100000,
"fee_amount": 5000,
"total_amount": 105000,
"fee": {
"base_amount": 100000,
"fee_amount": 5000,
"total_amount": 105000,
"base_fee_flat": 4000,
"base_fee_pct": 0,
"markup_fee_flat": 1000,
"markup_fee_pct": 0,
"fee_flat": 5000,
"fee_pct": 0
},
"fx": null,
"currency": "IDR",
"method": "VA",
"channel": "BCA",
"instructions": [],
"expires_at": "2025-01-31T09:30:00Z",
"order_no": "ORD-2025-000012",
"callback_url": "https://merchant.example.com/api/payment-callback",
"gateway_ref": "XEN-INV-123"
}
Cek status pembayaran
Endpoint: GET https://ocicio.com/api/v1/payments/{id}
curl -H "X-API-Key: ak_xxxxxx_yyyyyyyy" https://ocicio.com/api/v1/payments/pi_01hxx6g2k3s
Callback pembayaran
Callback dikirim ke callback_url saat status berubah.
- Header: X-Callback-Event, X-Callback-Timestamp, X-Callback-Signature.
- Signature: hash_hmac('sha256', $timestamp.'.'.$rawBody, $callbackSecret).
- Event: payment_paid, payment_failed, payment_expired.
{
"event": "payment_paid",
"payment_id": "pi_01hxx6g2k3s",
"external_id": "order-2025-0001",
"status": "paid",
"amount": 100000,
"fee_amount": 5000,
"total_amount": 105000,
"fee": {},
"fx": null,
"currency": "IDR",
"method": "VA",
"channel": "BCA",
"order_no": "ORD-2025-000012",
"gateway_ref": "XEN-INV-123",
"occurred_at": "2025-01-31T08:30:00Z",
"customer": {
"name": "Dita Saputra",
"email": "dita@example.com"
},
"item": {
"name": "Membership Premium",
"description": "Akses 30 hari"
},
"metadata": {
"order_type": "subscription"
}
}
Status dan error
Status pembayaran
- created, pending, paid, failed, expired.
Error umum
- 401 API key missing/invalid.
- 403 akses ditolak (role tidak valid).
- 422 validasi gagal (field wajib/format salah).
- 429 rate limit, lihat header Retry-After.
Format error
{
"message": "API key missing."
}