From 028a284790b5294b8e7cfbfde7dadec90bf8d7fa Mon Sep 17 00:00:00 2001 From: mftee Date: Sun, 13 Sep 2026 08:12:01 +0100 Subject: [PATCH] feat: add automatic retry policy for failed payments Closes #58 --- internal/retry/retry.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 internal/retry/retry.go diff --git a/internal/retry/retry.go b/internal/retry/retry.go new file mode 100644 index 0000000..fb2c41b --- /dev/null +++ b/internal/retry/retry.go @@ -0,0 +1,38 @@ +package retry + +import ( + "context" + "time" +) + +// Policy configures automatic retry behavior for failed payment operations. +type Policy struct { + MaxAttempts int + Backoff time.Duration +} + +// DefaultPolicy retries up to 3 times with a 2 second backoff between +// attempts. +var DefaultPolicy = Policy{MaxAttempts: 3, Backoff: 2 * time.Second} + +// Do runs fn, retrying on error according to the policy. It stops retrying +// once ctx is done and returns the last error encountered. +func (p Policy) Do(ctx context.Context, fn func() error) error { + var err error + for attempt := 1; attempt <= p.MaxAttempts; attempt++ { + if err = fn(); err == nil { + return nil + } + + if attempt == p.MaxAttempts { + break + } + + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(p.Backoff): + } + } + return err +}