npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@finverse/sdk-typescript

v0.0.345

Published

OpenAPI client for @finverse/sdk-typescript

Readme

Finverse API - Typescript SDK

This SDK enables a basic end-to-end backend integration with the Finverse API, including API authentication, institution linking, and data retrieval.

Installation

npm install @finverse/sdk-typescript

Getting started (Linking flow)

1. Authenticate with Finverse API: Obtain Customer Access Token

// Obtain these from https://dashboard.finverse.com
const apiHost = "https://api.sandbox.finverse.net"
const clientId = process.env.FINVERSE_CLIENTID
const clientSecret = process.env.FINVERSE_SECRET
const redirectUri = process.env.REDIRECT_URI

const configuration = new Configuration({ basePath: apiHost });
// Obtain customer access token
const customerTokenResp = await new PublicApi(configuration).generateCustomerAccessToken({
	client_id: clientId,
	client_secret: clientSecret,
	grant_type: 'client_credentials',
});

const customerAccessToken = customerTokenResp.access_token

2. Link new institution: Obtain Link Token and Link URL to launch Finverse Link UI

// generate a link token

// reference back to your system userId, finverse does not use this
const userId = "someUserId"     
// this will be sent in the redirectUri callback, can be used to identify the state
const state = "someUniqueState" 
const configuration = new Configuration({ 
	basePath: apiHost, 
	accessToken: customerToken.access_token
});
const linkTokenResp = await new CustomerApi(configuration).generateLinkToken({
	client_id:     clientId,
        user_id:       userId,
        redirect_uri:  redirectUri,
        state:        state,
        response_mode: "form_post",
        response_type: "code",
	grant_type:    "client_credentials",
});

// The linkUrl can be used to initiate Finverse Link
console.log("linkUrl: " + linkTokenResp.link_url)

3. Finalize linking: Exchange code for Login Identity Access Token

// when Finverse Link UI is successful, obtain the code from Finverse Link
// exchange it for a Login Identity Access Token
const code = "obtainAfterLink"
const configuration = new Configuration({ 
	basePath: apiHost, 
	accessToken: customerToken.access_token 
});
const loginIdentityTokenResp = await new LinkApi(configuration).token(
	"authorization_code",
	code,
	clientId,
	redirectURI,
);

// The loginIdentityToken can be used to retrieve data
const loginIdentityToken = loginIdentityTokenResp.access_token

4. Retrieve data: Get data using Login Identity Access Token

// get LoginIdentity
const configuration = new Configuration({
	basePath: apiHost,
	accessToken: loginIdentityToken.access_token 
});
const loginIdentityResp = await new LoginIdentityApi(configuration).getLoginIdentity();


console.log("login identity: " + loginIdentityResp.login_identity)
    
// get other products (Accounts, Account Numbers, Transactions)

5. Poll loginIdentityStatus until ready

enum FinalStatus {
	ERROR = 'ERROR',
	DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL = 'DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL',
	DATA_RETRIEVAL_COMPLETE = 'DATA_RETRIEVAL_COMPLETE',
}

const configuration = new Configuration({
	basePath: apiHost,
	accessToken: loginIdentityToken.access_token 
});
let loginIdentity: AxiosResponse<GetLoginIdentityByIdResponse>;

// Poll until loginIdentityStatus is ready
for (let i = 0; i < 20; i++) {
	loginIdentity = await new LoginIdentityApi(configuration).getLoginIdentity();
	const loginIdentityStatus = loginIdentity.data.login_identity.status;
	if ( 
	  loginIdentityStatus === FinalStatus.ERROR ||
	  loginIdentityStatus === FinalStatus.DATA_RETRIEVAL_COMPLETE ||
	  loginIdentityStatus === FinalStatus.DATA_RETRIEVAL_PARTIALLY_SUCCESSFUL
	) { break; }
	
	await new Promise((resolve) => setTimeout(resolve, 3000));
}

console.log("login identity: " + loginIdentityResp.login_identity)
// get other products (Accounts, Account Numbers, Transactions)

6. Get Accounts

// Get Accounts
const configuration = new Configuration({ basePath: apiHost, accessToken: loginIdentityToken.access_token });
const accountsRsp = await new LoginIdentityApi(configuration).listAccounts();

console.log("accounts: " + accountsResp.accounts)

7. Get Transactions

// Get Transactions with pagination using offset and limit
let offset = 0
while(true) {
	const configuration = new Configuration({ basePath: apiHost, accessToken: loginIdentityToken.access_token });
        const transactionsResp = await new LoginIdentityApi(configuration).listTransactionsByLoginIdentityId();

	console.log(`total: ${transactionsResp.total_transactions}, transactions: ${transactionsResp.transactions}`)
	offset += transactionsResp.transactions.length

	if offset >= transactionsResp.total_transactions {
			break
	}
}

8. Get Statements

// Get Statements metadata
const configuration = new Configuration({ basePath: apiHost, accessToken: loginIdentityToken.access_token });
const statements = await new LoginIdentityApi(configuration).getStatements();

console.log("statements: "  + statementsResp.statements)

// Get link to statement
// Assuming there is only one statement
const statementId = statements.data.statements[0].id;

// Can download statement from here 
const statementResp = await new LoginIdentityApi(configuration).getStatement(statementId, true, {responseType: "arraybuffer"});
writeFileSync("statement.pdf", Buffer.from(statementResp.data));

Getting started (Payment flow)

1. Authenticate with Finverse API: Obtain Customer Access Token

// Obtain these from https://dashboard.finverse.com
const apiHost = "https://api.sandbox.finverse.net"
const clientId = process.env.FINVERSE_CLIENTID
const clientSecret = process.env.FINVERSE_SECRET
const redirectUri = process.env.REDIRECT_URI

const configuration = new Configuration({ basePath: apiHost });
// Obtain customer access token
const customerTokenResp = await new PublicApi(configuration).generateCustomerAccessToken({
	client_id: clientId,
	client_secret: clientSecret,
	grant_type: 'client_credentials',
});

const customerAccessToken = customerTokenResp.access_token

2. Create payment instruction

    const configuration = new Configuration({ basePath: config.apiHost, accessToken: customerToken.access_token });
    const paymentInstruction: CustomerPaymentInstruction = {
      type: "DEBIT_AUTHORIZATION",
      user_id: "customer_user1",
      frequency: "MONTHLY",
      start_date: "2022-04-01",
      end_date: "2022-12-01",
      amount: 1000,
      currency: "PHP",
      recipient_name: "HOMECREDIT",
      recipient_account_id: "Recipient Account Id",
      sender_name: "Sender Name",
      sender_account_id: "LOAN102345",
      remarks: "HOME CREDIT REPAYMENT"
    };
    const createPaymentInstructionResponse = await new CustomerApi(configuration).createPaymentInstruction(paymentInstruction);

    // createPaymentInstructionResponse.data.payment_instruction_id can be used to retrieve the status

3. Link with payment instruction: Obtain Link Token and Link URL to launch Finverse Link UI

// generate a link token

// reference back to your system userId, finverse does not use this
const userId = "someUserId"     
// this will be sent in the redirectUri callback, can be used to identify the state
const state = "someUniqueState" 
const configuration = new Configuration({ 
  basePath: apiHost, 
	accessToken: customerToken.access_token
});
const linkTokenResp = await new CustomerApi(configuration).generateLinkToken({
	client_id:     clientId,
  user_id:       userId,
  redirect_uri:  redirectUri,
  state:        state,
  response_mode: "form_post",
  response_type: "code",
	grant_type:    "client_credentials",
  payment_instruction_id: createPaymentInstructionResponse.data.payment_instruction_id,
  products_requested: "PAYMENTS",
});

// The linkUrl can be used to initiate Finverse Link
console.log("linkUrl: " + linkTokenResp.link_url)

4. Finalize linking: Exchange code for Login Identity Access Token

// when Finverse Link UI is successful, obtain the code from Finverse Link
// exchange it for a Login Identity Access Token
const code = "obtainAfterLink"
const configuration = new Configuration({ 
	basePath: apiHost, 
	accessToken: customerToken.access_token 
});
const loginIdentityTokenResp = await new LinkApi(configuration).token(
	"authorization_code",
	code,
	clientId,
	redirectURI,
);

// The loginIdentityToken can be used to retrieve data
const loginIdentityToken = loginIdentityTokenResp.access_token

5. Poll loginIdentityStatus until ready

Alternatively you can use webhook to receive LoginIdentity event.

enum FinalStatus {
	ERROR = 'ERROR',
	CONNECTION_COMPLETE= 'CONNECTION_COMPLETE',
}

const configuration = new Configuration({
	basePath: apiHost,
	accessToken: loginIdentityToken.access_token 
});
let loginIdentity: AxiosResponse<GetLoginIdentityByIdResponse>;

// Poll until loginIdentityStatus is ready
for (let i = 0; i < 20; i++) {
	loginIdentity = await new LoginIdentityApi(configuration).getLoginIdentity();
	const loginIdentityStatus = loginIdentity.data.login_identity.status;
	if ( 
	  loginIdentityStatus === FinalStatus.ERROR ||
	  loginIdentityStatus === FinalStatus.CONNECTION_COMPLETE
	) { break; }
	
	await new Promise((resolve) => setTimeout(resolve, 3000));
}

console.log("login identity: " + loginIdentityResp.login_identity)

6. Get payment instruction status

    const configuration = new Configuration({ basePath: config.apiHost, accessToken: customerToken.access_token });
    const getPaymentInstructionResponse = await new CustomerApi(configuration).getPaymentInstruction(createPaymentInstructionResponse.data.payment_instruction_id);

    console.log("paymentInstruction status: " + getPaymentInstructionResponse.data.payment_instruction.status);