Skip to content

Commit

Permalink
feat(sdk): show default payment method (#624)
Browse files Browse the repository at this point in the history
* chore: update proto generated client

* chore: update apsara to v0.13.0

* feat: show default payment method if user marked it as default

* Revert "chore: update apsara to v0.13.0"

This reverts commit ac96c57.
  • Loading branch information
rsbh authored May 20, 2024
1 parent 9818d93 commit e03efeb
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 6 deletions.
106 changes: 105 additions & 1 deletion sdks/js/packages/core/client/V1Beta1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
V1Beta1BatchCheckPermissionRequest,
V1Beta1BatchCheckPermissionResponse,
V1Beta1BillingAccountRequestBody,
V1Beta1BillingWebhookCallbackResponse,
V1Beta1CancelSubscriptionResponse,
V1Beta1ChangeSubscriptionResponse,
V1Beta1CheckFeatureEntitlementRequest,
Expand Down Expand Up @@ -77,6 +78,8 @@ import {
V1Beta1CreateServiceUserTokenResponse,
V1Beta1CreateUserPreferencesResponse,
V1Beta1CreateUserResponse,
V1Beta1CreateWebhookRequest,
V1Beta1CreateWebhookResponse,
V1Beta1DelegatedCheckoutResponse,
V1Beta1DeleteBillingAccountResponse,
V1Beta1DeleteGroupResponse,
Expand All @@ -96,6 +99,7 @@ import {
V1Beta1DeleteServiceUserResponse,
V1Beta1DeleteServiceUserTokenResponse,
V1Beta1DeleteUserResponse,
V1Beta1DeleteWebhookResponse,
V1Beta1DescribePreferencesResponse,
V1Beta1DisableGroupResponse,
V1Beta1DisableOrganizationResponse,
Expand Down Expand Up @@ -192,6 +196,7 @@ import {
V1Beta1ListUserInvitationsResponse,
V1Beta1ListUserPreferencesResponse,
V1Beta1ListUsersResponse,
V1Beta1ListWebhooksResponse,
V1Beta1MetaSchemaRequestBody,
V1Beta1OrganizationRequestBody,
V1Beta1PermissionRequestBody,
Expand Down Expand Up @@ -223,9 +228,11 @@ import {
V1Beta1UpdateRoleResponse,
V1Beta1UpdateSubscriptionResponse,
V1Beta1UpdateUserResponse,
V1Beta1UpdateWebhookResponse,
V1Beta1Usage,
V1Beta1UserRequestBody,
V1Beta1VerifyOrganizationDomainResponse
V1Beta1VerifyOrganizationDomainResponse,
V1Beta1WebhookRequestBody
} from './data-contracts';
import { ContentType, HttpClient, RequestParams } from './http-client';

Expand Down Expand Up @@ -569,6 +576,84 @@ export class V1Beta1<SecurityDataType = unknown> extends HttpClient<SecurityData
format: 'json',
...params
});
/**
* @description List all webhooks.
*
* @tags Webhook
* @name AdminServiceListWebhooks
* @summary List webhooks
* @request GET:/v1beta1/admin/webhooks
* @secure
*/
adminServiceListWebhooks = (params: RequestParams = {}) =>
this.request<V1Beta1ListWebhooksResponse, RpcStatus>({
path: `/v1beta1/admin/webhooks`,
method: 'GET',
secure: true,
format: 'json',
...params
});
/**
* @description Create a new webhook.
*
* @tags Webhook
* @name AdminServiceCreateWebhook
* @summary Create webhook
* @request POST:/v1beta1/admin/webhooks
* @secure
*/
adminServiceCreateWebhook = (body: V1Beta1CreateWebhookRequest, params: RequestParams = {}) =>
this.request<V1Beta1CreateWebhookResponse, RpcStatus>({
path: `/v1beta1/admin/webhooks`,
method: 'POST',
body: body,
secure: true,
type: ContentType.Json,
format: 'json',
...params
});
/**
* @description Delete a webhook.
*
* @tags Webhook
* @name AdminServiceDeleteWebhook
* @summary Delete webhook
* @request DELETE:/v1beta1/admin/webhooks/{id}
* @secure
*/
adminServiceDeleteWebhook = (id: string, params: RequestParams = {}) =>
this.request<V1Beta1DeleteWebhookResponse, RpcStatus>({
path: `/v1beta1/admin/webhooks/${id}`,
method: 'DELETE',
secure: true,
format: 'json',
...params
});
/**
* @description Update a webhook.
*
* @tags Webhook
* @name AdminServiceUpdateWebhook
* @summary Update webhook
* @request PUT:/v1beta1/admin/webhooks/{id}
* @secure
*/
adminServiceUpdateWebhook = (
id: string,
body: {
body?: V1Beta1WebhookRequestBody;
},
params: RequestParams = {}
) =>
this.request<V1Beta1UpdateWebhookResponse, RpcStatus>({
path: `/v1beta1/admin/webhooks/${id}`,
method: 'PUT',
body: body,
secure: true,
type: ContentType.Json,
format: 'json',
...params
});
/**
* @description Returns a list of identity providers configured on an instance level in Frontier. e.g Google, AzureAD, Github etc
*
Expand Down Expand Up @@ -1072,6 +1157,25 @@ export class V1Beta1<SecurityDataType = unknown> extends HttpClient<SecurityData
format: 'json',
...params
});
/**
* @description Accepts a Billing webhook and processes it.
*
* @tags Webhook
* @name FrontierServiceBillingWebhookCallback
* @summary Accept Billing webhook
* @request POST:/v1beta1/billing/webhooks/callback/{provider}
* @secure
*/
frontierServiceBillingWebhookCallback = (provider: string, body: string, params: RequestParams = {}) =>
this.request<V1Beta1BillingWebhookCallbackResponse, RpcStatus>({
path: `/v1beta1/billing/webhooks/callback/${provider}`,
method: 'POST',
body: body,
secure: true,
type: ContentType.Json,
format: 'json',
...params
});
/**
* @description Returns true if a principal has required permissions to access a resource and false otherwise.<br/> Note the principal can be a user or a service account. Frontier will extract principal from the current logged in session cookie (if any), or the client id and secret (in case of service users) or the access token.
*
Expand Down
59 changes: 58 additions & 1 deletion sdks/js/packages/core/client/data-contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ export interface SubscriptionPhase {
plan_id?: string;
}

export interface WebhookSecret {
id?: string;
value?: string;
}

export interface ProtobufAny {
'@type'?: string;
[key: string]: any;
Expand All @@ -74,7 +79,7 @@ export interface ProtobufAny {
* `NullValue` is a singleton enumeration to represent the null value for the
* `Value` type union.
*
* The JSON representation for `NullValue` is JSON `null`.
* The JSON representation for `NullValue` is JSON `null`.
*
* - NULL_VALUE: Null value.
* @default "NULL_VALUE"
Expand Down Expand Up @@ -264,6 +269,8 @@ export interface V1Beta1BillingTransaction {
customer?: V1Beta1BillingAccount;
}

export type V1Beta1BillingWebhookCallbackResponse = object;

export type V1Beta1CancelSubscriptionResponse = object;

export interface V1Beta1ChangeSubscriptionResponse {
Expand Down Expand Up @@ -522,6 +529,14 @@ export interface V1Beta1CreateUserResponse {
user?: V1Beta1User;
}

export interface V1Beta1CreateWebhookRequest {
body?: V1Beta1WebhookRequestBody;
}

export interface V1Beta1CreateWebhookResponse {
webhook?: V1Beta1Webhook;
}

export interface V1Beta1DelegatedCheckoutResponse {
/** subscription if created */
subscription?: V1Beta1Subscription;
Expand Down Expand Up @@ -565,6 +580,8 @@ export type V1Beta1DeleteServiceUserTokenResponse = object;

export type V1Beta1DeleteUserResponse = object;

export type V1Beta1DeleteWebhookResponse = object;

export interface V1Beta1DescribePreferencesResponse {
traits?: V1Beta1PreferenceTrait[];
}
Expand Down Expand Up @@ -1195,6 +1212,10 @@ export interface V1Beta1ListUsersResponse {
users?: V1Beta1User[];
}

export interface V1Beta1ListWebhooksResponse {
webhooks?: V1Beta1Webhook[];
}

export interface V1Beta1MetaSchema {
/**
* The unique metaschema uuid.
Expand Down Expand Up @@ -1861,6 +1882,10 @@ export interface V1Beta1UpdateUserResponse {
user?: V1Beta1User;
}

export interface V1Beta1UpdateWebhookResponse {
webhook?: V1Beta1Webhook;
}

export interface V1Beta1Usage {
/** uuid used as an idempotent key */
id?: string;
Expand Down Expand Up @@ -1940,3 +1965,35 @@ export interface V1Beta1UserRequestBody {
export interface V1Beta1VerifyOrganizationDomainResponse {
state?: string;
}

export interface V1Beta1Webhook {
id?: string;
description?: string;
url?: string;
subscribed_events?: string[];
/** headers to be sent with the webhook */
headers?: Record<string, string>;
/**
* secret to sign the payload, there could be multiple enabled secrets for a webhook
* but only one will be used to sign the payload, this is useful for rotating secrets
*/
secrets?: WebhookSecret[];
state?: string;
metadata?: object;
/** @format date-time */
created_at?: string;
/** @format date-time */
updated_at?: string;
}

export interface V1Beta1WebhookRequestBody {
/** URL to send the webhook to (valid absolute URI via RFC 3986) */
url?: string;
description?: string;
/** events to subscribe to, if empty all events are subscribed */
subscribed_events?: string[];
/** headers to be sent with the webhook */
headers?: Record<string, string>;
state?: string;
metadata?: object;
}
6 changes: 4 additions & 2 deletions sdks/js/packages/core/react/contexts/FrontierContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
V1Beta1User
} from '../../client/data-contracts';
import Frontier from '../frontier';
import { getActiveSubscription } from '../utils';
import { getActiveSubscription, getDefaultPaymentMethod } from '../utils';
import {
DEFAULT_DATE_FORMAT,
DEFAULT_DATE_SHORT_FORMAT
Expand Down Expand Up @@ -339,7 +339,9 @@ export const FrontierContextProvider = ({
if (resp?.data) {
const paymentMethods = resp?.data?.payment_methods || [];
setBillingAccount(resp.data.billing_account);
setPaymentMethod(paymentMethods[0]);
const defaultPaymentMethod =
getDefaultPaymentMethod(paymentMethods);
setPaymentMethod(defaultPaymentMethod);
}
} else {
setBillingAccount(undefined);
Expand Down
25 changes: 23 additions & 2 deletions sdks/js/packages/core/react/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import dayjs from 'dayjs';
import { V1Beta1Subscription, BillingAccountAddress, V1Beta1Plan } from '~/src';
import { IntervalKeys, IntervalLabelMap, IntervalPricing } from '~/src/types';
import {
V1Beta1Subscription,
BillingAccountAddress,
V1Beta1Plan,
V1Beta1PaymentMethod
} from '~/src';
import {
IntervalKeys,
IntervalLabelMap,
IntervalPricing,
PaymentMethodMetadata
} from '~/src/types';
import { SUBSCRIPTION_STATES } from './constants';
import slugify from 'slugify';

Expand Down Expand Up @@ -127,3 +137,14 @@ export function getPlanPrice(plan: V1Beta1Plan) {
}, {} as IntervalPricing) || ({} as IntervalPricing)
);
}

export function getDefaultPaymentMethod(
paymentMethods: V1Beta1PaymentMethod[] = []
) {
const defaultMethod = paymentMethods.find(pm => {
const metadata = pm.metadata as PaymentMethodMetadata;
return metadata.default;
});

return defaultMethod ? defaultMethod : paymentMethods[0];
}
4 changes: 4 additions & 0 deletions sdks/js/packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,7 @@ export interface PlanIntervalPricing {
intervals: Record<IntervalKeys, IntervalPricingWithPlan>;
weightage: number;
}

export interface PaymentMethodMetadata extends Record<string, any> {
default?: boolean;
}

0 comments on commit e03efeb

Please sign in to comment.