Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #38 from oxygenpay/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
swift1337 authored Sep 28, 2023
2 parents 272c5ed + 5df6991 commit dcb11c2
Show file tree
Hide file tree
Showing 23 changed files with 239 additions and 231 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func Execute() {

// resolveConfig or exit with error
func resolveConfig() *config.Config {
cfg, err := config.New(Version, Commit, configPath, skipConfig, EmbedFrontend)
cfg, err := config.New(Commit, Version, configPath, skipConfig, EmbedFrontend)
if err != nil {
fmt.Printf("unable to initialize config: %s\n", err.Error())
os.Exit(1)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ require (
github.com/oxygenpay/tatum-sdk v0.0.0-20230529210116-d986b7743613
github.com/pkg/errors v0.9.1
github.com/robfig/cron/v3 v3.0.1
github.com/rs/zerolog v1.26.1
github.com/rs/zerolog v1.29.0
github.com/rubenv/sql-migrate v1.2.0
github.com/samber/lo v1.37.0
github.com/spf13/cobra v1.6.1
github.com/stretchr/testify v1.8.1
github.com/tidwall/gjson v1.14.4
github.com/wemeetagain/go-hdwallet v0.1.0
github.com/ziflex/lecho/v3 v3.1.0
github.com/ziflex/lecho/v3 v3.5.0
go.etcd.io/bbolt v1.3.6
go.uber.org/atomic v1.10.0
golang.org/x/crypto v0.11.0
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
Expand Down Expand Up @@ -458,6 +459,7 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
Expand Down Expand Up @@ -541,11 +543,14 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rs/zerolog v1.26.0/go.mod h1:yBiM87lvSqX8h0Ww4sdzNSkVYZ8dL2xjZJG1lAuGZEo=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/rubenv/sql-migrate v1.2.0 h1:fOXMPLMd41sK7Tg75SXDec15k3zg5WNV6SjuDRiNfcU=
github.com/rubenv/sql-migrate v1.2.0/go.mod h1:Z5uVnq7vrIrPmHbVFfR4YLHRZquxeHpckCnRq0P/K9Y=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down Expand Up @@ -636,6 +641,8 @@ github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/ziflex/lecho/v3 v3.1.0 h1:65bSzSc0yw7EEhi44lMnkOI877ZzbE7tGDWfYCQXZwI=
github.com/ziflex/lecho/v3 v3.1.0/go.mod h1:dwQ6xCAKmSBHhwZ6XmiAiDptD7iklVkW7xQYGUncX0Q=
github.com/ziflex/lecho/v3 v3.5.0 h1:Z4TBr8SbUUnfaVc8tGJf1Jhu0G9Jxjl77lPW0riXKak=
github.com/ziflex/lecho/v3 v3.5.0/go.mod h1:+eInrytYHxVPI6NQbua9xXGerB1x0ujj9jAV33yBIko=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
Expand Down
15 changes: 15 additions & 0 deletions internal/server/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func WithLogger(logger *zerolog.Logger) Opt {
s.echo.Use(lecho.Middleware(lecho.Config{
Logger: lecho.From(l, lecho.WithLevel(log.INFO)),
RequestIDKey: middleware.RequestIDKey,
Enricher: loggerEnricher,
Skipper: func(c echo.Context) bool {
path := c.Request().URL.Path

Expand All @@ -106,6 +107,20 @@ func WithLogger(logger *zerolog.Logger) Opt {
}
}

func loggerEnricher(c echo.Context, logger zerolog.Context) zerolog.Context {
merchantID := c.Param("merchantId")
if merchantID != "" {
logger = logger.Str("merchant_id", merchantID)
}

paymentID := c.Param("paymentId")
if paymentID != "" {
logger = logger.Str("payment_id", paymentID)
}

return logger.Str("path", c.Path())
}

const healthcheckPath = "/health"

func withHealthcheck(e *echo.Echo) {
Expand Down
5 changes: 5 additions & 0 deletions internal/service/payment/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,11 @@ func (s *Service) Update(ctx context.Context, merchantID, id int64, props Update
return s.entryToPayment(pt)
}

func (s *Service) Fail(ctx context.Context, pt *Payment) error {
_, err := s.Update(ctx, pt.MerchantID, pt.ID, UpdateProps{Status: StatusFailed})
return err
}

func (s *Service) SetWebhookTimestamp(ctx context.Context, merchantID, id int64, sentAt time.Time) error {
err := s.repo.UpdatePaymentWebhookInfo(ctx, repository.UpdatePaymentWebhookInfoParams{
ID: id,
Expand Down
3 changes: 2 additions & 1 deletion internal/service/payment/service_withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package payment

import (
"context"
"fmt"
"strconv"
"time"

Expand Down Expand Up @@ -33,7 +34,7 @@ func (s *Service) ListWithdrawals(ctx context.Context, status Status, filterByID
}

if len(filterByIDs) > 0 && len(results) != len(filterByIDs) {
return nil, errors.New("results len mismatch")
return nil, fmt.Errorf("withdrawals filter mismatch for status %q", status)
}

payments := make([]*Payment, len(results))
Expand Down
55 changes: 31 additions & 24 deletions internal/service/processing/service_withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,16 @@ func (s *Service) BatchCreateWithdrawals(ctx context.Context, withdrawalIDs []in
return nil, err
}

// 1.Validate payments
if errValidate := s.validateWithdrawals(withdrawals); errValidate != nil {
return nil, errValidate
}

// 2. Get OUTBOUND wallets and balances
// 1. Get OUTBOUND wallets and balances
outboundWallets, outboundBalances, err := s.getOutboundWalletsWithBalancesAsMap(ctx)
if err != nil {
return nil, errors.Wrap(err, "unable to get outbound wallets with balances")
}

result := &TransferResult{}

// 3. For each withdrawal:
// 2. For each withdrawal:
// - Validate
// - Resolve currency
// - Resolve outbound system wallet & balance
// - Resolve merchant balance & withdrawal address
Expand All @@ -47,6 +43,18 @@ func (s *Service) BatchCreateWithdrawals(ctx context.Context, withdrawalIDs []in
for i := range withdrawals {
withdrawal := withdrawals[i]
group.Go(func() error {
// Let's validate each withdrawal individually.
// By doing so, we can reject it without blocking other withdrawals.
if errValidate := validateWithdrawal(withdrawal); errValidate != nil {
if errUpdate := s.payments.Fail(ctx, withdrawal); errUpdate != nil {
result.registerErr(errors.Wrap(errUpdate, "unable to mark invalid withdrawal as failed"))
} else {
result.registerErr(errors.Wrap(errValidate, "withdrawal is invalid, marked as failed"))
}

return nil
}

currency, err := s.blockchain.GetCurrencyByTicker(withdrawal.Price.Ticker())
if err != nil {
result.registerErr(errors.Wrap(err, "unable to get withdrawal currency"))
Expand Down Expand Up @@ -540,27 +548,26 @@ func (s *Service) cancelWithdrawal(
return nil
}

func (s *Service) validateWithdrawals(withdrawals []*payment.Payment) error {
for _, pt := range withdrawals {
if pt.Type != payment.TypeWithdrawal {
return errors.Wrap(ErrInvalidInput, "payment is not withdrawal")
}
func validateWithdrawal(pt *payment.Payment) error {
if pt.Type != payment.TypeWithdrawal {
return errors.Wrap(ErrInvalidInput, "payment is not withdrawal")
}

if pt.Status != payment.StatusPending {
return errors.Wrap(ErrInvalidInput, "withdrawal is not pending")
}
if pt.Status != payment.StatusPending {
return errors.Wrap(ErrInvalidInput, "withdrawal is not pending")
}

if pt.MerchantID == 0 {
return errors.Wrap(ErrInvalidInput, "invalid merchant id")
}
if pt.MerchantID == 0 {
return errors.Wrap(ErrInvalidInput, "invalid merchant id")
}

if pt.WithdrawalBalanceID() < 1 {
return errors.Wrap(ErrInvalidInput, "invalid balance id")
}
if pt.WithdrawalBalanceID() < 1 {
return errors.Wrap(ErrInvalidInput, "invalid balance id")
}

if pt.WithdrawalAddressID() < 1 {
return errors.Wrap(ErrInvalidInput, "invalid address id")
}
// edge-case: a customer can delete the address while withdrawal is pending
if pt.WithdrawalAddressID() < 1 {
return errors.Wrap(ErrInvalidInput, "invalid address id")
}

return nil
Expand Down
Loading

0 comments on commit dcb11c2

Please sign in to comment.