WP Manifestindependent plugin directory
manifest / ecommerce / vd-payment-gateway

VD Payment Gateway

Payment gateway terpusat (DOKU, Duitku) untuk plugin Velocity

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/velocity-developer/vd-payment-gateway/archive/refs/heads/master.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Plugin payment gateway terpusat untuk plugin/theme Velocity Developer (vd-store, vd-marketplace, velocity-donasi, velocity-toko). Gateway ditulis sekali di sini; plugin lain cukup memanggil API di bawah.

Gateway: DOKU Checkout (Non-SNAP), Duitku Pop, dan Midtrans Snap.

Pengaturan

Menu Payment Gateway → DOKU di wp-admin:

  • Aktifkan, Mode (Sandbox/Production), Client ID, Secret Key, batas bayar (menit).
  • Salin Notification URL (/wp-json/vd-pg/v1/notify/doku) ke DOKU Back Office → Integration → Notification.

Menu Payment Gateway → Duitku: Aktifkan, Mode, Kode Merchant, API Key, batas bayar, Return URL bawaan. Callback URL dikirim otomatis per transaksi (/wp-json/vd-pg/v1/notify/duitku), tidak perlu diisi di dashboard Duitku.

Menu Payment Gateway → Midtrans: Aktifkan, Mode, Merchant ID, Client Key, Server Key, Signature Secret Key (wajib bila akun Midtrans memilikinya; tanpa itu notifikasi ditolak dan status pesanan tidak berubah otomatis; bila kosong notifikasi diverifikasi dengan Server Key), batas bayar, dan (opsional) daftar metode yang ditampilkan (enabled_payments, mis. bca_va,bni_va,gopay,other_qris). Notification URL (/wp-json/vd-pg/v1/notify/midtrans) dikirim otomatis per transaksi lewat header X-Override-Notification, jadi tidak wajib diisi di dashboard Midtrans. Notifikasi diverifikasi dengan signature_key (SHA512 order_id + status_code + gross_amount + Signature Secret Key atau Server Key). Pemetaan status: settlement / capture+accept → lunas, capture+challenge / pending / deny → menunggu, expire → kedaluwarsa, cancel / failure → gagal, refund → refund, partial_refund → tetap lunas (payload tersimpan). Keterangan kolom di admin sengaja umum (tanpa jalur menu dashboard Midtrans) karena tampilan dashboard sering berubah. Merchant ID hanya catatan dan tidak dipakai saat transaksi. Invoice Midtrans maksimal 50 karakter (huruf, angka, - _ ~ .). chargeback belum didukung (transaksi lunas tidak berubah, payload tetap tersimpan).

Tab Transaksi menampilkan kartu statistik (lunas, menunggu, kedaluwarsa, gagal), pencarian invoice/referensi, filter status dan gateway, serta tombol Cek status (memanggil API cek status gateway).

Dashboard (0.3.0)

  • Simpan, filter, dan cek status berjalan tanpa muat ulang lewat Alpine.js + REST vd-pg/v1/admin/* (hanya manage_options, wajib header X-WP-Nonce). Secret key tidak pernah dikirim ke browser.
  • Alpine.js 3.14.8 disimpan lokal di assets/vendor/alpinejs/ (versi, sumber, SHA-256 di README folder itu) dan hanya dimuat di halaman Payment Gateway; tidak memakai CDN.
  • Bila JavaScript gagal dimuat, semua formulir tetap tersimpan lewat admin-post.php seperti sebelumnya.

API untuk plugin lain

if (function_exists('vd_pg_is_available') && vd_pg_is_available('doku')) {
    $result = vd_pg_create_payment('doku', [
        'invoice'    => 'INV-001',          // unik per gateway, maks 64 (30 bila kartu kredit aktif)
        'amount'     => 150000,             // rupiah, tanpa desimal
        'source'     => 'vd-store',         // pemilik transaksi
        'ref_id'     => $order_id,
        'return_url' => home_url('/terima-kasih'),
        'customer'   => ['name' => 'Budi', 'email' => 'budi@contoh.com', 'phone' => '0812...'],
        'items'      => [['name' => 'Kaos', 'price' => 75000, 'qty' => 2]],
    ]);
    if (!is_wp_error($result)) {
        wp_redirect($result['payment_url']);
    }
}

Fungsi lain: vd_pg_gateway($id), vd_pg_active_gateways(), vd_pg_get_transaction($gateway, $invoice), vd_pg_sync_status($gateway, $invoice).

Action saat status berubah

Dipicu sekali per perubahan status (notifikasi ganda diabaikan):

  • vd_pg_payment_paid / vd_pg_payment_paid_{source} — ($transaction, $payload)
  • vd_pg_payment_expired, vd_pg_payment_refunded (dan varian _{source})
  • vd_pg_payment_status_changed — ($transaction, $status, $payload)
  • vd_pg_payment_amount_mismatch — nominal notifikasi ≠ nominal tagihan; transaksi tidak ditandai lunas.

Filter: vd_pg_gateways (daftarkan gateway baru, implementasi GatewayInterface), vd_pg_doku_payment_body, vd_pg_midtrans_snap_body.

Kompatibilitas Duitku lama (velocity-addons < 2.3)

Duitku dihapus dari velocity-addons (commit 2a81d86). Plugin ini menyediakan pengganti supaya vd-store, vd-marketplace, dan velocity-donasi versi sekarang langsung bisa memakai Duitku lagi tanpa rilis ulang:

  • Kelas Velocity_Addons_Duitku (is_active(), options(), createInvoice($params) → respons Duitku mentah, get_by_invoice()). Dimuat lewat autoloader dan hanya bila kelas aslinya tidak ada, jadi aman dipasang bersama addons lama.
  • Shortcode [tombol_bayar_duitku invoice="..."] (Duitku Pop).
  • Endpoint lama /wp-json/velocityaddons/v1/duitku_callback tetap menerima callback invoice lama.
  • Action lama velocity_duitku_callback($payload) dipicu sekali per perubahan status (resultCode 00 = lunas).
  • Saat aktivasi, pengaturan velocity_duitku_options dan riwayat tabel vd_duitku_invoice/vd_duitku_callback diimpor sekali (hasilnya di opsi vdpg_duitku_imported).

Catatan Duitku

  • Signature memakai HMAC-SHA256 (Duitku menyatakan MD5/SHA256 lama obsolete sejak Apr 2026). Callback dengan signature MD5 lama masih diterima.
  • itemDetails.price = harga satuan × qty; totalnya disamakan dengan paymentAmount seperti pada DOKU.

Catatan DOKU

  • Signature request & notifikasi: HMAC-SHA256 atas Client-Id, Request-Id, Request-Timestamp, Request-Target, Digest (SHA-256 base64 body).
  • Status FAILED di DOKU Checkout diabaikan (pelanggan bisa ganti metode bayar), sesuai anjuran DOKU.
  • Status lunas/refund tidak bisa turun kembali ke pending/expired.
  • Status lunas ditetapkan dari notifikasi yang signature-nya valid dan nominalnya cocok; Check Status API tidak dipanggil otomatis (DOKU menyarankan jeda 60 detik). Gunakan tombol Cek status atau vd_pg_sync_status() bila notifikasi tidak datang.
  • Nominal notifikasi yang tidak cocok diberi catatan merah di tab Transaksi.
  • Total line_items disamakan dengan amount: selisih (ongkir/biaya) jadi satu baris tambahan; bila ada diskon, line_items tidak dikirim.

Log debug

Tab Payment Gateway › Log (mati secara bawaan, opsi vdpg_debug_log). Isinya per baris (JSON, waktu UTC):

  • doku.request / duitku.request: permintaan ke API gateway, kode HTTP, waktu respons, dan isi responsnya.
  • notify.<gateway>: notifikasi masuk (header, body, hasil cek signature, status akhir, kode HTTP balasan).
  • status.changed / status.amount_mismatch: perubahan status transaksi atau nominal yang tidak cocok.

Secret key, signature, token, dan password disamarkan (4 karakter awal…4 akhir). Data pelanggan juga disamarkan: email bu***@example.com, HP 6281****6789, nama B*** S***, alamat Jl.***. Notifikasi mencatat IP pengirim (remote_addr, x_forwarded_for, x_real_ip, cf_connecting_ip) hanya untuk analisis, tidak dipakai untuk menolak notifikasi. Berkas harian wp-content/uploads/vdpg-logs/vdpg-YYYY-MM-DD-<hash>.log, otomatis dihapus setelah 14 hari. Nama berkas memakai hash acak per situs. Bila perlu, pindahkan foldernya ke luar folder publik lewat filter vdpg_log_dir.

Pengujian

Skrip ujung-ke-ujung (mock DOKU & Duitku, aman dijalankan berulang) ada di folder tests/ (tidak ikut zip rilis). Jalankan VDPG_TEST_WP=/path/wordpress tests/run-tests.sh; lihat tests/README.md.