satellite/payments: remove mockpayments and add Stripe client mock

instead

Change-Id: If3496f6abc16da90d2b43fa0c5be356847a39507
This commit is contained in:
Michal Niewrzal 2020-05-18 11:17:05 +02:00
parent 16abf02b35
commit ac375d37bc
8 changed files with 362 additions and 305 deletions

View File

@ -47,6 +47,10 @@ func (ce *consoleEndpoints) Register() string {
return ce.appendPath("/api/v0/auth/register")
}
func (ce *consoleEndpoints) SetupAccount() string {
return ce.appendPath("/api/v0/payments/account")
}
func (ce *consoleEndpoints) Activation(token string) string {
return ce.appendPath("/activation/?token=" + token)
}
@ -101,6 +105,11 @@ func (ce *consoleEndpoints) createOrGetAPIKey() (string, error) {
}
}
err = ce.setupAccount(authToken)
if err != nil {
return "", errs.Wrap(err)
}
projectID, err := ce.getOrCreateProject(authToken)
if err != nil {
return "", errs.Wrap(err)
@ -285,6 +294,34 @@ func (ce *consoleEndpoints) activateUser(userID string) error {
return nil
}
func (ce *consoleEndpoints) setupAccount(token string) error {
request, err := http.NewRequest(
http.MethodPost,
ce.SetupAccount(),
nil)
if err != nil {
return err
}
request.AddCookie(&http.Cookie{
Name: ce.cookieName,
Value: token,
})
resp, err := ce.client.Do(request)
if err != nil {
return err
}
defer func() { err = errs.Combine(err, resp.Body.Close()) }()
if resp.StatusCode != http.StatusOK {
return errs.New("unexpected status code: %d (%q)",
resp.StatusCode, tryReadLine(resp.Body))
}
return nil
}
func (ce *consoleEndpoints) getOrCreateProject(token string) (string, error) {
projectID, err := ce.getProject(token)
if err == nil {

View File

@ -53,6 +53,8 @@ import (
"storj.io/storj/satellite/nodestats"
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/overlay"
"storj.io/storj/satellite/payments/paymentsconfig"
"storj.io/storj/satellite/payments/stripecoinpayments"
"storj.io/storj/satellite/repair/checker"
"storj.io/storj/satellite/repair/irreparable"
"storj.io/storj/satellite/repair/repairer"
@ -396,6 +398,16 @@ func (planet *Planet) newSatellites(count int, satelliteDatabases satellitedbtes
IrreparableInterval: defaultInterval,
ReliabilityCacheStaleness: 1 * time.Minute,
},
Payments: paymentsconfig.Config{
StorageTBPrice: "10",
EgressTBPrice: "45",
ObjectPrice: "0.0000022",
StripeCoinPayments: stripecoinpayments.Config{
TransactionUpdateInterval: defaultInterval,
AccountBalanceUpdateInterval: defaultInterval,
ConversionRatesCycleInterval: defaultInterval,
},
},
Repairer: repairer.Config{
MaxRepair: 10,
Interval: defaultInterval,

View File

@ -47,7 +47,6 @@ import (
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/overlay"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/mockpayments"
"storj.io/storj/satellite/payments/stripecoinpayments"
"storj.io/storj/satellite/referrals"
"storj.io/storj/satellite/repair/irreparable"
@ -131,6 +130,7 @@ type API struct {
Payments struct {
Accounts payments.Accounts
Version *stripecoinpayments.VersionService
Service *stripecoinpayments.Service
}
Referrals struct {
@ -524,44 +524,45 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
{ // setup payments
pc := config.Payments
var stripeClient stripecoinpayments.StripeClient
switch pc.Provider {
default:
peer.Payments.Accounts = mockpayments.Accounts()
stripeClient = stripecoinpayments.NewStripeMock()
case "stripecoinpayments":
stripeClient := stripecoinpayments.NewStripeClient(log, pc.StripeCoinPayments)
service, err := stripecoinpayments.NewService(
peer.Log.Named("payments.stripe:service"),
stripeClient,
pc.StripeCoinPayments,
peer.DB.StripeCoinPayments(),
peer.DB.Console().Projects(),
peer.DB.ProjectAccounting(),
pc.StorageTBPrice,
pc.EgressTBPrice,
pc.ObjectPrice,
pc.BonusRate,
pc.CouponValue,
pc.CouponDuration,
pc.CouponProjectLimit,
pc.MinCoinPayment)
if err != nil {
return nil, errs.Combine(err, peer.Close())
}
peer.Payments.Accounts = service.Accounts()
peer.Payments.Version = stripecoinpayments.NewVersionService(
peer.Log.Named("payments.stripe:version"),
service,
pc.StripeCoinPayments.ConversionRatesCycleInterval)
peer.Services.Add(lifecycle.Item{
Name: "payments.stripe:version",
Run: peer.Payments.Version.Run,
Close: peer.Payments.Version.Close,
})
stripeClient = stripecoinpayments.NewStripeClient(log, pc.StripeCoinPayments)
}
peer.Payments.Service, err = stripecoinpayments.NewService(
peer.Log.Named("payments.stripe:service"),
stripeClient,
pc.StripeCoinPayments,
peer.DB.StripeCoinPayments(),
peer.DB.Console().Projects(),
peer.DB.ProjectAccounting(),
pc.StorageTBPrice,
pc.EgressTBPrice,
pc.ObjectPrice,
pc.BonusRate,
pc.CouponValue,
pc.CouponDuration,
pc.CouponProjectLimit,
pc.MinCoinPayment)
if err != nil {
return nil, errs.Combine(err, peer.Close())
}
peer.Payments.Accounts = peer.Payments.Service.Accounts()
peer.Payments.Version = stripecoinpayments.NewVersionService(
peer.Log.Named("payments.stripe:version"),
peer.Payments.Service,
pc.StripeCoinPayments.ConversionRatesCycleInterval)
peer.Services.Add(lifecycle.Item{
Name: "payments.stripe:version",
Run: peer.Payments.Version.Run,
Close: peer.Payments.Version.Close,
})
}
{ // setup console

View File

@ -24,7 +24,8 @@ import (
"storj.io/storj/satellite/console/consoleauth"
"storj.io/storj/satellite/console/consoleweb/consoleql"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/payments/mockpayments"
"storj.io/storj/satellite/payments/paymentsconfig"
"storj.io/storj/satellite/payments/stripecoinpayments"
"storj.io/storj/satellite/rewards"
"storj.io/storj/satellite/satellitedb/satellitedbtest"
"storj.io/storj/storage/redis/redisserver"
@ -66,6 +67,30 @@ func TestGrapqhlMutation(t *testing.T) {
projectUsage := accounting.NewService(db.ProjectAccounting(), cache, 0, 0)
// TODO maybe switch this test to testplanet to avoid defining config and Stripe service
pc := paymentsconfig.Config{
StorageTBPrice: "10",
EgressTBPrice: "45",
ObjectPrice: "0.0000022",
}
paymentsService, err := stripecoinpayments.NewService(
log.Named("payments.stripe:service"),
stripecoinpayments.NewStripeMock(),
pc.StripeCoinPayments,
db.StripeCoinPayments(),
db.Console().Projects(),
db.ProjectAccounting(),
pc.StorageTBPrice,
pc.EgressTBPrice,
pc.ObjectPrice,
pc.BonusRate,
pc.CouponValue,
pc.CouponDuration,
pc.CouponProjectLimit,
pc.MinCoinPayment)
require.NoError(t, err)
service, err := console.NewService(
log.Named("console"),
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
@ -74,7 +99,7 @@ func TestGrapqhlMutation(t *testing.T) {
projectUsage,
db.Rewards(),
partnersService,
mockpayments.Accounts(),
paymentsService.Accounts(),
console.Config{PasswordCost: console.TestPasswordCost},
5000,
)
@ -111,6 +136,9 @@ func TestGrapqhlMutation(t *testing.T) {
require.NoError(t, err)
require.Equal(t, createUser.PartnerID, rootUser.PartnerID.String())
err = paymentsService.Accounts().Setup(ctx, rootUser.ID, rootUser.Email)
require.NoError(t, err)
activationToken, err := service.GenerateActivationToken(ctx, rootUser.ID, rootUser.Email)
require.NoError(t, err)

View File

@ -22,7 +22,8 @@ import (
"storj.io/storj/satellite/console/consoleauth"
"storj.io/storj/satellite/console/consoleweb/consoleql"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/payments/mockpayments"
"storj.io/storj/satellite/payments/paymentsconfig"
"storj.io/storj/satellite/payments/stripecoinpayments"
"storj.io/storj/satellite/rewards"
"storj.io/storj/satellite/satellitedb/satellitedbtest"
"storj.io/storj/storage/redis/redisserver"
@ -51,6 +52,30 @@ func TestGraphqlQuery(t *testing.T) {
projectUsage := accounting.NewService(db.ProjectAccounting(), cache, 0, 0)
// TODO maybe switch this test to testplanet to avoid defining config and Stripe service
pc := paymentsconfig.Config{
StorageTBPrice: "10",
EgressTBPrice: "45",
ObjectPrice: "0.0000022",
}
paymentsService, err := stripecoinpayments.NewService(
log.Named("payments.stripe:service"),
stripecoinpayments.NewStripeMock(),
pc.StripeCoinPayments,
db.StripeCoinPayments(),
db.Console().Projects(),
db.ProjectAccounting(),
pc.StorageTBPrice,
pc.EgressTBPrice,
pc.ObjectPrice,
pc.BonusRate,
pc.CouponValue,
pc.CouponDuration,
pc.CouponProjectLimit,
pc.MinCoinPayment)
require.NoError(t, err)
service, err := console.NewService(
log.Named("console"),
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
@ -59,7 +84,7 @@ func TestGraphqlQuery(t *testing.T) {
projectUsage,
db.Rewards(),
partnersService,
mockpayments.Accounts(),
paymentsService.Accounts(),
console.Config{PasswordCost: console.TestPasswordCost},
5000,
)
@ -100,6 +125,9 @@ func TestGraphqlQuery(t *testing.T) {
rootUser, err := service.CreateUser(ctx, createUser, regToken.Secret, refUserID)
require.NoError(t, err)
err = paymentsService.Accounts().Setup(ctx, rootUser.ID, rootUser.Email)
require.NoError(t, err)
t.Run("Activation", func(t *testing.T) {
activationToken, err := service.GenerateActivationToken(
ctx,

View File

@ -40,7 +40,6 @@ import (
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/overlay"
"storj.io/storj/satellite/payments"
"storj.io/storj/satellite/payments/mockpayments"
"storj.io/storj/satellite/payments/stripecoinpayments"
"storj.io/storj/satellite/repair/checker"
)
@ -443,49 +442,50 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB,
{ // setup payments
pc := config.Payments
var stripeClient stripecoinpayments.StripeClient
switch pc.Provider {
default:
peer.Payments.Accounts = mockpayments.Accounts()
stripeClient = stripecoinpayments.NewStripeMock()
case "stripecoinpayments":
stripeClient := stripecoinpayments.NewStripeClient(log, pc.StripeCoinPayments)
service, err := stripecoinpayments.NewService(
peer.Log.Named("payments.stripe:service"),
stripeClient,
pc.StripeCoinPayments,
peer.DB.StripeCoinPayments(),
peer.DB.Console().Projects(),
peer.DB.ProjectAccounting(),
pc.StorageTBPrice,
pc.EgressTBPrice,
pc.ObjectPrice,
pc.BonusRate,
pc.CouponValue,
pc.CouponDuration,
pc.CouponProjectLimit,
pc.MinCoinPayment)
if err != nil {
return nil, errs.Combine(err, peer.Close())
}
peer.Payments.Accounts = service.Accounts()
peer.Payments.Chore = stripecoinpayments.NewChore(
peer.Log.Named("payments.stripe:clearing"),
service,
pc.StripeCoinPayments.TransactionUpdateInterval,
pc.StripeCoinPayments.AccountBalanceUpdateInterval,
)
peer.Services.Add(lifecycle.Item{
Name: "payments.stripe:service",
Run: peer.Payments.Chore.Run,
})
peer.Debug.Server.Panel.Add(
debug.Cycle("Payments Stripe Transactions", peer.Payments.Chore.TransactionCycle),
debug.Cycle("Payments Stripe Account Balance", peer.Payments.Chore.AccountBalanceCycle),
)
stripeClient = stripecoinpayments.NewStripeClient(log, pc.StripeCoinPayments)
}
service, err := stripecoinpayments.NewService(
peer.Log.Named("payments.stripe:service"),
stripeClient,
pc.StripeCoinPayments,
peer.DB.StripeCoinPayments(),
peer.DB.Console().Projects(),
peer.DB.ProjectAccounting(),
pc.StorageTBPrice,
pc.EgressTBPrice,
pc.ObjectPrice,
pc.BonusRate,
pc.CouponValue,
pc.CouponDuration,
pc.CouponProjectLimit,
pc.MinCoinPayment)
if err != nil {
return nil, errs.Combine(err, peer.Close())
}
peer.Payments.Accounts = service.Accounts()
peer.Payments.Chore = stripecoinpayments.NewChore(
peer.Log.Named("payments.stripe:clearing"),
service,
pc.StripeCoinPayments.TransactionUpdateInterval,
pc.StripeCoinPayments.AccountBalanceUpdateInterval,
)
peer.Services.Add(lifecycle.Item{
Name: "payments.stripe:service",
Run: peer.Payments.Chore.Run,
})
peer.Debug.Server.Panel.Add(
debug.Cycle("Payments Stripe Transactions", peer.Payments.Chore.TransactionCycle),
debug.Cycle("Payments Stripe Account Balance", peer.Payments.Chore.AccountBalanceCycle),
)
}
{ // setup graceful exit

View File

@ -1,226 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package mockpayments
import (
"context"
"time"
"github.com/spacemonkeygo/monkit/v3"
"github.com/zeebo/errs"
"storj.io/common/memory"
"storj.io/common/uuid"
"storj.io/storj/satellite/payments"
)
var (
// Error defines mock payment service error.
Error = errs.Class("mock payment service error")
mon = monkit.Package()
)
var _ payments.Accounts = (*accounts)(nil)
// accounts is a mock implementation of payments.Accounts.
//
// architecture: Service
type accounts struct{}
var _ payments.CreditCards = (*creditCards)(nil)
// creditCards is a mock implementation of payments.CreditCards.
//
// architecture: Service
type creditCards struct{}
var _ payments.Invoices = (*invoices)(nil)
// invoices is a mock implementation of payments.Invoices.
//
// architecture: Service
type invoices struct{}
var _ payments.StorjTokens = (*storjTokens)(nil)
// storjTokens is a mock implementation of payments.StorjTokens.
//
// architecture: Service
type storjTokens struct{}
// ensures that coupons implements payments.Coupons.
var _ payments.Coupons = (*coupons)(nil)
// coupons is an implementation of payments.Coupons.
//
// architecture: Service
type coupons struct{}
// ensures that credits implements payments.Credits.
var _ payments.Credits = (*credits)(nil)
// credits is an implementation of payments.Credits.
//
// architecture: Service
type credits struct{}
// Accounts exposes all needed functionality to manage payment accounts.
func Accounts() payments.Accounts {
return &accounts{}
}
// CreditCards exposes all needed functionality to manage account credit cards.
func (accounts *accounts) CreditCards() payments.CreditCards {
return &creditCards{}
}
// Invoices exposes all needed functionality to manage account invoices.
func (accounts *accounts) Invoices() payments.Invoices {
return &invoices{}
}
// StorjTokens exposes all storj token related functionality.
func (accounts *accounts) StorjTokens() payments.StorjTokens {
return &storjTokens{}
}
// Coupons exposes all needed functionality to manage coupons.
func (accounts *accounts) Coupons() payments.Coupons {
return &coupons{}
}
// Credits exposes all needed functionality to manage coupons.
func (accounts *accounts) Credits() payments.Credits {
return &credits{}
}
// Setup creates a payment account for the user.
// 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)
return nil
}
// Balance returns an object that represents current free credits and coins balance in cents.
func (accounts *accounts) Balance(ctx context.Context, userID uuid.UUID) (balance payments.Balance, err error) {
defer mon.Task()(&ctx, userID)(&err)
return payments.Balance{}, nil
}
// ProjectCharges returns how much money current user will be charged for each project.
func (accounts *accounts) ProjectCharges(ctx context.Context, userID uuid.UUID, since, before time.Time) (charges []payments.ProjectCharge, err error) {
defer mon.Task()(&ctx, userID, since, before)(&err)
return []payments.ProjectCharge{}, nil
}
// Charges returns empty charges list.
func (accounts accounts) Charges(ctx context.Context, userID uuid.UUID) (_ []payments.Charge, err error) {
defer mon.Task()(&ctx, userID)(&err)
return []payments.Charge{}, nil
}
// List returns a list of credit cards for a given payment account.
func (creditCards *creditCards) List(ctx context.Context, userID uuid.UUID) (_ []payments.CreditCard, err error) {
defer mon.Task()(&ctx, userID)(&err)
return []payments.CreditCard{{
ID: "pm_card_mastercard",
ExpMonth: 12,
ExpYear: 2050,
Brand: "Mastercard",
Last4: "4444",
IsDefault: true,
}}, nil
}
// Add is used to save new credit card, attach it to payment account and make it default.
func (creditCards *creditCards) Add(ctx context.Context, userID uuid.UUID, cardToken string) (err error) {
defer mon.Task()(&ctx, userID, cardToken)(&err)
return nil
}
// MakeDefault makes a credit card default payment method.
func (creditCards *creditCards) MakeDefault(ctx context.Context, userID uuid.UUID, cardID string) (err error) {
defer mon.Task()(&ctx, userID, cardID)(&err)
return nil
}
// Remove is used to remove credit card from payment account.
func (creditCards *creditCards) Remove(ctx context.Context, userID uuid.UUID, cardID string) (err error) {
defer mon.Task()(&ctx, cardID)(&err)
return nil
}
// List returns a list of invoices for a given payment account.
func (invoices *invoices) List(ctx context.Context, userID uuid.UUID) (_ []payments.Invoice, err error) {
defer mon.Task()(&ctx, userID)(&err)
return []payments.Invoice{}, nil
}
// Deposit creates new deposit transaction.
func (tokens *storjTokens) Deposit(ctx context.Context, userID uuid.UUID, amount int64) (_ *payments.Transaction, err error) {
defer mon.Task()(&ctx, userID, amount)(&err)
return nil, Error.Wrap(errs.New("can not make deposit"))
}
// ListTransactionInfos returns empty transaction infos slice.
func (tokens *storjTokens) ListTransactionInfos(ctx context.Context, userID uuid.UUID) (_ []payments.TransactionInfo, err error) {
defer mon.Task()(&ctx, userID)(&err)
return ([]payments.TransactionInfo)(nil), nil
}
// Create attaches a coupon for payment account.
func (coupons *coupons) Create(ctx context.Context, coupon payments.Coupon) (err error) {
defer mon.Task()(&ctx, coupon)(&err)
return nil
}
// ListByUserID return list of all coupons of specified payment account.
func (coupons *coupons) ListByUserID(ctx context.Context, userID uuid.UUID) (_ []payments.Coupon, err error) {
defer mon.Task()(&ctx, userID)(&err)
return ([]payments.Coupon)(nil), Error.Wrap(err)
}
// PopulatePromotionalCoupons is used to populate promotional coupons through all active users who already have
// a project, payment method and do not have a promotional coupon yet.
// And updates project limits to selected size.
func (coupons *coupons) PopulatePromotionalCoupons(ctx context.Context, duration int, amount int64, projectLimit memory.Size) (err error) {
defer mon.Task()(&ctx, duration, amount, projectLimit)(&err)
return nil
}
// AddPromotionalCoupon is used to add a promotional coupon for specified users who already have
// a project and do not have a promotional coupon yet.
// And updates project limits to selected size.
func (coupons *coupons) AddPromotionalCoupon(ctx context.Context, userID uuid.UUID) (err error) {
defer mon.Task()(&ctx, userID)(&err)
return nil
}
// Create attaches a credit for payment account.
func (credits *credits) Create(ctx context.Context, credit payments.Credit) (err error) {
defer mon.Task()(&ctx, credit)(&err)
return nil
}
// ListByUserID return list of all credits of specified payment account.
func (credits *credits) ListByUserID(ctx context.Context, userID uuid.UUID) (_ []payments.Credit, err error) {
defer mon.Task()(&ctx, userID)(&err)
return ([]payments.Credit)(nil), Error.Wrap(err)
}

View File

@ -0,0 +1,177 @@
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package stripecoinpayments
import (
"errors"
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/charge"
"github.com/stripe/stripe-go/form"
"github.com/stripe/stripe-go/invoice"
"github.com/stripe/stripe-go/paymentmethod"
"storj.io/common/uuid"
)
// MockStripeClient Stripe client mock.
type mockStripeClient struct {
customers *mockCustomers
paymentMethods *mockPaymentMethods
invoices *mockInvoices
invoiceItems *mockInvoiceItems
customerBalanceTransactions *mockCustomerBalanceTransactions
charges *mockCharges
}
// NewStripeMock creates new Stripe client mock.
func NewStripeMock() StripeClient {
return &mockStripeClient{
customers: newMockCustomers(),
paymentMethods: &mockPaymentMethods{},
invoices: &mockInvoices{},
invoiceItems: &mockInvoiceItems{},
customerBalanceTransactions: &mockCustomerBalanceTransactions{},
charges: &mockCharges{},
}
}
func (m *mockStripeClient) Customers() StripeCustomers {
return m.customers
}
func (m *mockStripeClient) PaymentMethods() StripePaymentMethods {
return m.paymentMethods
}
func (m *mockStripeClient) Invoices() StripeInvoices {
return m.invoices
}
func (m *mockStripeClient) InvoiceItems() StripeInvoiceItems {
return m.invoiceItems
}
func (m *mockStripeClient) CustomerBalanceTransactions() StripeCustomerBalanceTransactions {
return m.customerBalanceTransactions
}
func (m *mockStripeClient) Charges() StripeCharges {
return m.charges
}
type mockCustomers struct {
customers []*stripe.Customer
}
func newMockCustomers() *mockCustomers {
return &mockCustomers{
customers: make([]*stripe.Customer, 0, 5),
}
}
func (m *mockCustomers) New(params *stripe.CustomerParams) (*stripe.Customer, error) {
uuid, err := uuid.New()
if err != nil {
return nil, err
}
customer := &stripe.Customer{
ID: uuid.String(),
Email: *params.Email,
InvoiceSettings: &stripe.CustomerInvoiceSettings{
DefaultPaymentMethod: &stripe.PaymentMethod{
ID: "pm_card_mastercard",
},
},
}
m.customers = append(m.customers, customer)
return customer, nil
}
func (m *mockCustomers) Get(id string, params *stripe.CustomerParams) (*stripe.Customer, error) {
for _, customer := range m.customers {
if id == customer.ID {
return customer, nil
}
}
return nil, errors.New("customer not found")
}
func (m *mockCustomers) Update(id string, params *stripe.CustomerParams) (*stripe.Customer, error) {
customer, err := m.Get(id, nil)
if err != nil {
return nil, err
}
// TODO add customer updating according to params
return customer, nil
}
type mockPaymentMethods struct {
}
func (m *mockPaymentMethods) List(listParams *stripe.PaymentMethodListParams) *paymentmethod.Iter {
values := []interface{}{
&stripe.PaymentMethod{
ID: "pm_card_mastercard",
Card: &stripe.PaymentMethodCard{
ExpMonth: 12,
ExpYear: 2050,
Brand: "Mastercard",
Last4: "4444",
},
},
}
listMeta := stripe.ListMeta{
HasMore: false,
TotalCount: uint32(len(values)),
}
return &paymentmethod.Iter{Iter: stripe.GetIter(nil, func(*stripe.Params, *form.Values) ([]interface{}, stripe.ListMeta, error) {
return values, listMeta, nil
})}
}
func (m *mockPaymentMethods) New(params *stripe.PaymentMethodParams) (*stripe.PaymentMethod, error) {
return nil, nil
}
func (m *mockPaymentMethods) Attach(id string, params *stripe.PaymentMethodAttachParams) (*stripe.PaymentMethod, error) {
return nil, nil
}
func (m *mockPaymentMethods) Detach(id string, params *stripe.PaymentMethodDetachParams) (*stripe.PaymentMethod, error) {
return nil, nil
}
type mockInvoices struct {
}
func (m *mockInvoices) New(params *stripe.InvoiceParams) (*stripe.Invoice, error) {
return nil, nil
}
func (m *mockInvoices) List(listParams *stripe.InvoiceListParams) *invoice.Iter {
return nil
}
type mockInvoiceItems struct {
}
func (m *mockInvoiceItems) New(params *stripe.InvoiceItemParams) (*stripe.InvoiceItem, error) {
return nil, nil
}
type mockCustomerBalanceTransactions struct {
}
func (m *mockCustomerBalanceTransactions) New(params *stripe.CustomerBalanceTransactionParams) (*stripe.CustomerBalanceTransaction, error) {
return nil, nil
}
type mockCharges struct {
}
func (m *mockCharges) List(listParams *stripe.ChargeListParams) *charge.Iter {
return nil
}