satellite/{console,payments}: unfreeze user on token payment

This change unfreezes/unwarns users in either state after successful
payment with tokens.

Change-Id: I7494d6a33cf9383576f42af695df522d8f409e03
This commit is contained in:
Wilfred Asomani 2023-09-07 16:38:24 +00:00 committed by Storj Robot
parent c52554a2b9
commit cd7d9cf079
3 changed files with 67 additions and 9 deletions

View File

@ -14,15 +14,17 @@ var _ billing.Observer = (*InvoiceTokenPaymentObserver)(nil)
// InvoiceTokenPaymentObserver used to pay pending payments with STORJ tokens. // InvoiceTokenPaymentObserver used to pay pending payments with STORJ tokens.
type InvoiceTokenPaymentObserver struct { type InvoiceTokenPaymentObserver struct {
consoleDB DB consoleDB DB
payments payments.Accounts invoices payments.Invoices
freezeService *AccountFreezeService
} }
// NewInvoiceTokenPaymentObserver creates new observer instance. // NewInvoiceTokenPaymentObserver creates new observer instance.
func NewInvoiceTokenPaymentObserver(consoleDB DB, payments payments.Accounts) *InvoiceTokenPaymentObserver { func NewInvoiceTokenPaymentObserver(consoleDB DB, invoices payments.Invoices, freezeService *AccountFreezeService) *InvoiceTokenPaymentObserver {
return &InvoiceTokenPaymentObserver{ return &InvoiceTokenPaymentObserver{
consoleDB: consoleDB, consoleDB: consoleDB,
payments: payments, invoices: invoices,
freezeService: freezeService,
} }
} }
@ -39,10 +41,42 @@ func (o *InvoiceTokenPaymentObserver) Process(ctx context.Context, transaction b
return nil return nil
} }
err = o.payments.Invoices().AttemptPayOverdueInvoicesWithTokens(ctx, user.ID) err = o.invoices.AttemptPayOverdueInvoicesWithTokens(ctx, user.ID)
if err != nil { if err != nil {
return err return err
} }
freeze, warning, err := o.freezeService.GetAll(ctx, user.ID)
if err != nil {
return err
}
if freeze == nil && warning == nil {
return nil
}
invoices, err := o.invoices.List(ctx, user.ID)
if err != nil {
return err
}
for _, inv := range invoices {
if inv.Status != payments.InvoiceStatusPaid {
return nil
}
}
if freeze != nil {
err = o.freezeService.UnfreezeUser(ctx, user.ID)
if err != nil {
return err
}
} else if warning != nil {
err = o.freezeService.UnWarnUser(ctx, user.ID)
if err != nil {
return err
}
}
return nil return nil
} }

View File

@ -521,7 +521,15 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB,
choreObservers := billing.ChoreObservers{ choreObservers := billing.ChoreObservers{
UpgradeUser: console.NewUpgradeUserObserver(peer.DB.Console(), peer.DB.Billing(), config.Console.UsageLimits, config.Console.UserBalanceForUpgrade), UpgradeUser: console.NewUpgradeUserObserver(peer.DB.Console(), peer.DB.Billing(), config.Console.UsageLimits, config.Console.UserBalanceForUpgrade),
PayInvoices: console.NewInvoiceTokenPaymentObserver(peer.DB.Console(), peer.Payments.Accounts), PayInvoices: console.NewInvoiceTokenPaymentObserver(
peer.DB.Console(), peer.Payments.Accounts.Invoices(),
console.NewAccountFreezeService(
peer.DB.Console().AccountFreezeEvents(),
peer.DB.Console().Users(),
peer.DB.Console().Projects(),
peer.Analytics.Service,
),
),
} }
peer.Payments.BillingChore = billing.NewChore( peer.Payments.BillingChore = billing.NewChore(

View File

@ -250,6 +250,7 @@ func TestChore_PayInvoiceObserver(t *testing.T) {
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) { }, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
sat := planet.Satellites[0] sat := planet.Satellites[0]
db := sat.DB db := sat.DB
consoleDB := db.Console()
invoicesDB := sat.Core.Payments.Accounts.Invoices() invoicesDB := sat.Core.Payments.Accounts.Invoices()
stripeClient := sat.API.Payments.StripeClient stripeClient := sat.API.Payments.StripeClient
customerDB := sat.Core.DB.StripeCoinPayments().Customers() customerDB := sat.Core.DB.StripeCoinPayments().Customers()
@ -271,9 +272,11 @@ func TestChore_PayInvoiceObserver(t *testing.T) {
err = sat.DB.Wallets().Add(ctx, userID, address) err = sat.DB.Wallets().Add(ctx, userID, address)
require.NoError(t, err) require.NoError(t, err)
freezeService := console.NewAccountFreezeService(consoleDB.AccountFreezeEvents(), consoleDB.Users(), consoleDB.Projects(), sat.Core.Analytics.Service)
choreObservers := billing.ChoreObservers{ choreObservers := billing.ChoreObservers{
UpgradeUser: console.NewUpgradeUserObserver(db.Console(), db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade), UpgradeUser: console.NewUpgradeUserObserver(consoleDB, db.Billing(), sat.Config.Console.UsageLimits, sat.Config.Console.UserBalanceForUpgrade),
PayInvoices: console.NewInvoiceTokenPaymentObserver(db.Console(), sat.Core.Payments.Accounts), PayInvoices: console.NewInvoiceTokenPaymentObserver(consoleDB, sat.Core.Payments.Accounts.Invoices(), freezeService),
} }
amount := int64(2000) // $20 amount := int64(2000) // $20
@ -328,6 +331,9 @@ func TestChore_PayInvoiceObserver(t *testing.T) {
require.Equal(t, inv.ID, invoices[0].ID) require.Equal(t, inv.ID, invoices[0].ID)
require.Equal(t, string(inv.Status), invoices[0].Status) require.Equal(t, string(inv.Status), invoices[0].Status)
err = freezeService.FreezeUser(ctx, userID)
require.NoError(t, err)
chore.TransactionCycle.TriggerWait() chore.TransactionCycle.TriggerWait()
// user balance would've been the value of amount ($20) but // user balance would've been the value of amount ($20) but
@ -342,6 +348,11 @@ func TestChore_PayInvoiceObserver(t *testing.T) {
// invoice remains unpaid since only $20 was paid. // invoice remains unpaid since only $20 was paid.
require.Equal(t, string(stripe.InvoiceStatusOpen), invoices[0].Status) require.Equal(t, string(stripe.InvoiceStatusOpen), invoices[0].Status)
// user remains frozen since payment is not complete.
frozen, err := freezeService.IsUserFrozen(ctx, userID)
require.NoError(t, err)
require.True(t, frozen)
chore.TransactionCycle.TriggerWait() chore.TransactionCycle.TriggerWait()
// the second transaction of $10 reflects at this point and // the second transaction of $10 reflects at this point and
@ -350,6 +361,11 @@ func TestChore_PayInvoiceObserver(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotEmpty(t, invoices) require.NotEmpty(t, invoices)
require.Equal(t, string(stripe.InvoiceStatusPaid), invoices[0].Status) require.Equal(t, string(stripe.InvoiceStatusPaid), invoices[0].Status)
// user is not frozen since payment is complete.
frozen, err = freezeService.IsUserFrozen(ctx, userID)
require.NoError(t, err)
require.False(t, frozen)
}) })
} }