-
Notifications
You must be signed in to change notification settings - Fork 371
feat(backend): Add billing api and an endpoint for fetching plans #6449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
panteliselef
merged 14 commits into
main
from
elef/com-1028-expose-bapi-endpoints-from-clerkbackend
Aug 8, 2025
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
e853b50
feat(backend): Add billing api and an endpoint for fetching plans
panteliselef ee3edef
add plan to export
panteliselef 289eeda
remove logs
panteliselef 2554a2f
Merge branch 'main' into elef/com-1028-expose-bapi-endpoints-from-cle…
panteliselef fbaffb2
remove fields and add comments
panteliselef 4b43d14
add query by payer type
panteliselef ae89b78
update json types
panteliselef 7ef81fa
add notices
panteliselef 8ae406c
changelog
panteliselef 6f36af2
Merge branch 'main' into elef/com-1028-expose-bapi-endpoints-from-cle…
panteliselef e414254
Merge branch 'main' into elef/com-1028-expose-bapi-endpoints-from-cle…
panteliselef e04a74b
update typedocs
panteliselef 73e4851
Merge branch 'main' into elef/com-1028-expose-bapi-endpoints-from-cle…
panteliselef b5d9a51
Merge branch 'main' into elef/com-1028-expose-bapi-endpoints-from-cle…
panteliselef File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@clerk/backend': minor | ||
--- | ||
|
||
Add billing API for fetching available plans. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { ClerkPaginationRequest } from '@clerk/types'; | ||
|
||
import { joinPaths } from '../../util/path'; | ||
import type { CommercePlan } from '../resources/CommercePlan'; | ||
import type { PaginatedResourceResponse } from '../resources/Deserializer'; | ||
import { AbstractAPI } from './AbstractApi'; | ||
|
||
const basePath = '/commerce'; | ||
|
||
type GetOrganizationListParams = ClerkPaginationRequest<{ | ||
payerType: 'org' | 'user'; | ||
}>; | ||
|
||
export class BillingAPI extends AbstractAPI { | ||
/** | ||
* @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. | ||
* It is advised to pin the SDK version to avoid breaking changes. | ||
*/ | ||
public async getPlanList(params?: GetOrganizationListParams) { | ||
return this.request<PaginatedResourceResponse<CommercePlan[]>>({ | ||
method: 'GET', | ||
path: joinPaths(basePath, 'plans'), | ||
queryParams: params, | ||
}); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { Feature } from './Feature'; | ||
import type { CommercePlanJSON } from './JSON'; | ||
|
||
type CommerceFee = { | ||
amount: number; | ||
amountFormatted: string; | ||
currency: string; | ||
currencySymbol: string; | ||
}; | ||
|
||
/** | ||
* @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change. | ||
* It is advised to pin the SDK version to avoid breaking changes. | ||
*/ | ||
export class CommercePlan { | ||
panteliselef marked this conversation as resolved.
Show resolved
Hide resolved
|
||
constructor( | ||
/** | ||
* The unique identifier for the plan. | ||
*/ | ||
readonly id: string, | ||
/** | ||
* The id of the product the plan belongs to. | ||
*/ | ||
readonly productId: string, | ||
/** | ||
* The name of the plan. | ||
*/ | ||
readonly name: string, | ||
/** | ||
* The URL-friendly identifier of the plan. | ||
*/ | ||
readonly slug: string, | ||
/** | ||
* The description of the plan. | ||
*/ | ||
readonly description: string | undefined, | ||
/** | ||
* Whether the plan is the default plan. | ||
*/ | ||
readonly isDefault: boolean, | ||
/** | ||
* Whether the plan is recurring. | ||
*/ | ||
readonly isRecurring: boolean, | ||
/** | ||
* Whether the plan has a base fee. | ||
*/ | ||
readonly hasBaseFee: boolean, | ||
/** | ||
* Whether the plan is displayed in the `<PriceTable/>` component. | ||
*/ | ||
readonly publiclyVisible: boolean, | ||
/** | ||
* The monthly fee of the plan. | ||
*/ | ||
readonly fee: CommerceFee, | ||
/** | ||
* The annual fee of the plan. | ||
*/ | ||
readonly annualFee: CommerceFee, | ||
/** | ||
* The annual fee of the plan on a monthly basis. | ||
*/ | ||
readonly annualMonthlyFee: CommerceFee, | ||
/** | ||
* The type of payer for the plan. | ||
*/ | ||
readonly forPayerType: 'org' | 'user', | ||
/** | ||
* The features the plan offers. | ||
*/ | ||
readonly features: Feature[], | ||
) {} | ||
|
||
static fromJSON(data: CommercePlanJSON): CommercePlan { | ||
panteliselef marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const formatAmountJSON = (fee: CommercePlanJSON['fee']) => { | ||
return { | ||
amount: fee.amount, | ||
amountFormatted: fee.amount_formatted, | ||
currency: fee.currency, | ||
currencySymbol: fee.currency_symbol, | ||
}; | ||
}; | ||
return new CommercePlan( | ||
data.id, | ||
data.product_id, | ||
data.name, | ||
data.slug, | ||
data.description, | ||
data.is_default, | ||
data.is_recurring, | ||
data.has_base_fee, | ||
data.publicly_visible, | ||
formatAmountJSON(data.fee), | ||
formatAmountJSON(data.annual_fee), | ||
formatAmountJSON(data.annual_monthly_fee), | ||
data.for_payer_type, | ||
data.features.map(feature => Feature.fromJSON(feature)), | ||
); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { FeatureJSON } from './JSON'; | ||
|
||
export class Feature { | ||
constructor( | ||
readonly id: string, | ||
readonly name: string, | ||
readonly description: string, | ||
readonly slug: string, | ||
readonly avatarUrl: string, | ||
) {} | ||
panteliselef marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
static fromJSON(data: FeatureJSON): Feature { | ||
return new Feature(data.id, data.name, data.description, data.slug, data.avatar_url); | ||
} | ||
panteliselef marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.