Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@internxt/sdk",
"author": "Internxt <[email protected]>",
"version": "1.9.15",
"version": "1.9.16",
"description": "An sdk for interacting with Internxt's services",
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * as photos from './photos';
export * as Shared from './shared';
export * as Workspaces from './workspaces';
export * from './meet';
export * as Payments from './payments';
172 changes: 172 additions & 0 deletions src/payments/checkout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { CreatedSubscriptionData } from '../drive/payments/types/types';
import { ApiSecurity, ApiUrl, AppDetails } from '../shared';
import { basicHeaders, headersWithToken } from '../shared/headers';
import { HttpClient } from '../shared/http/client';
import { CreatePaymentIntentPayload, CreateSubscriptionPayload, GetPriceByIdPayload, PriceWithTax } from './types';

export class Checkout {
private readonly client: HttpClient;
private readonly appDetails: AppDetails;
private readonly apiSecurity: ApiSecurity;

public static client(apiUrl: ApiUrl, appDetails: AppDetails, apiSecurity: ApiSecurity) {
return new Checkout(apiUrl, appDetails, apiSecurity);
}

private constructor(apiUrl: ApiUrl, appDetails: AppDetails, apiSecurity: ApiSecurity) {
this.client = HttpClient.create(apiUrl, apiSecurity.unauthorizedCallback);
this.appDetails = appDetails;
this.apiSecurity = apiSecurity;
}

/**
* @description Creates a customer or gets the existing one if it already exists
* @param country - The country of the customer
* @param postalCode - The postal code of the customer
* @param companyVatId - The VAT ID of the company (optional)
* @returns The customer ID and the user token used to create a subscription or payment intent
*/
public getCustomerId({
country,
postalCode,
companyVatId,
companyName,
}: {
country: string;
postalCode: string;
companyVatId?: string;
companyName?: string;
}): Promise<{
customerId: string;
token: string;
}> {
const query = new URLSearchParams();
query.set('country', country);
query.set('postalCode', postalCode);
if (companyVatId !== undefined) query.set('companyVatId', companyVatId);
if (companyName !== undefined) query.set('companyName', companyName);
return this.client.get(`/checkout/customer?${query.toString()}`, this.authHeaders());
}

/**
* @description Creates a subscription for a given customer
* @param customerId - The ID of the customer
* @param priceId - The ID of the price
* @param token - The token used to authenticate the customer
* @param currency - The currency of the subscription (optional)
* @param promoCodeId - The ID of the promo code (optional)
* @param quantity - The quantity of the subscription (optional)
* @returns The created subscription data:
* - `type`: The type of the subscription (setup or payment)
* - `clientSecret`: The client secret for the subscription to be used with Stripe Elements
* - `subscriptionId`: The ID of the subscription (optional)
* - `paymentIntentId`: The ID of the payment intent (optional)
*/
public createSubscription({
customerId,
priceId,
token,
currency,
promoCodeId,
quantity,
}: CreateSubscriptionPayload): Promise<CreatedSubscriptionData> {
return this.client.post(
'/checkout/subscription',
{
customerId,
priceId,
token,
currency,
promoCodeId,
quantity,
},
this.authHeaders(),
);
}

/**
* @description Creates a payment intent for a given customer
* @param customerId - The ID of the customer
* @param priceId - The ID of the price
* @param token - The token used to authenticate the customer
* @param currency - The currency of the payment intent (optional)
* @param promoCodeId - The ID of the promo code (optional)
* @returns The created invoice data:
* - `clientSecret`: The client secret for the invoice to be used with Stripe Elements
* - `id`: The ID of the invoice
* - `invoiceStatus`: The status of the invoice (only when the status is 'paid')
*/
public createPaymentIntent({
customerId,
priceId,
token,
currency,
promoCodeId,
}: CreatePaymentIntentPayload): Promise<{ clientSecret: string; id: string; invoiceStatus?: string }> {
return this.client.post(
'/checkout/payment-intent',
{
customerId,
priceId,
token,
currency,
promoCodeId,
},
this.authHeaders(),
);
}

/**
* @description Fetch a requested price by its ID and its tax rate
* @param priceId - The ID of the price
* @param promoCodeName - The name of the promo code (optional)
* @param currency - The currency of the price (optional)
* @returns The price object containing the details of the requested price
*/
public getPriceById({
priceId,
promoCodeName,
currency,
postalCode,
country,
}: GetPriceByIdPayload): Promise<PriceWithTax> {
const query = new URLSearchParams();
query.set('priceId', priceId);
if (promoCodeName !== undefined) query.set('promoCodeName', promoCodeName);
if (currency !== undefined) query.set('currency', currency);
if (postalCode !== undefined) query.set('postalCode', postalCode);
if (country !== undefined) query.set('country', country);
return this.client.get<PriceWithTax>(`/checkout/price-by-id?${query.toString()}`, this.headers());
}

/**
* Returns the needed headers with authorization header for the module requests
* @private
*/
private authHeaders() {
const additionalHeaders: Record<string, string> = {};

if (this.appDetails.desktopHeader) {
additionalHeaders['x-internxt-desktop-header'] = this.appDetails.desktopHeader;
}

return headersWithToken(
this.appDetails.clientName,
this.appDetails.clientVersion,
this.apiSecurity.token,
undefined,
additionalHeaders,
);
}

/**
* Returns the basic needed headers for the module requests
* @private
*/
private headers() {
const additionalHeaders: Record<string, string> = {
...(this.appDetails.customHeaders ?? {}),
};
return basicHeaders(this.appDetails.clientName, this.appDetails.clientVersion, additionalHeaders);
}
}
1 change: 1 addition & 0 deletions src/payments/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './checkout';
51 changes: 51 additions & 0 deletions src/payments/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { UserType } from 'src/drive/payments/types/types';

export interface CreateSubscriptionPayload {
customerId: string;
priceId: string;
token: string;
currency?: string;
promoCodeId?: string;
quantity?: number;
}

export interface CreatePaymentIntentPayload {
customerId: string;
priceId: string;
token: string;
currency?: string;
promoCodeId?: string;
}

export interface GetPriceByIdPayload {
priceId: string;
promoCodeName?: string;
currency?: string;
postalCode?: string;
country?: string;
}

export type Price = {
id: string;
currency: string;
amount: number;
bytes: number;
interval: 'lifetime' | 'year';
decimalAmount: number;
type: UserType;
product: string;
minimumSeats?: number;
maximumSeats?: number;
};

export type Taxes = {
tax: number;
decimalTax: number;
amountWithTax: number;
decimalAmountWithTax: number;
};

export type PriceWithTax = {
price: Price;
taxes: Taxes;
};
7 changes: 6 additions & 1 deletion src/shared/headers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ type InternxtHeaders = {
'internxt-resources-token'?: string;
};

export function basicHeaders(clientName: string, clientVersion: string): InternxtHeaders {
export function basicHeaders(
clientName: string,
clientVersion: string,
customHeaders?: Record<string, string>,
): InternxtHeaders {
return {
'content-type': 'application/json; charset=utf-8',
'internxt-version': clientVersion,
'internxt-client': clientName,
...customHeaders,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/shared/types/apiConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type ApiUrl = string;
export interface AppDetails {
clientName: string;
clientVersion: string;
customHeaders?: Record<string, string>;
desktopHeader?: string;
}

Expand Down