Go SDK
0.1.1 kaynak etiketi ve resmi Go modül proxy’si üzerinden erişilebilir. Boş, yalıtılmış önbellekle indirilen arşiv sum.golang.org üzerinden doğrulandı; herkese açık checksum kaydı (opens in a new tab) hem modül hem go.mod hash’lerini içerir.
0.1.1 sürümü mağaza sitesi için somut bir sunum örneği ekler. Varsayılan gömülü ödemedir: yalnız resmi Lunixi bundle yüklenir ve mevcut form mount edilir; yöntem ve çoklu kart seçenekleri Lunixi panelinde kalır. İsteğe bağlı yönlendirme yalnız backend paymentPageUrl adresini, tam HTTPS pay.lunixi.com/payment/ doğrulamasından sonra kullanır. Adresin token’ı gömülü token’dan farklı olabilir. Eksik adres gömülü ödemeyi engellemez; yönlendirme aynı deneme/anahtarla inceleme veya uzlaştırmada kalır. Tarayıcı token’ından adres üretmeyin. Formdan önce müşteri/sipariş sahipliğini ve yerel tarayıcı CSRF’yi doğrulayın; Cache-Control: private, no-store gönderin, mağazanın CSP nonce değerini koruyun; token, HTML ve yönlendirme adreslerini loglamayın. Genel yanıt verisi paymentPageUrl alanını korur; yeni tipli ürün eşitliği iddiası yoktur.
github.com/Lunixi-Payment/lunixi-go, Go 1.26+ sunucu uygulamaları için Lunixi istemcisidir. Çalışma zamanı bağımlılığı yoktur; net/http, Gin, Echo ve Fiber ile kullanılabilir.
Kurulum
Aşağıdaki bağımlılığı uygulamanızın mevcut go.mod dosyasına ekleyin. Var olan module tanımını ve Go direktifini koruyun; SDK Go 1.26 veya üzerini gerektirir.
require github.com/Lunixi-Payment/lunixi-go v0.1.1Aşağıda gösterilen SDK import'unu ekledikten sonra sabitlenen sürümü indirin ve uygulamanın bağımlılıklarını düzenleyin:
go mod download github.com/Lunixi-Payment/lunixi-go
go mod tidyKaynak kod ve örnekler (opens in a new tab) · Go referansı (opens in a new tab)
Merchant başına bir istemci
import (
"os"
"time"
lunixi "github.com/Lunixi-Payment/lunixi-go"
)
client, err := lunixi.New(lunixi.Config{
BaseURL: "https://api-gateway.lunixi.com",
KeyID: os.Getenv("LUNIXI_KEY_ID"),
PrivateKey: os.Getenv("LUNIXI_PRIVATE_KEY_PEM"),
Timeout: 30 * time.Second,
MaxRetries: 2,
})
if err != nil { return err }Ed25519 açık anahtarını panelde kaydedin; özel anahtar yalnız sunucunuzda kalır. PKCS8 PEM, base64 PKCS8 DER, base64 32 bayt seed ve doğrulanmış base64 64 bayt Ed25519 özel anahtar kabul edilir. TEST/LIVE ortamını merchant anahtarı seçer. Özel anahtar ve webhook secret tarayıcıya gönderilmez.
İstemciyi goroutine'ler arasında paylaşabilirsiniz. SDK istekleri imzalar, token'ı önbellekte tutar ve eşzamanlı yenilemeleri birleştirir. HTTPS zorunludur; yönlendirmeler izlenmez. BaseURL yol, kullanıcı bilgisi veya sorgu içermeyen güvenilir bir köken olmalıdır. Üretimde TLS sertifika doğrulamasını kapatmayın.
| Ayar | Varsayılan | Sınır |
|---|---|---|
Timeout | İstek başına 30 saniye | En çok 2 dakika; ayrıca context deadline kullanın |
MaxRetries | 0 | 0–5; yalnız GET veya sabit idempotency anahtarı olan istek |
MaxResponseBytes | 8 MiB | En çok 32 MiB |
HTTPClient | Standart istemci | Kopyalanır; yönlendirmeler kapatılır |
AllowInsecureLocalhost | false | Yalnız açıkça seçilen loopback/localhost HTTP testleri |
Checkout başlatma
Sipariş ve tutarı sunucudaki kayıtlarınızdan okuyun. Deneme anahtarını API çağrısından önce kaydedin; sonucu belirsiz isteği aynı gövde ve anahtarla tekrar edin.
ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second)
defer cancel()
response, err := client.Payments.CreateIntent(ctx, lunixi.IntentRequest{
Amount: 10050,
Currency: "TRY",
OrderID: "ORD-1001",
CallbackURL: "https://merchant.example/payment/return",
BasketItems: []lunixi.BasketItem{
{ID:"line-1", Name:"Örnek ürün", ItemType:"PHYSICAL", Price:10050},
},
}, kayitliDenemeAnahtari)
if err != nil { return err }
var checkout struct { Token string `json:"token"` }
if err := response.DecodeData(&checkout); err != nil { return err }
if checkout.Token == "" { return errors.New("checkout token eksik") }Örnekte standart kütüphaneden context ve errors kullanılır. kayitliDenemeAnahtari, ödeme denemenizle kaydettiğiniz anahtardır. Token'ı yalnız ilgili siparişin yetkili müşterisine Cache-Control: no-store ile verip mevcut Lunixi ödeme formunu açın. Token'ı loga veya analitik verisine yazmayın.
Tutarlar pozitif tam sayı kuruştur: 10050 = 100,50 TRY. Sepet Price alanı kalem toplamıdır; kalemlerin toplamı Amount ile aynı olmalıdır. Güvenli JSON tam sayı sınırını aşan değerler reddedilir. Kök ödeme toplamı amount alanıdır. Taksit ve vade farkını Lunixi formu yönetir. IntentRequest alıcı, adres ve belgelenmiş sigorta sepet alanlarını destekler. Yöntem kısıtlaması yalnız Lunixi panelindeki açık yöntemleri daraltır.
Form, açık kart ve alternatif ödeme yöntemlerini gösterir; SDK ham kart toplamaz. Token, tarayıcı dönüşü, HTTP başarısı veya AUTHORIZED tahsilat kanıtı değildir. Siparişi ancak doğrulanmış gateway sonucunda merchant, sipariş, ödeme kimliği, beklenen tutar/para birimi ve nihai tahsilat/uzlaştırma durumunu eşleştirerek tamamlayın. İade, iptal ve itiraz ayrı durum geçişleridir.
Desteklenen API'ler
| İstemci | Yardımcılar |
|---|---|
Payments | CreateIntent, Get, List, Methods, Capture, Refund, Void |
Payments split | Split, GetSplit, RefundSplit |
Fraud | Evaluate, RecordEvent, Decisions, Decision |
Client.Do | Diğer belgelenmiş /api/v1/ merchant uçlarına aynı imzalı taşıma |
WebhookVerifier / SQLInbox | Ham v2 imza doğrulama ve kalıcı tekrar koruması |
0.1.1 sürümünde cüzdan, banka, ödeme linki, sigorta, pazaryeri, abonelik ve kimlik için ayrı tipli istemciler yoktur. Bu ürünlerin REST şemaları Do ile kullanılır; tüm ürünlerde tipli yardımcı eşitliği iddia edilmez.
kismi := int64(2500)
response, err := client.Payments.Refund(ctx, paymentID, &kismi, "Müşteri iadesi", kayitliIadeAnahtari)nil tutar tam capture/refund ister. Void provizyonu bırakır. Split, tam sayı bacak tutarlarını, 1–5 bacağı ve toplamı denetler; yönteme özgü şema gateway tarafından doğrulanır. Bekleyen split durumlarında HTTP 400 içeren Response gelebilir; sipariş ödenmiş sayılmaz. Teslimattan önce durum ve toplam denge doğrulanır.
Yanıt Envelope, Data, PageInfo ve ikili Bytes alanlarını korur. DecodeData, arayüz değerlerinde json.Number kullanır. APIError, StatusCode, güvenli Code ve RequestID taşır; hata metnine uzak sunucunun gövdesi/mesajı alınmaz. Yanıt nesneleri müşteri bilgisi içerebilir; loglanmaz.
Finansal yardımcılar 16–128 karakterlik, boşluksuz yazdırılabilir ASCII idempotency anahtarı ister. Tekrarlar aynı anahtar/gövdeyi korur, yeni imza nonce'ı kullanır. Anahtarsız mutasyon otomatik tekrarlanmaz. Belirsiz sonucu yeni bir ödeme başlatmadan önce uzlaştırın.
Kalıcı webhook tekrar koruması
Ham baytları JSON middleware'den önce doğrulayın. v2 HMAC event ID, zaman damgasının birebir metni ve ham gövdeyi kapsar; sabit zamanlı karşılaştırılır. Varsayılan tolerans 5 dakikadır, en çok 15 dakika ayarlanabilir; kapatılamaz. İmzalı gövdede type gerekir; imzasız başlık tek başına finansal işleme izin vermez. Tekrarlanan başlık/JSON anahtarı ve ID/tür uyuşmazlığı reddedilir.
verifier, err := lunixi.NewWebhookVerifier(lunixi.WebhookConfig{
Secrets: []string{os.Getenv("LUNIXI_WEBHOOK_SECRET")},
})
if err != nil { return err }
event, err := verifier.VerifyRequest(ctx, request)
if err != nil { return err }
inbox, err := lunixi.NewSQLInbox(db,"lunixi_webhook_inbox",merchantScope)
if err != nil { return err }
// EnsureSchema başlangıçta veya migration sırasında bir kez çalıştırılır.
applied, err := inbox.Process(ctx,event,func(tx *sql.Tx)error {
return dogrulanmisSiparisiIsle(ctx,tx,event)
})db, database/sql bağlantınızdır; dogrulanmisSiparisiIsle, finansal alanları eşleyip verilen transaction ile durum geçişini uygulayan kendi adaptörünüzdür. Inbox, uygulamanın sağladığı sürücüyle PostgreSQL ve SQLite destekler. Merchant başına ayrı scope kullanın. Olay kaydı ve sipariş güncellemesi aynı transaction içinde commit edilmelidir. Tekrar callback'i çalıştırmaz; aynı ID farklı gövdeyle gelirse reddedilir. Callback başarısızsa olay kaydı da geri alınır; sağlayıcı güvenle tekrar teslim edebilir.
Harici yan etkiler için outbox kullanın. Tekrar kayıtlarını teslim/replay politikanız boyunca saklayın. Rotasyonda en fazla üç güncel/önceki secret kullanılabilir. Eski bir olay için zaman kontrolünü kaldırmak yerine sağlayıcıdan yeni replay isteyin.
Çalıştırılabilir SQLite örneği (opens in a new tab), doğrulanmış bildirim ID/türlerini transaction içinde kaydeder; geri alma, yeniden başlatma, eşzamanlı tekrar ve HTTP gövde değiştirme testleri içerir. Siparişi tamamlamaz; doğrulanmış finansal adaptörünüz callback'e eklenir. Örnek CGO ve C derleyicisi ister; ana SDK istemez. Dinleyiciyi güvenilir HTTPS proxy arkasına yerleştirin.
Doğrulama
go test -race ./...
go vet ./...
go build ./...
go run golang.org/x/vuln/cmd/[email protected] ./...Aynı kontrolleri examples/webhook içinde de çalıştırın. CI, Go 1.26/1.27, bağımsız Node.js JSON/Ed25519 vektörleri, ham v2 HMAC örnekleri ve gerçek TLS test sunucularını kontrol eder. Test anahtarları sentetiktir; canlı ödeme yapılmaz. Güvenlik politikası (opens in a new tab).
Mağaza içi entegrasyon örneği
Kaynak örnekteki RenderCheckoutHTML(token, nonce) ve HostedCheckoutURL(paymentPageUrl) yardımcıları presentation.go (opens in a new tab) dosyasındadır. Kendi yetkili ve CSRF korumalı mağaza controller’ınıza uyarlayın. CLI varsayılanı LUNIXI_CHECKOUT_MODE=embedded; hosted backend adresini doğrular. HTML, token veya URL konsola basılmaz. Bunlar yeni SDK istemci yöntemleri değil, kaynak örnek yardımcılarıdır.