UnitPay
  • Products
  • Pricing
  • Docs
  • Help
  • About
  • Security
  • Legal
|
Demo Get a quote

Developer documentation

Refund a payment

Last updated: 07 May 2026

Contents

    The refundPayment method reverses a previously settled payment, in full or in part. Refunds are server-to-server only — never expose the secret key to client-side code.

    When you can refund

    • The payment must be in paid status. Pending or failed payments cannot be refunded.
    • One refund per payment. After a partial refund is issued, that payment can no longer be refunded again — the remaining amount stays with the customer's order.
    • The refund window depends on the payment method (typically 180 days for cards, shorter for some VA and QRIS rails). The cabinet rejects refunds outside the window.

    Endpoint

    Send a request to https://api.unitpay.net/api. POST over TLS is recommended for production traffic; GET is accepted for compatibility but exposes the secret key in URL logs and proxy buffers — do not use it.

    Required parameters

    ParameterTypeDescription
    methodstringAlways refundPayment.
    params[paymentId]integerUnitPay payment identifier returned by initPayment and echoed in callbacks as unitpayId.
    params[secretKey]stringProject secret key. Send it only over TLS in a POST body, never in a GET query string.

    Optional parameters

    ParameterTypeDescription
    params[sum]numberRefund amount in major currency units. Omit for a full refund. Must be less than or equal to the original payment sum.

    Example request

    POST https://api.unitpay.net/api
    Content-Type: application/x-www-form-urlencoded
    
    method=refundPayment
    &params[paymentId]=1234512345
    &params[secretKey]=<your-project-secret-key>
    &params[sum]=50000.00

    The example above issues a partial refund of IDR 50,000 against payment 1234512345. Omitting params[sum] would refund the full original amount.

    Successful response

    {
      "result": {
        "message": "Refund issued."
      }
    }

    UnitPay returns HTTP 200 once the refund is queued. Funds reach the customer within the timeframe of the underlying payment rail (cards: same business day to several business days; QRIS and VA: typically faster). The refund also flows back through your callback handler as a balance adjustment, so you can reconcile by listening to those events.

    Error response

    {
      "error": {
        "message": "Invalid secretKey.",
        "code": -32000
      }
    }

    Common causes:

    codeMeaning
    -32000Invalid secret key. Rotate from Settings → Project → Secret key and update your application secret store.
    -32001Payment not found. Verify the paymentId matches a payment on the project that owns the secret key.
    -32002Payment not in a refundable state — pending, failed, or already refunded.
    -32003Refund amount exceeds the original payment sum or the remaining refundable balance.
    -32004Refund window expired for this payment method.

    Treat any error response as a hard failure: do not retry the same request blindly. Investigate, fix the input, and resubmit.

    Important restrictions

    • One refund per payment. If you issue a partial refund and later need to refund more, that is not supported — size partial refunds carefully.
    • No client-side duplicate suppression. Two near-simultaneous partial refunds for the same amount on the same payment are not blocked by the API. Add idempotency on your side: keep the refund request behind a database-locked operation that records "refund attempted" before calling UnitPay, and never retry without first checking the recorded outcome.
    • Test mode. Test-mode payments use the test secret key and a separate refundPayment sandbox; refunds in test mode never move real funds. Validate your refund flow in test mode before enabling live refunds.

    Refunds via the merchant cabinet

    Operators can also issue refunds without writing code: open Statistics → Payment details for the payment in the merchant cabinet and click Issue refund. The cabinet wraps the same API call and is the recommended path for one-off, manually-approved refunds (chargebacks, disputed orders, customer-service exceptions).

    Next steps

    • Create a payment via API — obtain the paymentId you will later refund.
    • Callback handler — reconcile refund events on your server.
    • Refund & Chargeback Policy — merchant-facing policy for refund timing and chargeback handling.

    Metode refundPayment membalik pembayaran yang sudah terselesaikan, secara penuh atau sebagian. Pengembalian dana hanya dilakukan server-ke-server — jangan mengekspos kunci rahasia pada kode sisi klien.

    Kapan pengembalian dana dapat dilakukan

    • Pembayaran harus berstatus paid. Pembayaran tertunda atau gagal tidak dapat dikembalikan.
    • Satu pengembalian per pembayaran. Setelah pengembalian sebagian diterbitkan, pembayaran tersebut tidak dapat dikembalikan lagi — sisa jumlahnya tetap pada pesanan pelanggan.
    • Jendela pengembalian bergantung pada metode pembayaran (umumnya 180 hari untuk kartu, lebih singkat untuk sebagian rel VA dan QRIS). Kabinet menolak pengembalian di luar jendela tersebut.

    Endpoint

    Kirim permintaan ke https://api.unitpay.net/api. POST melalui TLS direkomendasikan untuk trafik produksi; GET diterima untuk kompatibilitas tetapi membuka kunci rahasia di log URL dan buffer proxy — jangan gunakan.

    Parameter wajib

    ParameterTipeDeskripsi
    methodstringSelalu refundPayment.
    params[paymentId]integerIdentifikasi pembayaran UnitPay yang dikembalikan oleh initPayment dan dikutip dalam callback sebagai unitpayId.
    params[secretKey]stringKunci rahasia proyek. Kirim hanya melalui TLS dalam body POST, jangan dalam query string GET.

    Parameter opsional

    ParameterTipeDeskripsi
    params[sum]numberJumlah pengembalian dalam satuan mata uang utama. Kosongkan untuk pengembalian penuh. Harus kurang dari atau sama dengan jumlah pembayaran asli.

    Contoh permintaan

    POST https://api.unitpay.net/api
    Content-Type: application/x-www-form-urlencoded
    
    method=refundPayment
    &params[paymentId]=1234512345
    &params[secretKey]=<your-project-secret-key>
    &params[sum]=50000.00

    Contoh di atas menerbitkan pengembalian sebagian sebesar IDR 50.000 atas pembayaran 1234512345. Mengosongkan params[sum] akan mengembalikan jumlah asli secara penuh.

    Respons sukses

    {
      "result": {
        "message": "Refund issued."
      }
    }

    UnitPay membalas dengan HTTP 200 begitu pengembalian masuk antrian. Dana akan sampai ke pelanggan dalam jangka waktu rel pembayaran yang mendasarinya (kartu: hari kerja yang sama hingga beberapa hari kerja; QRIS dan VA: umumnya lebih cepat). Pengembalian juga mengalir kembali melalui callback handler Anda sebagai penyesuaian saldo, sehingga Anda dapat merekonsiliasi dengan mendengarkan event tersebut.

    Respons error

    {
      "error": {
        "message": "Invalid secretKey.",
        "code": -32000
      }
    }

    Penyebab umum:

    codeArti
    -32000Kunci rahasia tidak valid. Lakukan rotasi dari Pengaturan → Proyek → Kunci rahasia dan perbarui penyimpanan rahasia aplikasi Anda.
    -32001Pembayaran tidak ditemukan. Verifikasi paymentId cocok dengan pembayaran pada proyek yang memiliki kunci rahasia tersebut.
    -32002Pembayaran tidak berada dalam status yang dapat dikembalikan — tertunda, gagal, atau sudah dikembalikan.
    -32003Jumlah pengembalian melebihi jumlah pembayaran asli atau saldo refundable yang tersisa.
    -32004Jendela pengembalian untuk metode pembayaran ini telah berakhir.

    Anggap respons error apa pun sebagai kegagalan keras: jangan mengulang permintaan yang sama tanpa pemeriksaan. Selidiki, perbaiki input, lalu kirim ulang.

    Batasan penting

    • Satu pengembalian per pembayaran. Jika Anda menerbitkan pengembalian sebagian dan kemudian perlu mengembalikan lebih banyak, itu tidak didukung — tentukan jumlah pengembalian sebagian dengan hati-hati.
    • Tidak ada penekanan duplikat sisi klien. Dua pengembalian sebagian yang dikirim hampir bersamaan untuk jumlah yang sama pada pembayaran yang sama tidak diblokir oleh API. Tambahkan idempotensi di sisi Anda: simpan permintaan pengembalian di balik operasi yang dikunci database yang mencatat "refund attempted" sebelum memanggil UnitPay, dan jangan mencoba ulang tanpa memeriksa hasil yang tercatat terlebih dahulu.
    • Mode uji. Pembayaran mode uji menggunakan kunci rahasia uji dan sandbox refundPayment terpisah; pengembalian dalam mode uji tidak pernah memindahkan dana sungguhan. Validasi alur pengembalian dalam mode uji sebelum mengaktifkan pengembalian live.

    Pengembalian melalui kabinet merchant

    Operator juga dapat menerbitkan pengembalian tanpa menulis kode: buka Statistik → Detail pembayaran untuk pembayaran tersebut di kabinet merchant dan klik Terbitkan pengembalian. Kabinet membungkus panggilan API yang sama dan merupakan jalur yang disarankan untuk pengembalian sekali pakai yang disetujui manual (chargeback, pesanan yang disengketakan, pengecualian layanan pelanggan).

    Langkah selanjutnya

    • Membuat pembayaran melalui API — dapatkan paymentId yang nanti akan Anda kembalikan.
    • Penanganan callback — rekonsiliasi event pengembalian pada server Anda.
    • Kebijakan Pengembalian Dana & Chargeback — kebijakan menghadap merchant untuk waktu pengembalian dan penanganan chargeback.

    Related documentation

    • Create a payment via API Membuat pembayaran melalui API
    • Callback handler Penanganan callback
    • Generate a payment link Membuat tautan pembayaran

    Company

    • About
    • Security
    • Contact

    Products

    • Online Payments
    • Payouts (USDT)
    • Pricing
    • Docs
    • Help

    Support

    • support@unitpay.net
    • sales@unitpay.net
    • compliance@unitpay.net
    • legal@unitpay.net

    WhatsApp

    +6285121084571

    Mon-Fri 09:00-18:00 WIB

    Legal

    • Privacy Policy
    • Cookie Policy
    • Terms of Service
    • Acceptable Use Policy
    • AML/CFT Statement
    • Legal Center

    Tidak puas? / Not satisfied?

    • Hubungi OJK / Contact OJK: 157 (24 jam) / (24h)
    • LAPS SJK: https://lapssjk.id
    • Email keluhan / Complaint email: complaints@unitpay.net
    • Didit
    • Didit
    • Amazon Web Services (Asia Pacific - Jakarta)
    • Iubenda
    |
    Sitemap

    (c) 2026 PT UNIT GLOBAL SYSTEM. All rights reserved. NPWP: 22.709.627.8-021.000 · NIB: 2511240128903