Files
Nip-05-api/internal/payments/dispatch.go
2026-04-29 02:35:00 +00:00

70 lines
2.1 KiB
Go

package payments
import (
"context"
"log/slog"
"strconv"
"time"
"github.com/noderunners/nip05api/internal/audit"
"github.com/noderunners/nip05api/internal/dm"
"github.com/noderunners/nip05api/internal/invoice"
"github.com/noderunners/nip05api/internal/nostr"
"github.com/noderunners/nip05api/internal/user"
"github.com/noderunners/nip05api/internal/webhook"
)
func (w *Worker) dispatchEvents(ctx context.Context, u *user.User, p *invoice.PendingInvoice, ev dm.EventType) {
vars := buildVars(u, w.domain, w.frontend)
if err := w.dms.Send(ctx, ev, u.Pubkey, vars); err != nil {
slog.Error("dm enqueue", "err", err)
}
data := map[string]any{
"pubkey": u.Pubkey,
"npub": nostr.HexToNpub(u.Pubkey),
"username": u.Username,
"subscription_type": string(u.SubscriptionType),
"amount_sats": p.AmountSats,
"payment_hash": p.PaymentHash,
"is_renewal": p.IsRenewal,
}
if u.ExpiresAt != nil {
data["expires_at"] = u.ExpiresAt.UTC().Format(time.RFC3339)
}
if err := w.hooks.Enqueue(ctx, webhook.EventUserPaid, data); err != nil {
slog.Error("webhook enqueue", "err", err)
}
w.audit.Log(ctx, audit.ActionPaymentConfirmed, audit.ActorSystem, u.Pubkey, map[string]any{
"payment_hash": p.PaymentHash,
"amount_sats": p.AmountSats,
"is_renewal": p.IsRenewal,
"event": string(ev),
})
slog.Info("payment confirmed",
"pubkey", u.Pubkey, "username", u.Username,
"amount_sats", p.AmountSats, "renewal", p.IsRenewal)
}
func buildVars(u *user.User, domain, frontend string) map[string]string {
expires := "lifetime"
days := ""
if u.ExpiresAt != nil {
expires = u.ExpiresAt.Format("2006-01-02")
d := int(time.Until(*u.ExpiresAt).Hours() / 24)
if d < 0 {
d = 0
}
days = strconv.Itoa(d)
}
return map[string]string{
"username": u.Username,
"npub": nostr.HexToNpub(u.Pubkey),
"pubkey": u.Pubkey,
"domain": domain,
"expires_at": expires,
"days_remaining": days,
"frontend_url": frontend,
"subscription_type": string(u.SubscriptionType),
}
}