|
|
@@ -1,10 +1,12 @@
|
|
|
package billing
|
|
|
|
|
|
import (
|
|
|
+ "context"
|
|
|
"fmt"
|
|
|
|
|
|
"github.com/porter-dev/porter/api/types"
|
|
|
"github.com/porter-dev/porter/internal/models"
|
|
|
+ "github.com/porter-dev/porter/internal/telemetry"
|
|
|
"github.com/stripe/stripe-go/v76"
|
|
|
"github.com/stripe/stripe-go/v76/customer"
|
|
|
"github.com/stripe/stripe-go/v76/paymentmethod"
|
|
|
@@ -19,9 +21,16 @@ type StripeBillingManager struct {
|
|
|
}
|
|
|
|
|
|
// CreateCustomer will create a customer in Stripe only if the project doesn't have a BillingID
|
|
|
-func (s *StripeBillingManager) CreateCustomer(userEmail string, proj *models.Project) (customerID string, err error) {
|
|
|
+func (s *StripeBillingManager) CreateCustomer(ctx context.Context, userEmail string, proj *models.Project) (customerID string, err error) {
|
|
|
+ ctx, span := telemetry.NewSpan(ctx, "create-stripe-customer")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
stripe.Key = s.StripeSecretKey
|
|
|
|
|
|
+ telemetry.WithAttributes(span,
|
|
|
+ telemetry.AttributeKV{Key: "billing-id", Value: proj.BillingID},
|
|
|
+ )
|
|
|
+
|
|
|
if proj.BillingID == "" {
|
|
|
// Create customer if not exists
|
|
|
customerName := fmt.Sprintf("project_%s", proj.Name)
|
|
|
@@ -33,7 +42,7 @@ func (s *StripeBillingManager) CreateCustomer(userEmail string, proj *models.Pro
|
|
|
// Create in Stripe
|
|
|
customer, err := customer.New(params)
|
|
|
if err != nil {
|
|
|
- return "", err
|
|
|
+ return "", telemetry.Error(ctx, span, err, "failed to create Stripe customer")
|
|
|
}
|
|
|
|
|
|
customerID = customer.ID
|
|
|
@@ -43,14 +52,21 @@ func (s *StripeBillingManager) CreateCustomer(userEmail string, proj *models.Pro
|
|
|
}
|
|
|
|
|
|
// DeleteCustomer will delete the customer from the billing provider
|
|
|
-func (s *StripeBillingManager) DeleteCustomer(proj *models.Project) (err error) {
|
|
|
+func (s *StripeBillingManager) DeleteCustomer(ctx context.Context, proj *models.Project) (err error) {
|
|
|
+ ctx, span := telemetry.NewSpan(ctx, "delete-stripe-customer")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
stripe.Key = s.StripeSecretKey
|
|
|
|
|
|
+ telemetry.WithAttributes(span,
|
|
|
+ telemetry.AttributeKV{Key: "billing-id", Value: proj.BillingID},
|
|
|
+ )
|
|
|
+
|
|
|
if proj.BillingID != "" {
|
|
|
params := &stripe.CustomerParams{}
|
|
|
_, err := customer.Del(proj.BillingID, params)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return telemetry.Error(ctx, span, err, "failed to delete Stripe customer")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -58,7 +74,10 @@ func (s *StripeBillingManager) DeleteCustomer(proj *models.Project) (err error)
|
|
|
}
|
|
|
|
|
|
// CheckPaymentEnabled will return true if the project has a payment method added, false otherwise
|
|
|
-func (s *StripeBillingManager) CheckPaymentEnabled(proj *models.Project) (paymentEnabled bool, err error) {
|
|
|
+func (s *StripeBillingManager) CheckPaymentEnabled(ctx context.Context, proj *models.Project) (paymentEnabled bool, err error) {
|
|
|
+ _, span := telemetry.NewSpan(ctx, "check-stripe-payment-enabled")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
stripe.Key = s.StripeSecretKey
|
|
|
|
|
|
params := &stripe.PaymentMethodListParams{
|
|
|
@@ -71,7 +90,10 @@ func (s *StripeBillingManager) CheckPaymentEnabled(proj *models.Project) (paymen
|
|
|
}
|
|
|
|
|
|
// ListPaymentMethod will return all payment methods for the project
|
|
|
-func (s *StripeBillingManager) ListPaymentMethod(proj *models.Project) (paymentMethods []types.PaymentMethod, err error) {
|
|
|
+func (s *StripeBillingManager) ListPaymentMethod(ctx context.Context, proj *models.Project) (paymentMethods []types.PaymentMethod, err error) {
|
|
|
+ ctx, span := telemetry.NewSpan(ctx, "list-stripe-payment-method")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
stripe.Key = s.StripeSecretKey
|
|
|
|
|
|
// Get configured payment methods
|
|
|
@@ -83,7 +105,7 @@ func (s *StripeBillingManager) ListPaymentMethod(proj *models.Project) (paymentM
|
|
|
|
|
|
defaultPaymentExists, defaultPaymentID, err := s.checkDefaultPaymentMethod(proj.BillingID)
|
|
|
if err != nil {
|
|
|
- return paymentMethods, err
|
|
|
+ return paymentMethods, telemetry.Error(ctx, span, err, "failed to list Stripe payment method")
|
|
|
}
|
|
|
|
|
|
for result.Next() {
|
|
|
@@ -107,9 +129,9 @@ func (s *StripeBillingManager) ListPaymentMethod(proj *models.Project) (paymentM
|
|
|
// Set default payment method when project has payment methods enabled but
|
|
|
// no default setup
|
|
|
if len(paymentMethods) > 0 && !defaultPaymentExists {
|
|
|
- err = s.SetDefaultPaymentMethod(paymentMethods[len(paymentMethods)-1].ID, proj)
|
|
|
+ err = s.SetDefaultPaymentMethod(ctx, paymentMethods[len(paymentMethods)-1].ID, proj)
|
|
|
if err != nil {
|
|
|
- return paymentMethods, err
|
|
|
+ return paymentMethods, telemetry.Error(ctx, span, err, "failed to list Stripe payment method")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -117,7 +139,10 @@ func (s *StripeBillingManager) ListPaymentMethod(proj *models.Project) (paymentM
|
|
|
}
|
|
|
|
|
|
// CreatePaymentMethod will add a new payment method to the project in Stripe
|
|
|
-func (s *StripeBillingManager) CreatePaymentMethod(proj *models.Project) (clientSecret string, err error) {
|
|
|
+func (s *StripeBillingManager) CreatePaymentMethod(ctx context.Context, proj *models.Project) (clientSecret string, err error) {
|
|
|
+ ctx, span := telemetry.NewSpan(ctx, "create-stripe-payment-method")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
stripe.Key = s.StripeSecretKey
|
|
|
|
|
|
params := &stripe.SetupIntentParams{
|
|
|
@@ -130,14 +155,17 @@ func (s *StripeBillingManager) CreatePaymentMethod(proj *models.Project) (client
|
|
|
|
|
|
intent, err := setupintent.New(params)
|
|
|
if err != nil {
|
|
|
- return "", err
|
|
|
+ return "", telemetry.Error(ctx, span, err, "failed to create Stripe payment method")
|
|
|
}
|
|
|
|
|
|
return intent.ClientSecret, nil
|
|
|
}
|
|
|
|
|
|
// SetDefaultPaymentMethod will add a new payment method to the project in Stripe
|
|
|
-func (s *StripeBillingManager) SetDefaultPaymentMethod(paymentMethodID string, proj *models.Project) (err error) {
|
|
|
+func (s *StripeBillingManager) SetDefaultPaymentMethod(ctx context.Context, paymentMethodID string, proj *models.Project) (err error) {
|
|
|
+ ctx, span := telemetry.NewSpan(ctx, "set-default-stripe-payment-method")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
stripe.Key = s.StripeSecretKey
|
|
|
|
|
|
params := &stripe.CustomerParams{
|
|
|
@@ -148,26 +176,32 @@ func (s *StripeBillingManager) SetDefaultPaymentMethod(paymentMethodID string, p
|
|
|
|
|
|
_, err = customer.Update(proj.BillingID, params)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return telemetry.Error(ctx, span, err, "failed to set default Stripe payment method")
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// DeletePaymentMethod will remove a payment method for the project in Stripe
|
|
|
-func (s *StripeBillingManager) DeletePaymentMethod(paymentMethodID string) (err error) {
|
|
|
+func (s *StripeBillingManager) DeletePaymentMethod(ctx context.Context, paymentMethodID string) (err error) {
|
|
|
+ ctx, span := telemetry.NewSpan(ctx, "delete-stripe-payment-method")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
stripe.Key = s.StripeSecretKey
|
|
|
|
|
|
_, err = paymentmethod.Detach(paymentMethodID, nil)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return telemetry.Error(ctx, span, err, "failed to delete Stripe payment method")
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// GetPublishableKey is a no-op
|
|
|
-func (s *StripeBillingManager) GetPublishableKey() (key string) {
|
|
|
+// GetPublishableKey returns the Stripe publishable key
|
|
|
+func (s *StripeBillingManager) GetPublishableKey(ctx context.Context) (key string) {
|
|
|
+ _, span := telemetry.NewSpan(ctx, "get-stripe-publishable-key")
|
|
|
+ defer span.End()
|
|
|
+
|
|
|
return s.StripePublishableKey
|
|
|
}
|
|
|
|