Kembali ke Blog
Insight

Panduan Integrasi Midtrans & Xendit untuk Produk Digital

24 Feb 2026 Idiarsosimbang 14 menit baca
Panduan Integrasi Midtrans & Xendit untuk Produk Digital

Step-by-step integrasi payment gateway Midtrans dan Xendit untuk marketplace produk digital. Termasuk tips handling webhook, refund, dan subscription.


Payment gateway adalah jantung dari setiap marketplace produk digital. Di Indonesia, dua pemain utama yang mendominasi adalah Midtrans (milik GoTo/Gojek) dan Xendit. Keduanya menawarkan API yang developer-friendly, tapi masing-masing punya kelebihan dan kekurangan yang perlu dipahami sebelum Anda memilih. Artikel ini memberikan panduan lengkap integrasi kedua payment gateway ini untuk marketplace produk digital.

Infografik ringkasan Panduan Integrasi Midtrans & Xendit untuk Produk Digital
Ringkasan visual: konteks masalah, hasil yang ingin dicapai, dan relevansi topik untuk produk digital ID TECH.

Perbandingan Midtrans vs Xendit

Midtrans

  • Kelebihan: Payment method terlengkap (GoPay, ShopeePay, QRIS, VA semua bank, kartu kredit, Alfamart/Indomaret), Snap (hosted payment page) yang sangat mudah diintegrasikan, dokumentasi dalam Bahasa Indonesia yang excellent.
  • Kekurangan: Proses verifikasi merchant yang ketat (bisa 1-2 minggu), minimum payout Rp 50K, dashboard yang agak kompleks untuk pemula.
  • Fee: QRIS 0.7%, VA transfer Rp 4.000, GoPay/ShopeePay 2%, Credit Card 2.9% + Rp 2.000
  • Ideal untuk: Marketplace besar, e-commerce dengan banyak payment method, bisnis yang butuh GoPay/ShopeePay integration.

Xendit

  • Kelebihan: Setup lebih cepat (verifikasi 1-3 hari), API yang lebih simpel dan konsisten, fitur disbursement (kirim uang ke banyak rekening) yang unggul, webhook reliability yang excellent.
  • Kekurangan: Payment method sedikit lebih terbatas (tidak ada GoPay native), dokumentasi utama dalam Bahasa Inggris.
  • Fee: QRIS 0.7%, VA transfer Rp 4.500, OVO 2%, Credit Card 2.9% + Rp 2.000
  • Ideal untuk: SaaS, subscription billing, marketplace yang perlu disbursement otomatis ke seller.

Arsitektur Payment untuk Marketplace

Untuk marketplace produk digital, arsitektur payment memiliki kompleksitas tambahan: uang dari buyer harus split antara platform (komisi) dan seller (revenue). Berikut arsitektur yang recommended:

Flow Transaksi

  1. Buyer checkout: Pilih produk → pilih payment method → create payment di gateway
  2. Payment processing: Gateway memproses pembayaran (VA, QRIS, e-wallet)
  3. Webhook notification: Gateway mengirim webhook ke server Anda saat pembayaran berhasil
  4. Order fulfillment: Server memproses order — kirim link download ke buyer, notifikasi ke seller
  5. Settlement: Gateway mengirim uang ke rekening platform (T+1 atau T+2)
  6. Disbursement: Platform mengirim bagian seller ke rekening seller (menggunakan Xendit Disbursement API atau manual transfer)

Implementasi Midtrans (Snap)

Midtrans Snap adalah cara termudah untuk menerima pembayaran. Buyer diarahkan ke halaman pembayaran Midtrans yang sudah handle semua payment method.

Backend (PHP/Symfony)


// Install SDK
// composer require midtrans/midtrans-php

use Midtrans\Config;
use Midtrans\Snap;

class PaymentController extends AbstractController
{
    #[Route('/checkout/{productId}', methods: ['POST'])]
    public function checkout(int $productId): JsonResponse
    {
        // Konfigurasi Midtrans
        Config::$serverKey = $this->getParameter('midtrans_server_key');
        Config::$isProduction = true;
        Config::$isSanitized = true;
        Config::$is3ds = true;

        $product = $this->productRepo->find($productId);
        $orderId = 'ORD-' . time() . '-' . random_int(1000, 9999);

        $params = [
            'transaction_details' => [
                'order_id' => $orderId,
                'gross_amount' => $product->getPrice(),
            ],
            'customer_details' => [
                'first_name' => $this->getUser()->getName(),
                'email' => $this->getUser()->getEmail(),
            ],
            'item_details' => [[
                'id' => $product->getId(),
                'price' => $product->getPrice(),
                'quantity' => 1,
                'name' => substr($product->getName(), 0, 50),
            ]],
            'callbacks' => [
                'finish' => $this->generateUrl('order_finish',
                    [], UrlGeneratorInterface::ABSOLUTE_URL),
            ],
        ];

        $snapToken = Snap::getSnapToken($params);

        // Simpan order ke database
        $order = new Order();
        $order->setOrderId($orderId);
        $order->setProduct($product);
        $order->setBuyer($this->getUser());
        $order->setAmount($product->getPrice());
        $order->setStatus('pending');
        $order->setSnapToken($snapToken);
        $this->em->persist($order);
        $this->em->flush();

        return $this->json(['snap_token' => $snapToken]);
    }
}

Frontend (JavaScript)


// Di halaman checkout
async function checkout(productId) {
    const response = await fetch(`/checkout/${productId}`, {
        method: 'POST',
        headers: { 'X-Requested-With': 'XMLHttpRequest' }
    });
    const data = await response.json();

    // Tampilkan popup pembayaran Midtrans
    snap.pay(data.snap_token, {
        onSuccess: function(result) {
            window.location.href = '/order/success/' + result.order_id;
        },
        onPending: function(result) {
            window.location.href = '/order/pending/' + result.order_id;
        },
        onError: function(result) {
            alert('Pembayaran gagal. Silakan coba lagi.');
        }
    });
}

Webhook Handler

Ini adalah bagian paling kritial — webhook memastikan order diproses meskipun buyer menutup browser setelah bayar:


#[Route('/webhook/midtrans', methods: ['POST'])]
public function midtransWebhook(Request $request): Response
{
    $serverKey = $this->getParameter('midtrans_server_key');
    $payload = json_decode($request->getContent(), true);

    // Verifikasi signature
    $signatureKey = hash('sha512',
        $payload['order_id'] .
        $payload['status_code'] .
        $payload['gross_amount'] .
        $serverKey
    );

    if ($signatureKey !== $payload['signature_key']) {
        return new Response('Invalid signature', 403);
    }

    $order = $this->orderRepo->findByOrderId($payload['order_id']);
    if (!$order) {
        return new Response('Order not found', 404);
    }

    // Update status berdasarkan transaction_status
    switch ($payload['transaction_status']) {
        case 'capture':
        case 'settlement':
            $order->setStatus('paid');
            $order->setPaidAt(new \DateTime());
            // Kirim produk ke buyer
            $this->fulfillOrder($order);
            break;
        case 'expire':
        case 'cancel':
            $order->setStatus('cancelled');
            break;
        case 'deny':
            $order->setStatus('denied');
            break;
    }

    $this->em->flush();
    return new Response('OK', 200);
}

Implementasi Xendit

Xendit menggunakan pendekatan yang lebih RESTful. Berikut contoh integrasi untuk pembuatan invoice:

Create Invoice


use GuzzleHttp\Client;

public function createXenditInvoice(Product $product, User $buyer): array
{
    $client = new Client([
        'base_uri' => 'https://api.xendit.co/',
        'auth' => [$this->getParameter('xendit_secret_key'), ''],
    ]);

    $invoiceId = 'INV-' . time() . '-' . random_int(1000, 9999);

    $response = $client->post('v2/invoices', [
        'json' => [
            'external_id' => $invoiceId,
            'amount' => $product->getPrice(),
            'payer_email' => $buyer->getEmail(),
            'description' => 'Pembelian: ' . $product->getName(),
            'invoice_duration' => 86400, // 24 jam
            'currency' => 'IDR',
            'success_redirect_url' => 'https://yoursite.com/order/success',
            'failure_redirect_url' => 'https://yoursite.com/order/failed',
            'payment_methods' => ['QRIS', 'BCA', 'BNI', 'MANDIRI', 'OVO', 'DANA'],
            'items' => [[
                'name' => $product->getName(),
                'quantity' => 1,
                'price' => $product->getPrice(),
            ]],
        ],
    ]);

    return json_decode($response->getBody(), true);
    // Response berisi 'invoice_url' - redirect buyer ke URL ini
}

Tips Handling Webhook

Webhook adalah area yang paling sering bermasalah dalam integrasi payment gateway. Berikut best practices:

  1. Idempotency: Webhook bisa dikirim berkali-kali (retry mechanism). Pastikan handler Anda idempotent — memproses webhook yang sama 2x tidak boleh menghasilkan 2x fulfillment.
  2. Verifikasi signature: Selalu verifikasi signature/token dari webhook. Jangan pernah percaya payload tanpa verifikasi — siapapun bisa mengirim POST request ke webhook URL Anda.
  3. Response cepat: Return HTTP 200 ASAP. Jangan lakukan processing berat di webhook handler. Dispatch ke queue (Symfony Messenger/Laravel Queue) untuk processing async.
  4. Logging: Log setiap webhook yang masuk — payload, signature verification result, processing result. Ini invaluable untuk debugging masalah pembayaran.
  5. Retry handling: Jika webhook handler Anda return non-2xx, gateway akan retry. Midtrans retry 5x, Xendit retry 3x. Pastikan server Anda bisa handle retry tanpa side effect.

Dual Gateway Strategy

Untuk production, kami merekomendasikan menggunakan kedua gateway sekaligus:

  • Midtrans sebagai primary: untuk GoPay, ShopeePay, dan QRIS (payment method yang paling sering dipakai buyer Indonesia)
  • Xendit sebagai secondary + disbursement: untuk VA transfer dan disbursement otomatis ke seller

Implementasi abstraction layer di code Anda sehingga switch antara gateway tidak mengubah business logic:


interface PaymentGatewayInterface
{
    public function createPayment(Order $order): PaymentResult;
    public function handleWebhook(array $payload): WebhookResult;
    public function refund(Order $order, float $amount): RefundResult;
}

class MidtransGateway implements PaymentGatewayInterface { /* ... */ }
class XenditGateway implements PaymentGatewayInterface { /* ... */ }

Testing Payment Integration

Keduanya menyediakan sandbox/test environment:

  • Midtrans Sandbox: app.sandbox.midtrans.com — gunakan test card number dan VA simulasi
  • Xendit Test Mode: Gunakan API key dengan prefix xnd_development_

Buat automated test untuk setiap payment flow: create → pending → paid → fulfilled. Jangan hanya test happy path — test juga expired, cancelled, dan refund scenario. Ini akan menghemat banyak waktu debugging di production.

Payment gateway integration yang solid adalah fondasi dari marketplace yang dipercaya buyer dan seller. Investasikan waktu untuk mengimplementasikannya dengan benar — error di payment = kehilangan uang dan kepercayaan pelanggan. Start dengan Midtrans Snap untuk kecepatan integrasi, tambahkan Xendit untuk disbursement ketika marketplace Anda sudah mulai punya banyak seller.


Ringkasan Praktis untuk 2026

Panduan Integrasi Midtrans & Xendit untuk Produk Digital penting dibaca bukan hanya sebagai tren teknologi, tetapi sebagai panduan kerja untuk bisnis yang memakai produk digital setiap hari. Fokus utamanya adalah membantu seller software, founder kecil, freelancer, dan tim yang ingin mengubah source code menjadi produk yang bisa dijual mengurangi produk sudah dibuat tetapi positioning, pricing, lisensi, support, dan funnel penjualan belum konsisten.

Step-by-step integrasi payment gateway Midtrans dan Xendit untuk marketplace produk digital. Termasuk tips handling webhook, refund, dan subscription.

Di konteks ID TECH, topik ini selalu dikaitkan dengan hasil bisnis: aplikasi lebih mudah dipakai, support lebih ringan, data lebih aman, dan proses penjualan produk digital lebih jelas bagi calon pembeli.

Kapan Topik Ini Menjadi Prioritas?

Topik Strategi Produk Digital sebaiknya diprioritaskan ketika tim mulai melihat tanda-tanda pekerjaan manual bertambah, data tersebar, atau pengguna mulai bergantung pada sistem untuk transaksi harian. Pada fase ini, solusi tidak cukup hanya dibuat berfungsi; solusinya harus bisa dipantau, dijelaskan, dan dipulihkan ketika ada masalah.

  • Bisnis mulai menerima lebih banyak transaksi, chat, order, atau permintaan custom.
  • Tim sulit mengetahui status pekerjaan karena data berada di spreadsheet, grup chat, atau catatan personal.
  • Owner membutuhkan laporan yang bisa dipakai untuk keputusan, bukan sekadar arsip.
  • Produk perlu bukti visual, dokumentasi, dan alur demo agar lebih mudah dijual.
  • Risiko operasional mulai naik: akun bersama, backup tidak jelas, atau perubahan data tanpa audit.
Diagram kerangka implementasi Panduan Integrasi Midtrans & Xendit untuk Produk Digital
Kerangka implementasi: urutan kerja yang membantu tim memulai dari data inti sampai monitoring.

Kerangka Implementasi

Mulai dari kebutuhan paling dekat dengan operasional. Jangan langsung menumpuk fitur; buat alur utama yang bisa diuji oleh pengguna sebenarnya. Setelah itu baru tambahkan otomasi, integrasi, dan dashboard.

  1. Petakan aktor. Tulis siapa yang memakai sistem: owner, admin, kasir, guru, staf, teknisi, pelanggan, atau reseller.
  2. Tentukan data inti. Pilih data yang wajib benar: transaksi, stok, jadwal, pelanggan, pembayaran, tugas, atau laporan.
  3. Buat alur minimum. Pastikan pengguna bisa menyelesaikan pekerjaan utama dari awal sampai selesai tanpa bantuan developer.
  4. Tambahkan kontrol. Siapkan role, audit log, validasi input, backup, dan notifikasi agar sistem bisa dipercaya.
  5. Ukur dampak. Bandingkan kondisi sebelum dan sesudah: waktu input, kesalahan data, jumlah komplain, dan kecepatan laporan.

Checklist Teknis

  • paket lisensi
  • landing page
  • payment gateway
  • CRM sederhana
  • SOP support
  • analytics penjualan

Kesalahan yang Sering Terjadi

Banyak proyek digital gagal bukan karena teknologinya kurang canggih, tetapi karena scope dan operasionalnya tidak disiplin. Beberapa kesalahan yang perlu dihindari:

  • Membangun fitur sebelum memahami proses manual yang sedang dipakai pengguna.
  • Tidak membedakan fitur wajib, fitur nice-to-have, dan layanan custom berbayar.
  • Menunda dokumentasi sampai produk selesai, padahal dokumentasi membantu demo dan support sejak awal.
  • Mengabaikan backup, hak akses, dan audit log ketika aplikasi mulai dipakai untuk data nyata.
  • Membuat halaman produk terlalu teknis sehingga calon pembeli tidak langsung paham manfaat bisnisnya.

Indikator Keberhasilan

Supaya implementasi tidak hanya terlihat sibuk, tetapkan metrik sederhana sejak awal. Metrik ini membantu tim mengetahui apakah perubahan benar-benar menghasilkan nilai.

  • views produk
  • CTR listing
  • chat rate
  • checkout rate
  • refund/support ticket rate
Roadmap 30 60 90 hari Panduan Integrasi Midtrans & Xendit untuk Produk Digital
Roadmap eksekusi: fondasi 30 hari, validasi 60 hari, dan skala 90 hari.

Rencana 30-60-90 Hari

30 Hari Pertama: Rapikan Fondasi

Audit workflow, pilih data utama, bersihkan duplikasi, dan pastikan ada satu sumber kebenaran. Pada fase ini, targetnya bukan membuat sistem kompleks, tetapi membuat pekerjaan harian lebih konsisten.

60 Hari: Validasi dan Otomasi

Mulai ukur bottleneck yang paling sering muncul. Tambahkan template, import/export, notifikasi, atau integrasi ringan hanya untuk pekerjaan yang sudah terbukti berulang.

90 Hari: Produkkan dan Skalakan

Jika workflow sudah stabil, dokumentasikan sebagai paket produk atau SOP. Buat halaman demo, screenshot fitur, FAQ, dan materi support agar produk lebih mudah dijual atau diimplementasikan ke cabang lain.

Hubungan dengan Produk Digital ID TECH

ID TECH punya 84 produk Shopee aktif; setiap artikel blog bisa menjadi pintu edukasi sebelum pengunjung masuk ke halaman produk.

Untuk pembeli, artikel seperti ini bisa dipakai sebagai bahan diskusi sebelum checkout: fitur apa yang benar-benar dibutuhkan, paket apa yang paling sesuai, dan bagian mana yang perlu custom. Untuk tim internal, artikel ini menjadi referensi agar listing, demo, dan dokumentasi lebih konsisten.

FAQ Singkat

Apakah harus langsung memakai sistem besar?

Tidak. Mulai dari alur yang paling sering dipakai dan paling berdampak. Sistem kecil yang dipakai setiap hari lebih bernilai daripada sistem besar yang tidak pernah selesai.

Apa yang perlu disiapkan sebelum membeli atau custom software?

Siapkan contoh data, alur kerja manual, role pengguna, contoh laporan yang diinginkan, dan daftar masalah yang ingin dikurangi. Semakin konkret inputnya, semakin cepat scope bisa ditentukan.

Bagaimana cara memastikan produk digital mudah disupport?

Gunakan dokumentasi singkat, screenshot langkah penting, data demo, backup restore, serta batas jelas antara support penggunaan dan custom fitur baru.

Penutup

Panduan Integrasi Midtrans & Xendit untuk Produk Digital adalah bagian dari disiplin membangun produk digital yang bukan hanya terlihat modern, tetapi benar-benar membantu operasional. Mulai dari fondasi kecil, ukur dampaknya, lalu skalakan dengan dokumentasi dan proses support yang sehat.

Lihat katalog produk ID TECH untuk menemukan aplikasi POS, sekolah, kesehatan, HR, SaaS, dan sistem operasional yang bisa menjadi titik awal implementasi: Katalog Produk ID TECH.

Bagikan artikel ini
Chat Kami