DEV Community

Cover image for Cara Menangkap dan Memvalidasi Webhook Stripe di CI dengan Apidog
Walse
Walse

Posted on • Originally published at apidog.com

Cara Menangkap dan Memvalidasi Webhook Stripe di CI dengan Apidog

Seorang pelanggan membayar, Stripe mengirimkan peristiwa payment_intent.succeeded ke backend Anda, dan endpoint Anda harus menandai pesanan sebagai lunas. Bagian terakhir ini sering gagal tanpa terdeteksi: webhook tiba, penangan mengalami error, lalu masalah baru terlihat ketika pengguna melapor bahwa pembayaran berhasil tetapi status akun masih belum lunas. Solusinya adalah pengujian CI yang memverifikasi bahwa peristiwa benar-benar tiba dan diproses dengan benar pada setiap pengiriman kode.

Coba Apidog hari ini

Tantangannya, webhook adalah panggilan HTTP masuk dari Stripe ke aplikasi Anda, bukan request yang Anda kirim sendiri. Banyak alat pengujian API dirancang untuk mengirim request dan memeriksa respons, sehingga model webhook terlihat terbalik. Panduan ini menjelaskan pendekatan yang didukung dengan Apidog: tangkap webhook di backend Anda, simpan hasilnya, lalu validasi data tersebut dari skenario CI. Untuk konteks lebih umum, baca panduan cara menguji webhook dan dokumentasi webhook Stripe.

Batasan yang harus Anda rancang

Menurut dokumentasi Apidog, Apidog tidak secara bawaan mendukung pendengaran webhook masuk secara real-time. Anda tidak dapat mengarahkan Stripe ke URL Apidog lalu menunggu peristiwa masuk di sana.

Namun, ini bukan jalan buntu. Ubah desain pengujian menjadi pola tangkap lalu kueri:

  1. Backend Anda menerima webhook dari Stripe.
  2. Backend menyimpan data peristiwa ke database.
  3. Apidog mengkueri data tersimpan tersebut.
  4. Skenario pengujian memvalidasi bahwa peristiwa dan efek bisnisnya sesuai harapan.

Pola ini cocok untuk CI karena kueri database dapat diulang dan hasilnya deterministik.

Seperti apa pola tangkap-lalu-kueri itu

Implementasinya memiliki empat bagian:

  1. Buat endpoint backend untuk menerima webhook Stripe.
  2. Simpan peristiwa webhook ke tabel stripe_event_logs.
  3. Konfigurasikan koneksi database pada environment Apidog.
  4. Gunakan Post-Request Processor untuk mengkueri dan memvalidasi data peristiwa.

Endpoint dan tabel log adalah tanggung jawab aplikasi Anda. Setelah peristiwa tersimpan, Apidog dapat membaca baris tersebut untuk memverifikasi apakah webhook sudah diproses seperti yang diharapkan.

Langkah 1: buat endpoint penangkapan

Backend membutuhkan rute yang dapat di-POST oleh Stripe. Berikut contoh minimal dengan Express:

import express from "express";
import Stripe from "stripe";

const app = express();
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

app.post(
  "/webhooks/stripe",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    let event;

    try {
      event = stripe.webhooks.constructEvent(
        req.body,
        req.headers["stripe-signature"],
        endpointSecret
      );
    } catch (err) {
      return res.status(400).send(`Signature check failed: ${err.message}`);
    }

    // Simpan event agar dapat diverifikasi oleh pengujian.
    await db.query(
      `INSERT INTO stripe_event_logs (event_id, type, payload, handled_at)
       VALUES ($1, $2, $3, now())
       ON CONFLICT (event_id) DO NOTHING`,
      [event.id, event.type, JSON.stringify(event.data.object)]
    );

    if (event.type === "payment_intent.succeeded") {
      const intent = event.data.object;
      await markOrderPaid(intent.metadata.order_id);
    }

    res.json({ received: true });
  }
);
Enter fullscreen mode Exit fullscreen mode

Perhatikan dua hal penting:

  • Verifikasi tanda tangan Stripe dengan constructEvent sebelum memproses payload. Ini wajib untuk memastikan request benar-benar berasal dari Stripe. Lihat panduan verifikasi tanda tangan webhook untuk pembahasan lebih lanjut.
  • Simpan event ke stripe_event_logs. Baris ini menjadi bukti yang akan dibaca oleh Apidog.
  • Gunakan ON CONFLICT (event_id) DO NOTHING untuk menjaga proses tetap idempoten karena Stripe dapat mengirim ulang event yang sama.

Langkah 2: hubungkan database di environment Apidog

Konfigurasikan koneksi database pada environment Apidog yang dipakai oleh CI, misalnya database staging atau database pengujian khusus.

Pastikan environment aplikasi dan environment Apidog mengarah ke database yang sama:

  • Pengujian terhadap staging harus membaca database staging.
  • Pengujian terhadap database test harus memicu webhook ke aplikasi test.
  • Jangan gunakan database produksi untuk skenario ini.

Ketidaksesuaian environment adalah penyebab umum pengujian gagal meskipun endpoint webhook sebenarnya sudah menerima event.

Langkah 3: tambahkan Post-Request Processor untuk mengkueri log

Post-Request Processor memungkinkan Apidog menjalankan kueri database setelah request dalam skenario pengujian selesai.

Alur untuk memvalidasi payment_intent.succeeded:

  1. Skenario memicu pembayaran, misalnya membuat dan mengonfirmasi payment intent dalam mode test Stripe.
  2. Stripe mengirim webhook ke /webhooks/stripe.
  3. Endpoint memverifikasi signature dan menyimpan event ke stripe_event_logs.
  4. Langkah berikutnya menjalankan Post-Request Processor untuk mengambil event tersebut.
  5. Skenario memvalidasi event dan perubahan status pesanan.

Contoh kueri SQL:

SELECT event_id, type, payload, handled_at
FROM stripe_event_logs
WHERE type = 'payment_intent.succeeded'
ORDER BY handled_at DESC
LIMIT 1;
Enter fullscreen mode Exit fullscreen mode

Validasi minimal yang sebaiknya dilakukan:

  • type harus bernilai payment_intent.succeeded.
  • event_id harus cocok dengan event yang dipicu oleh skenario.
  • Nilai dalam payload, seperti jumlah pembayaran atau ID pesanan, harus sesuai.
  • handled_at harus terisi untuk membuktikan penangan benar-benar berjalan.

Jangan hanya mengambil event terbaru tanpa membandingkan event_id. Jika tabel log berisi data dari eksekusi sebelumnya, pengujian dapat memberikan hasil positif palsu.

Karena webhook bersifat asinkron, tambahkan jeda singkat atau mekanisme polling sebelum menjalankan kueri. Contohnya, ulangi kueri beberapa kali dalam interval singkat hingga event ditemukan atau batas waktu tercapai.

Catatan tentang penerusan real-time selama pengembangan lokal

Pola tangkap-lalu-kueri ideal untuk CI. Namun, saat pengembangan lokal, Stripe tidak dapat mengakses localhost secara langsung. Anda memerlukan layanan penerusan webhook.

Stripe CLI dapat meneruskan event ke endpoint lokal:

stripe listen --forward-to localhost:3000/webhooks/stripe
Enter fullscreen mode Exit fullscreen mode

Alternatifnya, gunakan Ngrok untuk mengekspos port lokal sebagai URL publik yang dapat didaftarkan pada Stripe.

Gunakan pendekatan berikut:

  • Pengembangan lokal: Stripe CLI atau Ngrok untuk melihat event secara langsung.
  • CI: database log dan Post-Request Processor untuk validasi otomatis.

Jangan keliru dengan fitur Webhook bawaan Apidog

Apidog memiliki fitur bernama Webhook, tetapi fitur ini bukan listener untuk menerima event Stripe masuk.

Fitur Webhook bawaan digunakan untuk mendefinisikan dan mendokumentasikan outbound webhook: webhook yang dikirim oleh sistem Anda ke URL eksternal ketika suatu event terjadi.

Untuk membuat dokumentasi outbound webhook di Apidog:

  1. Klik ikon + di sidebar kiri.
  2. Pilih New Other Protocol APIs, lalu Webhook.
  3. Isi Request Method, Webhook Name, Debug URL, serta konfigurasi body dan header.
  4. Klik Save.

Anda dapat memasukkan URL pada Debug URL lalu menekan Send untuk mensimulasikan request. Perlu diingat, Debug URL hanya digunakan saat pengujian dan tidak muncul pada dokumentasi yang diterbitkan atau ekspor OpenAPI.

Untuk pembahasan desain callback, baca webhook dalam desain API.

Ringkasnya:

  • Fitur Webhook Apidog: dokumentasi dan simulasi webhook outbound.
  • Pola tangkap-lalu-kueri: validasi webhook Stripe inbound.

Variasi dan penguatan

Setelah validasi dasar berjalan, tambahkan pengujian berikut.

1. Validasi event secara end-to-end

Jangan hanya memeriksa jenis event. Cocokkan juga event_id agar Anda tahu event yang divalidasi adalah event yang dipicu oleh test saat ini.

Jika tabel log terus bertambah, pertimbangkan untuk:

  • Menghapus data test sebelum skenario dijalankan.
  • Menambahkan test_run_id.
  • Membatasi kueri berdasarkan ID pesanan atau metadata unik.

2. Uji jalur kegagalan

Uji kondisi yang seharusnya ditolak, misalnya:

  • Signature tidak valid.
  • Jenis event tidak didukung.
  • Payload tidak memiliki data pesanan yang diperlukan.

Untuk event yang ditolak, pastikan aplikasi tidak menulis handled_at dan tidak mengubah status pesanan. Pengujian hanya pada jalur sukses tidak cukup untuk menangkap masalah yang dapat muncul di produksi.

Lihat juga praktik terbaik webhook pembayaran untuk idempotensi dan perilaku percobaan ulang.

3. Validasi hasil bisnis

“Webhook diterima” belum berarti proses pembayaran berhasil secara bisnis.

Jika handler memperbarui tabel orders, tambahkan kueri kedua:

SELECT id, payment_status, paid_at
FROM orders
WHERE id = $1;
Enter fullscreen mode Exit fullscreen mode

Kemudian verifikasi bahwa:

  • payment_status berubah menjadi status lunas yang diharapkan.
  • paid_at terisi.
  • Pesanan yang tepat diperbarui.

Dengan begitu, test membuktikan seluruh rantai: Stripe mengirim event, handler memprosesnya, dan status pesanan berubah.

4. Jadwalkan validasi

Selain menjadikannya merge gate, Anda dapat menjalankan skenario secara berkala. Setelah skenario tersimpan di Apidog, jadwalkan eksekusinya untuk mendeteksi handler rusak di antara deployment.

Panduan cara menjadwalkan pengujian API di Apidog membahas pengaturan tersebut.

Otomatiskan alur kerja dengan Apidog CLI

Agar pengujian berjalan tanpa pengawasan, jalankan skenario dengan Apidog CLI di pipeline CI.

Instal CLI dan autentikasi dengan token:

npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
Enter fullscreen mode Exit fullscreen mode

Jalankan skenario validasi webhook terhadap environment yang benar:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t <SCENARIO_ID> -e <ENV_ID> -r cli
Enter fullscreen mode Exit fullscreen mode

Keterangan:

  • -t: ID skenario pengujian.
  • -e: ID environment.
  • -r: reporter output.

Jika Anda membutuhkan laporan HTML sebagai artifact CI:

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <SCENARIO_ID> \
  -e <ENV_ID> \
  -r html,cli
Enter fullscreen mode Exit fullscreen mode

Skenario tersebut membawa konfigurasi Post-Request Processor dan kueri database. Jika validasi gagal, perintah mengembalikan kode keluar non-nol sehingga pipeline dapat memblokir merge.

Lihat panduan instalasi Apidog CLI dan panduan alur kerja CI/CD pipeline untuk contoh integrasi lebih lengkap.

Pertanyaan yang Sering Diajukan

Bisakah Apidog menerima webhook Stripe secara langsung?

Tidak. Apidog tidak secara bawaan mendengarkan webhook masuk. Tangkap event di endpoint backend Anda, simpan ke database, lalu validasi menggunakan Post-Request Processor. Untuk pengembangan lokal, gunakan Stripe CLI atau Ngrok.

Di mana verifikasi terjadi?

Verifikasi terjadi di Post-Request Processor dalam skenario pengujian Apidog. Prosesor mengkueri tabel stripe_event_logs melalui koneksi database environment, lalu membandingkan hasilnya dengan nilai yang diharapkan.

Apakah saya perlu paket berbayar untuk alur validasi database?

Dokumentasi alur kerja ini tidak menyatakan pembatasan paket tertentu. Periksa detail paket terbaru di halaman harga. Anda juga dapat mengunduh Apidog untuk meninjau konfigurasi Post-Request Processor dan koneksi database environment.

Bagaimana menangani jeda antara pemicuan pembayaran dan pengiriman webhook?

Tambahkan delay singkat atau polling retry sebelum menjalankan kueri. Ulangi kueri beberapa kali selama beberapa detik hingga event ditemukan. Untuk konsep dasarnya, baca cara menguji webhook.

Apakah fitur Webhook bawaan Apidog berguna untuk menangkap event Stripe?

Tidak. Fitur tersebut digunakan untuk mendefinisikan webhook outbound dari sistem Anda. Untuk event Stripe inbound, gunakan pola tangkap-lalu-kueri.

Kesimpulan

Anda tidak dapat mengarahkan Stripe ke Apidog untuk menangkap webhook secara langsung. Pendekatan yang didukung adalah:

  1. Terima webhook Stripe di endpoint backend Anda.
  2. Verifikasi signature.
  3. Catat event ke tabel stripe_event_logs.
  4. Gunakan Post-Request Processor Apidog untuk mengkueri event.
  5. Validasi event dan perubahan status pesanan.
  6. Jalankan skenario dengan apidog run di pipeline CI.

Dengan pola ini, setiap merge dapat membuktikan bahwa event pembayaran benar-benar mengubah pesanan menjadi lunas.

Top comments (0)