Skip to main content

Payment & Cash Order

Modul ini fokus pada endpoint pembayaran user-side (Xendit/Duitku) dan transaksi cash order buy/sell.

Semua endpoint pada halaman ini adalah API v1 (/api/...).

Cash order (buy/sell instan)

Route

MethodPathController@methodMiddleware
POST/api/cashOrder/place-orderCashOrderController@placeCashOrderauth.xtoken, verified:api
GET/api/cash-ordersCashOrderController@listCashOrderauth.xtoken, verified:api
GET/api/cashOrder/get-priceCashOrderController@getPricepublik

Payload create order

Request validation: CashOrderRequest.

FieldTypeRequiredCatatan
basestringTidakdefault IDR
coinstringYasimbol aset (mis. USDT)
sidestringYaBUY atau SELL
amountnumber/stringYadipakai terutama untuk BUY
volumenumber/stringYadipakai terutama untuk SELL

Contoh:

{
"base": "IDR",
"coin": "USDT",
"side": "BUY",
"amount": 100000,
"volume": 0
}

Logic penting placeCashOrder

  • User wajib status verifikasi sukses (User::STATUS_SUCCESS), jika tidak → api.identity_verification_are_required.
  • Cek saldo:
    • side BUY: saldo base (IDR) harus >= amount
    • side SELL: saldo coin harus >= volume
  • Hitung fee platform, fee CFX, VAT, income tax dari setting (Dict).
  • Simpan CashOrder + TaxHistory.
  • Mutasi saldo:
    • BUY: IDR berkurang, coin bertambah
    • SELL: coin berkurang, IDR bertambah
  • Trigger report CFX (best effort; lihat implementasi controller).

Response

  • sukses create: sendResponse($cashOrder->data(), trans('api.cash_order_successful'))
  • gagal umum:
    • api.identity_verification_are_required
    • api.user_coin_not_found
    • api.insufficient_funds

Get price

Request validation: CashOrderGetPriceRequest.

Payload/query:

{
"side": "BUY"
}

side wajib BUY/SELL.


Xendit payment endpoint (user-side)

Route

MethodPathController@methodMiddleware
GET/api/xendit/payment-method/{type}XenditController@paymentMethodpublik
GET/api/payment-methods/va/{code}/{lang}XenditController@vaDetailpublik
GET/api/xendit/fix-va/numberXenditController@fixedVaNumberauth.xtoken, verified:api
POST/api/xendit/create-qrisXenditController@createQrisauth.xtoken, verified:api
GET/api/xendit/status-qris/{qr_id}XenditController@statusQrisauth.xtoken, verified:api

paymentMethod/{type}

  • type umum: va, bank, ewallet.
  • Sumber data dari DepositList + relasi (xenditVa, eWallet).
  • Response sukses berisi kategori:
    • virtualAccount, fixedVA, retail, eWallet, qris, creditCard, payLater.

vaDetail/{code}/{lang}

  • Mengambil detail instruksi VA (tab + translation) berdasarkan kode dan bahasa.
  • Gagal jika VA tidak ditemukan: sendError('VA payment method not found or inactive').

fixedVaNumber

  • User harus punya bank terdaftar (UserBankAddress), jika tidak:
    • error 422: api.no_bank_account_registered
  • Sistem generate/ambil fixed VA dari Xendit, simpan ke Redis/DB (UserVa) jika perlu.

createQris & statusQris

  • createQris: membuat dynamic QRIS via Xendit, simpan QrisPayment, return qr_string, qr_id, amount, expiration_date.
  • statusQris/{qr_id}: mengambil status terbaru dari tabel QrisPayment.

Duitku payment endpoint (user-side)

Route

MethodPathController@methodMiddleware
GET/api/duitku/disbursement/list-bankDuitkuController@disbursementBankListpublik
GET/api/duitku/fix-va/numberDuitkuController@fixedVaNumberauth.xtoken, verified:api
POST/api/duitku/withdraw/cash-outDuitkuController@withdrawCashOutauth.xtoken, verified:api

fixedVaNumber

  • Mengembalikan mapping fixed VA number berdasarkan user ID dan konfigurasi env.
  • Jika xenditStatusEnabled() true, request diteruskan ke XenditController@fixedVaNumber.

withdrawCashOut

Request validation: DuitkuDisbursementRequest.

FieldTypeRequired
amountnumberYa
bankCodestring/numberYa
accountNamestringYa
accountAddressstringTidak
accountIdentitystringYa
twoFACodestringYa
purposestringTidak

Logic penting:

  • Wajib 2FA aktif dan kode valid:
    • gagal 2FA → api.two_fa_failed (403)
    • belum bind 2FA → api.required_for_twofa_binding
  • Proses withdraw diteruskan ke DuitKuLibrary::withdrawCashOut.

Response:

  • sukses: api.duitku_withdraw_cash_out_successful
  • gagal: api.duitku_withdraw_cash_out_fail