|
|
@@ -119,7 +119,7 @@ func (m MetronomeClient) createCustomer(ctx context.Context, userEmail string, p
|
|
|
Data types.Customer `json:"data"`
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodPost, path, customer, &result)
|
|
|
+ _, err = m.do(http.MethodPost, path, nil, customer, &result)
|
|
|
if err != nil {
|
|
|
return customerID, telemetry.Error(ctx, span, err, "error creating customer")
|
|
|
}
|
|
|
@@ -159,7 +159,7 @@ func (m MetronomeClient) addCustomerPlan(ctx context.Context, customerID uuid.UU
|
|
|
} `json:"data"`
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodPost, path, req, &result)
|
|
|
+ _, err = m.do(http.MethodPost, path, nil, req, &result)
|
|
|
if err != nil {
|
|
|
return customerPlanID, telemetry.Error(ctx, span, err, "failed to add customer to plan")
|
|
|
}
|
|
|
@@ -182,7 +182,7 @@ func (m MetronomeClient) ListCustomerPlan(ctx context.Context, customerID uuid.U
|
|
|
Data []types.Plan `json:"data"`
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodGet, path, nil, &result)
|
|
|
+ _, err = m.do(http.MethodGet, path, nil, nil, &result)
|
|
|
if err != nil {
|
|
|
return plan, telemetry.Error(ctx, span, err, "failed to list customer plans")
|
|
|
}
|
|
|
@@ -214,7 +214,7 @@ func (m MetronomeClient) EndCustomerPlan(ctx context.Context, customerID uuid.UU
|
|
|
EndingBeforeUTC: endBefore,
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodPost, path, req, nil)
|
|
|
+ _, err = m.do(http.MethodPost, path, nil, req, nil)
|
|
|
if err != nil {
|
|
|
return telemetry.Error(ctx, span, err, "failed to end customer plan")
|
|
|
}
|
|
|
@@ -243,7 +243,7 @@ func (m MetronomeClient) ListCustomerCredits(ctx context.Context, customerID uui
|
|
|
Data []types.CreditGrant `json:"data"`
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodPost, path, req, &result)
|
|
|
+ _, err = m.do(http.MethodPost, path, nil, req, &result)
|
|
|
if err != nil {
|
|
|
return credits, telemetry.Error(ctx, span, err, "failed to list customer credits")
|
|
|
}
|
|
|
@@ -289,7 +289,7 @@ func (m MetronomeClient) CreateCreditsGrant(ctx context.Context, customerID uuid
|
|
|
Priority: 1,
|
|
|
}
|
|
|
|
|
|
- statusCode, err := m.do(http.MethodPost, path, req, nil)
|
|
|
+ statusCode, err := m.do(http.MethodPost, path, nil, req, nil)
|
|
|
if err != nil && statusCode != http.StatusConflict {
|
|
|
// a conflict response indicates the grant already exists
|
|
|
return telemetry.Error(ctx, span, err, "failed to create credits grant")
|
|
|
@@ -341,7 +341,7 @@ func (m MetronomeClient) ListCustomerUsage(ctx context.Context, customerID uuid.
|
|
|
}
|
|
|
|
|
|
baseReq.BillableMetricID = billableMetric.ID
|
|
|
- _, err = m.do(http.MethodPost, path, baseReq, &result)
|
|
|
+ _, err = m.do(http.MethodPost, path, nil, baseReq, &result)
|
|
|
if err != nil {
|
|
|
return usage, telemetry.Error(ctx, span, err, "failed to get customer usage")
|
|
|
}
|
|
|
@@ -355,6 +355,7 @@ func (m MetronomeClient) ListCustomerUsage(ctx context.Context, customerID uuid.
|
|
|
return usage, nil
|
|
|
}
|
|
|
|
|
|
+// ListCustomerInvoices will return the invoices for a customer for the given status and time range
|
|
|
func (m MetronomeClient) ListCustomerInvoices(ctx context.Context, customerID uuid.UUID, status string, startingOn string, endingBefore string) (invoices []types.Invoice, err error) {
|
|
|
ctx, span := telemetry.NewSpan(ctx, "list-customer-invoices")
|
|
|
defer span.End()
|
|
|
@@ -363,12 +364,25 @@ func (m MetronomeClient) ListCustomerInvoices(ctx context.Context, customerID uu
|
|
|
return invoices, telemetry.Error(ctx, span, err, "customer id empty")
|
|
|
}
|
|
|
|
|
|
- path := fmt.Sprintf("/customers/%s/invoices?status=%s&starting_on=%s&ending_before=%s", customerID, status, startingOn, endingBefore)
|
|
|
+ path := fmt.Sprintf("customers/%s/invoices", customerID)
|
|
|
+
|
|
|
+ queryParams := map[string]string{
|
|
|
+ "status": status,
|
|
|
+ }
|
|
|
+
|
|
|
+ if startingOn != "" {
|
|
|
+ queryParams["starting_on"] = startingOn
|
|
|
+ }
|
|
|
+
|
|
|
+ if endingBefore != "" {
|
|
|
+ queryParams["ending_before"] = endingBefore
|
|
|
+ }
|
|
|
+
|
|
|
var result struct {
|
|
|
Data []types.Invoice `json:"data"`
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodGet, path, nil, &result)
|
|
|
+ _, err = m.do(http.MethodGet, path, queryParams, nil, &result)
|
|
|
if err != nil {
|
|
|
return invoices, telemetry.Error(ctx, span, err, "failed to list customer invoices")
|
|
|
}
|
|
|
@@ -389,7 +403,7 @@ func (m MetronomeClient) IngestEvents(ctx context.Context, events []types.Billin
|
|
|
|
|
|
var currentAttempts int
|
|
|
for currentAttempts < defaultMaxRetries {
|
|
|
- statusCode, err := m.do(http.MethodPost, path, events, nil)
|
|
|
+ statusCode, err := m.do(http.MethodPost, path, nil, events, nil)
|
|
|
// Check errors that are not from error http codes
|
|
|
if statusCode == 0 && err != nil {
|
|
|
return telemetry.Error(ctx, span, err, "failed to ingest billing events")
|
|
|
@@ -428,7 +442,7 @@ func (m MetronomeClient) listBillableMetricIDs(ctx context.Context, customerID u
|
|
|
Data []types.BillableMetric `json:"data"`
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodGet, path, nil, &result)
|
|
|
+ _, err = m.do(http.MethodGet, path, nil, nil, &result)
|
|
|
if err != nil {
|
|
|
return billableMetrics, telemetry.Error(ctx, span, err, "failed to retrieve billable metrics from metronome")
|
|
|
}
|
|
|
@@ -446,7 +460,7 @@ func (m MetronomeClient) getCreditTypeID(ctx context.Context, currencyCode strin
|
|
|
Data []types.PricingUnit `json:"data"`
|
|
|
}
|
|
|
|
|
|
- _, err = m.do(http.MethodGet, path, nil, &result)
|
|
|
+ _, err = m.do(http.MethodGet, path, nil, nil, &result)
|
|
|
if err != nil {
|
|
|
return creditTypeID, telemetry.Error(ctx, span, err, "failed to retrieve billable metrics from metronome")
|
|
|
}
|
|
|
@@ -460,7 +474,7 @@ func (m MetronomeClient) getCreditTypeID(ctx context.Context, currencyCode strin
|
|
|
return creditTypeID, telemetry.Error(ctx, span, fmt.Errorf("credit type not found for currency code %s", currencyCode), "failed to find credit type")
|
|
|
}
|
|
|
|
|
|
-func (m MetronomeClient) do(method string, path string, body interface{}, data interface{}) (statusCode int, err error) {
|
|
|
+func (m MetronomeClient) do(method string, path string, queryParams map[string]string, body interface{}, data interface{}) (statusCode int, err error) {
|
|
|
client := http.Client{}
|
|
|
endpoint, err := url.JoinPath(metronomeBaseUrl, path)
|
|
|
if err != nil {
|
|
|
@@ -475,6 +489,14 @@ func (m MetronomeClient) do(method string, path string, body interface{}, data i
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if queryParams != nil {
|
|
|
+ q := url.Values{}
|
|
|
+ for k, v := range queryParams {
|
|
|
+ q.Add(k, v)
|
|
|
+ }
|
|
|
+ endpoint = fmt.Sprintf("%s?%s", endpoint, q.Encode())
|
|
|
+ }
|
|
|
+
|
|
|
req, err := http.NewRequest(method, endpoint, bytes.NewBuffer(bodyJson))
|
|
|
if err != nil {
|
|
|
return statusCode, err
|