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
| Method | Path | Controller@method | Middleware |
|---|---|---|---|
| POST | /api/cashOrder/place-order | CashOrderController@placeCashOrder | auth.xtoken, verified:api |
| GET | /api/cash-orders | CashOrderController@listCashOrder | auth.xtoken, verified:api |
| GET | /api/cashOrder/get-price | CashOrderController@getPrice | publik |
Payload create order
Request validation: CashOrderRequest.
| Field | Type | Required | Catatan |
|---|---|---|---|
base | string | Tidak | default IDR |
coin | string | Ya | simbol aset (mis. USDT) |
side | string | Ya | BUY atau SELL |
amount | number/string | Ya | dipakai terutama untuk BUY |
volume | number/string | Ya | dipakai 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
- side
- 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_requiredapi.user_coin_not_foundapi.insufficient_funds
Get price
Request validation: CashOrderGetPriceRequest.
Payload/query:
{
"side": "BUY"
}
side wajib BUY/SELL.
Xendit payment endpoint (user-side)
Route
| Method | Path | Controller@method | Middleware |
|---|---|---|---|
| GET | /api/xendit/payment-method/{type} | XenditController@paymentMethod | publik |
| GET | /api/payment-methods/va/{code}/{lang} | XenditController@vaDetail | publik |
| GET | /api/xendit/fix-va/number | XenditController@fixedVaNumber | auth.xtoken, verified:api |
| POST | /api/xendit/create-qris | XenditController@createQris | auth.xtoken, verified:api |
| GET | /api/xendit/status-qris/{qr_id} | XenditController@statusQris | auth.xtoken, verified:api |
paymentMethod/{type}
typeumum: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
- error 422:
- Sistem generate/ambil fixed VA dari Xendit, simpan ke Redis/DB (
UserVa) jika perlu.
createQris & statusQris
createQris: membuat dynamic QRIS via Xendit, simpanQrisPayment, returnqr_string,qr_id,amount,expiration_date.statusQris/{qr_id}: mengambil status terbaru dari tabelQrisPayment.
Duitku payment endpoint (user-side)
Route
| Method | Path | Controller@method | Middleware |
|---|---|---|---|
| GET | /api/duitku/disbursement/list-bank | DuitkuController@disbursementBankList | publik |
| GET | /api/duitku/fix-va/number | DuitkuController@fixedVaNumber | auth.xtoken, verified:api |
| POST | /api/duitku/withdraw/cash-out | DuitkuController@withdrawCashOut | auth.xtoken, verified:api |
fixedVaNumber
- Mengembalikan mapping fixed VA number berdasarkan user ID dan konfigurasi env.
- Jika
xenditStatusEnabled()true, request diteruskan keXenditController@fixedVaNumber.
withdrawCashOut
Request validation: DuitkuDisbursementRequest.
| Field | Type | Required |
|---|---|---|
amount | number | Ya |
bankCode | string/number | Ya |
accountName | string | Ya |
accountAddress | string | Tidak |
accountIdentity | string | Ya |
twoFACode | string | Ya |
purpose | string | Tidak |
Logic penting:
- Wajib 2FA aktif dan kode valid:
- gagal 2FA →
api.two_fa_failed(403) - belum bind 2FA →
api.required_for_twofa_binding
- gagal 2FA →
- Proses withdraw diteruskan ke
DuitKuLibrary::withdrawCashOut.
Response:
- sukses:
api.duitku_withdraw_cash_out_successful - gagal:
api.duitku_withdraw_cash_out_fail