From 26cc625dc628dc93db527f2498162d6e6f9c3723 Mon Sep 17 00:00:00 2001 From: Yehor Butko Date: Thu, 17 Oct 2019 17:42:18 +0300 Subject: [PATCH] satellite/console: payments api (#3297) --- cmd/storj-sim/network.go | 2 +- satellite/api.go | 5 + .../console/consoleweb/consoleapi/payments.go | 143 ++++++++++++++++++ .../consoleweb/consoleql/mutation_test.go | 5 + .../consoleweb/consoleql/query_test.go | 5 + satellite/console/consoleweb/server.go | 34 +++-- satellite/console/service.go | 65 +++++++- satellite/payments/account.go | 11 +- satellite/payments/creditcards.go | 9 +- .../payments/stripecoinpayments/accounts.go | 19 ++- .../stripecoinpayments/creditcards.go | 15 +- .../payments/stripecoinpayments/service.go | 5 +- .../payments/stripecoinpayments/tokens.go | 11 +- satellite/payments/tokens.go | 2 +- satellite/peer.go | 3 + web/satellite/.env | 2 +- 16 files changed, 281 insertions(+), 55 deletions(-) create mode 100644 satellite/console/consoleweb/consoleapi/payments.go diff --git a/cmd/storj-sim/network.go b/cmd/storj-sim/network.go index f8b397638..652b31c9a 100644 --- a/cmd/storj-sim/network.go +++ b/cmd/storj-sim/network.go @@ -370,7 +370,7 @@ func newNetwork(flags *Flags) (*Processes, error) { host := "http://" + consoleAddress createRegistrationTokenAddress := host + "/registrationToken/?projectsLimit=1" consoleActivationAddress := host + "/activation/?token=" - consoleAPIAddress := host + "/api/graphql/v0" + consoleAPIAddress := host + "/api/v0/graphql" // wait for console server to start time.Sleep(3 * time.Second) diff --git a/satellite/api.go b/satellite/api.go index 4e37269ef..dbd7e3be1 100644 --- a/satellite/api.go +++ b/satellite/api.go @@ -40,6 +40,7 @@ import ( "storj.io/storj/satellite/nodestats" "storj.io/storj/satellite/orders" "storj.io/storj/satellite/overlay" + "storj.io/storj/satellite/payments/stripecoinpayments" "storj.io/storj/satellite/repair/irreparable" "storj.io/storj/satellite/vouchers" ) @@ -363,11 +364,15 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB, pointerDB metai if consoleConfig.AuthTokenSecret == "" { return nil, errs.New("Auth token secret required") } + + payments := stripecoinpayments.NewService(stripecoinpayments.Config{}, peer.DB.Customers(), peer.DB.CoinpaymentsTransactions()) + peer.Console.Service, err = console.NewService( peer.Log.Named("console:service"), &consoleauth.Hmac{Secret: []byte(consoleConfig.AuthTokenSecret)}, peer.DB.Console(), peer.DB.Rewards(), + payments.Accounts(), consoleConfig.PasswordCost, ) if err != nil { diff --git a/satellite/console/consoleweb/consoleapi/payments.go b/satellite/console/consoleweb/consoleapi/payments.go new file mode 100644 index 000000000..8cec05f12 --- /dev/null +++ b/satellite/console/consoleweb/consoleapi/payments.go @@ -0,0 +1,143 @@ +// Copyright (C) 2019 Storj Labs, Inc. +// See LICENSE for copying information. + +package consoleapi + +import ( + "context" + "encoding/json" + "net/http" + "strings" + + "go.uber.org/zap" + monkit "gopkg.in/spacemonkeygo/monkit.v2" + + "storj.io/storj/pkg/auth" + "storj.io/storj/satellite/console" +) + +var mon = monkit.Package() + +// Payments is an api controller that exposes all payment related functionality +type Payments struct { + log *zap.Logger + service *console.Service +} + +// NewPayments is a constructor for api payments controller. +func NewPayments(log *zap.Logger, service *console.Service) *Payments { + return &Payments{ + log: log, + service: service, + } +} + +// SetupAccount creates a payment account for the user. +func (p *Payments) SetupAccount(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + var err error + defer mon.Task()(&ctx)(&err) + + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusNotFound) + return + } + + ctx = p.authorize(ctx, r) + + err = p.service.Payments().SetupAccount(ctx) + if err != nil { + p.serveJSONError(w, http.StatusInternalServerError, err) + } +} + +// AccountBalance returns an integer amount in cents that represents the current balance of payment account. +func (p *Payments) AccountBalance(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + var err error + defer mon.Task()(&ctx)(&err) + + if r.Method != http.MethodGet { + w.WriteHeader(http.StatusNotFound) + return + } + + ctx = p.authorize(ctx, r) + + balance, err := p.service.Payments().AccountBalance(ctx) + if err != nil { + p.serveJSONError(w, http.StatusInternalServerError, err) + return + } + + var balanceResponse struct { + Balance int64 `json:"balance"` + } + + balanceResponse.Balance = balance + + err = json.NewEncoder(w).Encode(balanceResponse) + if err != nil { + p.log.Error("failed to write json balance response", zap.Error(err)) + } +} + +// AddCreditCard is used to save new credit card and attach it to payment account. +func (p *Payments) AddCreditCard(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + var err error + defer mon.Task()(&ctx)(&err) + + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusNotFound) + return + } + + ctx = p.authorize(ctx, r) + + var requestBody struct { + Token string `json:"token"` + } + + decoder := json.NewDecoder(r.Body) + + err = decoder.Decode(&requestBody) + if err != nil { + p.serveJSONError(w, http.StatusBadRequest, err) + return + } + + err = p.service.Payments().AddCreditCard(ctx, requestBody.Token) + if err != nil { + p.serveJSONError(w, http.StatusInternalServerError, err) + } +} + +// serveJSONError writes JSON error to response output stream. +func (p *Payments) serveJSONError(w http.ResponseWriter, status int, err error) { + w.WriteHeader(status) + + var response struct { + Error string `json:"error"` + } + + response.Error = err.Error() + + err = json.NewEncoder(w).Encode(response) + if err != nil { + p.log.Error("failed to write json error response", zap.Error(err)) + } +} + +// authorize checks request for authorization token, validates it and updates context with auth data. +func (p *Payments) authorize(ctx context.Context, r *http.Request) context.Context { + authHeaderValue := r.Header.Get("Authorization") + token := strings.TrimPrefix(authHeaderValue, "Bearer ") + + auth, err := p.service.Authorize(auth.WithAPIKey(ctx, []byte(token))) + if err != nil { + return console.WithAuthFailure(ctx, err) + } + + return console.WithAuth(ctx, auth) +} diff --git a/satellite/console/consoleweb/consoleql/mutation_test.go b/satellite/console/consoleweb/consoleql/mutation_test.go index 61efcf56e..b6be03061 100644 --- a/satellite/console/consoleweb/consoleql/mutation_test.go +++ b/satellite/console/consoleweb/consoleql/mutation_test.go @@ -25,6 +25,7 @@ import ( "storj.io/storj/satellite/console/consoleauth" "storj.io/storj/satellite/console/consoleweb/consoleql" "storj.io/storj/satellite/mailservice" + "storj.io/storj/satellite/payments/stripecoinpayments" "storj.io/storj/satellite/rewards" "storj.io/storj/satellite/satellitedb/satellitedbtest" ) @@ -49,11 +50,15 @@ func TestGrapqhlMutation(t *testing.T) { log := zaptest.NewLogger(t) + paymentsConfig := stripecoinpayments.Config{} + payments := stripecoinpayments.NewService(paymentsConfig, db.Customers(), db.CoinpaymentsTransactions()) + service, err := console.NewService( log, &consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")}, db.Console(), db.Rewards(), + payments.Accounts(), console.TestPasswordCost, ) require.NoError(t, err) diff --git a/satellite/console/consoleweb/consoleql/query_test.go b/satellite/console/consoleweb/consoleql/query_test.go index e4a501147..3c86ac062 100644 --- a/satellite/console/consoleweb/consoleql/query_test.go +++ b/satellite/console/consoleweb/consoleql/query_test.go @@ -20,6 +20,7 @@ import ( "storj.io/storj/satellite/console/consoleauth" "storj.io/storj/satellite/console/consoleweb/consoleql" "storj.io/storj/satellite/mailservice" + "storj.io/storj/satellite/payments/stripecoinpayments" "storj.io/storj/satellite/satellitedb/satellitedbtest" ) @@ -30,11 +31,15 @@ func TestGraphqlQuery(t *testing.T) { log := zaptest.NewLogger(t) + paymentsConfig := stripecoinpayments.Config{} + payments := stripecoinpayments.NewService(paymentsConfig, db.Customers(), db.CoinpaymentsTransactions()) + service, err := console.NewService( log, &consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")}, db.Console(), db.Rewards(), + payments.Accounts(), console.TestPasswordCost, ) require.NoError(t, err) diff --git a/satellite/console/consoleweb/server.go b/satellite/console/consoleweb/server.go index 4b0c4c57d..d3c9c2fab 100644 --- a/satellite/console/consoleweb/server.go +++ b/satellite/console/consoleweb/server.go @@ -22,10 +22,11 @@ import ( "github.com/zeebo/errs" "go.uber.org/zap" "golang.org/x/sync/errgroup" - monkit "gopkg.in/spacemonkeygo/monkit.v2" + "gopkg.in/spacemonkeygo/monkit.v2" "storj.io/storj/pkg/auth" "storj.io/storj/satellite/console" + "storj.io/storj/satellite/console/consoleweb/consoleapi" "storj.io/storj/satellite/console/consoleweb/consoleql" "storj.io/storj/satellite/mailservice" ) @@ -92,7 +93,7 @@ type Server struct { } } -// NewServer creates new instance of console server +// NewServer creates new instance of console server. func NewServer(logger *zap.Logger, config Config, service *console.Service, mailService *mailservice.Service, listener net.Listener) *Server { server := Server{ log: logger, @@ -112,25 +113,30 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, mail server.config.ExternalAddress = "http://" + server.listener.Addr().String() + "/" } - mux := http.NewServeMux() + router := http.NewServeMux() fs := http.FileServer(http.Dir(server.config.StaticDir)) - mux.Handle("/api/graphql/v0", http.HandlerFunc(server.grapqlHandler)) - mux.Handle("/api/v0/token", http.HandlerFunc(server.tokenHandler)) + paymentController := consoleapi.NewPayments(logger, service) + router.Handle("/api/v0/payments/cards", http.HandlerFunc(paymentController.AddCreditCard)) + router.Handle("/api/v0/payments/account/balance", http.HandlerFunc(paymentController.AccountBalance)) + router.Handle("/api/v0/payments/account", http.HandlerFunc(paymentController.SetupAccount)) + + router.Handle("/api/v0/graphql", http.HandlerFunc(server.grapqlHandler)) + router.Handle("/api/v0/token", http.HandlerFunc(server.tokenHandler)) + router.Handle("/registrationToken/", http.HandlerFunc(server.createRegistrationTokenHandler)) + router.Handle("/robots.txt", http.HandlerFunc(server.seoHandler)) if server.config.StaticDir != "" { - mux.Handle("/activation/", http.HandlerFunc(server.accountActivationHandler)) - mux.Handle("/password-recovery/", http.HandlerFunc(server.passwordRecoveryHandler)) - mux.Handle("/cancel-password-recovery/", http.HandlerFunc(server.cancelPasswordRecoveryHandler)) - mux.Handle("/registrationToken/", http.HandlerFunc(server.createRegistrationTokenHandler)) - mux.Handle("/usage-report/", http.HandlerFunc(server.bucketUsageReportHandler)) - mux.Handle("/static/", server.gzipHandler(http.StripPrefix("/static", fs))) - mux.Handle("/robots.txt", http.HandlerFunc(server.seoHandler)) - mux.Handle("/", http.HandlerFunc(server.appHandler)) + router.Handle("/activation/", http.HandlerFunc(server.accountActivationHandler)) + router.Handle("/password-recovery/", http.HandlerFunc(server.passwordRecoveryHandler)) + router.Handle("/cancel-password-recovery/", http.HandlerFunc(server.cancelPasswordRecoveryHandler)) + router.Handle("/usage-report/", http.HandlerFunc(server.bucketUsageReportHandler)) + router.Handle("/static/", server.gzipHandler(http.StripPrefix("/static", fs))) + router.Handle("/", http.HandlerFunc(server.appHandler)) } server.server = http.Server{ - Handler: mux, + Handler: router, MaxHeaderBytes: ContentLengthLimit.Int(), } diff --git a/satellite/console/service.go b/satellite/console/service.go index 00d4063f5..4b915c7dd 100644 --- a/satellite/console/service.go +++ b/satellite/console/service.go @@ -12,11 +12,12 @@ import ( "github.com/zeebo/errs" "go.uber.org/zap" "golang.org/x/crypto/bcrypt" - "gopkg.in/spacemonkeygo/monkit.v2" + monkit "gopkg.in/spacemonkeygo/monkit.v2" "storj.io/storj/pkg/auth" "storj.io/storj/pkg/macaroon" "storj.io/storj/satellite/console/consoleauth" + "storj.io/storj/satellite/payments" "storj.io/storj/satellite/rewards" ) @@ -56,21 +57,30 @@ const ( // ErrConsoleInternal describes internal console error var ErrConsoleInternal = errs.Class("internal error") +// ErrNoMembership is error type of not belonging to a specific project +var ErrNoMembership = errs.Class("no membership error") + // Service is handling accounts related logic // // architecture: Service type Service struct { Signer - log *zap.Logger - store DB - rewards rewards.DB + log *zap.Logger + store DB + rewards rewards.DB + accounts payments.Accounts passwordCost int } +// PaymentsService separates all payment related functionality +type PaymentsService struct { + service *Service +} + // NewService returns new instance of Service -func NewService(log *zap.Logger, signer Signer, store DB, rewards rewards.DB, passwordCost int) (*Service, error) { +func NewService(log *zap.Logger, signer Signer, store DB, rewards rewards.DB, accounts payments.Accounts, passwordCost int) (*Service, error) { if signer == nil { return nil, errs.New("signer can't be nil") } @@ -89,10 +99,52 @@ func NewService(log *zap.Logger, signer Signer, store DB, rewards rewards.DB, pa Signer: signer, store: store, rewards: rewards, + accounts: accounts, passwordCost: passwordCost, }, nil } +// Payments separates all payment related functionality +func (s *Service) Payments() PaymentsService { + return PaymentsService{service: s} +} + +// SetupAccount creates payment account for authorized user. +func (payments PaymentsService) SetupAccount(ctx context.Context) (err error) { + defer mon.Task()(&ctx)(&err) + + auth, err := GetAuth(ctx) + if err != nil { + return err + } + + return payments.service.accounts.Setup(ctx, auth.User.ID, auth.User.Email) +} + +// AccountBalance return account balance. +func (payments PaymentsService) AccountBalance(ctx context.Context) (balance int64, err error) { + defer mon.Task()(&ctx)(&err) + + auth, err := GetAuth(ctx) + if err != nil { + return 0, err + } + + return payments.service.accounts.Balance(ctx, auth.User.ID) +} + +// AddCreditCard adds a card as a new payment method. +func (payments PaymentsService) AddCreditCard(ctx context.Context, creditCardToken string) (err error) { + defer mon.Task()(&ctx)(&err) + + auth, err := GetAuth(ctx) + if err != nil { + return err + } + + return payments.service.accounts.CreditCards().Add(ctx, auth.User.ID, creditCardToken) +} + // CreateUser gets password hash value and creates new inactive User func (s *Service) CreateUser(ctx context.Context, user CreateUser, tokenSecret RegistrationSecret, refUserID string) (u *User, err error) { defer mon.Task()(&ctx)(&err) @@ -1081,9 +1133,6 @@ type isProjectMember struct { membership *ProjectMember } -// ErrNoMembership is error type of not belonging to a specific project -var ErrNoMembership = errs.Class("no membership error") - // isProjectOwner checks if the user is an owner of a project func (s *Service) isProjectOwner(ctx context.Context, userID uuid.UUID, projectID uuid.UUID) (err error) { defer mon.Task()(&ctx)(&err) diff --git a/satellite/payments/account.go b/satellite/payments/account.go index 581047746..842492ddd 100644 --- a/satellite/payments/account.go +++ b/satellite/payments/account.go @@ -5,15 +5,22 @@ package payments import ( "context" + + "github.com/skyrings/skyring-common/tools/uuid" + "github.com/zeebo/errs" ) +// ErrAccountNotSetup is an error type which indicates that payment account is not created. +var ErrAccountNotSetup = errs.Class("payment account is not set up") + // Accounts exposes all needed functionality to manage payment accounts. type Accounts interface { // Setup creates a payment account for the user. - Setup(ctx context.Context, email string) error + // If account is already set up it will return nil. + Setup(ctx context.Context, userID uuid.UUID, email string) error // Balance returns an integer amount in cents that represents the current balance of payment account. - Balance(ctx context.Context) (int64, error) + Balance(ctx context.Context, userID uuid.UUID) (int64, error) // CreditCards exposes all needed functionality to manage account credit cards. CreditCards() CreditCards diff --git a/satellite/payments/creditcards.go b/satellite/payments/creditcards.go index a7a77a7c0..188868c15 100644 --- a/satellite/payments/creditcards.go +++ b/satellite/payments/creditcards.go @@ -5,21 +5,22 @@ package payments import ( "context" + + "github.com/skyrings/skyring-common/tools/uuid" ) // CreditCards exposes all needed functionality to manage account credit cards. type CreditCards interface { // List returns a list of PaymentMethods for a given account. - List(ctx context.Context) ([]CreditCard, error) + List(ctx context.Context, userID uuid.UUID) ([]CreditCard, error) // Add is used to save new credit card and attach it to payment account. - Add(ctx context.Context, cardToken string) error + Add(ctx context.Context, userID uuid.UUID, cardToken string) error } // CreditCard holds all public information about credit card. type CreditCard struct { - ID []byte - + ID []byte `json:"id"` ExpMonth int `json:"exp_month"` ExpYear int `json:"exp_year"` Brand string `json:"brand"` diff --git a/satellite/payments/stripecoinpayments/accounts.go b/satellite/payments/stripecoinpayments/accounts.go index b1e76678f..ba7b995eb 100644 --- a/satellite/payments/stripecoinpayments/accounts.go +++ b/satellite/payments/stripecoinpayments/accounts.go @@ -15,7 +15,6 @@ import ( // accounts is an implementation of payments.Accounts. type accounts struct { service *Service - userID uuid.UUID } // CreditCards exposes all needed functionality to manage account credit cards. @@ -24,8 +23,14 @@ func (accounts *accounts) CreditCards() payments.CreditCards { } // Setup creates a payment account for the user. -func (accounts *accounts) Setup(ctx context.Context, email string) (err error) { - defer mon.Task()(&ctx, accounts.userID, email)(&err) +// If account is already set up it will return nil. +func (accounts *accounts) Setup(ctx context.Context, userID uuid.UUID, email string) (err error) { + defer mon.Task()(&ctx, userID, email)(&err) + + _, err = accounts.service.customers.GetCustomerID(ctx, userID) + if err == nil { + return nil + } params := &stripe.CustomerParams{ Email: stripe.String(email), @@ -36,14 +41,14 @@ func (accounts *accounts) Setup(ctx context.Context, email string) (err error) { } // TODO: delete customer from stripe, if db insertion fails - return Error.Wrap(accounts.service.customers.Insert(ctx, accounts.userID, email)) + return Error.Wrap(accounts.service.customers.Insert(ctx, userID, email)) } // Balance returns an integer amount in cents that represents the current balance of payment account. -func (accounts *accounts) Balance(ctx context.Context) (_ int64, err error) { - defer mon.Task()(&ctx, accounts.userID)(&err) +func (accounts *accounts) Balance(ctx context.Context, userID uuid.UUID) (_ int64, err error) { + defer mon.Task()(&ctx, userID)(&err) - customerID, err := accounts.service.customers.GetCustomerID(ctx, accounts.userID) + customerID, err := accounts.service.customers.GetCustomerID(ctx, userID) if err != nil { return 0, Error.Wrap(err) } diff --git a/satellite/payments/stripecoinpayments/creditcards.go b/satellite/payments/stripecoinpayments/creditcards.go index f0b68d829..61d3d2fab 100644 --- a/satellite/payments/stripecoinpayments/creditcards.go +++ b/satellite/payments/stripecoinpayments/creditcards.go @@ -15,14 +15,13 @@ import ( // creditCards is an implementation of payments.CreditCards. type creditCards struct { service *Service - userID uuid.UUID } // List returns a list of PaymentMethods for a given Customer. -func (creditCards *creditCards) List(ctx context.Context) (cards []payments.CreditCard, err error) { - defer mon.Task()(&ctx, creditCards.userID)(&err) +func (creditCards *creditCards) List(ctx context.Context, userID uuid.UUID) (cards []payments.CreditCard, err error) { + defer mon.Task()(&ctx, userID)(&err) - customerID, err := creditCards.service.customers.GetCustomerID(ctx, creditCards.userID) + customerID, err := creditCards.service.customers.GetCustomerID(ctx, userID) if err != nil { return nil, Error.Wrap(err) } @@ -53,12 +52,12 @@ func (creditCards *creditCards) List(ctx context.Context) (cards []payments.Cred } // Add is used to save new credit card and attach it to payment account. -func (creditCards *creditCards) Add(ctx context.Context, cardToken string) (err error) { - defer mon.Task()(&ctx, creditCards.userID, cardToken)(&err) +func (creditCards *creditCards) Add(ctx context.Context, userID uuid.UUID, cardToken string) (err error) { + defer mon.Task()(&ctx, userID, cardToken)(&err) - customerID, err := creditCards.service.customers.GetCustomerID(ctx, creditCards.userID) + customerID, err := creditCards.service.customers.GetCustomerID(ctx, userID) if err != nil { - return err + return payments.ErrAccountNotSetup.Wrap(err) } cardParams := &stripe.PaymentMethodParams{ diff --git a/satellite/payments/stripecoinpayments/service.go b/satellite/payments/stripecoinpayments/service.go index 372c86643..5b2db981c 100644 --- a/satellite/payments/stripecoinpayments/service.go +++ b/satellite/payments/stripecoinpayments/service.go @@ -4,10 +4,9 @@ package stripecoinpayments import ( - "github.com/skyrings/skyring-common/tools/uuid" "github.com/stripe/stripe-go/client" "github.com/zeebo/errs" - "gopkg.in/spacemonkeygo/monkit.v2" + monkit "gopkg.in/spacemonkeygo/monkit.v2" "storj.io/storj/satellite/payments" "storj.io/storj/satellite/payments/coinpayments" @@ -53,6 +52,6 @@ func NewService(config Config, customers CustomersDB, transactionsDB Transaction } // Accounts exposes all needed functionality to manage payment accounts. -func (service *Service) Accounts(userID uuid.UUID) payments.Accounts { +func (service *Service) Accounts() payments.Accounts { return &accounts{service: service} } diff --git a/satellite/payments/stripecoinpayments/tokens.go b/satellite/payments/stripecoinpayments/tokens.go index e4a7acf2f..b4561a870 100644 --- a/satellite/payments/stripecoinpayments/tokens.go +++ b/satellite/payments/stripecoinpayments/tokens.go @@ -18,7 +18,6 @@ var _ payments.StorjTokens = (*storjTokens)(nil) // storjTokens implements payments.StorjTokens. type storjTokens struct { - userID uuid.UUID service *Service } @@ -26,10 +25,10 @@ type storjTokens struct { // ETH wallet address where funds should be sent. There is one // hour limit to complete the transaction. Transaction is saved to DB with // reference to the user who made the deposit. -func (tokens *storjTokens) Deposit(ctx context.Context, amount big.Float) (_ *payments.Transaction, err error) { - defer mon.Task()(&ctx, amount)(&err) +func (tokens *storjTokens) Deposit(ctx context.Context, userID uuid.UUID, amount big.Float) (_ *payments.Transaction, err error) { + defer mon.Task()(&ctx, userID, amount)(&err) - customerID, err := tokens.service.customers.GetCustomerID(ctx, tokens.userID) + customerID, err := tokens.service.customers.GetCustomerID(ctx, userID) if err != nil { return nil, Error.Wrap(err) } @@ -59,7 +58,7 @@ func (tokens *storjTokens) Deposit(ctx context.Context, amount big.Float) (_ *pa cpTX, err := tokens.service.transactionsDB.Insert(ctx, Transaction{ ID: tx.ID, - AccountID: tokens.userID, + AccountID: userID, Address: tx.Address, Amount: tx.Amount, Received: big.Float{}, @@ -73,7 +72,7 @@ func (tokens *storjTokens) Deposit(ctx context.Context, amount big.Float) (_ *pa return &payments.Transaction{ ID: payments.TransactionID(tx.ID), - AccountID: tokens.userID, + AccountID: userID, Amount: tx.Amount, Received: big.Float{}, Address: tx.Address, diff --git a/satellite/payments/tokens.go b/satellite/payments/tokens.go index f354b1b80..0a149e6a8 100644 --- a/satellite/payments/tokens.go +++ b/satellite/payments/tokens.go @@ -14,7 +14,7 @@ import ( // StorjTokens defines all payments STORJ token related functionality. type StorjTokens interface { // Deposit creates deposit transaction for specified amount. - Deposit(ctx context.Context, amount big.Float) (*Transaction, error) + Deposit(ctx context.Context, userID uuid.UUID, amount big.Float) (*Transaction, error) } // TransactionStatus defines allowed statuses diff --git a/satellite/peer.go b/satellite/peer.go index 6963aed69..056942064 100644 --- a/satellite/peer.go +++ b/satellite/peer.go @@ -594,11 +594,14 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, pointerDB metainfo return nil, errs.New("Auth token secret required") } + payments := stripecoinpayments.NewService(stripecoinpayments.Config{}, peer.DB.Customers(), peer.DB.CoinpaymentsTransactions()) + peer.Console.Service, err = console.NewService( peer.Log.Named("console:service"), &consoleauth.Hmac{Secret: []byte(consoleConfig.AuthTokenSecret)}, peer.DB.Console(), peer.DB.Rewards(), + payments.Accounts(), consoleConfig.PasswordCost, ) diff --git a/web/satellite/.env b/web/satellite/.env index d947dae05..a98b0d7ae 100644 --- a/web/satellite/.env +++ b/web/satellite/.env @@ -1,2 +1,2 @@ VUE_APP_STRIPE_PUBLIC_KEY=pk_test -VUE_APP_ENDPOINT_URL=/api/graphql/v0 +VUE_APP_ENDPOINT_URL=/api/v0/graphql