Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dd9c0bd

Browse files
satellite/payments: always fallback to default pricing
This change makes it so that if pricing is not able to be fetched for any reason for a partner and placement, it'll fallback to the global pricing. Change-Id: I10bdc9d391987f514be90217b61a6d7683b7bf86
1 parent 65ebc5b commit dd9c0bd

File tree

7 files changed

+34
-63
lines changed

7 files changed

+34
-63
lines changed

satellite/console/consoleweb/consoleapi/payments.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"storj.io/storj/satellite/console"
2424
"storj.io/storj/satellite/payments"
2525
"storj.io/storj/satellite/payments/billing"
26-
"storj.io/storj/satellite/payments/stripe"
2726
)
2827

2928
var (
@@ -685,10 +684,6 @@ func (p *Payments) GetPartnerPlacementPriceModel(w http.ResponseWriter, r *http.
685684

686685
_, pricing, err := p.service.Payments().GetPartnerPlacementPriceModel(ctx, projectID, placement)
687686
if err != nil {
688-
if stripe.ErrPricingNotfound.Has(err) {
689-
p.serveJSONError(ctx, w, http.StatusNotFound, err)
690-
return
691-
}
692687
p.serveJSONError(ctx, w, http.StatusInternalServerError, err)
693688
return
694689
}

satellite/console/service.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5485,14 +5485,7 @@ func (s *Service) GetUsageReportHeaders(param GetUsageReportParam) (disclaimer [
54855485
func (s *Service) transformProjectReportItem(ctx context.Context, item accounting.ProjectReportItem, addCost bool, priceModel payments.ProductUsagePriceModel) (_ accounting.ProjectReportItem, err error) {
54865486
hoursPerMonthDecimal := decimal.NewFromInt(hoursPerMonth)
54875487
if priceModel == (payments.ProductUsagePriceModel{}) {
5488-
_, priceModel, err = s.accounts.GetPartnerPlacementPriceModel(ctx, item.ProjectPublicID, string(item.UserAgent), item.Placement)
5489-
if err != nil {
5490-
s.log.Error("failed to get partner placement price model", zap.String("partner", string(item.UserAgent)), zap.Int("placement", int(item.Placement)), zap.Error(err))
5491-
// Use partner-only price model as a fallback.
5492-
priceModel = payments.ProductUsagePriceModel{
5493-
ProjectUsagePriceModel: s.accounts.GetProjectUsagePriceModel(string(item.UserAgent)),
5494-
}
5495-
}
5488+
_, priceModel = s.accounts.GetPartnerPlacementPriceModel(ctx, item.ProjectPublicID, string(item.UserAgent), item.Placement)
54965489
}
54975490
item.ProductName = priceModel.ProductName
54985491
if s.config.SkuEnabled {
@@ -6447,10 +6440,7 @@ func (payment Payments) GetPartnerPlacementPriceModel(ctx context.Context, proje
64476440
}
64486441

64496442
project := isMember.project
6450-
productID, model, err := payment.service.accounts.GetPartnerPlacementPriceModel(ctx, project.PublicID, string(project.UserAgent), placement)
6451-
if err != nil {
6452-
return 0, payments.ProjectUsagePriceModel{}, Error.Wrap(err)
6453-
}
6443+
productID, model := payment.service.accounts.GetPartnerPlacementPriceModel(ctx, project.PublicID, string(project.UserAgent), placement)
64546444

64556445
return productID, model.ProjectUsagePriceModel, nil
64566446
}

satellite/console/service_test.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,19 +1902,9 @@ func TestGetUsageReport(t *testing.T) {
19021902
return hours.Div(hoursPerMonth).Round(0)
19031903
}
19041904

1905-
priceForItem := func(item accounting.ProjectReportItem) payments.ProductUsagePriceModel {
1906-
_, priceModel, err := sat.API.Payments.Accounts.GetPartnerPlacementPriceModel(ctx, project.PublicID,
1907-
string(project.UserAgent), item.Placement)
1908-
if err != nil {
1909-
priceModel = payments.ProductUsagePriceModel{
1910-
ProjectUsagePriceModel: sat.API.Payments.Accounts.GetProjectUsagePriceModel(string(item.UserAgent)),
1911-
}
1912-
}
1913-
return priceModel
1914-
}
1915-
19161905
testCosts := func(item accounting.ProjectReportItem, rollup accounting.BucketUsageRollup) {
1917-
priceModel := priceForItem(item)
1906+
_, priceModel := sat.API.Payments.Accounts.GetPartnerPlacementPriceModel(ctx, project.PublicID,
1907+
string(project.UserAgent), item.Placement)
19181908
require.Equal(t, priceModel.StorageSKU, item.StorageSKU)
19191909
require.Equal(t, priceModel.EgressSKU, item.EgressSKU)
19201910
require.Equal(t, priceModel.SegmentSKU, item.SegmentSKU)
@@ -2089,7 +2079,8 @@ func TestGetUsageReport(t *testing.T) {
20892079
require.Len(t, items, numbBuckets+1)
20902080
for _, item := range items {
20912081
if item.Placement == placement13 {
2092-
priceModel := priceForItem(item)
2082+
_, priceModel := sat.API.Payments.Accounts.GetPartnerPlacementPriceModel(ctx, project.PublicID,
2083+
string(project.UserAgent), item.Placement)
20932084
defaultModel, err := defaultPrice.ToModel()
20942085
require.NoError(t, err)
20952086
require.Equal(t, defaultModel, priceModel.ProjectUsagePriceModel)

satellite/payments/account.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,7 @@ type Accounts interface {
8787

8888
// GetPartnerPlacementPriceModel returns the productID and related usage price model for a partner and placement,
8989
// if there is none defined for the project ID.
90-
GetPartnerPlacementPriceModel(ctx context.Context, projectPublicID uuid.UUID, partner string, placement storj.PlacementConstraint) (productID int32, _ ProductUsagePriceModel, _ error)
91-
92-
// GetProductName returns the product name for a given product ID.
93-
GetProductName(productID int32) (string, error)
90+
GetPartnerPlacementPriceModel(ctx context.Context, projectPublicID uuid.UUID, partner string, placement storj.PlacementConstraint) (productID int32, _ ProductUsagePriceModel)
9491

9592
// GetPartnerNames returns the partners relevant to billing.
9693
GetPartnerNames() []string

satellite/payments/stripe/accounts.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ import (
1313
"github.com/shopspring/decimal"
1414
"github.com/stripe/stripe-go/v81"
1515
"github.com/zeebo/errs"
16+
"go.uber.org/zap"
1617

1718
"storj.io/common/currency"
1819
"storj.io/common/storj"
1920
"storj.io/common/uuid"
2021
"storj.io/storj/satellite/accounting"
21-
"storj.io/storj/satellite/entitlements"
2222
"storj.io/storj/satellite/payments"
2323
"storj.io/storj/satellite/payments/coinpayments"
2424
)
@@ -634,23 +634,26 @@ func (accounts *accounts) GetProjectUsagePriceModel(partner string) payments.Pro
634634

635635
// GetPartnerPlacementPriceModel returns the productID and related usage price model for a partner and placement,
636636
// if there is none defined for the project ID.
637-
func (accounts *accounts) GetPartnerPlacementPriceModel(ctx context.Context, projectPublicID uuid.UUID, partner string, placement storj.PlacementConstraint) (_ int32, _ payments.ProductUsagePriceModel, _ error) {
637+
func (accounts *accounts) GetPartnerPlacementPriceModel(ctx context.Context, projectPublicID uuid.UUID, partner string, placement storj.PlacementConstraint) (_ int32, _ payments.ProductUsagePriceModel) {
638638
if accounts.service.config.EntitlementsEnabled {
639639
feats, err := accounts.service.entitlements.Projects().GetByPublicID(ctx, projectPublicID)
640640
if err != nil {
641-
if !entitlements.ErrNotFound.Has(err) {
642-
return 0, payments.ProductUsagePriceModel{}, err
643-
}
641+
accounts.service.log.Error(
642+
"could not get pricing entitlements for project, falling back to defaults",
643+
zap.String("partner", partner), zap.Int("placement", int(placement)), zap.Error(err))
644644
}
645645
for productID, placementConstraints := range feats.ProductPlacementMappings {
646646
for _, pC := range placementConstraints {
647647
if pC != placement {
648648
continue
649649
}
650650
if price, ok := accounts.service.pricingConfig.ProductPriceMap[productID]; ok {
651-
return productID, price, nil
651+
return productID, price
652652
}
653-
return 0, payments.ProductUsagePriceModel{}, ErrPricingNotfound.New("pricing not found for product %d", productID)
653+
accounts.service.log.Info(
654+
"no product definition for product and partner, falling back to defaults",
655+
zap.String("partner", partner), zap.Int("placement", int(placement)))
656+
// fall through to global pricing
654657
}
655658
}
656659
}
@@ -660,17 +663,17 @@ func (accounts *accounts) GetPartnerPlacementPriceModel(ctx context.Context, pro
660663
productID, _ = accounts.service.pricingConfig.PlacementProductMap.GetProductByPlacement(int(placement))
661664
}
662665
if price, ok := accounts.service.pricingConfig.ProductPriceMap[productID]; ok {
663-
return productID, price, nil
666+
return productID, price
664667
}
665-
return 0, payments.ProductUsagePriceModel{}, ErrPricingNotfound.New("pricing not found for partner %s and placement %d", partner, placement)
666-
}
667668

668-
// GetProductName returns the product name for a given product ID.
669-
func (accounts *accounts) GetProductName(productID int32) (string, error) {
670-
if price, ok := accounts.service.pricingConfig.ProductPriceMap[productID]; ok {
671-
return price.ProductName, nil
669+
accounts.service.log.Info(
670+
"no product definition for product and partner, falling back to defaults",
671+
zap.String("partner", partner), zap.Int("placement", int(placement)))
672+
673+
// fall back to default pricing for partner
674+
return 0, payments.ProductUsagePriceModel{
675+
ProjectUsagePriceModel: accounts.GetProjectUsagePriceModel(partner),
672676
}
673-
return "", ErrPricingNotfound.New("pricing not found for product %d", productID)
674677
}
675678

676679
// GetPartnerNames returns the partners relevant to billing.

satellite/payments/stripe/service.go

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ var (
4242
// Error defines stripecoinpayments service error.
4343
Error = errs.Class("stripecoinpayments service")
4444

45-
// ErrPricingNotfound is returned when pricing model for a
46-
// partner and/or placement is not found.
47-
ErrPricingNotfound = errs.Class("pricing not found")
48-
4945
mon = monkit.Package()
5046

5147
_ healthcheck.HealthCheck = (*Service)(nil)
@@ -714,16 +710,7 @@ func (service *Service) productIdAndPriceForUsageKey(ctx context.Context, projec
714710
}
715711

716712
// Get price model for the partner and placement.
717-
productID, priceModel, err := service.Accounts().GetPartnerPlacementPriceModel(ctx, projectPublicID, partner, storj.PlacementConstraint(placement))
718-
if err != nil {
719-
service.log.Error("failed to get partner placement price model", zap.String("partner", partner), zap.Int("placement", placement), zap.Error(err))
720-
// Use partner-only price model as a fallback.
721-
// This should be removed once the tests are updated
722-
priceModel = payments.ProductUsagePriceModel{
723-
ProjectUsagePriceModel: service.Accounts().GetProjectUsagePriceModel(partner),
724-
}
725-
}
726-
return productID, priceModel
713+
return service.Accounts().GetPartnerPlacementPriceModel(ctx, projectPublicID, partner, storj.PlacementConstraint(placement))
727714
}
728715

729716
// InvoiceItemsFromTotalProjectUsages calculates per-product Stripe invoice items from total project usages.

satellite/payments/stripe/service_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,14 @@ func TestPartnerPlacements(t *testing.T) {
16681668
// expect global product for placement12
16691669
require.Equal(t, productModel, model)
16701670
require.Equal(t, productID, prodID)
1671+
1672+
// expect default pricing for placement without mapping
1673+
defaultPrice, err := sat.Config.Payments.UsagePrice.ToModel()
1674+
require.NoError(t, err)
1675+
1676+
_, model, err = paymentsAPI.GetPartnerPlacementPriceModel(userCtx, proj.ID, storj.PlacementConstraint(50))
1677+
require.NoError(t, err)
1678+
require.Equal(t, defaultPrice, model)
16711679
})
16721680
}
16731681

0 commit comments

Comments
 (0)