Skip to content

Commit

Permalink
feat: get upcoming invoice due amount for customer (#444)
Browse files Browse the repository at this point in the history
* feat: get upcoming invoice due amount for customer

Signed-off-by: Kush Sharma <[email protected]>

* build: docs

Signed-off-by: Kush Sharma <[email protected]>

---------

Signed-off-by: Kush Sharma <[email protected]>
  • Loading branch information
kushsharma authored Jan 2, 2024
1 parent dac6be3 commit c449799
Show file tree
Hide file tree
Showing 37 changed files with 7,874 additions and 6,783 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ TAG := $(shell git rev-list --tags --max-count=1)
VERSION := $(shell git describe --tags ${TAG})
.PHONY: build check fmt lint test test-race vet test-cover-html help install proto ui
.DEFAULT_GOAL := build
PROTON_COMMIT := "41581c2eb9697b65ce4f3cc1cbd98bd8eaf47034"
PROTON_COMMIT := "c596fa2bfc4a9c6c42260ab6983b261cd5fb1013"

ui:
@echo " > generating ui build"
Expand Down
31 changes: 31 additions & 0 deletions billing/invoice/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,34 @@ func (s *Service) List(ctx context.Context, filter Filter) ([]Invoice, error) {
}
return invoices, nil
}

func (s *Service) GetUpcoming(ctx context.Context, customerID string) (Invoice, error) {
custmr, err := s.customerService.GetByID(ctx, customerID)
if err != nil {
return Invoice{}, fmt.Errorf("failed to find customer: %w", err)
}

stripeInvoice, err := s.stripeClient.Invoices.Upcoming(&stripe.InvoiceUpcomingParams{
Customer: stripe.String(custmr.ProviderID),
Params: stripe.Params{
Context: ctx,
},
})
if err != nil {
return Invoice{}, fmt.Errorf("failed to get upcoming invoice: %w", err)
}

return Invoice{
ID: "", // TODO: should we persist this?
ProviderID: stripeInvoice.ID,
CustomerID: custmr.ID,
State: string(stripeInvoice.Status),
Currency: string(stripeInvoice.Currency),
Amount: stripeInvoice.Total,
HostedURL: stripeInvoice.HostedInvoiceURL,
Metadata: metadata.FromString(stripeInvoice.Metadata),
EffectiveAt: time.Unix(stripeInvoice.EffectiveAt, 0),
DueDate: time.Unix(stripeInvoice.DueDate, 0),
CreatedAt: time.Unix(stripeInvoice.Created, 0),
}, nil
}
7 changes: 7 additions & 0 deletions billing/subscription/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ func (s *Service) SyncWithProvider(ctx context.Context, customr customer.Custome
},
},
},
PendingInvoiceItemInterval: &stripe.SubscriptionPendingInvoiceItemIntervalParams{
// TODO(kushsharma): make this configurable as for now
// every month we will charge the customer for the number of users
// they have in the org
Interval: stripe.String("month"),
IntervalCount: stripe.Int64(1),
},
})
if err != nil {
return fmt.Errorf("failed to update subscription quantity at billing provider: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/apis/admin-service-delegated-checkout.api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ Checkout a feature to buy it one time or start a subscription plan on a billing

A successful response.

</div><div><MimeTabs schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs><TabItem label={"Schema"} value={"Schema"}><details style={{}} data-collapsed={false} open={true}><summary style={{"textAlign":"left"}}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}}><summary style={{}}><strong>checkoutSession</strong><span style={{"opacity":"0.6"}}> object</span></summary><div style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"id"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"checkoutUrl"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"successUrl"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"cancelUrl"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"metadata"} required={false} schemaName={"object"} qualifierMessage={undefined} schema={{"type":"object"}}></SchemaItem><SchemaItem collapsible={false} name={"createdAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem><SchemaItem collapsible={false} name={"updatedAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem><SchemaItem collapsible={false} name={"expireAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem></div></details></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n \"checkoutSession\": {\n \"id\": \"string\",\n \"checkoutUrl\": \"string\",\n \"successUrl\": \"string\",\n \"cancelUrl\": \"string\",\n \"state\": \"string\",\n \"metadata\": {},\n \"createdAt\": \"2024-01-01T17:13:19.549Z\",\n \"updatedAt\": \"2024-01-01T17:13:19.549Z\",\n \"expireAt\": \"2024-01-01T17:13:19.549Z\"\n }\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"400"} value={"400"}><div>
</div><div><MimeTabs schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs><TabItem label={"Schema"} value={"Schema"}><details style={{}} data-collapsed={false} open={true}><summary style={{"textAlign":"left"}}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}}><summary style={{}}><strong>checkoutSession</strong><span style={{"opacity":"0.6"}}> object</span></summary><div style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"id"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"checkoutUrl"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"successUrl"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"cancelUrl"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"metadata"} required={false} schemaName={"object"} qualifierMessage={undefined} schema={{"type":"object"}}></SchemaItem><SchemaItem collapsible={false} name={"createdAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem><SchemaItem collapsible={false} name={"updatedAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem><SchemaItem collapsible={false} name={"expireAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem></div></details></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n \"checkoutSession\": {\n \"id\": \"string\",\n \"checkoutUrl\": \"string\",\n \"successUrl\": \"string\",\n \"cancelUrl\": \"string\",\n \"state\": \"string\",\n \"metadata\": {},\n \"createdAt\": \"2024-01-02T15:11:02.039Z\",\n \"updatedAt\": \"2024-01-02T15:11:02.039Z\",\n \"expireAt\": \"2024-01-02T15:11:02.039Z\"\n }\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"400"} value={"400"}><div>

Bad Request - The request was malformed or contained invalid parameters.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ Billing account to create.

A successful response.

</div><div><MimeTabs schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs><TabItem label={"Schema"} value={"Schema"}><details style={{}} data-collapsed={false} open={true}><summary style={{"textAlign":"left"}}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}}><summary style={{}}><strong>billingAccount</strong><span style={{"opacity":"0.6"}}> object</span></summary><div style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"id"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"orgId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"name"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"email"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"phone"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}}><summary style={{}}><strong>address</strong><span style={{"opacity":"0.6"}}> object</span></summary><div style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"line1"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"line2"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"city"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"postalCode"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"country"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem></div></details></SchemaItem><SchemaItem collapsible={false} name={"providerId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"provider"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"currency"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"metadata"} required={false} schemaName={"object"} qualifierMessage={undefined} schema={{"type":"object"}}></SchemaItem><SchemaItem collapsible={false} name={"createdAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem><SchemaItem collapsible={false} name={"updatedAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem></div></details></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n \"billingAccount\": {\n \"id\": \"string\",\n \"orgId\": \"string\",\n \"name\": \"string\",\n \"email\": \"string\",\n \"phone\": \"string\",\n \"address\": {\n \"line1\": \"string\",\n \"line2\": \"string\",\n \"city\": \"string\",\n \"state\": \"string\",\n \"postalCode\": \"string\",\n \"country\": \"string\"\n },\n \"providerId\": \"string\",\n \"provider\": \"string\",\n \"currency\": \"string\",\n \"state\": \"string\",\n \"metadata\": {},\n \"createdAt\": \"2024-01-01T17:13:19.582Z\",\n \"updatedAt\": \"2024-01-01T17:13:19.582Z\"\n }\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"400"} value={"400"}><div>
</div><div><MimeTabs schemaType={"response"}><TabItem label={"application/json"} value={"application/json"}><SchemaTabs><TabItem label={"Schema"} value={"Schema"}><details style={{}} data-collapsed={false} open={true}><summary style={{"textAlign":"left"}}><strong>Schema</strong></summary><div style={{"textAlign":"left","marginLeft":"1rem"}}></div><ul style={{"marginLeft":"1rem"}}><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}}><summary style={{}}><strong>billingAccount</strong><span style={{"opacity":"0.6"}}> object</span></summary><div style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"id"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"orgId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"name"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"email"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"phone"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={true} className={"schemaItem"}><details style={{}}><summary style={{}}><strong>address</strong><span style={{"opacity":"0.6"}}> object</span></summary><div style={{"marginLeft":"1rem"}}><SchemaItem collapsible={false} name={"line1"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"line2"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"city"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"postalCode"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"country"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem></div></details></SchemaItem><SchemaItem collapsible={false} name={"providerId"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"provider"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"currency"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"state"} required={false} schemaName={"string"} qualifierMessage={undefined} schema={{"type":"string"}}></SchemaItem><SchemaItem collapsible={false} name={"metadata"} required={false} schemaName={"object"} qualifierMessage={undefined} schema={{"type":"object"}}></SchemaItem><SchemaItem collapsible={false} name={"createdAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem><SchemaItem collapsible={false} name={"updatedAt"} required={false} schemaName={"date-time"} qualifierMessage={undefined} schema={{"type":"string","format":"date-time"}}></SchemaItem></div></details></SchemaItem></ul></details></TabItem><TabItem label={"Example (from schema)"} value={"Example (from schema)"}><ResponseSamples responseExample={"{\n \"billingAccount\": {\n \"id\": \"string\",\n \"orgId\": \"string\",\n \"name\": \"string\",\n \"email\": \"string\",\n \"phone\": \"string\",\n \"address\": {\n \"line1\": \"string\",\n \"line2\": \"string\",\n \"city\": \"string\",\n \"state\": \"string\",\n \"postalCode\": \"string\",\n \"country\": \"string\"\n },\n \"providerId\": \"string\",\n \"provider\": \"string\",\n \"currency\": \"string\",\n \"state\": \"string\",\n \"metadata\": {},\n \"createdAt\": \"2024-01-02T15:11:02.078Z\",\n \"updatedAt\": \"2024-01-02T15:11:02.078Z\"\n }\n}"} language={"json"}></ResponseSamples></TabItem></SchemaTabs></TabItem></MimeTabs></div></TabItem><TabItem label={"400"} value={"400"}><div>

Bad Request - The request was malformed or contained invalid parameters.

Expand Down
4 changes: 2 additions & 2 deletions docs/docs/apis/frontier-service-create-billing-usage.api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ api:
"type": "string",
"amount": "string",
"metadata": {},
"createdAt": "2024-01-01T17:13:19.537Z",
"updatedAt": "2024-01-01T17:13:19.537Z",
"createdAt": "2024-01-02T15:11:02.027Z",
"updatedAt": "2024-01-02T15:11:02.027Z",
},
],
},
Expand Down
Loading

0 comments on commit c449799

Please sign in to comment.