2019-06-03 14:46:57 +01:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package localpayments
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/rand"
|
2019-07-10 21:29:26 +01:00
|
|
|
mathRand "math/rand"
|
2019-06-03 14:46:57 +01:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
2019-07-10 21:29:26 +01:00
|
|
|
"gopkg.in/spacemonkeygo/monkit.v2"
|
2019-06-03 14:46:57 +01:00
|
|
|
|
|
|
|
"storj.io/storj/satellite/payments"
|
|
|
|
)
|
|
|
|
|
2019-06-04 12:55:38 +01:00
|
|
|
var (
|
2019-06-06 17:07:14 +01:00
|
|
|
// creationDate is a Storj creation date.
|
|
|
|
creationDate = time.Date(2016, 1, 1, 0, 0, 0, 0, time.UTC)
|
2019-06-04 12:55:38 +01:00
|
|
|
|
|
|
|
mon = monkit.Package()
|
|
|
|
)
|
2019-06-03 14:46:57 +01:00
|
|
|
|
2019-06-06 17:07:14 +01:00
|
|
|
// StorjCustomer is a predefined customer
|
|
|
|
// which is linked with every user by default
|
|
|
|
var storjCustomer = payments.Customer{
|
|
|
|
ID: []byte("0"),
|
|
|
|
Name: "Storj",
|
2019-06-18 01:28:40 +01:00
|
|
|
Email: "storj@mail.test",
|
2019-06-06 17:07:14 +01:00
|
|
|
CreatedAt: creationDate,
|
|
|
|
}
|
|
|
|
|
2019-06-03 14:46:57 +01:00
|
|
|
// internalPaymentsErr is a wrapper for local payments service errors
|
|
|
|
var internalPaymentsErr = errs.Class("internal payments error")
|
|
|
|
|
|
|
|
// DB is internal payment methods storage
|
|
|
|
type DB interface {
|
|
|
|
// TODO: add method to retrieve invoice information from project invoice stamp
|
|
|
|
}
|
|
|
|
|
|
|
|
// service is internal payments.Service implementation
|
|
|
|
type service struct {
|
|
|
|
db DB
|
|
|
|
}
|
|
|
|
|
2019-07-10 21:29:26 +01:00
|
|
|
func (*service) AddPaymentMethod(ctx context.Context, params payments.AddPaymentMethodParams) (*payments.PaymentMethod, error) {
|
|
|
|
return paymentMethod("", []byte(params.CustomerID)), nil
|
|
|
|
}
|
|
|
|
|
2019-06-03 14:46:57 +01:00
|
|
|
// NewService create new instance of local payments service
|
|
|
|
func NewService(db DB) payments.Service {
|
|
|
|
return &service{db: db}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CreateCustomer creates new payments.Customer with random id to satisfy unique db constraint
|
2019-06-04 12:55:38 +01:00
|
|
|
func (*service) CreateCustomer(ctx context.Context, params payments.CreateCustomerParams) (_ *payments.Customer, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
2019-06-03 14:46:57 +01:00
|
|
|
var b [8]byte
|
|
|
|
|
2019-06-04 12:55:38 +01:00
|
|
|
_, err = rand.Read(b[:])
|
2019-06-03 14:46:57 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, internalPaymentsErr.New("error creating customer")
|
|
|
|
}
|
|
|
|
|
|
|
|
return &payments.Customer{
|
|
|
|
ID: b[:],
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCustomer always returns default storjCustomer
|
2019-06-04 12:55:38 +01:00
|
|
|
func (*service) GetCustomer(ctx context.Context, id []byte) (_ *payments.Customer, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
2019-06-03 14:46:57 +01:00
|
|
|
return &storjCustomer, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCustomerDefaultPaymentMethod always returns defaultPaymentMethod
|
2019-06-04 12:55:38 +01:00
|
|
|
func (*service) GetCustomerDefaultPaymentMethod(ctx context.Context, customerID []byte) (_ *payments.PaymentMethod, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
2019-07-10 21:29:26 +01:00
|
|
|
return paymentMethod("", customerID), nil
|
2019-06-03 14:46:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetCustomerPaymentsMethods always returns payments.Customer list with defaultPaymentMethod
|
2019-06-04 12:55:38 +01:00
|
|
|
func (*service) GetCustomerPaymentsMethods(ctx context.Context, customerID []byte) (_ []payments.PaymentMethod, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
2019-07-10 21:29:26 +01:00
|
|
|
return []payments.PaymentMethod{*paymentMethod("", customerID)}, nil
|
2019-06-03 14:46:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetPaymentMethod always returns defaultPaymentMethod or error
|
2019-06-04 12:55:38 +01:00
|
|
|
func (*service) GetPaymentMethod(ctx context.Context, id []byte) (_ *payments.PaymentMethod, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
2019-07-10 21:29:26 +01:00
|
|
|
return paymentMethod(string(id), []byte("")), nil
|
2019-06-03 14:46:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// CreateProjectInvoice creates invoice from provided params
|
2019-06-04 12:55:38 +01:00
|
|
|
func (*service) CreateProjectInvoice(ctx context.Context, params payments.CreateProjectInvoiceParams) (_ *payments.Invoice, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
2019-06-03 14:46:57 +01:00
|
|
|
// TODO: fill data
|
|
|
|
return &payments.Invoice{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetInvoice retrieves invoice information from project invoice stamp by invoice id
|
|
|
|
// and returns invoice
|
2019-06-04 12:55:38 +01:00
|
|
|
func (*service) GetInvoice(ctx context.Context, id []byte) (_ *payments.Invoice, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
2019-06-03 14:46:57 +01:00
|
|
|
// TODO: get project invoice stamp by invoice id from the db and fill data
|
|
|
|
return &payments.Invoice{}, nil
|
|
|
|
}
|
2019-07-10 21:29:26 +01:00
|
|
|
|
|
|
|
// paymentMethod returns paymentMethod object which mocks stripe response
|
|
|
|
func paymentMethod(methodID string, customerID []byte) *payments.PaymentMethod {
|
|
|
|
id := methodID
|
|
|
|
if methodID == "" {
|
|
|
|
id = "pm_" + randomString(24)
|
|
|
|
}
|
|
|
|
|
|
|
|
cusID := customerID
|
|
|
|
if len(customerID) <= 1 {
|
|
|
|
cusID = []byte("cus_" + randomString(14))
|
|
|
|
}
|
|
|
|
|
|
|
|
return &payments.PaymentMethod{
|
|
|
|
ID: []byte(id),
|
|
|
|
CustomerID: cusID,
|
|
|
|
Card: payments.Card{
|
|
|
|
Country: "us",
|
|
|
|
Brand: "visa",
|
|
|
|
Name: "Storj Labs",
|
|
|
|
ExpMonth: 12,
|
|
|
|
ExpYear: 2024,
|
|
|
|
LastFour: "3567",
|
|
|
|
},
|
|
|
|
CreatedAt: creationDate,
|
|
|
|
IsDefault: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func randomString(len int) string {
|
|
|
|
bytes := make([]byte, len)
|
|
|
|
for i := 0; i < len; i++ {
|
|
|
|
bytes[i] = byte(65 + mathRand.Intn(25))
|
|
|
|
}
|
|
|
|
return string(bytes)
|
|
|
|
}
|