Realtime Payment Processing: Implementasi Consume Payment Menggunakan Kafka dan Golang

Table of Contents
Pastinya tidak menutup kemungkinan anda yang membaca ini pernah membeli sebuah barang di aplikasi toko online seperti tokopedia, shopee, atau bahkan pernah membayar tagihan menggunakan e-wallet seperti DANA, Doku, Gopay. 
Nah, di balik semua kejadian yang anda tekan "bayar" pastinya ada proses pembayaran yang harus cepat ( bisa terjadi dalam hitungan milisecond ) sehingga uang yang anda bayar dapat berpindah ke saldo merchant, dan merchant menerima notifikasi, serta saldo merchant di perbarui. 
Tidak ada loading yang lama, prosess sinkronasi manual. semuanya terjadi secara REAL TIME.

Di balik semua proses di atas, terdapat arsitektur yang bekerja tanpa henti, salah satunya menggunakan teknologi apache kafka.

Pada artikel kali ini saya akan memberikan sedikit penjelasan dan gambaran bagaimana consume payment dilakukan menggunakan teknologi kafka dan bahasa pemerograman golang. 

Implementasi Consume Payment Menggunakan Kafka dan Golang

Lets go

Apache Kafka

Apache kafka merupakan teknologi streaming data terdistribusi yang dapat di gunakan untuk membangun apps yang realtime. Sama seperti sistem antrian pesan ( message queue ), akan tetapi jauh lebih cepat dan tahan terhadap beban yang besar. 
Ada beberapa organisasi yang besar mengimplementasikan apache kafka untuk proses streaming data seperti : Grab, Linkedin, Paypal, Shopify.

Untuk penjelasan lebih lanjut soal kafka mungkin bisa ke website nya aja guys. 

Alasan Kenapa Proses Pembayaran Harus Cepat

  • Kecepatan : Pastinya user tidak ingin menunggu lama proses pembayarannya selesai.
  • Skalabilitas : Sistem harus mendukung proses transaksi yang ribuan perdetik. 
  • Akurasi : Proses settlement ( dana yang masuk ke merchant ) harus akurat, tidak boleh double settle.
  • Integrasi : Payment prosess biasanya melibatkan beberapa service. Seperti settlement service, notif service.

Contoh Skenario Sederhana

Di sini saya ingin memberikan contoh arsitektur yang sederhana dan mengimplementasikannya di bahasa pemerograman golang. 

Contoh yang paling sederhana adalah ketika user melakukan transaksi/membeli suatu barang pada applikasi kita, maka di belakang layar akan ada service yang berjalan. Misalnya Payment Service. 

Realtime Payment Processing: Implementasi Consume Payment Menggunakan Kafka dan Golang

Penjelasan dari gambar flow di atas : 
  1. Actor atau user melakukan pembayaran
  2. Payment Service langsung memprosess transaksi. contohnya melakukan validasi apakah saldo nya cukup, kartu nya valid. Nah, jika proses transaksi ini berhasil, maka Payment Service atau producer akan melakukan atau mengirim event ke kafka dengan topic payment.success 
  3. Kafka akan menyimpan event tersebut dalam cluster
  4. Kemudian ada 2 service ( Settle Service, Notif Service ) yang akan membaca dari topic yang sama : payment.success
  5. Settle Service akan melakukan update saldo merchant 
  6. Notif Service akan melakukan kirim notifikasi ke actor atau customer
Jadi semua service berjalan secara independen dan asyncronous ( tidak saling menunggu )

Mari kita implementasikan flow di atas menggunakan bahasa pemerograman golang dan pastinya apache kafka. 

Implementasi

Setup Golang Module menggunakan perintah go mod init payment_consumer

Kemudian kita akan get library kafka segmentio/kafka-go. link repo github disini 
gunakan perintah : go get github.com/segmentio/kafka-go

Setelah itu, kita akan membuat folder model terlebih dahulu dan di dalamnya terdapat class struct PaymentEvent. bisa di lihat pada baris code di bawah ini : 

package model

type PaymentEvent struct {
	ID     string  `json:"id"`
	UserID string  `json:"user_id"`
	Amount float64 `json:"amount"`
	Status string  `json:"status"`
}

Setelah struct selesai di buat, mari kita buat file main.go nya. Untuk full code nya saya siapkan di bawah ini : 

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/segmentio/kafka-go"
	"log"
	"payment-consumer/model"
	"time"
)

func main() {

	kafkaReader := kafka.NewReader(kafka.ReaderConfig{
		Brokers: []string{"localhost:9092"},
		Topic:   "payment.success",
		GroupID: "payment-group",
	})
	defer kafkaReader.Close()

	fmt.Println("Payment Consumer Started, Waiting for messages.")

	for {
		msg, err := kafkaReader.ReadMessage(context.Background())
		if err != nil {
			log.Fatalf("Error reading message: %v", err)
		}

		var eventPayment model.PaymentEvent
		if err := json.Unmarshal(msg.Value, &eventPayment); err != nil {
			log.Printf("failed to parse event: %v", err)
			continue
		}

		processSettlement(eventPayment)
		sendNotificationToUser(eventPayment)
	}
}

func processSettlement(event model.PaymentEvent) {
	fmt.Printf("Processing settlement for payment %s, amount: %.2f\n", event.ID, event.Amount)
	time.Sleep(500 * time.Millisecond)
}

func sendNotificationToUser(event model.PaymentEvent) {
	fmt.Printf("Sending notification to user %s, amount: %.2f\n", event.ID, event.Amount)
	time.Sleep(500 * time.Millisecond)
}

Sedikit penjelasan pada program di atas.

Kita menggunakan kafka reader agar program bisa membaca pesan dari topic payment.success di cluster kafka. Begitu ada pesan masuk ke topic, pesan tersebut akan di baca dan di deserialize dari json ke struct PaymentEvent.

Biasanya dalam setiap proses payment ada checkIdempotency, tapi di sini saya cuman ingin memberikan contoh implementasi simple 😁. Jadi teman2 bisa menambahkan fungsi checkIdempotency agar program bisa mencegah adanya prosess double sehingga dapat menyebabkan double settle.  

Mari kita test program di atas. 

Testing

Pada tahap test, saya akan menjalankan kafka di local saya dengan menggunakan perintah brew service start kafka (disini saya menggunakan mac ya, jadi perintahnya menggunakan brew) Solusi yang bagusnya sebenarnya jalankan via docker aja hehe. 
Kemudian jalankan program golang yang barusan anda buat dengan mengetikkan perintah go run main.go

Ketika anda selesai menjalankan code golangnya, maka akan muncul output seperti ini : 

Implementasi Consume Payment Menggunakan Kafka dan Golang

Artinya program sedang menunggu pesan yang masuk ke topic cluster kafka ( payment.success ).
Nah, bagaimana cara agar terdapat pesan di topic payment.success ? kita akan menggunakan perintah manual di terminal untuk memasukkan pesan ke topic payment.succcess. Bisa langsung lihat contoh perintahnya di bawah ini : 
echo '{"id":"trx123","user_id":"user001","amount":150000,"status":"SUCCESS","timestamp":"2025-08-21T10:00:00Z"}' \
  | /opt/homebrew/opt/kafka/bin/kafka-console-producer --bootstrap-server localhost:9092 --topic payment.success

Setelah pesan tersebut masuk ke topic, maka coba lihat output program anda, harusnya sudah seperti ini : 

Implementasi Consume Payment Menggunakan Kafka dan Golang

Artinya program telah melakukan consume payment dari kafka. 

Hmmm sepertinya agak ribet kalau mengirim pesan ke topic via terminal manual ya ? wkwk, di sini saya cuma ingin memberikan contoh untuk consume nya.  

Tapi jika anda tidak ingin mengirim pesan ke topic kafka via manual, anda bisa membuat program sendiri untuk publish pesan ke topic payment.success dan secara otomatis program akan consume payment nya.

Oke guysss, cukup sampai sini saja penjelasan saya. Jika terdapat kekeliruan, jangan lupa tinggalkan jejak di komentar wkwkw. dan semoga contoh dan penjelasan ini bisa menjadi inspirasi serta dasar untuk eksperimen dan implementasi lebih lanjut dalam tahap pembelajaran anda. 

Posting Komentar