From b8c2facbefe4c65593ae1becaca3308b2a95116a Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 19 Nov 2024 12:25:42 +0000 Subject: [PATCH 01/36] feat(commerce): add basic subscription listing for commerce --- commerce.go | 122 ++++++++++++++++++++++++++++++++++++++++ commerce/api.go | 20 +++++++ commerce/client.go | 42 ++++++++++++++ commerce/client_test.go | 27 +++++++++ 4 files changed, 211 insertions(+) create mode 100644 commerce.go create mode 100644 commerce/api.go create mode 100644 commerce/client.go create mode 100644 commerce/client_test.go diff --git a/commerce.go b/commerce.go new file mode 100644 index 0000000..f7b9ffe --- /dev/null +++ b/commerce.go @@ -0,0 +1,122 @@ +package clerk + +import "time" + +// CommercePlan represents a subscription plan. +type CommercePlan struct { + ID string `json:"id"` + AppID string `json:"app_id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Name string `json:"name"` + Slug string `json:"slug"` + ImageURL string `json:"image_url"` + Description *string `json:"description,omitempty"` + Product CommerceProduct `json:"product"` + BaseAmount int64 `json:"base_amount"` + IsRecurring bool `json:"is_recurring"` + IsProrated bool `json:"is_prorated"` + Period string `json:"period"` // Enum equivalent for CommercePlanPeriod + Interval int `json:"interval"` + BillingCycles *int `json:"billing_cycles,omitempty"` + SubscriberCount int64 `json:"subscriber_count"` +} + +// CommerceProduct represents a product associated with a plan. +type CommerceProduct struct { + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Currency string `json:"currency"` + SubscriberType []string `json:"subscriber_type"` // Enum equivalent for CommerceProductSubscriberType + OwnerEntityType string `json:"owner_entity_type"` // Enum equivalent for CommerceProductOwnerEntity +} + +// CommerceProductWithPlans combines a product and its associated plans. +type CommerceProductWithPlans struct { + CommerceProduct + Plans []CommercePlan `json:"plans"` +} + +// CommerceCustomer represents a customer subscribing to a product. +type CommerceCustomer struct { + ID string `json:"id"` + AppID string `json:"app_id"` + CreatedAt time.Time `json:"created_at"` + EntityType string `json:"entity_type"` // Enum equivalent for CommerceProductSubscriberType + Entity struct { + ID string `json:"id"` + Name string `json:"name"` + ImageURL *string `json:"image_url,omitempty"` + } `json:"entity"` +} + +// CommerceSubscription represents a subscription. +type CommerceSubscription struct { + ID string `json:"id"` + AppID string `json:"app_id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Customer CommerceCustomer `json:"customer"` + Plan CommercePlan `json:"plan"` + Status string `json:"status"` // Enum equivalent for CommerceSubscriptionStatus + ToBeCancelledAt *time.Time `json:"to_be_cancelled_at,omitempty"` + LastInvoice *InvoiceSummary `json:"last_invoice,omitempty"` + NextInvoice *InvoiceSummary `json:"next_invoice,omitempty"` +} + +// InvoiceSummary is a reduced representation of an invoice. +type InvoiceSummary struct { + ID string `json:"id"` + DueAt time.Time `json:"due_at"` + Amount int64 `json:"amount"` + Status string `json:"status"` // Enum equivalent for CommerceInvoiceStatus +} + +// CommerceInvoice represents a detailed invoice. +type CommerceInvoice struct { + ID string `json:"id"` + AppID string `json:"app_id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Subscription CommerceSubscription `json:"subscription"` + Amount int64 `json:"amount"` + Status string `json:"status"` // Enum equivalent for CommerceInvoiceStatus + DueAt time.Time `json:"due_at"` + FinalizingPaymentAttempt string `json:"finalizing_payment_attempt_id"` +} + +// CommercePaymentAttempt represents a payment attempt for an invoice. +type CommercePaymentAttempt struct { + ID string `json:"id"` + AppID string `json:"app_id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Customer CommerceCustomer `json:"customer"` + Invoice CommerceInvoice `json:"invoice"` + Status string `json:"status"` // Enum equivalent for CommercePaymentAttemptStatus + Amount int64 `json:"amount"` +} + +// PaginatedList is a generic response for paginated resources. +type PaginatedList[T any] struct { + Data []T `json:"data"` + TotalCount int64 `json:"total_count"` +} + +// ListCommerceSubscriptionsResponse represents a paginated list of subscriptions. +type ListCommerceSubscriptionsResponse struct { + PaginatedList[CommerceSubscription] +} + +// ListCommerceInvoicesResponse represents a paginated list of invoices. +type ListCommerceInvoicesResponse struct { + PaginatedList[CommerceInvoice] +} + +// ListCommercePaymentAttemptsResponse represents a paginated list of payment attempts. +type ListCommercePaymentAttemptsResponse struct { + PaginatedList[CommercePaymentAttempt] +} diff --git a/commerce/api.go b/commerce/api.go new file mode 100644 index 0000000..7bb8526 --- /dev/null +++ b/commerce/api.go @@ -0,0 +1,20 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package commerce + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +// ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. +func ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.SubscriptionList, error) { + return getClient().ListSubscriptionsByInstanceID(ctx, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/client.go b/commerce/client.go new file mode 100644 index 0000000..ada5876 --- /dev/null +++ b/commerce/client.go @@ -0,0 +1,42 @@ +// Package user provides the Users API. +package commerce + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../cmd/gen/main.go + +const path = "/commerce" +const subscriptionsPath = "/subscriptions" + +// Client is used to invoke the Users API. +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} + +type ListSubscriptionsByInstanceIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. +func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.SubscriptionList, error) { + path, err := clerk.JoinPath(path, subscriptionsPath, params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.SubscriptionList{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} diff --git a/commerce/client_test.go b/commerce/client_test.go new file mode 100644 index 0000000..d626a97 --- /dev/null +++ b/commerce/client_test.go @@ -0,0 +1,27 @@ +package commerce + +import ( + "testing" +) + +func TestSubscriptionListByInstanceID(t *testing.T) { + t.Parallel() + // userID := "user_123" + // config := &clerk.ClientConfig{} + // config.HTTPClient = &http.Client{ + // Transport: &clerktest.RoundTripper{ + // T: t, + // Method: http.MethodDelete, + // Out: json.RawMessage(fmt.Sprintf(`{"id":"%s","object":"external_account"}`, externalAccountID)), + // Path: fmt.Sprintf("/v1/users/%s/external_accounts/%s", userID, externalAccountID), + // }, + // } + // client := NewClient(config) + // externalAccount, err := client.DeleteExternalAccount(context.Background(), &DeleteExternalAccountParams{ + // UserID: userID, + // ID: externalAccountID, + // }) + // require.NoError(t, err) + // require.Equal(t, externalAccountID, externalAccount.ID) + // require.Equal(t, "external_account", externalAccount.Object) +} From 5743b3169dcbcc318687f0891389164cbb4d8476 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 19 Nov 2024 12:30:09 +0000 Subject: [PATCH 02/36] feat(commerce): fix types for commerce subscriptions --- commerce.go | 15 ++++++++------- commerce/client.go | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/commerce.go b/commerce.go index f7b9ffe..2e4eccd 100644 --- a/commerce.go +++ b/commerce.go @@ -4,7 +4,7 @@ import "time" // CommercePlan represents a subscription plan. type CommercePlan struct { - ID string `json:"id"` + APIResource AppID string `json:"app_id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` @@ -24,7 +24,7 @@ type CommercePlan struct { // CommerceProduct represents a product associated with a plan. type CommerceProduct struct { - ID string `json:"id"` + APIResource Name string `json:"name"` Slug string `json:"slug"` CreatedAt time.Time `json:"created_at"` @@ -42,7 +42,7 @@ type CommerceProductWithPlans struct { // CommerceCustomer represents a customer subscribing to a product. type CommerceCustomer struct { - ID string `json:"id"` + APIResource AppID string `json:"app_id"` CreatedAt time.Time `json:"created_at"` EntityType string `json:"entity_type"` // Enum equivalent for CommerceProductSubscriberType @@ -55,7 +55,7 @@ type CommerceCustomer struct { // CommerceSubscription represents a subscription. type CommerceSubscription struct { - ID string `json:"id"` + APIResource AppID string `json:"app_id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` @@ -69,7 +69,7 @@ type CommerceSubscription struct { // InvoiceSummary is a reduced representation of an invoice. type InvoiceSummary struct { - ID string `json:"id"` + APIResource DueAt time.Time `json:"due_at"` Amount int64 `json:"amount"` Status string `json:"status"` // Enum equivalent for CommerceInvoiceStatus @@ -77,7 +77,7 @@ type InvoiceSummary struct { // CommerceInvoice represents a detailed invoice. type CommerceInvoice struct { - ID string `json:"id"` + APIResource AppID string `json:"app_id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` @@ -90,7 +90,7 @@ type CommerceInvoice struct { // CommercePaymentAttempt represents a payment attempt for an invoice. type CommercePaymentAttempt struct { - ID string `json:"id"` + APIResource AppID string `json:"app_id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` @@ -102,6 +102,7 @@ type CommercePaymentAttempt struct { // PaginatedList is a generic response for paginated resources. type PaginatedList[T any] struct { + APIResource Data []T `json:"data"` TotalCount int64 `json:"total_count"` } diff --git a/commerce/client.go b/commerce/client.go index ada5876..5e313b7 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -30,13 +30,13 @@ type ListSubscriptionsByInstanceIDParams struct { } // ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. -func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.SubscriptionList, error) { +func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { path, err := clerk.JoinPath(path, subscriptionsPath, params.ID) if err != nil { return nil, err } req := clerk.NewAPIRequest(http.MethodGet, path) - resource := &clerk.SubscriptionList{} + resource := &clerk.ListCommerceSubscriptionsResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } From b7d4a1cb936103dcae1f0cb5869a46d856b90162 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 19 Nov 2024 13:23:22 +0000 Subject: [PATCH 03/36] feat(dapi): add remaining method --- commerce.go | 22 ++++++ commerce/client.go | 177 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 189 insertions(+), 10 deletions(-) diff --git a/commerce.go b/commerce.go index 2e4eccd..1825898 100644 --- a/commerce.go +++ b/commerce.go @@ -100,6 +100,23 @@ type CommercePaymentAttempt struct { Amount int64 `json:"amount"` } +// CommerceIntegration represents a response for integration creation. +type CommerceIntegration struct { + APIResource + AppID string `json:"app_id"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + IntegrationID string `json:"integration_id"` + IntegrationType string `json:"integration_type"` + Status string `json:"status"` +} + +// CommerceIntegrationResponse represents the response for integration creation. +type CommerceIntegrationResponse struct { + APIResource + URL string `json:"url"` +} + // PaginatedList is a generic response for paginated resources. type PaginatedList[T any] struct { APIResource @@ -121,3 +138,8 @@ type ListCommerceInvoicesResponse struct { type ListCommercePaymentAttemptsResponse struct { PaginatedList[CommercePaymentAttempt] } + +// ListCommerceProductsResponse represents a paginated list of products. +type ListCommerceProductsResponse struct { + PaginatedList[CommerceProduct] +} diff --git a/commerce/client.go b/commerce/client.go index 5e313b7..9553cf3 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -1,4 +1,4 @@ -// Package user provides the Users API. +// Package commerce provides the Commerce API. package commerce import ( @@ -8,12 +8,18 @@ import ( "github.com/clerk/clerk-sdk-go/v2" ) -//go:generate go run ../cmd/gen/main.go - -const path = "/commerce" -const subscriptionsPath = "/subscriptions" +// Paths +const ( + path = "/commerce" + subscriptionsPath = "/subscriptions" + invoicesPath = "/invoices" + paymentAttemptsPath = "/payment_attempts" + productsPath = "/products" + plansPath = "/plans" + integrationsPath = "/integrations" +) -// Client is used to invoke the Users API. +// Client is used to invoke the Commerce API. type Client struct { Backend clerk.Backend } @@ -24,14 +30,16 @@ func NewClient(config *clerk.ClientConfig) *Client { } } -type ListSubscriptionsByInstanceIDParams struct { +// Subscriptions + +type ListSubscriptionsByUserIDParams struct { clerk.APIParams ID string `json:"-"` } -// ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. -func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - path, err := clerk.JoinPath(path, subscriptionsPath, params.ID) +// ListSubscriptionsByUserID returns a list of subscriptions for a given user ID. +func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + path, err := clerk.JoinPath(path, subscriptionsPath, "user", params.ID) if err != nil { return nil, err } @@ -40,3 +48,152 @@ func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *List err = c.Backend.Call(ctx, req, resource) return resource, err } + +type GetSubscriptionByIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// GetSubscriptionByID retrieves a subscription by its ID. +func (c *Client) GetSubscriptionByID(ctx context.Context, params *GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { + path, err := clerk.JoinPath(path, subscriptionsPath, params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.CommerceSubscription{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +// Invoices + +type ListInvoicesByInstanceIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// ListInvoicesByInstanceID returns a list of invoices for a given instance ID. +func (c *Client) ListInvoicesByInstanceID(ctx context.Context, params *ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { + path, err := clerk.JoinPath(path, invoicesPath, "instance", params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.ListCommerceInvoicesResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +type GetInvoiceByIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// GetInvoiceByID retrieves an invoice by its ID. +func (c *Client) GetInvoiceByID(ctx context.Context, params *GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { + path, err := clerk.JoinPath(path, invoicesPath, params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.CommerceInvoice{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +// Payment Attempts + +type ListPaymentAttemptsByInstanceIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// ListPaymentAttemptsByInstanceID returns a list of payment attempts for a given instance ID. +func (c *Client) ListPaymentAttemptsByInstanceID(ctx context.Context, params *ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { + path, err := clerk.JoinPath(path, paymentAttemptsPath, "instance", params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.ListCommercePaymentAttemptsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +type GetPaymentAttemptByIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// GetPaymentAttemptByID retrieves a payment attempt by its ID. +func (c *Client) GetPaymentAttemptByID(ctx context.Context, params *GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { + path, err := clerk.JoinPath(path, paymentAttemptsPath, params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.CommercePaymentAttempt{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +// Products + +type ListProductsByInstanceIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// ListProductsByInstanceID returns a list of products for a given instance ID. +func (c *Client) ListProductsByInstanceID(ctx context.Context, params *ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { + path, err := clerk.JoinPath(path, productsPath, "instance", params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.ListCommerceProductsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +// Plans + +type GetPlanByIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// GetPlanByID retrieves a plan by its ID. +func (c *Client) GetPlanByID(ctx context.Context, params *GetPlanByIDParams) (*clerk.CommercePlan, error) { + path, err := clerk.JoinPath(path, plansPath, params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.CommercePlan{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +// Integrations + +type CreateIntegrationParams struct { + clerk.APIParams + InstanceID string `json:"instance_id"` + Email string `json:"email"` + Type string `json:"type"` +} + +// CreateIntegration creates a new integration for the specified instance. +func (c *Client) CreateIntegration(ctx context.Context, params *CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + path, err := clerk.JoinPath(path, integrationsPath) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, path) + req.Body = params + resource := &clerk.CommerceIntegrationResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} From c4798385527423999b1468b5fe1b0f983510faa8 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 19 Nov 2024 17:16:44 +0000 Subject: [PATCH 04/36] feat(dapi): use commerce client --- commerce/client.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/commerce/client.go b/commerce/client.go index 9553cf3..a465885 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -32,6 +32,23 @@ func NewClient(config *clerk.ClientConfig) *Client { // Subscriptions +type ListSubscriptionsByInstanceIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. +func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + path, err := clerk.JoinPath(path, subscriptionsPath, params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.ListCommerceSubscriptionsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + type ListSubscriptionsByUserIDParams struct { clerk.APIParams ID string `json:"-"` From d33d577118660ad30523fc6cf2f3ea7b363d7a70 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Wed, 20 Nov 2024 12:35:22 +0000 Subject: [PATCH 05/36] feat(commerce): correct methods --- cmd/gen/main.go | 1 + commerce/api.go | 62 +++++++++++++++++++++++++++++++++++++++++++++- commerce/client.go | 61 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/cmd/gen/main.go b/cmd/gen/main.go index d1959b0..86afebf 100644 --- a/cmd/gen/main.go +++ b/cmd/gen/main.go @@ -28,6 +28,7 @@ func main() { // We're looking for source code in /client.go files. filePath, err := filepath.Abs(path.Join(cwd, "client.go")) + if err != nil { log.Fatal(fmt.Errorf("get absolute file path: %w", err)) } diff --git a/commerce/api.go b/commerce/api.go index 7bb8526..86b5393 100644 --- a/commerce/api.go +++ b/commerce/api.go @@ -9,10 +9,70 @@ import ( ) // ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. -func ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.SubscriptionList, error) { +func ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { return getClient().ListSubscriptionsByInstanceID(ctx, params) } +// ListSubscriptionsByUserID returns a list of subscriptions for a given user ID. +func ListSubscriptionsByUserID(ctx context.Context, params *ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + return getClient().ListSubscriptionsByUserID(ctx, params) +} + +// GetSubscriptionByID retrieves a subscription by its ID. +func GetSubscriptionByID(ctx context.Context, params *GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { + return getClient().GetSubscriptionByID(ctx, params) +} + +// ListInvoicesByInstanceID returns a list of invoices for a given instance ID. +func ListInvoicesByInstanceID(ctx context.Context, params *ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { + return getClient().ListInvoicesByInstanceID(ctx, params) +} + +// GetInvoiceByID retrieves an invoice by its ID. +func GetInvoiceByID(ctx context.Context, params *GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { + return getClient().GetInvoiceByID(ctx, params) +} + +// ListPaymentAttemptsByInstanceID returns a list of payment attempts for a given instance ID. +func ListPaymentAttemptsByInstanceID(ctx context.Context, params *ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { + return getClient().ListPaymentAttemptsByInstanceID(ctx, params) +} + +// GetPaymentAttemptByID retrieves a payment attempt by its ID. +func GetPaymentAttemptByID(ctx context.Context, params *GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { + return getClient().GetPaymentAttemptByID(ctx, params) +} + +// ListProductsByInstanceID returns a list of products for a given instance ID. +func ListProductsByInstanceID(ctx context.Context, params *ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { + return getClient().ListProductsByInstanceID(ctx, params) +} + +// GetPlanByID retrieves a plan by its ID. +func GetPlanByID(ctx context.Context, params *GetPlanByIDParams) (*clerk.CommercePlan, error) { + return getClient().GetPlanByID(ctx, params) +} + +// CreateIntegration creates a new integration for the specified instance. +func CreateIntegration(ctx context.Context, params *CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + return getClient().CreateIntegration(ctx, params) +} + +// UpdateCommerceIntegration updates an existing commerce integration's status. +func UpdateIntegration(ctx context.Context, params *UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + return getClient().UpdateIntegration(ctx, params) +} + +// GetIntegration retrieves a specific integration by its ID. +func GetIntegration(ctx context.Context, params *GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + return getClient().GetIntegration(ctx, params) +} + +// GetProductByID retrieves an Product by its ID. +func GetProductByID(ctx context.Context, params *GetProductByIDParams) (*clerk.CommerceProduct, error) { + return getClient().GetProductByID(ctx, params) +} + func getClient() *Client { return &Client{ Backend: clerk.GetBackend(), diff --git a/commerce/client.go b/commerce/client.go index a465885..97d002b 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -8,6 +8,8 @@ import ( "github.com/clerk/clerk-sdk-go/v2" ) +//go:generate go run ../cmd/gen/main.go + // Paths const ( path = "/commerce" @@ -209,8 +211,65 @@ func (c *Client) CreateIntegration(ctx context.Context, params *CreateIntegratio return nil, err } req := clerk.NewAPIRequest(http.MethodPost, path) - req.Body = params + req.SetParams(params) + resource := &clerk.CommerceIntegrationResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +// UpdateCommerceIntegrationParams represents the parameters for updating a commerce integration. +type UpdateIntegrationParams struct { + clerk.APIParams + CommerceIntegrationID string `json:"-"` + Status string `json:"status"` +} + +// UpdateCommerceIntegration updates an existing commerce integration's status. +func (c *Client) UpdateIntegration(ctx context.Context, params *UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + path, err := clerk.JoinPath(path, integrationsPath, params.CommerceIntegrationID) + if err != nil { + return nil, err + } + + req := clerk.NewAPIRequest(http.MethodPut, path) + req.SetParams(params) + resource := &clerk.CommerceIntegrationResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +// GetIntegrationParams represents the parameters for retrieving a commerce integration by ID. +type GetIntegrationParams struct { + clerk.APIParams + IntegrationID string `json:"-"` +} + +// GetIntegration retrieves a specific integration by its ID. +func (c *Client) GetIntegration(ctx context.Context, params *GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + path, err := clerk.JoinPath(path, integrationsPath, params.IntegrationID) + if err != nil { + return nil, err + } + + req := clerk.NewAPIRequest(http.MethodGet, path) resource := &clerk.CommerceIntegrationResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } + +type GetProductByIDParams struct { + clerk.APIParams + ID string `json:"-"` +} + +// GetProductByID retrieves an Product by its ID. +func (c *Client) GetProductByID(ctx context.Context, params *GetProductByIDParams) (*clerk.CommerceProduct, error) { + path, err := clerk.JoinPath(path, productsPath, params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, path) + resource := &clerk.CommerceProduct{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} From 1abb0ae56b74c965b9a9db71a77c60b1150ca571 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Wed, 20 Nov 2024 16:17:42 +0000 Subject: [PATCH 06/36] feat(commerce) types working --- commerce.go | 323 +++++++++++++++++++++++++++++++-------------- commerce/api.go | 97 ++++++++++---- commerce/client.go | 284 +++++++++++++++++++++++---------------- 3 files changed, 459 insertions(+), 245 deletions(-) diff --git a/commerce.go b/commerce.go index 1825898..4ebbbea 100644 --- a/commerce.go +++ b/commerce.go @@ -2,144 +2,267 @@ package clerk import "time" -// CommercePlan represents a subscription plan. -type CommercePlan struct { - APIResource - AppID string `json:"app_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Name string `json:"name"` - Slug string `json:"slug"` - ImageURL string `json:"image_url"` - Description *string `json:"description,omitempty"` - Product CommerceProduct `json:"product"` - BaseAmount int64 `json:"base_amount"` - IsRecurring bool `json:"is_recurring"` - IsProrated bool `json:"is_prorated"` - Period string `json:"period"` // Enum equivalent for CommercePlanPeriod - Interval int `json:"interval"` - BillingCycles *int `json:"billing_cycles,omitempty"` - SubscriberCount int64 `json:"subscriber_count"` -} - -// CommerceProduct represents a product associated with a plan. +// --- Product Types --- + +type CreateProductParams struct { + APIParams + InstanceID *string `json:"instance_id,omitempty"` + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *[]string `json:"subscriber_type,omitempty"` + OwnerEntityType *string `json:"owner_entity_type,omitempty"` +} + +type UpdateProductParams struct { + APIParams + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *[]string `json:"subscriber_type,omitempty"` + OwnerEntityType *string `json:"owner_entity_type,omitempty"` +} + +type GetProductByIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + type CommerceProduct struct { APIResource - Name string `json:"name"` - Slug string `json:"slug"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Currency string `json:"currency"` - SubscriberType []string `json:"subscriber_type"` // Enum equivalent for CommerceProductSubscriberType - OwnerEntityType string `json:"owner_entity_type"` // Enum equivalent for CommerceProductOwnerEntity + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *[]string `json:"subscriber_type,omitempty"` + OwnerEntityType *string `json:"owner_entity_type,omitempty"` } -// CommerceProductWithPlans combines a product and its associated plans. type CommerceProductWithPlans struct { CommerceProduct - Plans []CommercePlan `json:"plans"` + Plans *[]CommercePlan `json:"plans,omitempty"` } -// CommerceCustomer represents a customer subscribing to a product. -type CommerceCustomer struct { - APIResource - AppID string `json:"app_id"` - CreatedAt time.Time `json:"created_at"` - EntityType string `json:"entity_type"` // Enum equivalent for CommerceProductSubscriberType - Entity struct { - ID string `json:"id"` - Name string `json:"name"` - ImageURL *string `json:"image_url,omitempty"` - } `json:"entity"` +type ListProductsByInstanceIDParams struct { + APIParams + ID *string `json:"id,omitempty"` } -// CommerceSubscription represents a subscription. -type CommerceSubscription struct { - APIResource - AppID string `json:"app_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Customer CommerceCustomer `json:"customer"` - Plan CommercePlan `json:"plan"` - Status string `json:"status"` // Enum equivalent for CommerceSubscriptionStatus - ToBeCancelledAt *time.Time `json:"to_be_cancelled_at,omitempty"` - LastInvoice *InvoiceSummary `json:"last_invoice,omitempty"` - NextInvoice *InvoiceSummary `json:"next_invoice,omitempty"` -} - -// InvoiceSummary is a reduced representation of an invoice. -type InvoiceSummary struct { - APIResource - DueAt time.Time `json:"due_at"` - Amount int64 `json:"amount"` - Status string `json:"status"` // Enum equivalent for CommerceInvoiceStatus +type ListCommerceProductsResponse struct { + APIParams + PaginatedList[CommerceProduct] } -// CommerceInvoice represents a detailed invoice. -type CommerceInvoice struct { - APIResource - AppID string `json:"app_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Subscription CommerceSubscription `json:"subscription"` - Amount int64 `json:"amount"` - Status string `json:"status"` // Enum equivalent for CommerceInvoiceStatus - DueAt time.Time `json:"due_at"` - FinalizingPaymentAttempt string `json:"finalizing_payment_attempt_id"` +// --- Plan Types --- + +type CreatePlanParams struct { + APIParams + Name *string `json:"name,omitempty"` + ProductID *string `json:"product_id,omitempty"` + BaseAmount *int64 `json:"base_amount,omitempty"` + IsRecurring *bool `json:"is_recurring,omitempty"` } -// CommercePaymentAttempt represents a payment attempt for an invoice. -type CommercePaymentAttempt struct { +type UpdatePlanParams struct { + APIParams + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` +} + +type GetPlanByIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type CommercePlan struct { APIResource - AppID string `json:"app_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Customer CommerceCustomer `json:"customer"` - Invoice CommerceInvoice `json:"invoice"` - Status string `json:"status"` // Enum equivalent for CommercePaymentAttemptStatus - Amount int64 `json:"amount"` + Name *string `json:"name,omitempty"` + ProductID *string `json:"product_id,omitempty"` + BaseAmount *int64 `json:"base_amount,omitempty"` + IsRecurring *bool `json:"is_recurring,omitempty"` + Period *string `json:"period,omitempty"` + Interval *int `json:"interval,omitempty"` + BillingCycles *int `json:"billing_cycles,omitempty"` + SubscriberCount *int64 `json:"subscriber_count,omitempty"` +} + +type ListPlansByInstanceIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +// --- Integration Types --- + +type CreateIntegrationParams struct { + APIParams + InstanceID *string `json:"instance_id,omitempty"` + Email *string `json:"email,omitempty"` + Type *string `json:"type,omitempty"` +} + +type UpdateIntegrationParams struct { + APIParams + CommerceIntegrationID *string `json:"id,omitempty"` + Status *string `json:"status,omitempty"` +} + +type GetIntegrationParams struct { + APIParams + IntegrationID *string `json:"id,omitempty"` } -// CommerceIntegration represents a response for integration creation. type CommerceIntegration struct { APIResource - AppID string `json:"app_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - IntegrationID string `json:"integration_id"` - IntegrationType string `json:"integration_type"` - Status string `json:"status"` + IntegrationID *string `json:"integration_id,omitempty"` + IntegrationType *string `json:"integration_type,omitempty"` + Status *string `json:"status,omitempty"` } -// CommerceIntegrationResponse represents the response for integration creation. type CommerceIntegrationResponse struct { APIResource - URL string `json:"url"` + URL *string `json:"url,omitempty"` } -// PaginatedList is a generic response for paginated resources. -type PaginatedList[T any] struct { +type ListCommerceIntegrationsResponse struct { + APIParams + PaginatedList[CommerceIntegration] +} + +type ListIntegrationsByInstanceIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +// --- Subscription Types --- + +type CreateSubscriptionParams struct { + APIParams + CustomerID *string `json:"customer_id,omitempty"` + PlanID *string `json:"plan_id,omitempty"` + Status *string `json:"status,omitempty"` +} + +type UpdateSubscriptionParams struct { + APIParams + ID *string `json:"id,omitempty"` + Status *string `json:"status,omitempty"` +} + +type GetSubscriptionByIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type ListSubscriptionsByInstanceIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type ListSubscriptionsByUserIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type CommerceSubscription struct { APIResource - Data []T `json:"data"` - TotalCount int64 `json:"total_count"` + Customer *CommerceCustomer `json:"customer,omitempty"` + Plan *CommercePlan `json:"plan,omitempty"` + Status *string `json:"status,omitempty"` } -// ListCommerceSubscriptionsResponse represents a paginated list of subscriptions. type ListCommerceSubscriptionsResponse struct { + APIParams PaginatedList[CommerceSubscription] } -// ListCommerceInvoicesResponse represents a paginated list of invoices. +// --- Invoice Types --- + +type CreateInvoiceParams struct { + APIParams + SubscriptionID *string `json:"subscription_id,omitempty"` + Amount *int64 `json:"amount,omitempty"` + DueAt *string `json:"due_at,omitempty"` +} + +type UpdateInvoiceParams struct { + APIParams + ID *string `json:"id,omitempty"` + Status *string `json:"status,omitempty"` +} + +type GetInvoiceByIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type ListInvoicesByInstanceIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type CommerceInvoice struct { + APIResource + Subscription *CommerceSubscription `json:"subscription,omitempty"` + Amount *int64 `json:"amount,omitempty"` + Status *string `json:"status,omitempty"` + DueAt *time.Time `json:"due_at,omitempty"` +} + type ListCommerceInvoicesResponse struct { + APIParams PaginatedList[CommerceInvoice] } -// ListCommercePaymentAttemptsResponse represents a paginated list of payment attempts. +// --- Payment Attempt Types --- + +type CreatePaymentAttemptParams struct { + APIParams + InvoiceID *string `json:"invoice_id,omitempty"` + Amount *int64 `json:"amount,omitempty"` + Status *string `json:"status,omitempty"` +} + +type UpdatePaymentAttemptParams struct { + APIParams + ID *string `json:"id,omitempty"` + Status *string `json:"status,omitempty"` +} + +type GetPaymentAttemptByIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type ListPaymentAttemptsByInstanceIDParams struct { + APIParams + ID *string `json:"id,omitempty"` +} + +type CommercePaymentAttempt struct { + APIResource + Invoice *CommerceInvoice `json:"invoice,omitempty"` + Amount *int64 `json:"amount,omitempty"` + Status *string `json:"status,omitempty"` +} + type ListCommercePaymentAttemptsResponse struct { + APIParams PaginatedList[CommercePaymentAttempt] } -// ListCommerceProductsResponse represents a paginated list of products. -type ListCommerceProductsResponse struct { - PaginatedList[CommerceProduct] +// --- Customer Types --- + +type CommerceCustomer struct { + Entity *struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + } `json:"entity,omitempty"` +} + +// --- Pagination Types --- + +type PaginatedList[T any] struct { + APIResource + Data *[]T `json:"data,omitempty"` + TotalCount *int64 `json:"total_count,omitempty"` } diff --git a/commerce/api.go b/commerce/api.go index 86b5393..513fe6b 100644 --- a/commerce/api.go +++ b/commerce/api.go @@ -8,69 +8,110 @@ import ( "github.com/clerk/clerk-sdk-go/v2" ) -// ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. -func ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { +// --- Subscriptions --- +func CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { + return getClient().CreateSubscription(ctx, params) +} + +func ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { return getClient().ListSubscriptionsByInstanceID(ctx, params) } -// ListSubscriptionsByUserID returns a list of subscriptions for a given user ID. -func ListSubscriptionsByUserID(ctx context.Context, params *ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { +func ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { return getClient().ListSubscriptionsByUserID(ctx, params) } -// GetSubscriptionByID retrieves a subscription by its ID. -func GetSubscriptionByID(ctx context.Context, params *GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { +func GetSubscriptionByID(ctx context.Context, params *clerk.GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { return getClient().GetSubscriptionByID(ctx, params) } -// ListInvoicesByInstanceID returns a list of invoices for a given instance ID. -func ListInvoicesByInstanceID(ctx context.Context, params *ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { +func UpdateSubscription(ctx context.Context, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { + return getClient().UpdateSubscription(ctx, params) +} + +// --- Invoices --- +func CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*clerk.CommerceInvoice, error) { + return getClient().CreateInvoice(ctx, params) +} + +func ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { return getClient().ListInvoicesByInstanceID(ctx, params) } -// GetInvoiceByID retrieves an invoice by its ID. -func GetInvoiceByID(ctx context.Context, params *GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { +func GetInvoiceByID(ctx context.Context, params *clerk.GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { return getClient().GetInvoiceByID(ctx, params) } -// ListPaymentAttemptsByInstanceID returns a list of payment attempts for a given instance ID. -func ListPaymentAttemptsByInstanceID(ctx context.Context, params *ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { +func UpdateInvoice(ctx context.Context, params *clerk.UpdateInvoiceParams) (*clerk.CommerceInvoice, error) { + return getClient().UpdateInvoice(ctx, params) +} + +// --- Payment Attempts --- +func CreatePaymentAttempt(ctx context.Context, params *clerk.CreatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { + return getClient().CreatePaymentAttempt(ctx, params) +} + +func ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { return getClient().ListPaymentAttemptsByInstanceID(ctx, params) } -// GetPaymentAttemptByID retrieves a payment attempt by its ID. -func GetPaymentAttemptByID(ctx context.Context, params *GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { +func GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { return getClient().GetPaymentAttemptByID(ctx, params) } -// ListProductsByInstanceID returns a list of products for a given instance ID. -func ListProductsByInstanceID(ctx context.Context, params *ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { +func UpdatePaymentAttempt(ctx context.Context, params *clerk.UpdatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { + return getClient().UpdatePaymentAttempt(ctx, params) +} + +// --- Products --- +func CreateProduct(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { + return getClient().CreateProduct(ctx, params) +} + +func ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { return getClient().ListProductsByInstanceID(ctx, params) } -// GetPlanByID retrieves a plan by its ID. -func GetPlanByID(ctx context.Context, params *GetPlanByIDParams) (*clerk.CommercePlan, error) { +func GetProductByID(ctx context.Context, params *clerk.GetProductByIDParams) (*clerk.CommerceProduct, error) { + return getClient().GetProductByID(ctx, params) +} + +func UpdateProduct(ctx context.Context, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { + return getClient().UpdateProduct(ctx, params) +} + +// --- Plans --- +func CreatePlan(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { + return getClient().CreatePlan(ctx, params) +} + +func ListPlansByInstanceID(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { + return getClient().ListPlansByInstanceID(ctx, params) +} + +func GetPlanByID(ctx context.Context, params *clerk.GetPlanByIDParams) (*clerk.CommercePlan, error) { return getClient().GetPlanByID(ctx, params) } -// CreateIntegration creates a new integration for the specified instance. -func CreateIntegration(ctx context.Context, params *CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { +func UpdatePlan(ctx context.Context, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { + return getClient().UpdatePlan(ctx, params) +} + +// --- Integrations --- +func CreateIntegration(ctx context.Context, params *clerk.CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { return getClient().CreateIntegration(ctx, params) } -// UpdateCommerceIntegration updates an existing commerce integration's status. -func UpdateIntegration(ctx context.Context, params *UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - return getClient().UpdateIntegration(ctx, params) +func ListIntegrationsByInstanceID(ctx context.Context, params *clerk.ListIntegrationsByInstanceIDParams) (*clerk.ListCommerceIntegrationsResponse, error) { + return getClient().ListIntegrationsByInstanceID(ctx, params) } -// GetIntegration retrieves a specific integration by its ID. -func GetIntegration(ctx context.Context, params *GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { +func GetIntegration(ctx context.Context, params *clerk.GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { return getClient().GetIntegration(ctx, params) } -// GetProductByID retrieves an Product by its ID. -func GetProductByID(ctx context.Context, params *GetProductByIDParams) (*clerk.CommerceProduct, error) { - return getClient().GetProductByID(ctx, params) +func UpdateIntegration(ctx context.Context, params *clerk.UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + return getClient().UpdateIntegration(ctx, params) } func getClient() *Client { diff --git a/commerce/client.go b/commerce/client.go index 97d002b..45fa011 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -1,4 +1,3 @@ -// Package commerce provides the Commerce API. package commerce import ( @@ -32,244 +31,295 @@ func NewClient(config *clerk.ClientConfig) *Client { } } -// Subscriptions - -type ListSubscriptionsByInstanceIDParams struct { - clerk.APIParams - ID string `json:"-"` +// --- Subscriptions --- +func (c *Client) CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { + reqPath, err := clerk.JoinPath(path, subscriptionsPath) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceSubscription{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// ListSubscriptionsByInstanceID returns a list of subscriptions for a given instance ID. -func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - path, err := clerk.JoinPath(path, subscriptionsPath, params.ID) +func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + reqPath, err := clerk.JoinPath(path, subscriptionsPath, "instance", *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.ListCommerceSubscriptionsResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } -type ListSubscriptionsByUserIDParams struct { - clerk.APIParams - ID string `json:"-"` -} - -// ListSubscriptionsByUserID returns a list of subscriptions for a given user ID. -func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - path, err := clerk.JoinPath(path, subscriptionsPath, "user", params.ID) +func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + reqPath, err := clerk.JoinPath(path, subscriptionsPath, "user", *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.ListCommerceSubscriptionsResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } -type GetSubscriptionByIDParams struct { - clerk.APIParams - ID string `json:"-"` +func (c *Client) GetSubscriptionByID(ctx context.Context, params *clerk.GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { + reqPath, err := clerk.JoinPath(path, subscriptionsPath, *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceSubscription{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// GetSubscriptionByID retrieves a subscription by its ID. -func (c *Client) GetSubscriptionByID(ctx context.Context, params *GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { - path, err := clerk.JoinPath(path, subscriptionsPath, params.ID) +func (c *Client) UpdateSubscription(ctx context.Context, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { + reqPath, err := clerk.JoinPath(path, subscriptionsPath, *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) resource := &clerk.CommerceSubscription{} err = c.Backend.Call(ctx, req, resource) return resource, err } -// Invoices - -type ListInvoicesByInstanceIDParams struct { - clerk.APIParams - ID string `json:"-"` +// --- Invoices --- +func (c *Client) CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*clerk.CommerceInvoice, error) { + reqPath, err := clerk.JoinPath(path, invoicesPath) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceInvoice{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// ListInvoicesByInstanceID returns a list of invoices for a given instance ID. -func (c *Client) ListInvoicesByInstanceID(ctx context.Context, params *ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { - path, err := clerk.JoinPath(path, invoicesPath, "instance", params.ID) +func (c *Client) ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { + reqPath, err := clerk.JoinPath(path, invoicesPath, "instance", *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.ListCommerceInvoicesResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } -type GetInvoiceByIDParams struct { - clerk.APIParams - ID string `json:"-"` +func (c *Client) GetInvoiceByID(ctx context.Context, params *clerk.GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { + reqPath, err := clerk.JoinPath(path, invoicesPath, *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceInvoice{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// GetInvoiceByID retrieves an invoice by its ID. -func (c *Client) GetInvoiceByID(ctx context.Context, params *GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { - path, err := clerk.JoinPath(path, invoicesPath, params.ID) +func (c *Client) UpdateInvoice(ctx context.Context, params *clerk.UpdateInvoiceParams) (*clerk.CommerceInvoice, error) { + reqPath, err := clerk.JoinPath(path, invoicesPath, *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) resource := &clerk.CommerceInvoice{} err = c.Backend.Call(ctx, req, resource) return resource, err } -// Payment Attempts - -type ListPaymentAttemptsByInstanceIDParams struct { - clerk.APIParams - ID string `json:"-"` +// --- Payment Attempts --- +func (c *Client) CreatePaymentAttempt(ctx context.Context, params *clerk.CreatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { + reqPath, err := clerk.JoinPath(path, paymentAttemptsPath) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommercePaymentAttempt{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// ListPaymentAttemptsByInstanceID returns a list of payment attempts for a given instance ID. -func (c *Client) ListPaymentAttemptsByInstanceID(ctx context.Context, params *ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { - path, err := clerk.JoinPath(path, paymentAttemptsPath, "instance", params.ID) +func (c *Client) ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { + reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, "instance", *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.ListCommercePaymentAttemptsResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } -type GetPaymentAttemptByIDParams struct { - clerk.APIParams - ID string `json:"-"` +func (c *Client) GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { + reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommercePaymentAttempt{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// GetPaymentAttemptByID retrieves a payment attempt by its ID. -func (c *Client) GetPaymentAttemptByID(ctx context.Context, params *GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { - path, err := clerk.JoinPath(path, paymentAttemptsPath, params.ID) +func (c *Client) UpdatePaymentAttempt(ctx context.Context, params *clerk.UpdatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { + reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) resource := &clerk.CommercePaymentAttempt{} err = c.Backend.Call(ctx, req, resource) return resource, err } -// Products - -type ListProductsByInstanceIDParams struct { - clerk.APIParams - ID string `json:"-"` +// --- Products --- +func (c *Client) CreateProduct(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { + reqPath, err := clerk.JoinPath(path, productsPath) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceProduct{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// ListProductsByInstanceID returns a list of products for a given instance ID. -func (c *Client) ListProductsByInstanceID(ctx context.Context, params *ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - path, err := clerk.JoinPath(path, productsPath, "instance", params.ID) +func (c *Client) ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { + reqPath, err := clerk.JoinPath(path, productsPath, "instance", *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.ListCommerceProductsResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } -// Plans +func (c *Client) GetProductByID(ctx context.Context, params *clerk.GetProductByIDParams) (*clerk.CommerceProduct, error) { + reqPath, err := clerk.JoinPath(path, productsPath, *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceProduct{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} -type GetPlanByIDParams struct { - clerk.APIParams - ID string `json:"-"` +func (c *Client) UpdateProduct(ctx context.Context, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { + reqPath, err := clerk.JoinPath(path, productsPath, *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommerceProduct{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// GetPlanByID retrieves a plan by its ID. -func (c *Client) GetPlanByID(ctx context.Context, params *GetPlanByIDParams) (*clerk.CommercePlan, error) { - path, err := clerk.JoinPath(path, plansPath, params.ID) +// --- Plans --- +func (c *Client) CreatePlan(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { + reqPath, err := clerk.JoinPath(path, plansPath) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) resource := &clerk.CommercePlan{} err = c.Backend.Call(ctx, req, resource) return resource, err } -// Integrations - -type CreateIntegrationParams struct { - clerk.APIParams - InstanceID string `json:"instance_id"` - Email string `json:"email"` - Type string `json:"type"` +func (c *Client) ListPlansByInstanceID(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { + reqPath, err := clerk.JoinPath(path, plansPath, "instance", *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.ListCommerceProductsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// CreateIntegration creates a new integration for the specified instance. -func (c *Client) CreateIntegration(ctx context.Context, params *CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - path, err := clerk.JoinPath(path, integrationsPath) +func (c *Client) GetPlanByID(ctx context.Context, params *clerk.GetPlanByIDParams) (*clerk.CommercePlan, error) { + reqPath, err := clerk.JoinPath(path, plansPath, *params.ID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodPost, path) - req.SetParams(params) - resource := &clerk.CommerceIntegrationResponse{} + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommercePlan{} err = c.Backend.Call(ctx, req, resource) return resource, err } -// UpdateCommerceIntegrationParams represents the parameters for updating a commerce integration. -type UpdateIntegrationParams struct { - clerk.APIParams - CommerceIntegrationID string `json:"-"` - Status string `json:"status"` +func (c *Client) UpdatePlan(ctx context.Context, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { + reqPath, err := clerk.JoinPath(path, plansPath, *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommercePlan{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// UpdateCommerceIntegration updates an existing commerce integration's status. -func (c *Client) UpdateIntegration(ctx context.Context, params *UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - path, err := clerk.JoinPath(path, integrationsPath, params.CommerceIntegrationID) +// --- Integrations --- +func (c *Client) CreateIntegration(ctx context.Context, params *clerk.CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + reqPath, err := clerk.JoinPath(path, integrationsPath) if err != nil { return nil, err } - - req := clerk.NewAPIRequest(http.MethodPut, path) + req := clerk.NewAPIRequest(http.MethodPost, reqPath) req.SetParams(params) resource := &clerk.CommerceIntegrationResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } -// GetIntegrationParams represents the parameters for retrieving a commerce integration by ID. -type GetIntegrationParams struct { - clerk.APIParams - IntegrationID string `json:"-"` +func (c *Client) ListIntegrationsByInstanceID(ctx context.Context, params *clerk.ListIntegrationsByInstanceIDParams) (*clerk.ListCommerceIntegrationsResponse, error) { + reqPath, err := clerk.JoinPath(path, integrationsPath, "instance", *params.ID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.ListCommerceIntegrationsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err } -// GetIntegration retrieves a specific integration by its ID. -func (c *Client) GetIntegration(ctx context.Context, params *GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - path, err := clerk.JoinPath(path, integrationsPath, params.IntegrationID) +func (c *Client) GetIntegration(ctx context.Context, params *clerk.GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + reqPath, err := clerk.JoinPath(path, integrationsPath, *params.IntegrationID) if err != nil { return nil, err } - - req := clerk.NewAPIRequest(http.MethodGet, path) + req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.CommerceIntegrationResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } -type GetProductByIDParams struct { - clerk.APIParams - ID string `json:"-"` -} - -// GetProductByID retrieves an Product by its ID. -func (c *Client) GetProductByID(ctx context.Context, params *GetProductByIDParams) (*clerk.CommerceProduct, error) { - path, err := clerk.JoinPath(path, productsPath, params.ID) +func (c *Client) UpdateIntegration(ctx context.Context, params *clerk.UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { + reqPath, err := clerk.JoinPath(path, integrationsPath, *params.CommerceIntegrationID) if err != nil { return nil, err } - req := clerk.NewAPIRequest(http.MethodGet, path) - resource := &clerk.CommerceProduct{} + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommerceIntegrationResponse{} err = c.Backend.Call(ctx, req, resource) return resource, err } From 1838d992085d2cd09ea533f1833b52b9f36b2ff6 Mon Sep 17 00:00:00 2001 From: Michael Osuna Jr Date: Thu, 21 Nov 2024 03:11:19 -0800 Subject: [PATCH 07/36] chore: fixup some of the type definitions in commerce --- commerce.go | 55 +++++++++++++++++++++++----------------------- commerce/client.go | 8 +++---- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/commerce.go b/commerce.go index 4ebbbea..8287a87 100644 --- a/commerce.go +++ b/commerce.go @@ -1,55 +1,55 @@ package clerk -import "time" +import ( + "time" +) // --- Product Types --- type CreateProductParams struct { APIParams - InstanceID *string `json:"instance_id,omitempty"` - Name *string `json:"name,omitempty"` - Slug *string `json:"slug,omitempty"` - Currency *string `json:"currency,omitempty"` - SubscriberType *[]string `json:"subscriber_type,omitempty"` - OwnerEntityType *string `json:"owner_entity_type,omitempty"` + InstanceID string `json:"instance_id"` + Name string `json:"name"` + Slug string `json:"slug"` + Currency string `json:"currency"` + SubscriberType string `json:"subscriber_type"` } type UpdateProductParams struct { APIParams - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Slug *string `json:"slug,omitempty"` - Currency *string `json:"currency,omitempty"` - SubscriberType *[]string `json:"subscriber_type,omitempty"` - OwnerEntityType *string `json:"owner_entity_type,omitempty"` + ID string `json:"id"` + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *string `json:"subscriber_type,omitempty"` } type GetProductByIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type CommerceProduct struct { APIResource - Name *string `json:"name,omitempty"` - Slug *string `json:"slug,omitempty"` - Currency *string `json:"currency,omitempty"` - SubscriberType *[]string `json:"subscriber_type,omitempty"` - OwnerEntityType *string `json:"owner_entity_type,omitempty"` + Name string `json:"name"` + Slug string `json:"slug"` + Currency string `json:"currency"` + SubscriberType string `json:"subscriber_type"` + OwnerEntityType string `json:"owner_entity_type"` } type CommerceProductWithPlans struct { CommerceProduct - Plans *[]CommercePlan `json:"plans,omitempty"` + Plans []CommercePlan `json:"plans"` } type ListProductsByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type ListCommerceProductsResponse struct { - APIParams + APIResource PaginatedList[CommerceProduct] } @@ -124,7 +124,7 @@ type CommerceIntegrationResponse struct { } type ListCommerceIntegrationsResponse struct { - APIParams + APIResource PaginatedList[CommerceIntegration] } @@ -171,7 +171,7 @@ type CommerceSubscription struct { } type ListCommerceSubscriptionsResponse struct { - APIParams + APIResource PaginatedList[CommerceSubscription] } @@ -209,7 +209,7 @@ type CommerceInvoice struct { } type ListCommerceInvoicesResponse struct { - APIParams + APIResource PaginatedList[CommerceInvoice] } @@ -224,7 +224,7 @@ type CreatePaymentAttemptParams struct { type UpdatePaymentAttemptParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` Status *string `json:"status,omitempty"` } @@ -246,7 +246,7 @@ type CommercePaymentAttempt struct { } type ListCommercePaymentAttemptsResponse struct { - APIParams + APIResource PaginatedList[CommercePaymentAttempt] } @@ -262,7 +262,6 @@ type CommerceCustomer struct { // --- Pagination Types --- type PaginatedList[T any] struct { - APIResource Data *[]T `json:"data,omitempty"` TotalCount *int64 `json:"total_count,omitempty"` } diff --git a/commerce/client.go b/commerce/client.go index 45fa011..11f318e 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -172,7 +172,7 @@ func (c *Client) GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPay } func (c *Client) UpdatePaymentAttempt(ctx context.Context, params *clerk.UpdatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, *params.ID) + reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, params.ID) if err != nil { return nil, err } @@ -197,7 +197,7 @@ func (c *Client) CreateProduct(ctx context.Context, params *clerk.CreateProductP } func (c *Client) ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - reqPath, err := clerk.JoinPath(path, productsPath, "instance", *params.ID) + reqPath, err := clerk.JoinPath(path, productsPath, "instance", params.ID) if err != nil { return nil, err } @@ -208,7 +208,7 @@ func (c *Client) ListProductsByInstanceID(ctx context.Context, params *clerk.Lis } func (c *Client) GetProductByID(ctx context.Context, params *clerk.GetProductByIDParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath, *params.ID) + reqPath, err := clerk.JoinPath(path, productsPath, params.ID) if err != nil { return nil, err } @@ -219,7 +219,7 @@ func (c *Client) GetProductByID(ctx context.Context, params *clerk.GetProductByI } func (c *Client) UpdateProduct(ctx context.Context, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath, *params.ID) + reqPath, err := clerk.JoinPath(path, productsPath, params.ID) if err != nil { return nil, err } From d353362d4cf277cff2e1eb7b3635d06354b88186 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Thu, 21 Nov 2024 11:36:30 +0000 Subject: [PATCH 08/36] chore: fake data for subscription --- commerce/client.go | 50 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/commerce/client.go b/commerce/client.go index 45fa011..1d134f4 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -2,6 +2,7 @@ package commerce import ( "context" + "log" "net/http" "github.com/clerk/clerk-sdk-go/v2" @@ -52,7 +53,54 @@ func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *cler req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.ListCommerceSubscriptionsResponse{} err = c.Backend.Call(ctx, req, resource) - return resource, err + log.Default().Println("resource", resource) + // Fake data for testing + fakeSubscriptions := []clerk.CommerceSubscription{ + { + APIResource: clerk.APIResource{}, // Fill in with appropriate resource metadata if needed + Customer: &clerk.CommerceCustomer{ + Entity: &struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + }{ + ID: clerk.String("customer_1"), + Name: clerk.String("John Doe"), + }, + }, + Plan: &clerk.CommercePlan{ + Name: clerk.String("Basic Plan"), + BaseAmount: clerk.Int64(1000), + IsRecurring: clerk.Bool(true), + }, + Status: clerk.String("active"), + }, + { + APIResource: clerk.APIResource{}, + Customer: &clerk.CommerceCustomer{ + Entity: &struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + }{ + ID: clerk.String("customer_2"), + Name: clerk.String("Jane Smith"), + }, + }, + Plan: &clerk.CommercePlan{ + Name: clerk.String("Pro Plan"), + BaseAmount: clerk.Int64(2000), + IsRecurring: clerk.Bool(true), + }, + Status: clerk.String("inactive"), + }, + } + + return &clerk.ListCommerceSubscriptionsResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommerceSubscription]{ + Data: &fakeSubscriptions, + TotalCount: clerk.Int64(int64(len(fakeSubscriptions))), + }, + }, nil + // return resource, err } func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { From 3d0b37bdbf770374c022e01a728a079fc818021a Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Thu, 21 Nov 2024 15:27:05 +0000 Subject: [PATCH 09/36] feat: faked data for now --- commerce/client.go | 434 ++++++++++++++++++++++----------------------- 1 file changed, 213 insertions(+), 221 deletions(-) diff --git a/commerce/client.go b/commerce/client.go index 4b64089..c364203 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -2,8 +2,7 @@ package commerce import ( "context" - "log" - "net/http" + "time" "github.com/clerk/clerk-sdk-go/v2" ) @@ -32,32 +31,35 @@ func NewClient(config *clerk.ClientConfig) *Client { } } +// Helper function for creating a *time.Time from a time.Time +func TimePtr(t time.Time) *time.Time { + return &t +} + // --- Subscriptions --- func (c *Client) CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceSubscription{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceSubscription{ + Customer: &clerk.CommerceCustomer{ + Entity: &struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + }{ + ID: clerk.String("customer_123"), + Name: clerk.String("Alice Smith"), + }, + }, + Plan: &clerk.CommercePlan{ + Name: clerk.String("Basic Plan"), + BaseAmount: clerk.Int64(1000), + IsRecurring: clerk.Bool(true), + }, + Status: clerk.String("active"), + }, nil } func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, "instance", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceSubscriptionsResponse{} - err = c.Backend.Call(ctx, req, resource) - log.Default().Println("resource", resource) - // Fake data for testing fakeSubscriptions := []clerk.CommerceSubscription{ { - APIResource: clerk.APIResource{}, // Fill in with appropriate resource metadata if needed Customer: &clerk.CommerceCustomer{ Entity: &struct { ID *string `json:"id,omitempty"` @@ -68,21 +70,31 @@ func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *cler }, }, Plan: &clerk.CommercePlan{ - Name: clerk.String("Basic Plan"), - BaseAmount: clerk.Int64(1000), + Name: clerk.String("Starter Plan"), + BaseAmount: clerk.Int64(1500), IsRecurring: clerk.Bool(true), }, Status: clerk.String("active"), }, + } + return &clerk.ListCommerceSubscriptionsResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommerceSubscription]{ + Data: &fakeSubscriptions, + TotalCount: clerk.Int64(1), + }, + }, nil +} + +func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + fakeSubscriptions := []clerk.CommerceSubscription{ { - APIResource: clerk.APIResource{}, Customer: &clerk.CommerceCustomer{ Entity: &struct { ID *string `json:"id,omitempty"` Name *string `json:"name,omitempty"` }{ ID: clerk.String("customer_2"), - Name: clerk.String("Jane Smith"), + Name: clerk.String("Jane Doe"), }, }, Plan: &clerk.CommercePlan{ @@ -93,281 +105,261 @@ func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *cler Status: clerk.String("inactive"), }, } - return &clerk.ListCommerceSubscriptionsResponse{ PaginatedList: clerk.PaginatedList[clerk.CommerceSubscription]{ Data: &fakeSubscriptions, - TotalCount: clerk.Int64(int64(len(fakeSubscriptions))), + TotalCount: clerk.Int64(1), }, }, nil - // return resource, err -} - -func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, "user", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceSubscriptionsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err } func (c *Client) GetSubscriptionByID(ctx context.Context, params *clerk.GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceSubscription{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceSubscription{ + Customer: &clerk.CommerceCustomer{ + Entity: &struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + }{ + ID: clerk.String("customer_123"), + Name: clerk.String("Alice Smith"), + }, + }, + Plan: &clerk.CommercePlan{ + Name: clerk.String("Premium Plan"), + BaseAmount: clerk.Int64(3000), + IsRecurring: clerk.Bool(true), + }, + Status: clerk.String("active"), + }, nil } func (c *Client) UpdateSubscription(ctx context.Context, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceSubscription{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceSubscription{ + Customer: &clerk.CommerceCustomer{ + Entity: &struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + }{ + ID: clerk.String("customer_123"), + Name: clerk.String("Alice Smith"), + }, + }, + Plan: &clerk.CommercePlan{ + Name: clerk.String("Updated Plan"), + BaseAmount: clerk.Int64(3500), + IsRecurring: clerk.Bool(true), + }, + Status: clerk.String("updated"), + }, nil } // --- Invoices --- func (c *Client) CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*clerk.CommerceInvoice, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceInvoice{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceInvoice{ + Subscription: &clerk.CommerceSubscription{ + Status: clerk.String("active"), + }, + Amount: clerk.Int64(1000), + Status: clerk.String("unpaid"), + DueAt: TimePtr(time.Now().Add(7 * 24 * time.Hour)), + }, nil } func (c *Client) ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath, "instance", *params.ID) - if err != nil { - return nil, err + fakeInvoices := []clerk.CommerceInvoice{ + { + Amount: clerk.Int64(5000), + Status: clerk.String("paid"), + DueAt: TimePtr(time.Now().Add(14 * 24 * time.Hour)), + }, } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceInvoicesResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.ListCommerceInvoicesResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommerceInvoice]{ + Data: &fakeInvoices, + TotalCount: clerk.Int64(1), + }, + }, nil } func (c *Client) GetInvoiceByID(ctx context.Context, params *clerk.GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceInvoice{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceInvoice{ + Amount: clerk.Int64(7000), + Status: clerk.String("due"), + DueAt: TimePtr(time.Now().Add(5 * 24 * time.Hour)), + }, nil } func (c *Client) UpdateInvoice(ctx context.Context, params *clerk.UpdateInvoiceParams) (*clerk.CommerceInvoice, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceInvoice{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceInvoice{ + Amount: clerk.Int64(8000), + Status: clerk.String("overdue"), + DueAt: TimePtr(time.Now().Add(-2 * 24 * time.Hour)), + }, nil } // --- Payment Attempts --- func (c *Client) CreatePaymentAttempt(ctx context.Context, params *clerk.CreatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommercePaymentAttempt{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommercePaymentAttempt{ + Amount: clerk.Int64(1000), + Status: clerk.String("failed"), + }, nil } func (c *Client) ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, "instance", *params.ID) - if err != nil { - return nil, err + fakePaymentAttempts := []clerk.CommercePaymentAttempt{ + { + Amount: clerk.Int64(5000), + Status: clerk.String("success"), + }, } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommercePaymentAttemptsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.ListCommercePaymentAttemptsResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommercePaymentAttempt]{ + Data: &fakePaymentAttempts, + TotalCount: clerk.Int64(1), + }, + }, nil } func (c *Client) GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommercePaymentAttempt{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommercePaymentAttempt{ + Amount: clerk.Int64(3000), + Status: clerk.String("pending"), + }, nil } func (c *Client) UpdatePaymentAttempt(ctx context.Context, params *clerk.UpdatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommercePaymentAttempt{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommercePaymentAttempt{ + Amount: clerk.Int64(4000), + Status: clerk.String("refunded"), + }, nil } // --- Products --- func (c *Client) CreateProduct(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceProduct{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceProduct{ + Name: *clerk.String("New Product"), + Currency: *clerk.String("USD"), + SubscriberType: *clerk.String("individual"), + OwnerEntityType: *clerk.String("business"), + }, nil } func (c *Client) ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - reqPath, err := clerk.JoinPath(path, productsPath, "instance", params.ID) - if err != nil { - return nil, err + fakeProducts := []clerk.CommerceProduct{ + { + Name: *clerk.String("Product 1"), + Currency: *clerk.String("USD"), + SubscriberType: *clerk.String("organization"), + OwnerEntityType: *clerk.String("enterprise"), + }, } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceProductsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.ListCommerceProductsResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommerceProduct]{ + Data: &fakeProducts, + TotalCount: clerk.Int64(1), + }, + }, nil } func (c *Client) GetProductByID(ctx context.Context, params *clerk.GetProductByIDParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath, params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceProduct{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceProduct{ + Name: *clerk.String("Specific Product"), + Currency: *clerk.String("EUR"), + SubscriberType: *clerk.String("group"), + OwnerEntityType: *clerk.String("nonprofit"), + }, nil } func (c *Client) UpdateProduct(ctx context.Context, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath, params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceProduct{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceProduct{ + Name: *clerk.String("Updated Product"), + Currency: *clerk.String("GBP"), + SubscriberType: *clerk.String("individual"), + OwnerEntityType: *clerk.String("corporate"), + }, nil } // --- Plans --- func (c *Client) CreatePlan(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { - reqPath, err := clerk.JoinPath(path, plansPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommercePlan{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommercePlan{ + Name: clerk.String("Basic Plan"), + BaseAmount: clerk.Int64(1200), + IsRecurring: clerk.Bool(true), + }, nil } func (c *Client) ListPlansByInstanceID(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - reqPath, err := clerk.JoinPath(path, plansPath, "instance", *params.ID) - if err != nil { - return nil, err + fakeProducts := []clerk.CommerceProduct{ + { + Name: *clerk.String("Product A"), + Slug: *clerk.String("product-a"), + Currency: *clerk.String("USD"), + SubscriberType: "individual", + OwnerEntityType: *clerk.String("business"), + }, + { + Name: *clerk.String("Product B"), + Slug: *clerk.String("product-b"), + Currency: *clerk.String("EUR"), + SubscriberType: "organization", + OwnerEntityType: *clerk.String("enterprise"), + }, } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceProductsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.ListCommerceProductsResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommerceProduct]{ + Data: &fakeProducts, // Ensure this is a slice of CommerceProduct + TotalCount: clerk.Int64(int64(len(fakeProducts))), // Adjust the count based on the slice + }, + }, nil } func (c *Client) GetPlanByID(ctx context.Context, params *clerk.GetPlanByIDParams) (*clerk.CommercePlan, error) { - reqPath, err := clerk.JoinPath(path, plansPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommercePlan{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommercePlan{ + Name: clerk.String("Exclusive Plan"), + BaseAmount: clerk.Int64(5000), + IsRecurring: clerk.Bool(false), + }, nil } func (c *Client) UpdatePlan(ctx context.Context, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { - reqPath, err := clerk.JoinPath(path, plansPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommercePlan{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommercePlan{ + Name: clerk.String("Updated Plan"), + BaseAmount: clerk.Int64(5500), + IsRecurring: clerk.Bool(true), + }, nil } // --- Integrations --- func (c *Client) CreateIntegration(ctx context.Context, params *clerk.CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceIntegrationResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceIntegrationResponse{ + URL: clerk.String("https://fake-integration-url.com"), + }, nil } func (c *Client) ListIntegrationsByInstanceID(ctx context.Context, params *clerk.ListIntegrationsByInstanceIDParams) (*clerk.ListCommerceIntegrationsResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath, "instance", *params.ID) - if err != nil { - return nil, err + fakeIntegrations := []clerk.CommerceIntegration{ + { + IntegrationID: clerk.String("int_123"), + IntegrationType: clerk.String("type_a"), + Status: clerk.String("active"), + }, } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceIntegrationsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.ListCommerceIntegrationsResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommerceIntegration]{ + Data: &fakeIntegrations, + TotalCount: clerk.Int64(1), + }, + }, nil } func (c *Client) GetIntegration(ctx context.Context, params *clerk.GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath, *params.IntegrationID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceIntegrationResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceIntegrationResponse{ + URL: clerk.String("https://fake-integration-detail.com"), + }, nil } func (c *Client) UpdateIntegration(ctx context.Context, params *clerk.UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath, *params.CommerceIntegrationID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceIntegrationResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err + return &clerk.CommerceIntegrationResponse{ + URL: clerk.String("https://fake-integration-updated.com"), + }, nil } From dcef501d974bf4ae78c4b6cb4c289e76645398e8 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Thu, 21 Nov 2024 16:23:24 +0000 Subject: [PATCH 10/36] feat: better fake data --- commerce.go | 169 ++++++++++++++++------------- commerce/api.go | 1 + commerce/client.go | 259 ++++++++++++++++++++++++++------------------- 3 files changed, 245 insertions(+), 184 deletions(-) diff --git a/commerce.go b/commerce.go index 8287a87..be69238 100644 --- a/commerce.go +++ b/commerce.go @@ -8,20 +8,22 @@ import ( type CreateProductParams struct { APIParams - InstanceID string `json:"instance_id"` - Name string `json:"name"` - Slug string `json:"slug"` - Currency string `json:"currency"` - SubscriberType string `json:"subscriber_type"` + InstanceID string `json:"instance_id"` + Name string `json:"name"` + Slug string `json:"slug"` + Currency string `json:"currency"` + SubscriberType []string `json:"subscriber_type"` + OwnerEntityType string `json:"owner_entity_type"` } type UpdateProductParams struct { APIParams - ID string `json:"id"` - Name *string `json:"name,omitempty"` - Slug *string `json:"slug,omitempty"` - Currency *string `json:"currency,omitempty"` - SubscriberType *string `json:"subscriber_type,omitempty"` + ID string `json:"id"` + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *[]string `json:"subscriber_type,omitempty"` + OwnerEntityType *string `json:"owner_entity_type,omitempty"` } type GetProductByIDParams struct { @@ -31,11 +33,14 @@ type GetProductByIDParams struct { type CommerceProduct struct { APIResource - Name string `json:"name"` - Slug string `json:"slug"` - Currency string `json:"currency"` - SubscriberType string `json:"subscriber_type"` - OwnerEntityType string `json:"owner_entity_type"` + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Currency string `json:"currency"` + SubscriberType []string `json:"subscriber_type"` + OwnerEntityType string `json:"owner_entity_type"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type CommerceProductWithPlans struct { @@ -57,70 +62,74 @@ type ListCommerceProductsResponse struct { type CreatePlanParams struct { APIParams - Name *string `json:"name,omitempty"` - ProductID *string `json:"product_id,omitempty"` - BaseAmount *int64 `json:"base_amount,omitempty"` - IsRecurring *bool `json:"is_recurring,omitempty"` + Name string `json:"name"` + ProductID string `json:"product_id"` + BaseAmount int64 `json:"base_amount"` + IsRecurring bool `json:"is_recurring"` } type UpdatePlanParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` Name *string `json:"name,omitempty"` } type GetPlanByIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type CommercePlan struct { APIResource - Name *string `json:"name,omitempty"` - ProductID *string `json:"product_id,omitempty"` - BaseAmount *int64 `json:"base_amount,omitempty"` - IsRecurring *bool `json:"is_recurring,omitempty"` - Period *string `json:"period,omitempty"` - Interval *int `json:"interval,omitempty"` - BillingCycles *int `json:"billing_cycles,omitempty"` - SubscriberCount *int64 `json:"subscriber_count,omitempty"` + ID string `json:"id"` + Name string `json:"name"` + Product CommerceProduct `json:"product"` + BaseAmount int64 `json:"base_amount"` + IsRecurring bool `json:"is_recurring"` + IsProrated bool `json:"is_prorated"` + Period string `json:"period"` // e.g., "month" or "year" + Interval int `json:"interval"` + BillingCycles *int `json:"billing_cycles,omitempty"` + SubscriberCount int64 `json:"subscriber_count"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type ListPlansByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } // --- Integration Types --- type CreateIntegrationParams struct { APIParams - InstanceID *string `json:"instance_id,omitempty"` - Email *string `json:"email,omitempty"` - Type *string `json:"type,omitempty"` + InstanceID string `json:"instance_id"` + Email string `json:"email"` + Type string `json:"type"` } type UpdateIntegrationParams struct { APIParams - CommerceIntegrationID *string `json:"id,omitempty"` - Status *string `json:"status,omitempty"` + CommerceIntegrationID string `json:"id"` + Status string `json:"status"` } type GetIntegrationParams struct { APIParams - IntegrationID *string `json:"id,omitempty"` + IntegrationID string `json:"id"` } type CommerceIntegration struct { APIResource - IntegrationID *string `json:"integration_id,omitempty"` - IntegrationType *string `json:"integration_type,omitempty"` - Status *string `json:"status,omitempty"` + IntegrationID string `json:"integration_id"` + IntegrationType string `json:"integration_type"` + Status string `json:"status"` } type CommerceIntegrationResponse struct { APIResource - URL *string `json:"url,omitempty"` + URL string `json:"url"` } type ListCommerceIntegrationsResponse struct { @@ -130,44 +139,50 @@ type ListCommerceIntegrationsResponse struct { type ListIntegrationsByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } // --- Subscription Types --- type CreateSubscriptionParams struct { APIParams - CustomerID *string `json:"customer_id,omitempty"` - PlanID *string `json:"plan_id,omitempty"` - Status *string `json:"status,omitempty"` + CustomerID string `json:"customer_id"` + PlanID string `json:"plan_id"` + Status string `json:"status"` } type UpdateSubscriptionParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` Status *string `json:"status,omitempty"` } type GetSubscriptionByIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type ListSubscriptionsByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type ListSubscriptionsByUserIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type CommerceSubscription struct { APIResource - Customer *CommerceCustomer `json:"customer,omitempty"` - Plan *CommercePlan `json:"plan,omitempty"` - Status *string `json:"status,omitempty"` + ID string `json:"id"` + AppID string `json:"app_id"` + Customer CommerceCustomer `json:"customer"` + Plan CommercePlan `json:"plan"` + Status string `json:"status"` + LastInvoice *CommerceInvoice `json:"last_invoice,omitempty"` + NextInvoice *CommerceInvoice `json:"next_invoice,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type ListCommerceSubscriptionsResponse struct { @@ -179,33 +194,35 @@ type ListCommerceSubscriptionsResponse struct { type CreateInvoiceParams struct { APIParams - SubscriptionID *string `json:"subscription_id,omitempty"` - Amount *int64 `json:"amount,omitempty"` - DueAt *string `json:"due_at,omitempty"` + SubscriptionID string `json:"subscription_id"` + Amount int64 `json:"amount"` + DueAt string `json:"due_at"` } type UpdateInvoiceParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` Status *string `json:"status,omitempty"` } type GetInvoiceByIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type ListInvoicesByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type CommerceInvoice struct { APIResource - Subscription *CommerceSubscription `json:"subscription,omitempty"` - Amount *int64 `json:"amount,omitempty"` - Status *string `json:"status,omitempty"` - DueAt *time.Time `json:"due_at,omitempty"` + ID string `json:"id"` + Subscription *CommerceSubscription `json:"subscription,omitempty"` + Amount int64 `json:"amount"` + Status string `json:"status"` + DueAt *time.Time `json:"due_at,omitempty"` + FinalizingPaymentAttempt string `json:"finalizing_payment_attempt_id,omitempty"` } type ListCommerceInvoicesResponse struct { @@ -217,9 +234,9 @@ type ListCommerceInvoicesResponse struct { type CreatePaymentAttemptParams struct { APIParams - InvoiceID *string `json:"invoice_id,omitempty"` - Amount *int64 `json:"amount,omitempty"` - Status *string `json:"status,omitempty"` + InvoiceID string `json:"invoice_id"` + Amount int64 `json:"amount"` + Status string `json:"status"` } type UpdatePaymentAttemptParams struct { @@ -230,19 +247,21 @@ type UpdatePaymentAttemptParams struct { type GetPaymentAttemptByIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type ListPaymentAttemptsByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type CommercePaymentAttempt struct { APIResource - Invoice *CommerceInvoice `json:"invoice,omitempty"` - Amount *int64 `json:"amount,omitempty"` - Status *string `json:"status,omitempty"` + ID string `json:"id"` + Invoice CommerceInvoice `json:"invoice"` + Amount int64 `json:"amount"` + Status string `json:"status"` + CreatedAt time.Time `json:"created_at"` } type ListCommercePaymentAttemptsResponse struct { @@ -253,15 +272,17 @@ type ListCommercePaymentAttemptsResponse struct { // --- Customer Types --- type CommerceCustomer struct { + ID string `json:"id"` + AppID string `json:"app_id"` Entity *struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - } `json:"entity,omitempty"` + ID string `json:"id"` + Name string `json:"name"` + } `json:"entity"` } // --- Pagination Types --- type PaginatedList[T any] struct { - Data *[]T `json:"data,omitempty"` - TotalCount *int64 `json:"total_count,omitempty"` + Data []T `json:"data"` + TotalCount int64 `json:"total_count"` } diff --git a/commerce/api.go b/commerce/api.go index 513fe6b..79f1463 100644 --- a/commerce/api.go +++ b/commerce/api.go @@ -34,6 +34,7 @@ func CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*cle return getClient().CreateInvoice(ctx, params) } +// --- Common Fake Data Helpers --- func ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { return getClient().ListInvoicesByInstanceID(ctx, params) } diff --git a/commerce/client.go b/commerce/client.go index c364203..8d9620c 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -38,161 +38,200 @@ func TimePtr(t time.Time) *time.Time { // --- Subscriptions --- func (c *Client) CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { + fakePlan := c.fakePlan() return &clerk.CommerceSubscription{ - Customer: &clerk.CommerceCustomer{ + ID: *clerk.String("sub_123asdfa"), + Customer: clerk.CommerceCustomer{ + ID: *clerk.String("customer_123"), Entity: &struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` + ID string `json:"id"` + Name string `json:"name"` }{ - ID: clerk.String("customer_123"), - Name: clerk.String("Alice Smith"), + ID: *clerk.String("customer_123"), + Name: *clerk.String("Keanu Reeves"), }, }, - Plan: &clerk.CommercePlan{ - Name: clerk.String("Basic Plan"), - BaseAmount: clerk.Int64(1000), - IsRecurring: clerk.Bool(true), - }, - Status: clerk.String("active"), + Plan: *fakePlan, + Status: *clerk.String("active"), }, nil } func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + fakePlan := c.fakePlan() fakeSubscriptions := []clerk.CommerceSubscription{ { - Customer: &clerk.CommerceCustomer{ + ID: "sub_123", + Customer: clerk.CommerceCustomer{ + ID: *clerk.String("customer_456"), Entity: &struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` + ID string `json:"id"` + Name string `json:"name"` }{ - ID: clerk.String("customer_1"), - Name: clerk.String("John Doe"), + ID: *clerk.String("customer_456"), + Name: *clerk.String("John Wick"), }, }, - Plan: &clerk.CommercePlan{ - Name: clerk.String("Starter Plan"), - BaseAmount: clerk.Int64(1500), - IsRecurring: clerk.Bool(true), - }, - Status: clerk.String("active"), + Plan: *fakePlan, + Status: *clerk.String("active"), }, } return &clerk.ListCommerceSubscriptionsResponse{ PaginatedList: clerk.PaginatedList[clerk.CommerceSubscription]{ - Data: &fakeSubscriptions, - TotalCount: clerk.Int64(1), + Data: fakeSubscriptions, + TotalCount: *clerk.Int64(1), }, }, nil } func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + fakePlan := c.fakePlan() fakeSubscriptions := []clerk.CommerceSubscription{ { - Customer: &clerk.CommerceCustomer{ + ID: "sub_456", + Customer: clerk.CommerceCustomer{ + ID: "customer_789", Entity: &struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` + ID string `json:"id"` + Name string `json:"name"` }{ - ID: clerk.String("customer_2"), - Name: clerk.String("Jane Doe"), + ID: "customer_789", + Name: "Jane Doe", }, }, - Plan: &clerk.CommercePlan{ - Name: clerk.String("Pro Plan"), - BaseAmount: clerk.Int64(2000), - IsRecurring: clerk.Bool(true), - }, - Status: clerk.String("inactive"), + Plan: *fakePlan, + Status: "inactive", }, } return &clerk.ListCommerceSubscriptionsResponse{ PaginatedList: clerk.PaginatedList[clerk.CommerceSubscription]{ - Data: &fakeSubscriptions, - TotalCount: clerk.Int64(1), + Data: fakeSubscriptions, + TotalCount: 1, }, }, nil } func (c *Client) GetSubscriptionByID(ctx context.Context, params *clerk.GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { + fakePlan := c.fakePlan() return &clerk.CommerceSubscription{ - Customer: &clerk.CommerceCustomer{ + ID: *clerk.String("sub_123"), + Customer: clerk.CommerceCustomer{ + ID: "customer_123", Entity: &struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` + ID string `json:"id"` + Name string `json:"name"` }{ - ID: clerk.String("customer_123"), - Name: clerk.String("Alice Smith"), + ID: *clerk.String("customer_123"), + Name: *clerk.String("Keanu Reeves"), }, }, - Plan: &clerk.CommercePlan{ - Name: clerk.String("Premium Plan"), - BaseAmount: clerk.Int64(3000), - IsRecurring: clerk.Bool(true), - }, - Status: clerk.String("active"), + Plan: *fakePlan, + Status: *clerk.String("active"), }, nil } func (c *Client) UpdateSubscription(ctx context.Context, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { + fakePlan := c.fakePlan() return &clerk.CommerceSubscription{ - Customer: &clerk.CommerceCustomer{ + ID: *clerk.String("sub_456"), + Customer: clerk.CommerceCustomer{ + ID: ("customer_456"), Entity: &struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` + ID string `json:"id"` + Name string `json:"name"` }{ - ID: clerk.String("customer_123"), - Name: clerk.String("Alice Smith"), + ID: *clerk.String("customer_456"), + Name: *clerk.String("John Wick"), }, }, - Plan: &clerk.CommercePlan{ - Name: clerk.String("Updated Plan"), - BaseAmount: clerk.Int64(3500), - IsRecurring: clerk.Bool(true), - }, - Status: clerk.String("updated"), + Plan: *fakePlan, + Status: *clerk.String("updated"), }, nil } // --- Invoices --- func (c *Client) CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*clerk.CommerceInvoice, error) { + fakeSubscription := c.fakeSubscription() return &clerk.CommerceInvoice{ - Subscription: &clerk.CommerceSubscription{ - Status: clerk.String("active"), - }, - Amount: clerk.Int64(1000), - Status: clerk.String("unpaid"), - DueAt: TimePtr(time.Now().Add(7 * 24 * time.Hour)), + ID: *clerk.String("invoice_123"), + Subscription: fakeSubscription, + Amount: *clerk.Int64(2900), + Status: *clerk.String("unpaid"), + DueAt: TimePtr(time.Now().Add(7 * 24 * time.Hour)), }, nil } +// --- Common Fake Data Helpers --- +func (c *Client) fakePlan() *clerk.CommercePlan { + return &clerk.CommercePlan{ + ID: *clerk.String("product_plan_absdfsdmasdf"), + Product: clerk.CommerceProduct{ // Pass as a value, not a pointer + ID: "product_123", + Name: "Standard Product", + Slug: "standard", + CreatedAt: time.Unix(1720559641142/1000, 0), + UpdatedAt: time.Unix(1720559652642/1000, 0), + Currency: "USD", + OwnerEntityType: "app", + SubscriberType: []string{"user"}, + }, + Name: *clerk.String("Test Plan"), + BaseAmount: *clerk.Int64(2900), + IsRecurring: *clerk.Bool(true), + IsProrated: *clerk.Bool(false), + Period: *clerk.String("year"), + Interval: int(*clerk.Int64(1)), + CreatedAt: time.Unix(1720559641142/1000, 0), + UpdatedAt: time.Unix(1722559691642/1000, 0), + } +} + +func (c *Client) fakeSubscription() *clerk.CommerceSubscription { + fakePlan := c.fakePlan() + return &clerk.CommerceSubscription{ + ID: *clerk.String("sub_123"), + Plan: *fakePlan, + Customer: clerk.CommerceCustomer{ + ID: *clerk.String("cust_123"), + Entity: &struct { + ID string `json:"id"` + Name string `json:"name"` + }{ + ID: "cust_123", + Name: "Keanu Reeves", + }, + }, + Status: *clerk.String("active"), + } +} + func (c *Client) ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { fakeInvoices := []clerk.CommerceInvoice{ { - Amount: clerk.Int64(5000), - Status: clerk.String("paid"), + Amount: *clerk.Int64(5000), + Status: *clerk.String("paid"), DueAt: TimePtr(time.Now().Add(14 * 24 * time.Hour)), }, } return &clerk.ListCommerceInvoicesResponse{ PaginatedList: clerk.PaginatedList[clerk.CommerceInvoice]{ - Data: &fakeInvoices, - TotalCount: clerk.Int64(1), + Data: fakeInvoices, + TotalCount: *clerk.Int64(1), }, }, nil } func (c *Client) GetInvoiceByID(ctx context.Context, params *clerk.GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { return &clerk.CommerceInvoice{ - Amount: clerk.Int64(7000), - Status: clerk.String("due"), + Amount: *clerk.Int64(7000), + Status: *clerk.String("due"), DueAt: TimePtr(time.Now().Add(5 * 24 * time.Hour)), }, nil } func (c *Client) UpdateInvoice(ctx context.Context, params *clerk.UpdateInvoiceParams) (*clerk.CommerceInvoice, error) { return &clerk.CommerceInvoice{ - Amount: clerk.Int64(8000), - Status: clerk.String("overdue"), + Amount: *clerk.Int64(8000), + Status: *clerk.String("overdue"), DueAt: TimePtr(time.Now().Add(-2 * 24 * time.Hour)), }, nil } @@ -200,37 +239,37 @@ func (c *Client) UpdateInvoice(ctx context.Context, params *clerk.UpdateInvoiceP // --- Payment Attempts --- func (c *Client) CreatePaymentAttempt(ctx context.Context, params *clerk.CreatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { return &clerk.CommercePaymentAttempt{ - Amount: clerk.Int64(1000), - Status: clerk.String("failed"), + Amount: *clerk.Int64(1000), + Status: *clerk.String("failed"), }, nil } func (c *Client) ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { fakePaymentAttempts := []clerk.CommercePaymentAttempt{ { - Amount: clerk.Int64(5000), - Status: clerk.String("success"), + Amount: *clerk.Int64(5000), + Status: *clerk.String("success"), }, } return &clerk.ListCommercePaymentAttemptsResponse{ PaginatedList: clerk.PaginatedList[clerk.CommercePaymentAttempt]{ - Data: &fakePaymentAttempts, - TotalCount: clerk.Int64(1), + Data: fakePaymentAttempts, + TotalCount: *clerk.Int64(1), }, }, nil } func (c *Client) GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { return &clerk.CommercePaymentAttempt{ - Amount: clerk.Int64(3000), - Status: clerk.String("pending"), + Amount: *clerk.Int64(3000), + Status: *clerk.String("pending"), }, nil } func (c *Client) UpdatePaymentAttempt(ctx context.Context, params *clerk.UpdatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { return &clerk.CommercePaymentAttempt{ - Amount: clerk.Int64(4000), - Status: clerk.String("refunded"), + Amount: *clerk.Int64(4000), + Status: *clerk.String("refunded"), }, nil } @@ -239,7 +278,7 @@ func (c *Client) CreateProduct(ctx context.Context, params *clerk.CreateProductP return &clerk.CommerceProduct{ Name: *clerk.String("New Product"), Currency: *clerk.String("USD"), - SubscriberType: *clerk.String("individual"), + SubscriberType: []string{"individual"}, OwnerEntityType: *clerk.String("business"), }, nil } @@ -249,14 +288,14 @@ func (c *Client) ListProductsByInstanceID(ctx context.Context, params *clerk.Lis { Name: *clerk.String("Product 1"), Currency: *clerk.String("USD"), - SubscriberType: *clerk.String("organization"), + SubscriberType: []string{*clerk.String("organization")}, OwnerEntityType: *clerk.String("enterprise"), }, } return &clerk.ListCommerceProductsResponse{ PaginatedList: clerk.PaginatedList[clerk.CommerceProduct]{ - Data: &fakeProducts, - TotalCount: clerk.Int64(1), + Data: fakeProducts, + TotalCount: *clerk.Int64(1), }, }, nil } @@ -265,7 +304,7 @@ func (c *Client) GetProductByID(ctx context.Context, params *clerk.GetProductByI return &clerk.CommerceProduct{ Name: *clerk.String("Specific Product"), Currency: *clerk.String("EUR"), - SubscriberType: *clerk.String("group"), + SubscriberType: []string{*clerk.String("group")}, OwnerEntityType: *clerk.String("nonprofit"), }, nil } @@ -274,7 +313,7 @@ func (c *Client) UpdateProduct(ctx context.Context, params *clerk.UpdateProductP return &clerk.CommerceProduct{ Name: *clerk.String("Updated Product"), Currency: *clerk.String("GBP"), - SubscriberType: *clerk.String("individual"), + SubscriberType: []string{*clerk.String("individual")}, OwnerEntityType: *clerk.String("corporate"), }, nil } @@ -282,9 +321,9 @@ func (c *Client) UpdateProduct(ctx context.Context, params *clerk.UpdateProductP // --- Plans --- func (c *Client) CreatePlan(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { return &clerk.CommercePlan{ - Name: clerk.String("Basic Plan"), - BaseAmount: clerk.Int64(1200), - IsRecurring: clerk.Bool(true), + Name: *clerk.String("Basic Plan"), + BaseAmount: *clerk.Int64(1200), + IsRecurring: *clerk.Bool(true), }, nil } @@ -294,72 +333,72 @@ func (c *Client) ListPlansByInstanceID(ctx context.Context, params *clerk.ListPl Name: *clerk.String("Product A"), Slug: *clerk.String("product-a"), Currency: *clerk.String("USD"), - SubscriberType: "individual", + SubscriberType: []string{"individual"}, OwnerEntityType: *clerk.String("business"), }, { Name: *clerk.String("Product B"), Slug: *clerk.String("product-b"), Currency: *clerk.String("EUR"), - SubscriberType: "organization", + SubscriberType: []string{"organization"}, OwnerEntityType: *clerk.String("enterprise"), }, } return &clerk.ListCommerceProductsResponse{ PaginatedList: clerk.PaginatedList[clerk.CommerceProduct]{ - Data: &fakeProducts, // Ensure this is a slice of CommerceProduct - TotalCount: clerk.Int64(int64(len(fakeProducts))), // Adjust the count based on the slice + Data: fakeProducts, // Ensure this is a slice of CommerceProduct + TotalCount: *clerk.Int64(int64(len(fakeProducts))), // Adjust the count based on the slice }, }, nil } func (c *Client) GetPlanByID(ctx context.Context, params *clerk.GetPlanByIDParams) (*clerk.CommercePlan, error) { return &clerk.CommercePlan{ - Name: clerk.String("Exclusive Plan"), - BaseAmount: clerk.Int64(5000), - IsRecurring: clerk.Bool(false), + Name: *clerk.String("Exclusive Plan"), + BaseAmount: *clerk.Int64(5000), + IsRecurring: *clerk.Bool(false), }, nil } func (c *Client) UpdatePlan(ctx context.Context, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { return &clerk.CommercePlan{ - Name: clerk.String("Updated Plan"), - BaseAmount: clerk.Int64(5500), - IsRecurring: clerk.Bool(true), + Name: *clerk.String("Updated Plan"), + BaseAmount: *clerk.Int64(5500), + IsRecurring: *clerk.Bool(true), }, nil } // --- Integrations --- func (c *Client) CreateIntegration(ctx context.Context, params *clerk.CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { return &clerk.CommerceIntegrationResponse{ - URL: clerk.String("https://fake-integration-url.com"), + URL: *clerk.String("https://fake-integration-url.com"), }, nil } func (c *Client) ListIntegrationsByInstanceID(ctx context.Context, params *clerk.ListIntegrationsByInstanceIDParams) (*clerk.ListCommerceIntegrationsResponse, error) { fakeIntegrations := []clerk.CommerceIntegration{ { - IntegrationID: clerk.String("int_123"), - IntegrationType: clerk.String("type_a"), - Status: clerk.String("active"), + IntegrationID: *clerk.String("int_123"), + IntegrationType: *clerk.String("type_a"), + Status: *clerk.String("active"), }, } return &clerk.ListCommerceIntegrationsResponse{ PaginatedList: clerk.PaginatedList[clerk.CommerceIntegration]{ - Data: &fakeIntegrations, - TotalCount: clerk.Int64(1), + Data: fakeIntegrations, + TotalCount: *clerk.Int64(1), }, }, nil } func (c *Client) GetIntegration(ctx context.Context, params *clerk.GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { return &clerk.CommerceIntegrationResponse{ - URL: clerk.String("https://fake-integration-detail.com"), + URL: *clerk.String("https://fake-integration-detail.com"), }, nil } func (c *Client) UpdateIntegration(ctx context.Context, params *clerk.UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { return &clerk.CommerceIntegrationResponse{ - URL: clerk.String("https://fake-integration-updated.com"), + URL: *clerk.String("https://fake-integration-updated.com"), }, nil } From a87001d07942a9d586f67d6a5e45ca3e0ba92d52 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 22 Nov 2024 10:35:38 +0000 Subject: [PATCH 11/36] feat: add new subscriber methods --- commerce.go | 28 ++++++++++++++++++++++++++++ commerce/api.go | 8 ++++++++ commerce/client.go | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/commerce.go b/commerce.go index be69238..f9a135d 100644 --- a/commerce.go +++ b/commerce.go @@ -190,6 +190,34 @@ type ListCommerceSubscriptionsResponse struct { PaginatedList[CommerceSubscription] } +// --- Subscription Types --- + +type GetSubscriptionParams struct { + APIParams + ID string `json:"id"` +} + +type ListSubscribersParams struct { + APIParams + InstanceID string `json:"instance_id"` +} + +type CommerceSubscriber struct { + ID string `json:"id"` + Name string `json:"name"` + Email string `json:"email"` +} + +type ListCommerceSubscribersResponse struct { + APIResource + PaginatedList[CommerceSubscriber] +} + +// Supporting structs for emails +type ClerkEmail struct { + Address string `json:"address"` +} + // --- Invoice Types --- type CreateInvoiceParams struct { diff --git a/commerce/api.go b/commerce/api.go index 79f1463..5f332d4 100644 --- a/commerce/api.go +++ b/commerce/api.go @@ -17,6 +17,14 @@ func ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscr return getClient().ListSubscriptionsByInstanceID(ctx, params) } +func GetSubscription(ctx context.Context, params *clerk.GetSubscriptionParams) (*clerk.CommerceSubscription, error) { + return getClient().GetSubscription(ctx, params) +} + +func ListSubscribers(ctx context.Context, params *clerk.ListSubscribersParams) (*clerk.ListCommerceSubscribersResponse, error) { + return getClient().ListSubscribers(ctx, params) +} + func ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { return getClient().ListSubscriptionsByUserID(ctx, params) } diff --git a/commerce/client.go b/commerce/client.go index 8d9620c..1f31713 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -83,6 +83,46 @@ func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *cler }, nil } +func (c *Client) GetSubscription(ctx context.Context, params *clerk.GetSubscriptionParams) (*clerk.CommerceSubscription, error) { + fakePlan := c.fakePlan() + return &clerk.CommerceSubscription{ + ID: params.ID, + Customer: clerk.CommerceCustomer{ + ID: *clerk.String("customer_789"), + Entity: &struct { + ID string `json:"id"` + Name string `json:"name"` + }{ + ID: *clerk.String("customer_789"), + Name: *clerk.String("Neo"), + }, + }, + Plan: *fakePlan, + Status: *clerk.String("active"), + }, nil +} + +func (c *Client) ListSubscribers(ctx context.Context, params *clerk.ListSubscribersParams) (*clerk.ListCommerceSubscribersResponse, error) { + fakeSubscribers := []clerk.CommerceSubscriber{ + { + ID: "subscriber_001", + Name: "Trinity", + Email: "trinity@example.com", + }, + { + ID: "subscriber_002", + Name: "Morpheus", + Email: "morpheus@example.com", + }, + } + return &clerk.ListCommerceSubscribersResponse{ + PaginatedList: clerk.PaginatedList[clerk.CommerceSubscriber]{ + Data: fakeSubscribers, + TotalCount: *clerk.Int64(2), + }, + }, nil +} + func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { fakePlan := c.fakePlan() fakeSubscriptions := []clerk.CommerceSubscription{ From be07a854734df72fc53c47699024ad648727b3ef Mon Sep 17 00:00:00 2001 From: Michael Osuna Jr Date: Fri, 22 Nov 2024 03:32:03 -0800 Subject: [PATCH 12/36] fix(commerce): make the sdk changes look more consistent --- clerk.go | 6 + commerce.go | 126 ++------- commerce/api.go | 121 -------- commerce/client.go | 325 ---------------------- commerce/integration/api.go | 31 +++ commerce/integration/client.go | 87 ++++++ commerce/{ => integration}/client_test.go | 2 +- commerce/invoice/api.go | 31 +++ commerce/invoice/client.go | 87 ++++++ commerce/paymentattempt/api.go | 31 +++ commerce/paymentattempt/client.go | 84 ++++++ commerce/plans/api.go | 31 +++ commerce/plans/client.go | 70 +++++ commerce/products/api.go | 31 +++ commerce/products/client.go | 69 +++++ commerce/subscriptions/api.go | 35 +++ commerce/subscriptions/client.go | 82 ++++++ 17 files changed, 692 insertions(+), 557 deletions(-) delete mode 100644 commerce/api.go delete mode 100644 commerce/client.go create mode 100644 commerce/integration/api.go create mode 100644 commerce/integration/client.go rename commerce/{ => integration}/client_test.go (97%) create mode 100644 commerce/invoice/api.go create mode 100644 commerce/invoice/client.go create mode 100644 commerce/paymentattempt/api.go create mode 100644 commerce/paymentattempt/client.go create mode 100644 commerce/plans/api.go create mode 100644 commerce/plans/client.go create mode 100644 commerce/products/api.go create mode 100644 commerce/products/client.go create mode 100644 commerce/subscriptions/api.go create mode 100644 commerce/subscriptions/client.go diff --git a/clerk.go b/clerk.go index 0ff716b..2fe7dee 100644 --- a/clerk.go +++ b/clerk.go @@ -521,3 +521,9 @@ func Bool(v bool) *bool { func JSONRawMessage(v json.RawMessage) *json.RawMessage { return &v } + +type PaginatedList[T any] struct { + APIResource + Data *[]T `json:"data,omitempty"` + TotalCount *int64 `json:"total_count,omitempty"` +} diff --git a/commerce.go b/commerce.go index 4ebbbea..6477de3 100644 --- a/commerce.go +++ b/commerce.go @@ -6,22 +6,19 @@ import "time" type CreateProductParams struct { APIParams - InstanceID *string `json:"instance_id,omitempty"` - Name *string `json:"name,omitempty"` - Slug *string `json:"slug,omitempty"` - Currency *string `json:"currency,omitempty"` - SubscriberType *[]string `json:"subscriber_type,omitempty"` - OwnerEntityType *string `json:"owner_entity_type,omitempty"` + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *string `json:"subscriber_type,omitempty"` } type UpdateProductParams struct { APIParams - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Slug *string `json:"slug,omitempty"` - Currency *string `json:"currency,omitempty"` - SubscriberType *[]string `json:"subscriber_type,omitempty"` - OwnerEntityType *string `json:"owner_entity_type,omitempty"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *[]string `json:"subscriber_type,omitempty"` } type GetProductByIDParams struct { @@ -39,6 +36,7 @@ type CommerceProduct struct { } type CommerceProductWithPlans struct { + APIResource CommerceProduct Plans *[]CommercePlan `json:"plans,omitempty"` } @@ -48,10 +46,7 @@ type ListProductsByInstanceIDParams struct { ID *string `json:"id,omitempty"` } -type ListCommerceProductsResponse struct { - APIParams - PaginatedList[CommerceProduct] -} +type CommerceProductList PaginatedList[CommerceProduct] // --- Plan Types --- @@ -88,29 +83,9 @@ type CommercePlan struct { type ListPlansByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` } // --- Integration Types --- - -type CreateIntegrationParams struct { - APIParams - InstanceID *string `json:"instance_id,omitempty"` - Email *string `json:"email,omitempty"` - Type *string `json:"type,omitempty"` -} - -type UpdateIntegrationParams struct { - APIParams - CommerceIntegrationID *string `json:"id,omitempty"` - Status *string `json:"status,omitempty"` -} - -type GetIntegrationParams struct { - APIParams - IntegrationID *string `json:"id,omitempty"` -} - type CommerceIntegration struct { APIResource IntegrationID *string `json:"integration_id,omitempty"` @@ -118,21 +93,11 @@ type CommerceIntegration struct { Status *string `json:"status,omitempty"` } -type CommerceIntegrationResponse struct { +type CommerceIntegrationList struct { APIResource - URL *string `json:"url,omitempty"` -} - -type ListCommerceIntegrationsResponse struct { - APIParams PaginatedList[CommerceIntegration] } -type ListIntegrationsByInstanceIDParams struct { - APIParams - ID *string `json:"id,omitempty"` -} - // --- Subscription Types --- type CreateSubscriptionParams struct { @@ -144,23 +109,22 @@ type CreateSubscriptionParams struct { type UpdateSubscriptionParams struct { APIParams - ID *string `json:"id,omitempty"` Status *string `json:"status,omitempty"` } type GetSubscriptionByIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type ListSubscriptionsByInstanceIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type ListSubscriptionsByUserIDParams struct { APIParams - ID *string `json:"id,omitempty"` + ID string `json:"id"` } type CommerceSubscription struct { @@ -176,30 +140,6 @@ type ListCommerceSubscriptionsResponse struct { } // --- Invoice Types --- - -type CreateInvoiceParams struct { - APIParams - SubscriptionID *string `json:"subscription_id,omitempty"` - Amount *int64 `json:"amount,omitempty"` - DueAt *string `json:"due_at,omitempty"` -} - -type UpdateInvoiceParams struct { - APIParams - ID *string `json:"id,omitempty"` - Status *string `json:"status,omitempty"` -} - -type GetInvoiceByIDParams struct { - APIParams - ID *string `json:"id,omitempty"` -} - -type ListInvoicesByInstanceIDParams struct { - APIParams - ID *string `json:"id,omitempty"` -} - type CommerceInvoice struct { APIResource Subscription *CommerceSubscription `json:"subscription,omitempty"` @@ -208,36 +148,10 @@ type CommerceInvoice struct { DueAt *time.Time `json:"due_at,omitempty"` } -type ListCommerceInvoicesResponse struct { - APIParams - PaginatedList[CommerceInvoice] -} +type CommerceInvoiceList PaginatedList[CommerceInvoice] // --- Payment Attempt Types --- -type CreatePaymentAttemptParams struct { - APIParams - InvoiceID *string `json:"invoice_id,omitempty"` - Amount *int64 `json:"amount,omitempty"` - Status *string `json:"status,omitempty"` -} - -type UpdatePaymentAttemptParams struct { - APIParams - ID *string `json:"id,omitempty"` - Status *string `json:"status,omitempty"` -} - -type GetPaymentAttemptByIDParams struct { - APIParams - ID *string `json:"id,omitempty"` -} - -type ListPaymentAttemptsByInstanceIDParams struct { - APIParams - ID *string `json:"id,omitempty"` -} - type CommercePaymentAttempt struct { APIResource Invoice *CommerceInvoice `json:"invoice,omitempty"` @@ -258,11 +172,3 @@ type CommerceCustomer struct { Name *string `json:"name,omitempty"` } `json:"entity,omitempty"` } - -// --- Pagination Types --- - -type PaginatedList[T any] struct { - APIResource - Data *[]T `json:"data,omitempty"` - TotalCount *int64 `json:"total_count,omitempty"` -} diff --git a/commerce/api.go b/commerce/api.go deleted file mode 100644 index 513fe6b..0000000 --- a/commerce/api.go +++ /dev/null @@ -1,121 +0,0 @@ -// Code generated by "gen"; DO NOT EDIT. -// This file is meant to be re-generated in place and/or deleted at any time. -package commerce - -import ( - "context" - - "github.com/clerk/clerk-sdk-go/v2" -) - -// --- Subscriptions --- -func CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { - return getClient().CreateSubscription(ctx, params) -} - -func ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - return getClient().ListSubscriptionsByInstanceID(ctx, params) -} - -func ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - return getClient().ListSubscriptionsByUserID(ctx, params) -} - -func GetSubscriptionByID(ctx context.Context, params *clerk.GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { - return getClient().GetSubscriptionByID(ctx, params) -} - -func UpdateSubscription(ctx context.Context, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { - return getClient().UpdateSubscription(ctx, params) -} - -// --- Invoices --- -func CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*clerk.CommerceInvoice, error) { - return getClient().CreateInvoice(ctx, params) -} - -func ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { - return getClient().ListInvoicesByInstanceID(ctx, params) -} - -func GetInvoiceByID(ctx context.Context, params *clerk.GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { - return getClient().GetInvoiceByID(ctx, params) -} - -func UpdateInvoice(ctx context.Context, params *clerk.UpdateInvoiceParams) (*clerk.CommerceInvoice, error) { - return getClient().UpdateInvoice(ctx, params) -} - -// --- Payment Attempts --- -func CreatePaymentAttempt(ctx context.Context, params *clerk.CreatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { - return getClient().CreatePaymentAttempt(ctx, params) -} - -func ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { - return getClient().ListPaymentAttemptsByInstanceID(ctx, params) -} - -func GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { - return getClient().GetPaymentAttemptByID(ctx, params) -} - -func UpdatePaymentAttempt(ctx context.Context, params *clerk.UpdatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { - return getClient().UpdatePaymentAttempt(ctx, params) -} - -// --- Products --- -func CreateProduct(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { - return getClient().CreateProduct(ctx, params) -} - -func ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - return getClient().ListProductsByInstanceID(ctx, params) -} - -func GetProductByID(ctx context.Context, params *clerk.GetProductByIDParams) (*clerk.CommerceProduct, error) { - return getClient().GetProductByID(ctx, params) -} - -func UpdateProduct(ctx context.Context, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { - return getClient().UpdateProduct(ctx, params) -} - -// --- Plans --- -func CreatePlan(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { - return getClient().CreatePlan(ctx, params) -} - -func ListPlansByInstanceID(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - return getClient().ListPlansByInstanceID(ctx, params) -} - -func GetPlanByID(ctx context.Context, params *clerk.GetPlanByIDParams) (*clerk.CommercePlan, error) { - return getClient().GetPlanByID(ctx, params) -} - -func UpdatePlan(ctx context.Context, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { - return getClient().UpdatePlan(ctx, params) -} - -// --- Integrations --- -func CreateIntegration(ctx context.Context, params *clerk.CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - return getClient().CreateIntegration(ctx, params) -} - -func ListIntegrationsByInstanceID(ctx context.Context, params *clerk.ListIntegrationsByInstanceIDParams) (*clerk.ListCommerceIntegrationsResponse, error) { - return getClient().ListIntegrationsByInstanceID(ctx, params) -} - -func GetIntegration(ctx context.Context, params *clerk.GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - return getClient().GetIntegration(ctx, params) -} - -func UpdateIntegration(ctx context.Context, params *clerk.UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - return getClient().UpdateIntegration(ctx, params) -} - -func getClient() *Client { - return &Client{ - Backend: clerk.GetBackend(), - } -} diff --git a/commerce/client.go b/commerce/client.go deleted file mode 100644 index 45fa011..0000000 --- a/commerce/client.go +++ /dev/null @@ -1,325 +0,0 @@ -package commerce - -import ( - "context" - "net/http" - - "github.com/clerk/clerk-sdk-go/v2" -) - -//go:generate go run ../cmd/gen/main.go - -// Paths -const ( - path = "/commerce" - subscriptionsPath = "/subscriptions" - invoicesPath = "/invoices" - paymentAttemptsPath = "/payment_attempts" - productsPath = "/products" - plansPath = "/plans" - integrationsPath = "/integrations" -) - -// Client is used to invoke the Commerce API. -type Client struct { - Backend clerk.Backend -} - -func NewClient(config *clerk.ClientConfig) *Client { - return &Client{ - Backend: clerk.NewBackend(&config.BackendConfig), - } -} - -// --- Subscriptions --- -func (c *Client) CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceSubscription{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, "instance", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceSubscriptionsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, "user", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceSubscriptionsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) GetSubscriptionByID(ctx context.Context, params *clerk.GetSubscriptionByIDParams) (*clerk.CommerceSubscription, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceSubscription{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) UpdateSubscription(ctx context.Context, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { - reqPath, err := clerk.JoinPath(path, subscriptionsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceSubscription{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -// --- Invoices --- -func (c *Client) CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*clerk.CommerceInvoice, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceInvoice{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath, "instance", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceInvoicesResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) GetInvoiceByID(ctx context.Context, params *clerk.GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceInvoice{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) UpdateInvoice(ctx context.Context, params *clerk.UpdateInvoiceParams) (*clerk.CommerceInvoice, error) { - reqPath, err := clerk.JoinPath(path, invoicesPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceInvoice{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -// --- Payment Attempts --- -func (c *Client) CreatePaymentAttempt(ctx context.Context, params *clerk.CreatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommercePaymentAttempt{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, "instance", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommercePaymentAttemptsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommercePaymentAttempt{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) UpdatePaymentAttempt(ctx context.Context, params *clerk.UpdatePaymentAttemptParams) (*clerk.CommercePaymentAttempt, error) { - reqPath, err := clerk.JoinPath(path, paymentAttemptsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommercePaymentAttempt{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -// --- Products --- -func (c *Client) CreateProduct(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceProduct{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - reqPath, err := clerk.JoinPath(path, productsPath, "instance", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceProductsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) GetProductByID(ctx context.Context, params *clerk.GetProductByIDParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceProduct{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) UpdateProduct(ctx context.Context, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { - reqPath, err := clerk.JoinPath(path, productsPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceProduct{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -// --- Plans --- -func (c *Client) CreatePlan(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { - reqPath, err := clerk.JoinPath(path, plansPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommercePlan{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) ListPlansByInstanceID(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.ListCommerceProductsResponse, error) { - reqPath, err := clerk.JoinPath(path, plansPath, "instance", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceProductsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) GetPlanByID(ctx context.Context, params *clerk.GetPlanByIDParams) (*clerk.CommercePlan, error) { - reqPath, err := clerk.JoinPath(path, plansPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommercePlan{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) UpdatePlan(ctx context.Context, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { - reqPath, err := clerk.JoinPath(path, plansPath, *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommercePlan{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -// --- Integrations --- -func (c *Client) CreateIntegration(ctx context.Context, params *clerk.CreateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceIntegrationResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) ListIntegrationsByInstanceID(ctx context.Context, params *clerk.ListIntegrationsByInstanceIDParams) (*clerk.ListCommerceIntegrationsResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath, "instance", *params.ID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.ListCommerceIntegrationsResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) GetIntegration(ctx context.Context, params *clerk.GetIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath, *params.IntegrationID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceIntegrationResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) UpdateIntegration(ctx context.Context, params *clerk.UpdateIntegrationParams) (*clerk.CommerceIntegrationResponse, error) { - reqPath, err := clerk.JoinPath(path, integrationsPath, *params.CommerceIntegrationID) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceIntegrationResponse{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} diff --git a/commerce/integration/api.go b/commerce/integration/api.go new file mode 100644 index 0000000..65c3ea8 --- /dev/null +++ b/commerce/integration/api.go @@ -0,0 +1,31 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package integration + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +func Create(ctx context.Context, params *CreateParams) (*clerk.CommerceIntegration, error) { + return getClient().Create(ctx, params) +} + +func List(ctx context.Context, params *ListParams) (*clerk.CommerceIntegrationList, error) { + return getClient().List(ctx, params) +} + +func Get(ctx context.Context, id string) (*clerk.CommerceIntegration, error) { + return getClient().Get(ctx, id) +} + +func Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommerceIntegration, error) { + return getClient().Update(ctx, id, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/integration/client.go b/commerce/integration/client.go new file mode 100644 index 0000000..33df503 --- /dev/null +++ b/commerce/integration/client.go @@ -0,0 +1,87 @@ +package integration + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../../cmd/gen/main.go + +// Paths +const ( + rootPath = "/commerce" + path = "/integrations" +) + +type CreateParams struct { + clerk.APIParams + Email *string `json:"email,omitempty"` + Type *string `json:"type,omitempty"` +} + +type ListParams struct { + clerk.APIParams +} + +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} + +func (c *Client) Create(ctx context.Context, params *CreateParams) (*clerk.CommerceIntegration, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceIntegration{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) List(ctx context.Context, params *ListParams) (*clerk.CommerceIntegrationList, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceIntegrationList{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Get(ctx context.Context, id string) (*clerk.CommerceIntegration, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceIntegration{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +type UpdateParams struct { + clerk.APIParams + Status *string `json:"status,omitempty"` +} + +func (c *Client) Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommerceIntegration, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommerceIntegration{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} diff --git a/commerce/client_test.go b/commerce/integration/client_test.go similarity index 97% rename from commerce/client_test.go rename to commerce/integration/client_test.go index d626a97..0d325bf 100644 --- a/commerce/client_test.go +++ b/commerce/integration/client_test.go @@ -1,4 +1,4 @@ -package commerce +package integration import ( "testing" diff --git a/commerce/invoice/api.go b/commerce/invoice/api.go new file mode 100644 index 0000000..c25db99 --- /dev/null +++ b/commerce/invoice/api.go @@ -0,0 +1,31 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package invoice + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +func Create(ctx context.Context, params *CreateParams) (*clerk.CommerceInvoice, error) { + return getClient().Create(ctx, params) +} + +func List(ctx context.Context, params *ListParams) (*clerk.CommerceInvoiceList, error) { + return getClient().List(ctx, params) +} + +func Get(ctx context.Context, id string) (*clerk.CommerceInvoice, error) { + return getClient().Get(ctx, id) +} + +func Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommerceInvoice, error) { + return getClient().Update(ctx, id, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/invoice/client.go b/commerce/invoice/client.go new file mode 100644 index 0000000..3359c31 --- /dev/null +++ b/commerce/invoice/client.go @@ -0,0 +1,87 @@ +package invoice + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../../cmd/gen/main.go +const ( + rootPath = "/commerce" + path = "/invoices" +) + +type CreateParams struct { + clerk.APIParams + SubscriptionID *string `json:"subscription_id,omitempty"` + Amount *int64 `json:"amount,omitempty"` + DueAt *string `json:"due_at,omitempty"` +} + +type UpdateParams struct { + clerk.APIParams + Status *string `json:"status,omitempty"` +} + +type ListParams struct { + clerk.APIParams + InstanceID *string `json:"-"` +} + +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} + +func (c *Client) Create(ctx context.Context, params *CreateParams) (*clerk.CommerceInvoice, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceInvoice{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) List(ctx context.Context, params *ListParams) (*clerk.CommerceInvoiceList, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceInvoiceList{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Get(ctx context.Context, id string) (*clerk.CommerceInvoice, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceInvoice{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommerceInvoice, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommerceInvoice{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} diff --git a/commerce/paymentattempt/api.go b/commerce/paymentattempt/api.go new file mode 100644 index 0000000..be5cd94 --- /dev/null +++ b/commerce/paymentattempt/api.go @@ -0,0 +1,31 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package paymentattempt + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +func Create(ctx context.Context, params *CreateParams) (*clerk.CommercePaymentAttempt, error) { + return getClient().Create(ctx, params) +} + +func List(ctx context.Context, params *ListParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { + return getClient().List(ctx, params) +} + +func Get(ctx context.Context, id string) (*clerk.CommercePaymentAttempt, error) { + return getClient().Get(ctx, id) +} + +func Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommercePaymentAttempt, error) { + return getClient().Update(ctx, id, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/paymentattempt/client.go b/commerce/paymentattempt/client.go new file mode 100644 index 0000000..f99f6b5 --- /dev/null +++ b/commerce/paymentattempt/client.go @@ -0,0 +1,84 @@ +package paymentattempt + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../../cmd/gen/main.go +const ( + rootPath = "/commerce" + path = "/payment_attempts" +) + +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} + +type CreateParams struct { + clerk.APIParams + InvoiceID *string `json:"invoice_id,omitempty"` +} + +func (c *Client) Create(ctx context.Context, params *CreateParams) (*clerk.CommercePaymentAttempt, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommercePaymentAttempt{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +type ListParams struct { + clerk.APIParams +} + +func (c *Client) List(ctx context.Context, params *ListParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.ListCommercePaymentAttemptsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Get(ctx context.Context, id string) (*clerk.CommercePaymentAttempt, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommercePaymentAttempt{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +type UpdateParams struct { + clerk.APIParams + Status *string `json:"status,omitempty"` +} + +func (c *Client) Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommercePaymentAttempt, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommercePaymentAttempt{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} diff --git a/commerce/plans/api.go b/commerce/plans/api.go new file mode 100644 index 0000000..d7f1010 --- /dev/null +++ b/commerce/plans/api.go @@ -0,0 +1,31 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package plans + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +func Create(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { + return getClient().Create(ctx, params) +} + +func List(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.CommerceProductList, error) { + return getClient().List(ctx, params) +} + +func Get(ctx context.Context, id string) (*clerk.CommercePlan, error) { + return getClient().Get(ctx, id) +} + +func Update(ctx context.Context, id string, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { + return getClient().Update(ctx, id, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/plans/client.go b/commerce/plans/client.go new file mode 100644 index 0000000..1dde32e --- /dev/null +++ b/commerce/plans/client.go @@ -0,0 +1,70 @@ +package plans + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../../cmd/gen/main.go +const ( + rootPath = "/commerce" + path = "/plans" +) + +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} + +func (c *Client) Create(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.CommercePlan, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommercePlan{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) List(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.CommerceProductList, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceProductList{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Get(ctx context.Context, id string) (*clerk.CommercePlan, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommercePlan{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Update(ctx context.Context, id string, params *clerk.UpdatePlanParams) (*clerk.CommercePlan, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommercePlan{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} diff --git a/commerce/products/api.go b/commerce/products/api.go new file mode 100644 index 0000000..1553024 --- /dev/null +++ b/commerce/products/api.go @@ -0,0 +1,31 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package products + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +func CreateProduct(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { + return getClient().Create(ctx, params) +} + +func ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.CommerceProductList, error) { + return getClient().List(ctx, params) +} + +func GetProductByID(ctx context.Context, id string) (*clerk.CommerceProduct, error) { + return getClient().Get(ctx, id) +} + +func UpdateProduct(ctx context.Context, id string, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { + return getClient().Update(ctx, id, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/products/client.go b/commerce/products/client.go new file mode 100644 index 0000000..6c26ae4 --- /dev/null +++ b/commerce/products/client.go @@ -0,0 +1,69 @@ +package products + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../../cmd/gen/main.go +const ( + rootPath = "/commerce" + path = "/products" +) + +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} +func (c *Client) Create(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceProduct{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) List(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.CommerceProductList, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceProductList{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Get(ctx context.Context, id string) (*clerk.CommerceProduct, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceProduct{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Update(ctx context.Context, id string, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommerceProduct{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} diff --git a/commerce/subscriptions/api.go b/commerce/subscriptions/api.go new file mode 100644 index 0000000..a5a967a --- /dev/null +++ b/commerce/subscriptions/api.go @@ -0,0 +1,35 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package subscriptions + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +func CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { + return getClient().Create(ctx, params) +} + +func ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + return getClient().List(ctx, params) +} + +func ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + return getClient().ListByUserID(ctx, params) +} + +func GetSubscriptionByID(ctx context.Context, id string) (*clerk.CommerceSubscription, error) { + return getClient().Get(ctx, id) +} + +func UpdateSubscription(ctx context.Context, id string, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { + return getClient().Update(ctx, id, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/subscriptions/client.go b/commerce/subscriptions/client.go new file mode 100644 index 0000000..52c6a83 --- /dev/null +++ b/commerce/subscriptions/client.go @@ -0,0 +1,82 @@ +package subscriptions + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../../cmd/gen/main.go + +const ( + rootPath = "/commerce" + path = "/subscriptions" +) + +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} + +func (c *Client) Create(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceSubscription{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) List(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.ListCommerceSubscriptionsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) ListByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.ListCommerceSubscriptionsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Get(ctx context.Context, id string) (*clerk.CommerceSubscription, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceSubscription{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Update(ctx context.Context, id string, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommerceSubscription{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} From af7ae377afe197339496f1cd8d9039f870ec81fa Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 22 Nov 2024 11:43:45 +0000 Subject: [PATCH 13/36] fix: invoice and payment attempts methods --- commerce.go | 8 ++++---- commerce/api.go | 8 ++++---- commerce/client.go | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/commerce.go b/commerce.go index f9a135d..f2827a2 100644 --- a/commerce.go +++ b/commerce.go @@ -238,9 +238,9 @@ type GetInvoiceByIDParams struct { ID string `json:"id"` } -type ListInvoicesByInstanceIDParams struct { +type ListInvoicesBySubscriptionIDParams struct { APIParams - ID string `json:"id"` + SubscriptionID string `json:"subscription_id"` } type CommerceInvoice struct { @@ -278,9 +278,9 @@ type GetPaymentAttemptByIDParams struct { ID string `json:"id"` } -type ListPaymentAttemptsByInstanceIDParams struct { +type ListPaymentAttemptsByInvoiceIDParams struct { APIParams - ID string `json:"id"` + InvoiceID string `json:"invoice_id"` } type CommercePaymentAttempt struct { diff --git a/commerce/api.go b/commerce/api.go index 5f332d4..f4491c1 100644 --- a/commerce/api.go +++ b/commerce/api.go @@ -43,8 +43,8 @@ func CreateInvoice(ctx context.Context, params *clerk.CreateInvoiceParams) (*cle } // --- Common Fake Data Helpers --- -func ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { - return getClient().ListInvoicesByInstanceID(ctx, params) +func ListInvoicesBySubscriptionID(ctx context.Context, params *clerk.ListInvoicesBySubscriptionIDParams) (*clerk.ListCommerceInvoicesResponse, error) { + return getClient().ListInvoicesBySubscriptionID(ctx, params) } func GetInvoiceByID(ctx context.Context, params *clerk.GetInvoiceByIDParams) (*clerk.CommerceInvoice, error) { @@ -60,8 +60,8 @@ func CreatePaymentAttempt(ctx context.Context, params *clerk.CreatePaymentAttemp return getClient().CreatePaymentAttempt(ctx, params) } -func ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { - return getClient().ListPaymentAttemptsByInstanceID(ctx, params) +func ListPaymentAttemptsByInvoiceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInvoiceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { + return getClient().ListPaymentAttemptsByInvoiceID(ctx, params) } func GetPaymentAttemptByID(ctx context.Context, params *clerk.GetPaymentAttemptByIDParams) (*clerk.CommercePaymentAttempt, error) { diff --git a/commerce/client.go b/commerce/client.go index 1f31713..308c06f 100644 --- a/commerce/client.go +++ b/commerce/client.go @@ -244,7 +244,7 @@ func (c *Client) fakeSubscription() *clerk.CommerceSubscription { } } -func (c *Client) ListInvoicesByInstanceID(ctx context.Context, params *clerk.ListInvoicesByInstanceIDParams) (*clerk.ListCommerceInvoicesResponse, error) { +func (c *Client) ListInvoicesBySubscriptionID(ctx context.Context, params *clerk.ListInvoicesBySubscriptionIDParams) (*clerk.ListCommerceInvoicesResponse, error) { fakeInvoices := []clerk.CommerceInvoice{ { Amount: *clerk.Int64(5000), @@ -284,7 +284,7 @@ func (c *Client) CreatePaymentAttempt(ctx context.Context, params *clerk.CreateP }, nil } -func (c *Client) ListPaymentAttemptsByInstanceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInstanceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { +func (c *Client) ListPaymentAttemptsByInvoiceID(ctx context.Context, params *clerk.ListPaymentAttemptsByInvoiceIDParams) (*clerk.ListCommercePaymentAttemptsResponse, error) { fakePaymentAttempts := []clerk.CommercePaymentAttempt{ { Amount: *clerk.Int64(5000), From d87ecdec92f8b9626c0bbf4d3797acfdbbf98aa5 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 22 Nov 2024 15:14:57 +0000 Subject: [PATCH 14/36] feat(commerce): wiring up sub create --- commerce.go | 4 ++-- commerce/products/api.go | 8 ++++---- commerce/subscriptions/api.go | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/commerce.go b/commerce.go index 0bae20c..bb02f1c 100644 --- a/commerce.go +++ b/commerce.go @@ -156,8 +156,8 @@ type CommerceSubscription struct { Status string `json:"status"` LastInvoice *CommerceInvoice `json:"last_invoice,omitempty"` NextInvoice *CommerceInvoice `json:"next_invoice,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + CreatedAt string `json:"created_at"` // ISO 8601 format + UpdatedAt string `json:"updated_at"` // ISO 8601 format } type ListCommerceSubscriptionsResponse struct { diff --git a/commerce/products/api.go b/commerce/products/api.go index 1553024..0daa52f 100644 --- a/commerce/products/api.go +++ b/commerce/products/api.go @@ -8,19 +8,19 @@ import ( "github.com/clerk/clerk-sdk-go/v2" ) -func CreateProduct(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { +func Create(ctx context.Context, params *clerk.CreateProductParams) (*clerk.CommerceProduct, error) { return getClient().Create(ctx, params) } -func ListProductsByInstanceID(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.CommerceProductList, error) { +func List(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.CommerceProductList, error) { return getClient().List(ctx, params) } -func GetProductByID(ctx context.Context, id string) (*clerk.CommerceProduct, error) { +func Get(ctx context.Context, id string) (*clerk.CommerceProduct, error) { return getClient().Get(ctx, id) } -func UpdateProduct(ctx context.Context, id string, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { +func Update(ctx context.Context, id string, params *clerk.UpdateProductParams) (*clerk.CommerceProduct, error) { return getClient().Update(ctx, id, params) } diff --git a/commerce/subscriptions/api.go b/commerce/subscriptions/api.go index a5a967a..7ab473a 100644 --- a/commerce/subscriptions/api.go +++ b/commerce/subscriptions/api.go @@ -8,23 +8,23 @@ import ( "github.com/clerk/clerk-sdk-go/v2" ) -func CreateSubscription(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { +func Create(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk.CommerceSubscription, error) { return getClient().Create(ctx, params) } -func ListSubscriptionsByInstanceID(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { +func List(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { return getClient().List(ctx, params) } -func ListSubscriptionsByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { +func ListByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { return getClient().ListByUserID(ctx, params) } -func GetSubscriptionByID(ctx context.Context, id string) (*clerk.CommerceSubscription, error) { +func Get(ctx context.Context, id string) (*clerk.CommerceSubscription, error) { return getClient().Get(ctx, id) } -func UpdateSubscription(ctx context.Context, id string, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { +func Update(ctx context.Context, id string, params *clerk.UpdateSubscriptionParams) (*clerk.CommerceSubscription, error) { return getClient().Update(ctx, id, params) } From b721b93d4472f7f3c74e667ab247e3fa73957724 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 22 Nov 2024 15:56:06 +0000 Subject: [PATCH 15/36] fix(commerce): response for sub create and list --- commerce.go | 6 +----- commerce/subscriptions/api.go | 4 ++-- commerce/subscriptions/client.go | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/commerce.go b/commerce.go index bb02f1c..e01809b 100644 --- a/commerce.go +++ b/commerce.go @@ -138,13 +138,9 @@ type GetSubscriptionByIDParams struct { ID string `json:"id"` } -type ListSubscriptionsByInstanceIDParams struct { - APIParams - ID string `json:"id"` -} - type ListSubscriptionsByUserIDParams struct { APIParams + ID string `json:"id"` } type CommerceSubscription struct { diff --git a/commerce/subscriptions/api.go b/commerce/subscriptions/api.go index 7ab473a..868153b 100644 --- a/commerce/subscriptions/api.go +++ b/commerce/subscriptions/api.go @@ -12,8 +12,8 @@ func Create(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk return getClient().Create(ctx, params) } -func List(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - return getClient().List(ctx, params) +func List(ctx context.Context) (*clerk.ListCommerceSubscriptionsResponse, error) { + return getClient().List(ctx) } func ListByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { diff --git a/commerce/subscriptions/client.go b/commerce/subscriptions/client.go index 52c6a83..94bf1b4 100644 --- a/commerce/subscriptions/client.go +++ b/commerce/subscriptions/client.go @@ -36,7 +36,7 @@ func (c *Client) Create(ctx context.Context, params *clerk.CreateSubscriptionPar return resource, err } -func (c *Client) List(ctx context.Context, params *clerk.ListSubscriptionsByInstanceIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { +func (c *Client) List(ctx context.Context) (*clerk.ListCommerceSubscriptionsResponse, error) { reqPath, err := clerk.JoinPath(rootPath, path) if err != nil { return nil, err From 5311638d0337097ddd663f563ca42f324b41ed3d Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 22 Nov 2024 17:00:24 +0000 Subject: [PATCH 16/36] fix(commerce): integration responses --- commerce/integration/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commerce/integration/client.go b/commerce/integration/client.go index 33df503..ba6d275 100644 --- a/commerce/integration/client.go +++ b/commerce/integration/client.go @@ -17,8 +17,8 @@ const ( type CreateParams struct { clerk.APIParams - Email *string `json:"email,omitempty"` - Type *string `json:"type,omitempty"` + Email *string `json:"email,omitempty"` + IntegrationType *string `json:"integration_type,omitempty"` } type ListParams struct { From 54288ca33b68a65f3188d90bd4d2a737a0ae7a2a Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Mon, 25 Nov 2024 16:07:53 +0000 Subject: [PATCH 17/36] feat(commerce): get integration working --- commerce.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/commerce.go b/commerce.go index e01809b..0dfd99b 100644 --- a/commerce.go +++ b/commerce.go @@ -88,8 +88,8 @@ type CommercePlan struct { Interval int `json:"interval"` BillingCycles *int `json:"billing_cycles,omitempty"` SubscriberCount int64 `json:"subscriber_count"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + CreatedAt string `json:"created_at"` // ISO 8601 format + UpdatedAt string `json:"updated_at"` // ISO 8601 format } type ListPlansByInstanceIDParams struct { @@ -99,9 +99,12 @@ type ListPlansByInstanceIDParams struct { // --- Integration Types --- type CommerceIntegration struct { APIResource - IntegrationID string `json:"integration_id"` - IntegrationType string `json:"integration_type"` - Status string `json:"status"` + ID string `json:"id"` + IntegrationType string `json:"integration_type"` + IntegrationStatus string `json:"integration_status"` + CreatedAt string `json:"created_at"` // ISO 8601 format + UpdatedAt string `json:"updated_at"` // ISO 8601 format + InstanceID string `json:"instance_id"` } type CommerceIntegrationList struct { From e6e9732c659fb0469a070ba67a31d509f8f1331c Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 26 Nov 2024 13:25:23 +0000 Subject: [PATCH 18/36] feat(commerce): list invoices by sub id --- commerce/subscriptions/api.go | 8 ++++++-- commerce/subscriptions/client.go | 27 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/commerce/subscriptions/api.go b/commerce/subscriptions/api.go index 868153b..ccf7421 100644 --- a/commerce/subscriptions/api.go +++ b/commerce/subscriptions/api.go @@ -12,8 +12,12 @@ func Create(ctx context.Context, params *clerk.CreateSubscriptionParams) (*clerk return getClient().Create(ctx, params) } -func List(ctx context.Context) (*clerk.ListCommerceSubscriptionsResponse, error) { - return getClient().List(ctx) +func List(ctx context.Context, includes []string) (*clerk.ListCommerceSubscriptionsResponse, error) { + return getClient().List(ctx, includes) +} + +func ListInvoices(ctx context.Context, subscriptionID string) (*clerk.ListCommerceSubscriptionsResponse, error) { + return getClient().ListInvoices(ctx, subscriptionID) } func ListByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { diff --git a/commerce/subscriptions/client.go b/commerce/subscriptions/client.go index 94bf1b4..78dc18e 100644 --- a/commerce/subscriptions/client.go +++ b/commerce/subscriptions/client.go @@ -3,6 +3,8 @@ package subscriptions import ( "context" "net/http" + "net/url" + "strings" "github.com/clerk/clerk-sdk-go/v2" ) @@ -36,11 +38,34 @@ func (c *Client) Create(ctx context.Context, params *clerk.CreateSubscriptionPar return resource, err } -func (c *Client) List(ctx context.Context) (*clerk.ListCommerceSubscriptionsResponse, error) { +func (c *Client) List(ctx context.Context, includes []string) (*clerk.ListCommerceSubscriptionsResponse, error) { + // Build the base path reqPath, err := clerk.JoinPath(rootPath, path) if err != nil { return nil, err } + + if len(includes) > 0 { + query := url.Values{} + query.Set("include", strings.Join(includes, ",")) + reqPath += "?" + query.Encode() + } + + // Create the API request + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.ListCommerceSubscriptionsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) ListInvoices(ctx context.Context, subscriptionID string) (*clerk.ListCommerceSubscriptionsResponse, error) { + // Build the base path + reqPath, err := clerk.JoinPath(rootPath, path, subscriptionID, "invoices") + if err != nil { + return nil, err + } + + // Create the API request req := clerk.NewAPIRequest(http.MethodGet, reqPath) resource := &clerk.ListCommerceSubscriptionsResponse{} err = c.Backend.Call(ctx, req, resource) From 23792bd67e352686c3ebd2c50bb3889392d60fb3 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 26 Nov 2024 15:27:23 +0000 Subject: [PATCH 19/36] feat(commerce): add more commerce endpoints --- commerce/paymentattempt/api.go | 4 ++++ commerce/paymentattempt/client.go | 11 +++++++++++ commerce/products/api.go | 4 ++-- commerce/products/client.go | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/commerce/paymentattempt/api.go b/commerce/paymentattempt/api.go index be5cd94..5c6e43f 100644 --- a/commerce/paymentattempt/api.go +++ b/commerce/paymentattempt/api.go @@ -16,6 +16,10 @@ func List(ctx context.Context, params *ListParams) (*clerk.ListCommercePaymentAt return getClient().List(ctx, params) } +func ListByInvoiceID(ctx context.Context, invoiceID string) (*clerk.ListCommercePaymentAttemptsResponse, error) { + return getClient().ListByInvoiceID(ctx, invoiceID) +} + func Get(ctx context.Context, id string) (*clerk.CommercePaymentAttempt, error) { return getClient().Get(ctx, id) } diff --git a/commerce/paymentattempt/client.go b/commerce/paymentattempt/client.go index f99f6b5..c9fec0e 100644 --- a/commerce/paymentattempt/client.go +++ b/commerce/paymentattempt/client.go @@ -55,6 +55,17 @@ func (c *Client) List(ctx context.Context, params *ListParams) (*clerk.ListComme return resource, err } +func (c *Client) ListByInvoiceID(ctx context.Context, invoiceID string) (*clerk.ListCommercePaymentAttemptsResponse, error) { + reqPath, err := clerk.JoinPath(rootPath, path, "invoices", invoiceID) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.ListCommercePaymentAttemptsResponse{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + func (c *Client) Get(ctx context.Context, id string) (*clerk.CommercePaymentAttempt, error) { reqPath, err := clerk.JoinPath(rootPath, path, id) if err != nil { diff --git a/commerce/products/api.go b/commerce/products/api.go index 0daa52f..82fcbad 100644 --- a/commerce/products/api.go +++ b/commerce/products/api.go @@ -12,8 +12,8 @@ func Create(ctx context.Context, params *clerk.CreateProductParams) (*clerk.Comm return getClient().Create(ctx, params) } -func List(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.CommerceProductList, error) { - return getClient().List(ctx, params) +func List(ctx context.Context) (*clerk.CommerceProductList, error) { + return getClient().List(ctx) } func Get(ctx context.Context, id string) (*clerk.CommerceProduct, error) { diff --git a/commerce/products/client.go b/commerce/products/client.go index 6c26ae4..8be6128 100644 --- a/commerce/products/client.go +++ b/commerce/products/client.go @@ -34,7 +34,7 @@ func (c *Client) Create(ctx context.Context, params *clerk.CreateProductParams) return resource, err } -func (c *Client) List(ctx context.Context, params *clerk.ListProductsByInstanceIDParams) (*clerk.CommerceProductList, error) { +func (c *Client) List(ctx context.Context) (*clerk.CommerceProductList, error) { reqPath, err := clerk.JoinPath(rootPath, path) if err != nil { return nil, err From 95e8fa45570bb40e3e92c1e1d609a0ec0cd2409b Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 26 Nov 2024 16:33:28 +0000 Subject: [PATCH 20/36] feat(commerce): subscribers methods --- commerce.go | 3 ++- commerce/subscriptions/client.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/commerce.go b/commerce.go index 0dfd99b..665649a 100644 --- a/commerce.go +++ b/commerce.go @@ -143,7 +143,8 @@ type GetSubscriptionByIDParams struct { type ListSubscriptionsByUserIDParams struct { APIParams - ID string `json:"id"` + ID string `json:"id"` + SubscriberType string `json:"subscriber_type"` } type CommerceSubscription struct { diff --git a/commerce/subscriptions/client.go b/commerce/subscriptions/client.go index 78dc18e..e9e2458 100644 --- a/commerce/subscriptions/client.go +++ b/commerce/subscriptions/client.go @@ -73,7 +73,7 @@ func (c *Client) ListInvoices(ctx context.Context, subscriptionID string) (*cler } func (c *Client) ListByUserID(ctx context.Context, params *clerk.ListSubscriptionsByUserIDParams) (*clerk.ListCommerceSubscriptionsResponse, error) { - reqPath, err := clerk.JoinPath(rootPath, path) + reqPath, err := clerk.JoinPath(rootPath, "subscribers", params.SubscriberType, params.ID, "subscriptions") if err != nil { return nil, err } From cde1e4e90ed1aadc08209e68896e6781f8858250 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Wed, 27 Nov 2024 15:14:21 +0000 Subject: [PATCH 21/36] feat(commerce): get all integrations --- commerce.go | 3 ++- commerce/integration/api.go | 4 ++-- commerce/integration/client.go | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/commerce.go b/commerce.go index 665649a..535d2be 100644 --- a/commerce.go +++ b/commerce.go @@ -105,11 +105,12 @@ type CommerceIntegration struct { CreatedAt string `json:"created_at"` // ISO 8601 format UpdatedAt string `json:"updated_at"` // ISO 8601 format InstanceID string `json:"instance_id"` + URL string `json:"url"` } type CommerceIntegrationList struct { APIResource - URL string `json:"url"` + PaginatedList[CommerceIntegration] } type ListCommerceIntegrationsResponse struct { diff --git a/commerce/integration/api.go b/commerce/integration/api.go index 65c3ea8..d3cc738 100644 --- a/commerce/integration/api.go +++ b/commerce/integration/api.go @@ -12,8 +12,8 @@ func Create(ctx context.Context, params *CreateParams) (*clerk.CommerceIntegrati return getClient().Create(ctx, params) } -func List(ctx context.Context, params *ListParams) (*clerk.CommerceIntegrationList, error) { - return getClient().List(ctx, params) +func List(ctx context.Context) (*clerk.CommerceIntegrationList, error) { + return getClient().List(ctx) } func Get(ctx context.Context, id string) (*clerk.CommerceIntegration, error) { diff --git a/commerce/integration/client.go b/commerce/integration/client.go index ba6d275..f056990 100644 --- a/commerce/integration/client.go +++ b/commerce/integration/client.go @@ -47,7 +47,7 @@ func (c *Client) Create(ctx context.Context, params *CreateParams) (*clerk.Comme return resource, err } -func (c *Client) List(ctx context.Context, params *ListParams) (*clerk.CommerceIntegrationList, error) { +func (c *Client) List(ctx context.Context) (*clerk.CommerceIntegrationList, error) { reqPath, err := clerk.JoinPath(rootPath, path) if err != nil { return nil, err From 4a3bcdb9757bab4551f386c1dce44c197286683c Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Mon, 2 Dec 2024 15:38:06 +0000 Subject: [PATCH 22/36] fix(commerce): omitempty fields --- commerce.go | 56 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/commerce.go b/commerce.go index 535d2be..a890774 100644 --- a/commerce.go +++ b/commerce.go @@ -78,18 +78,23 @@ type GetPlanByIDParams struct { type CommercePlan struct { APIResource - ID string `json:"id"` - Name string `json:"name"` - Product CommerceProduct `json:"product"` - BaseAmount int64 `json:"base_amount"` - IsRecurring bool `json:"is_recurring"` - IsProrated bool `json:"is_prorated"` - Period string `json:"period"` // e.g., "month" or "year" - Interval int `json:"interval"` - BillingCycles *int `json:"billing_cycles,omitempty"` - SubscriberCount int64 `json:"subscriber_count"` - CreatedAt string `json:"created_at"` // ISO 8601 format - UpdatedAt string `json:"updated_at"` // ISO 8601 format + ID string `json:"id"` + Name string `json:"name"` + Product *CommerceProduct `json:"product,omitempty"` + BaseAmount int64 `json:"base_amount"` + IsRecurring bool `json:"is_recurring"` + IsProrated bool `json:"is_prorated"` + Period string `json:"period"` + Interval int `json:"interval"` + BillingCycles *int `json:"billing_cycles,omitempty"` + SubscriberCount int64 `json:"subscriber_count"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +type CommercePlanWithNoProduct struct { + CommercePlan + Product *CommerceProduct `json:"-"` } type ListPlansByInstanceIDParams struct { @@ -127,9 +132,9 @@ type ListIntegrationsByInstanceIDParams struct { type CreateSubscriptionParams struct { APIParams - CustomerID string `json:"customer_id"` - PlanID string `json:"plan_id"` - Status string `json:"status"` + CustomerID string `json:"customer_id"` + PlanID string `json:"plan_id"` + PaymentSourceID string `json:"payment_source_id"` } type UpdateSubscriptionParams struct { @@ -150,15 +155,18 @@ type ListSubscriptionsByUserIDParams struct { type CommerceSubscription struct { APIResource - ID string `json:"id"` - AppID string `json:"app_id"` - Customer CommerceCustomer `json:"customer"` - Plan CommercePlan `json:"plan"` - Status string `json:"status"` - LastInvoice *CommerceInvoice `json:"last_invoice,omitempty"` - NextInvoice *CommerceInvoice `json:"next_invoice,omitempty"` - CreatedAt string `json:"created_at"` // ISO 8601 format - UpdatedAt string `json:"updated_at"` // ISO 8601 format + ID string `json:"id"` + AppID string `json:"app_id"` + Customer *CommerceCustomer `json:"customer,omitempty"` + InstanceID string `json:"instance_id"` + PaymentSourceID string `json:"payment_source_id"` + PlanID string `json:"plan_id"` + Plan *CommercePlan `json:"plan,omitempty"` + Status string `json:"status"` + LastInvoice *CommerceInvoice `json:"last_invoice,omitempty"` + NextInvoice *CommerceInvoice `json:"next_invoice,omitempty"` + CreatedAt string `json:"created_at"` // ISO 8601 format + UpdatedAt string `json:"updated_at"` // ISO 8601 format } type ListCommerceSubscriptionsResponse struct { From 0e95eb1cd943f9d2fcddafdebf5575290709b95b Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 3 Dec 2024 12:51:46 +0000 Subject: [PATCH 23/36] fix(commerce): products response --- commerce.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/commerce.go b/commerce.go index a890774..cccc1db 100644 --- a/commerce.go +++ b/commerce.go @@ -79,13 +79,17 @@ type GetPlanByIDParams struct { type CommercePlan struct { APIResource ID string `json:"id"` - Name string `json:"name"` + Name string `json:"plan_name"` Product *CommerceProduct `json:"product,omitempty"` - BaseAmount int64 `json:"base_amount"` + BaseAmount int64 `json:"amount"` IsRecurring bool `json:"is_recurring"` IsProrated bool `json:"is_prorated"` Period string `json:"period"` - Interval int `json:"interval"` + IntervalUnit string `json:"interval_unit"` + IntervalCount int `json:"interval_count"` + AvatarURL string `json:"avatar_url"` + Description string `json:"plan_description"` + Slug string `json:"slug"` BillingCycles *int `json:"billing_cycles,omitempty"` SubscriberCount int64 `json:"subscriber_count"` CreatedAt string `json:"created_at"` From 3ad2438b6e7e8e104fbe3668ce605ec44f60035b Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 3 Dec 2024 15:34:22 +0000 Subject: [PATCH 24/36] fix(commerce): product responses --- commerce.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/commerce.go b/commerce.go index cccc1db..6dc5f23 100644 --- a/commerce.go +++ b/commerce.go @@ -32,14 +32,14 @@ type GetProductByIDParams struct { type CommerceProduct struct { APIResource - ID string `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` - Currency string `json:"currency"` - SubscriberType []string `json:"subscriber_type"` - OwnerEntityType string `json:"owner_entity_type"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Currency string `json:"currency"` + SubscriberType []string `json:"subscriber_type"` + OwnerEntityType string `json:"owner_entity_type"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` } type CommerceProductWithPlans struct { From f7cccf568d1004e914d53e7209c84a607b36de1d Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 3 Dec 2024 15:55:59 +0000 Subject: [PATCH 25/36] fix(commerce): plan response --- commerce.go | 1 + 1 file changed, 1 insertion(+) diff --git a/commerce.go b/commerce.go index 6dc5f23..9e9f19a 100644 --- a/commerce.go +++ b/commerce.go @@ -88,6 +88,7 @@ type CommercePlan struct { IntervalUnit string `json:"interval_unit"` IntervalCount int `json:"interval_count"` AvatarURL string `json:"avatar_url"` + ProductID string `json:"product_id"` Description string `json:"plan_description"` Slug string `json:"slug"` BillingCycles *int `json:"billing_cycles,omitempty"` From a10935b6a8fc2abbd0fa4f69cf52a51b2b4147b9 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Tue, 3 Dec 2024 16:52:08 +0000 Subject: [PATCH 26/36] fix(commerce): plans --- commerce.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/commerce.go b/commerce.go index 9e9f19a..ef94c83 100644 --- a/commerce.go +++ b/commerce.go @@ -32,14 +32,15 @@ type GetProductByIDParams struct { type CommerceProduct struct { APIResource - ID string `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` - Currency string `json:"currency"` - SubscriberType []string `json:"subscriber_type"` - OwnerEntityType string `json:"owner_entity_type"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Currency string `json:"currency"` + Plans []*CommercePlan `json:"plans,omitempty"` + SubscriberType []string `json:"subscriber_type"` + OwnerEntityType string `json:"owner_entity_type"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` } type CommerceProductWithPlans struct { From 5ed4b569556c21066ded22e9a8246352e37d415b Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Wed, 4 Dec 2024 09:57:23 +0000 Subject: [PATCH 27/36] feat(commerce): amend product update --- commerce.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/commerce.go b/commerce.go index ef94c83..c569484 100644 --- a/commerce.go +++ b/commerce.go @@ -18,11 +18,10 @@ type CreateProductParams struct { type UpdateProductParams struct { APIParams - Name *string `json:"name,omitempty"` - Slug *string `json:"slug,omitempty"` - Currency *string `json:"currency,omitempty"` - SubscriberType *[]string `json:"subscriber_type,omitempty"` - OwnerEntityType *string `json:"owner_entity_type,omitempty"` + Name *string `json:"name,omitempty"` + Slug *string `json:"slug,omitempty"` + Currency *string `json:"currency,omitempty"` + SubscriberType *[]string `json:"subscriber_type,omitempty"` } type GetProductByIDParams struct { From 5ce123c8f35277eeb97cdeff156c2ea02e6b65b3 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Wed, 4 Dec 2024 10:17:18 +0000 Subject: [PATCH 28/36] feat(commerce): update plan --- commerce.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/commerce.go b/commerce.go index c569484..9d332ac 100644 --- a/commerce.go +++ b/commerce.go @@ -67,8 +67,15 @@ type CreatePlanParams struct { type UpdatePlanParams struct { APIParams - ID string `json:"id"` - Name *string `json:"name,omitempty"` + ID string `json:"id"` + Name *string `json:"name,omitempty"` + Amount *int64 `json:"amount,omitempty"` + IsRecurring *bool `json:"is_recurring,omitempty"` + IsProrated *bool `json:"is_prorated,omitempty"` + Period *string `json:"period,omitempty"` + IntervalUnit *string `json:"interval_unit,omitempty"` + IntervalCount *int `json:"interval_count,omitempty"` + AvatarURL *string `json:"avatar_url,omitempty"` } type GetPlanByIDParams struct { From 6019f8a6130913f1f221d281d6554fe1c480f490 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Wed, 4 Dec 2024 14:06:20 +0000 Subject: [PATCH 29/36] feat(commerce): add product --- commerce.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/commerce.go b/commerce.go index 9d332ac..2f282c9 100644 --- a/commerce.go +++ b/commerce.go @@ -59,10 +59,16 @@ type CommerceProductList PaginatedList[CommerceProduct] type CreatePlanParams struct { APIParams - Name string `json:"name"` - ProductID string `json:"product_id"` - BaseAmount int64 `json:"base_amount"` - IsRecurring bool `json:"is_recurring"` + Name string `json:"name"` + ProductID string `json:"product_id"` + BaseAmount int64 `json:"base_amount"` + IsRecurring bool `json:"is_recurring"` + IsProrated bool `json:"is_prorated"` + Period string `json:"period"` + IntervalUnit string `json:"interval_unit"` + IntervalCount int `json:"interval_count"` + AvatarURL string `json:"avatar_url"` + Description string `json:"description"` } type UpdatePlanParams struct { From beeed522e1fe0ec152d9256834e66975288545dd Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Wed, 4 Dec 2024 15:43:43 +0000 Subject: [PATCH 30/36] fix(commerce): plans response --- commerce.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commerce.go b/commerce.go index 2f282c9..f990dcb 100644 --- a/commerce.go +++ b/commerce.go @@ -35,7 +35,7 @@ type CommerceProduct struct { Name string `json:"name"` Slug string `json:"slug"` Currency string `json:"currency"` - Plans []*CommercePlan `json:"plans,omitempty"` + Plans []*CommercePlan `json:"plans"` SubscriberType []string `json:"subscriber_type"` OwnerEntityType string `json:"owner_entity_type"` CreatedAt string `json:"created_at"` From 9967b56491f5059d3c2d97bcb18d266c464b352d Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Thu, 5 Dec 2024 16:06:41 +0000 Subject: [PATCH 31/36] feat(commerce): features --- commerce.go | 127 +++++++++++++++++++++++++++++------- commerce/features/api.go | 39 +++++++++++ commerce/features/client.go | 91 ++++++++++++++++++++++++++ 3 files changed, 233 insertions(+), 24 deletions(-) create mode 100644 commerce/features/api.go create mode 100644 commerce/features/client.go diff --git a/commerce.go b/commerce.go index f990dcb..b02af54 100644 --- a/commerce.go +++ b/commerce.go @@ -55,33 +55,113 @@ type ListProductsByInstanceIDParams struct { type CommerceProductList PaginatedList[CommerceProduct] +// --- Feature Types --- + +type CommerceFeatureUnitPricing struct { + Amount int64 `json:"amount"` + Qty int `json:"qty"` +} + +type CommerceFeature struct { + APIResource + ID string `json:"id"` + PlanID string `json:"plan_id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + Slug string `json:"slug"` + PubliclyVisible bool `json:"publicly_visible"` + IncludeInJWT bool `json:"include_in_jwt"` + JWTValue string `json:"jwt_value"` + IsAddon bool `json:"is_addon"` + BaseFeeAmount int64 `json:"base_fee_amount"` + IsMetered bool `json:"is_metered"` + BillingModel string `json:"billing_model"` + UnitName string `json:"unit_name"` + UnitNamePlural string `json:"unit_name_plural"` + HasTrialUnits bool `json:"has_trial_units"` + TrialUnits int `json:"trial_units"` + UnitPricing []CommerceFeatureUnitPricing `json:"unit_pricing"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +type CommerceFeatureList PaginatedList[CommerceFeature] + +type CreateFeatureParams struct { + APIParams + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + Slug string `json:"slug"` + PubliclyVisible bool `json:"publicly_visible"` + IncludeInJWT bool `json:"include_in_jwt"` + JWTValue string `json:"jwt_value"` + IsAddon bool `json:"is_addon"` + BaseFeeAmount int64 `json:"base_fee_amount"` + IsMetered bool `json:"is_metered"` + BillingModel string `json:"billing_model"` + UnitName string `json:"unit_name"` + UnitNamePlural string `json:"unit_name_plural"` + TrialUnits int `json:"trial_units"` + UnitPricing []CommerceFeatureUnitPricing `json:"unit_pricing"` +} + +type UpdateFeatureParams struct { + APIParams + ID string `json:"id"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + AvatarURL *string `json:"avatar_url,omitempty"` + Slug *string `json:"slug,omitempty"` + PubliclyVisible *bool `json:"publicly_visible,omitempty"` + IncludeInJWT *bool `json:"include_in_jwt,omitempty"` + JWTValue *string `json:"jwt_value,omitempty"` + IsAddon *bool `json:"is_addon,omitempty"` + BaseFeeAmount *int64 `json:"base_fee_amount,omitempty"` + IsMetered *bool `json:"is_metered,omitempty"` + BillingModel *string `json:"billing_model,omitempty"` + UnitName *string `json:"unit_name,omitempty"` + UnitNamePlural *string `json:"unit_name_plural,omitempty"` + TrialUnits *int `json:"trial_units,omitempty"` + UnitPricing *[]CommerceFeatureUnitPricing `json:"unit_pricing,omitempty"` +} + +type ListFeaturesByInstanceIDParams struct { + APIParams + ID string `json:"id"` +} + +type ListFeaturesByPlanIDParams struct { + APIParams + ID string `json:"id"` +} + // --- Plan Types --- type CreatePlanParams struct { APIParams - Name string `json:"name"` - ProductID string `json:"product_id"` - BaseAmount int64 `json:"base_amount"` - IsRecurring bool `json:"is_recurring"` - IsProrated bool `json:"is_prorated"` - Period string `json:"period"` - IntervalUnit string `json:"interval_unit"` - IntervalCount int `json:"interval_count"` - AvatarURL string `json:"avatar_url"` - Description string `json:"description"` + Name string `json:"name"` + ProductID string `json:"product_id"` + Amount int64 `json:"amount"` + IsRecurring bool `json:"is_recurring"` + IsProrated bool `json:"is_prorated"` + Period string `json:"period"` + Interval int `json:"interval"` + AvatarURL string `json:"avatar_url"` + Description string `json:"description"` } type UpdatePlanParams struct { APIParams - ID string `json:"id"` - Name *string `json:"name,omitempty"` - Amount *int64 `json:"amount,omitempty"` - IsRecurring *bool `json:"is_recurring,omitempty"` - IsProrated *bool `json:"is_prorated,omitempty"` - Period *string `json:"period,omitempty"` - IntervalUnit *string `json:"interval_unit,omitempty"` - IntervalCount *int `json:"interval_count,omitempty"` - AvatarURL *string `json:"avatar_url,omitempty"` + ID string `json:"id"` + Name *string `json:"name,omitempty"` + Amount *int64 `json:"amount,omitempty"` + IsRecurring *bool `json:"is_recurring,omitempty"` + IsProrated *bool `json:"is_prorated,omitempty"` + Period *string `json:"period,omitempty"` + Interval *int `json:"interval,omitempty"` + AvatarURL *string `json:"avatar_url,omitempty"` } type GetPlanByIDParams struct { @@ -92,17 +172,16 @@ type GetPlanByIDParams struct { type CommercePlan struct { APIResource ID string `json:"id"` - Name string `json:"plan_name"` + Name string `json:"name"` Product *CommerceProduct `json:"product,omitempty"` - BaseAmount int64 `json:"amount"` + Amount int64 `json:"amount"` IsRecurring bool `json:"is_recurring"` IsProrated bool `json:"is_prorated"` Period string `json:"period"` - IntervalUnit string `json:"interval_unit"` - IntervalCount int `json:"interval_count"` + Interval int `json:"interval"` AvatarURL string `json:"avatar_url"` ProductID string `json:"product_id"` - Description string `json:"plan_description"` + Description string `json:"description"` Slug string `json:"slug"` BillingCycles *int `json:"billing_cycles,omitempty"` SubscriberCount int64 `json:"subscriber_count"` diff --git a/commerce/features/api.go b/commerce/features/api.go new file mode 100644 index 0000000..473a96a --- /dev/null +++ b/commerce/features/api.go @@ -0,0 +1,39 @@ +// Code generated by "gen"; DO NOT EDIT. +// This file is meant to be re-generated in place and/or deleted at any time. +package features + +import ( + "context" + + "github.com/clerk/clerk-sdk-go/v2" +) + +func Create(ctx context.Context, params *clerk.CreateFeatureParams) (*clerk.CommerceFeature, error) { + return getClient().Create(ctx, params) +} + +func List(ctx context.Context, params *clerk.ListFeaturesByInstanceIDParams) (*clerk.CommerceFeatureList, error) { + return getClient().List(ctx, params) +} + +func ListByPlanID(ctx context.Context, params *clerk.ListFeaturesByPlanIDParams) (*clerk.CommerceFeatureList, error) { + return getClient().ListByPlanID(ctx, params) +} + +func Get(ctx context.Context, id string) (*clerk.CommerceFeature, error) { + return getClient().Get(ctx, id) +} + +func Delete(ctx context.Context, id string) error { + return getClient().Delete(ctx, id) +} + +func Update(ctx context.Context, id string, params *clerk.UpdateFeatureParams) (*clerk.CommerceFeature, error) { + return getClient().Update(ctx, id, params) +} + +func getClient() *Client { + return &Client{ + Backend: clerk.GetBackend(), + } +} diff --git a/commerce/features/client.go b/commerce/features/client.go new file mode 100644 index 0000000..b933e44 --- /dev/null +++ b/commerce/features/client.go @@ -0,0 +1,91 @@ +package features + +import ( + "context" + "net/http" + + "github.com/clerk/clerk-sdk-go/v2" +) + +//go:generate go run ../../cmd/gen/main.go +const ( + rootPath = "/commerce" + path = "/features" +) + +type Client struct { + Backend clerk.Backend +} + +func NewClient(config *clerk.ClientConfig) *Client { + return &Client{ + Backend: clerk.NewBackend(&config.BackendConfig), + } +} + +func (c *Client) Create(ctx context.Context, params *clerk.CreateFeatureParams) (*clerk.CommerceFeature, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPost, reqPath) + req.SetParams(params) + resource := &clerk.CommerceFeature{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) List(ctx context.Context, params *clerk.ListFeaturesByInstanceIDParams) (*clerk.CommerceFeatureList, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceFeatureList{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) ListByPlanID(ctx context.Context, params *clerk.ListFeaturesByPlanIDParams) (*clerk.CommerceFeatureList, error) { + reqPath, err := clerk.JoinPath(rootPath, path) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceFeatureList{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Get(ctx context.Context, id string) (*clerk.CommerceFeature, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodGet, reqPath) + resource := &clerk.CommerceFeature{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} + +func (c *Client) Delete(ctx context.Context, id string) error { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return err + } + req := clerk.NewAPIRequest(http.MethodDelete, reqPath) + err = c.Backend.Call(ctx, req, nil) + return err +} + +func (c *Client) Update(ctx context.Context, id string, params *clerk.UpdateFeatureParams) (*clerk.CommerceFeature, error) { + reqPath, err := clerk.JoinPath(rootPath, path, id) + if err != nil { + return nil, err + } + req := clerk.NewAPIRequest(http.MethodPut, reqPath) + req.SetParams(params) + resource := &clerk.CommerceFeature{} + err = c.Backend.Call(ctx, req, resource) + return resource, err +} From 1d3c5ad64123533d54f1ff3a7a4f8ea1e186443a Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 6 Dec 2024 12:37:26 +0000 Subject: [PATCH 32/36] feat(bapi): list features --- commerce.go | 2 ++ commerce/plans/api.go | 2 +- commerce/plans/client.go | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/commerce.go b/commerce.go index b02af54..54144fc 100644 --- a/commerce.go +++ b/commerce.go @@ -194,6 +194,8 @@ type CommercePlanWithNoProduct struct { Product *CommerceProduct `json:"-"` } +type CommercePlanList PaginatedList[CommercePlan] + type ListPlansByInstanceIDParams struct { APIParams } diff --git a/commerce/plans/api.go b/commerce/plans/api.go index d7f1010..0ec66d1 100644 --- a/commerce/plans/api.go +++ b/commerce/plans/api.go @@ -12,7 +12,7 @@ func Create(ctx context.Context, params *clerk.CreatePlanParams) (*clerk.Commerc return getClient().Create(ctx, params) } -func List(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.CommerceProductList, error) { +func List(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.CommercePlanList, error) { return getClient().List(ctx, params) } diff --git a/commerce/plans/client.go b/commerce/plans/client.go index 1dde32e..ad54c5f 100644 --- a/commerce/plans/client.go +++ b/commerce/plans/client.go @@ -35,13 +35,13 @@ func (c *Client) Create(ctx context.Context, params *clerk.CreatePlanParams) (*c return resource, err } -func (c *Client) List(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.CommerceProductList, error) { +func (c *Client) List(ctx context.Context, params *clerk.ListPlansByInstanceIDParams) (*clerk.CommercePlanList, error) { reqPath, err := clerk.JoinPath(rootPath, path) if err != nil { return nil, err } req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceProductList{} + resource := &clerk.CommercePlanList{} err = c.Backend.Call(ctx, req, resource) return resource, err } From c65d935ff3846f233d15c51c2a818855b9f9fc23 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 6 Dec 2024 12:48:46 +0000 Subject: [PATCH 33/36] feat(commerce): list features by plan ID --- commerce/features/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commerce/features/client.go b/commerce/features/client.go index b933e44..db32a50 100644 --- a/commerce/features/client.go +++ b/commerce/features/client.go @@ -47,7 +47,7 @@ func (c *Client) List(ctx context.Context, params *clerk.ListFeaturesByInstanceI } func (c *Client) ListByPlanID(ctx context.Context, params *clerk.ListFeaturesByPlanIDParams) (*clerk.CommerceFeatureList, error) { - reqPath, err := clerk.JoinPath(rootPath, path) + reqPath, err := clerk.JoinPath(rootPath, "plans", params.ID, path) if err != nil { return nil, err } From 5d2e12dbfa5fd2599aa0a71f24e2a53dd03f9778 Mon Sep 17 00:00:00 2001 From: Ben Howdle Date: Fri, 6 Dec 2024 13:53:17 +0000 Subject: [PATCH 34/36] feat(commerce): create/update features --- commerce.go | 1 + commerce/features/client.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/commerce.go b/commerce.go index 54144fc..2cb7fe5 100644 --- a/commerce.go +++ b/commerce.go @@ -92,6 +92,7 @@ type CreateFeatureParams struct { APIParams Name string `json:"name"` Description string `json:"description"` + PlanID string `json:"plan_id"` AvatarURL string `json:"avatar_url"` Slug string `json:"slug"` PubliclyVisible bool `json:"publicly_visible"` diff --git a/commerce/features/client.go b/commerce/features/client.go index db32a50..4fb60b5 100644 --- a/commerce/features/client.go +++ b/commerce/features/client.go @@ -24,7 +24,7 @@ func NewClient(config *clerk.ClientConfig) *Client { } func (c *Client) Create(ctx context.Context, params *clerk.CreateFeatureParams) (*clerk.CommerceFeature, error) { - reqPath, err := clerk.JoinPath(rootPath, path) + reqPath, err := clerk.JoinPath(rootPath, "plans", params.PlanID, path) if err != nil { return nil, err } From ab7ab4ea669ae060b8af081f19ee65749c63b95e Mon Sep 17 00:00:00 2001 From: Michael Osuna Jr Date: Sun, 8 Dec 2024 17:09:34 -0800 Subject: [PATCH 35/36] chore(commerce): remove integrations --- commerce.go | 27 --------- commerce/integration/api.go | 31 ---------- commerce/integration/client.go | 87 ----------------------------- commerce/integration/client_test.go | 27 --------- 4 files changed, 172 deletions(-) delete mode 100644 commerce/integration/api.go delete mode 100644 commerce/integration/client.go delete mode 100644 commerce/integration/client_test.go diff --git a/commerce.go b/commerce.go index 2cb7fe5..54e4b36 100644 --- a/commerce.go +++ b/commerce.go @@ -201,33 +201,6 @@ type ListPlansByInstanceIDParams struct { APIParams } -// --- Integration Types --- -type CommerceIntegration struct { - APIResource - ID string `json:"id"` - IntegrationType string `json:"integration_type"` - IntegrationStatus string `json:"integration_status"` - CreatedAt string `json:"created_at"` // ISO 8601 format - UpdatedAt string `json:"updated_at"` // ISO 8601 format - InstanceID string `json:"instance_id"` - URL string `json:"url"` -} - -type CommerceIntegrationList struct { - APIResource - PaginatedList[CommerceIntegration] -} - -type ListCommerceIntegrationsResponse struct { - APIResource - PaginatedList[CommerceIntegration] -} - -type ListIntegrationsByInstanceIDParams struct { - APIParams - ID string `json:"id"` -} - // --- Subscription Types --- type CreateSubscriptionParams struct { diff --git a/commerce/integration/api.go b/commerce/integration/api.go deleted file mode 100644 index d3cc738..0000000 --- a/commerce/integration/api.go +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated by "gen"; DO NOT EDIT. -// This file is meant to be re-generated in place and/or deleted at any time. -package integration - -import ( - "context" - - "github.com/clerk/clerk-sdk-go/v2" -) - -func Create(ctx context.Context, params *CreateParams) (*clerk.CommerceIntegration, error) { - return getClient().Create(ctx, params) -} - -func List(ctx context.Context) (*clerk.CommerceIntegrationList, error) { - return getClient().List(ctx) -} - -func Get(ctx context.Context, id string) (*clerk.CommerceIntegration, error) { - return getClient().Get(ctx, id) -} - -func Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommerceIntegration, error) { - return getClient().Update(ctx, id, params) -} - -func getClient() *Client { - return &Client{ - Backend: clerk.GetBackend(), - } -} diff --git a/commerce/integration/client.go b/commerce/integration/client.go deleted file mode 100644 index f056990..0000000 --- a/commerce/integration/client.go +++ /dev/null @@ -1,87 +0,0 @@ -package integration - -import ( - "context" - "net/http" - - "github.com/clerk/clerk-sdk-go/v2" -) - -//go:generate go run ../../cmd/gen/main.go - -// Paths -const ( - rootPath = "/commerce" - path = "/integrations" -) - -type CreateParams struct { - clerk.APIParams - Email *string `json:"email,omitempty"` - IntegrationType *string `json:"integration_type,omitempty"` -} - -type ListParams struct { - clerk.APIParams -} - -type Client struct { - Backend clerk.Backend -} - -func NewClient(config *clerk.ClientConfig) *Client { - return &Client{ - Backend: clerk.NewBackend(&config.BackendConfig), - } -} - -func (c *Client) Create(ctx context.Context, params *CreateParams) (*clerk.CommerceIntegration, error) { - reqPath, err := clerk.JoinPath(rootPath, path) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPost, reqPath) - req.SetParams(params) - resource := &clerk.CommerceIntegration{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) List(ctx context.Context) (*clerk.CommerceIntegrationList, error) { - reqPath, err := clerk.JoinPath(rootPath, path) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceIntegrationList{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -func (c *Client) Get(ctx context.Context, id string) (*clerk.CommerceIntegration, error) { - reqPath, err := clerk.JoinPath(rootPath, path, id) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodGet, reqPath) - resource := &clerk.CommerceIntegration{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} - -type UpdateParams struct { - clerk.APIParams - Status *string `json:"status,omitempty"` -} - -func (c *Client) Update(ctx context.Context, id string, params *UpdateParams) (*clerk.CommerceIntegration, error) { - reqPath, err := clerk.JoinPath(rootPath, path, id) - if err != nil { - return nil, err - } - req := clerk.NewAPIRequest(http.MethodPut, reqPath) - req.SetParams(params) - resource := &clerk.CommerceIntegration{} - err = c.Backend.Call(ctx, req, resource) - return resource, err -} diff --git a/commerce/integration/client_test.go b/commerce/integration/client_test.go deleted file mode 100644 index 0d325bf..0000000 --- a/commerce/integration/client_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package integration - -import ( - "testing" -) - -func TestSubscriptionListByInstanceID(t *testing.T) { - t.Parallel() - // userID := "user_123" - // config := &clerk.ClientConfig{} - // config.HTTPClient = &http.Client{ - // Transport: &clerktest.RoundTripper{ - // T: t, - // Method: http.MethodDelete, - // Out: json.RawMessage(fmt.Sprintf(`{"id":"%s","object":"external_account"}`, externalAccountID)), - // Path: fmt.Sprintf("/v1/users/%s/external_accounts/%s", userID, externalAccountID), - // }, - // } - // client := NewClient(config) - // externalAccount, err := client.DeleteExternalAccount(context.Background(), &DeleteExternalAccountParams{ - // UserID: userID, - // ID: externalAccountID, - // }) - // require.NoError(t, err) - // require.Equal(t, externalAccountID, externalAccount.ID) - // require.Equal(t, "external_account", externalAccount.Object) -} From b3771ea2f954918c7ac4c148b77542df83f694d0 Mon Sep 17 00:00:00 2001 From: Michael Osuna Jr Date: Tue, 10 Dec 2024 00:07:57 -0800 Subject: [PATCH 36/36] chore(commerce): fix merge --- CHANGELOG.md | 1 + cmd/gen/main.go | 1 - organization/client.go | 20 ++++++++++++++++++++ organization/client_test.go | 25 +++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02cc3aa..e424afb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Add support for the OAuth Applications API. Added the oauthapplication package for API operations and a clerk.OAuthApplication type. - Add support for multiple invitation templates with the `TemplateSlug` field in `invitation.Create`. - Add support for listing and creating waitlist entries with the `waitlistentry.List` and `waitlistentry.Create` methods. +- Add support for fetching an organization with its members count, via a new `organizations.GetWithParams` method. ## 2.2.0 diff --git a/cmd/gen/main.go b/cmd/gen/main.go index 86afebf..d1959b0 100644 --- a/cmd/gen/main.go +++ b/cmd/gen/main.go @@ -28,7 +28,6 @@ func main() { // We're looking for source code in /client.go files. filePath, err := filepath.Abs(path.Join(cwd, "client.go")) - if err != nil { log.Fatal(fmt.Errorf("get absolute file path: %w", err)) } diff --git a/organization/client.go b/organization/client.go index 8b1c4dd..e5d1d6a 100644 --- a/organization/client.go +++ b/organization/client.go @@ -48,14 +48,34 @@ func (c *Client) Create(ctx context.Context, params *CreateParams) (*clerk.Organ return organization, err } +type GetParams struct { + clerk.APIParams + IncludeMembersCount *bool `json:"include_members_count,omitempty"` +} + +func (params *GetParams) ToQuery() url.Values { + q := url.Values{} + if params.IncludeMembersCount != nil { + q.Set("include_members_count", strconv.FormatBool(*params.IncludeMembersCount)) + } + return q +} + // Get retrieves details for an organization. // The organization can be fetched by either the ID or its slug. func (c *Client) Get(ctx context.Context, idOrSlug string) (*clerk.Organization, error) { + return c.GetWithParams(ctx, idOrSlug, &GetParams{}) +} + +// GetWithParams retrieves details for an organization. +// The organization can be fetched by either the ID or its slug. +func (c *Client) GetWithParams(ctx context.Context, idOrSlug string, params *GetParams) (*clerk.Organization, error) { path, err := clerk.JoinPath(path, idOrSlug) if err != nil { return nil, err } req := clerk.NewAPIRequest(http.MethodGet, path) + req.SetParams(params) organization := &clerk.Organization{} err = c.Backend.Call(ctx, req, organization) return organization, err diff --git a/organization/client_test.go b/organization/client_test.go index 4809e1e..622b370 100644 --- a/organization/client_test.go +++ b/organization/client_test.go @@ -82,6 +82,31 @@ func TestOrganizationClientGet(t *testing.T) { require.Equal(t, name, organization.Name) } +func TestOrganizationClientGetWithParams(t *testing.T) { + t.Parallel() + id := "org_123" + name := "Acme Inc" + config := &clerk.ClientConfig{} + config.HTTPClient = &http.Client{ + Transport: &clerktest.RoundTripper{ + T: t, + Out: json.RawMessage(fmt.Sprintf(`{"id":"%s","name":"%s"}`, id, name)), + Method: http.MethodGet, + Path: "/v1/organizations/" + id, + Query: &url.Values{ + "include_members_count": []string{"true"}, + }, + }, + } + client := NewClient(config) + organization, err := client.GetWithParams(context.Background(), id, &GetParams{ + IncludeMembersCount: clerk.Bool(true), + }) + require.NoError(t, err) + require.Equal(t, id, organization.ID) + require.Equal(t, name, organization.Name) +} + func TestOrganizationClientUpdate(t *testing.T) { t.Parallel() id := "org_123"