0.0.269 • Published 7 months ago

@finverse/sdk-typescript v0.0.269

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

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);
0.0.269

7 months ago

0.0.268

8 months ago

0.0.267

8 months ago

0.0.266

8 months ago

0.0.259

9 months ago

0.0.258

9 months ago

0.0.263

8 months ago

0.0.262

8 months ago

0.0.261

9 months ago

0.0.260

9 months ago

0.0.265

8 months ago

0.0.264

8 months ago

0.0.257

9 months ago

0.0.256

9 months ago

0.0.255

9 months ago

0.0.254

9 months ago

0.0.238

1 year ago

0.0.237

1 year ago

0.0.239

1 year ago

0.0.249

11 months ago

0.0.248

12 months ago

0.0.247

12 months ago

0.0.246

12 months ago

0.0.241

1 year ago

0.0.240

1 year ago

0.0.245

1 year ago

0.0.244

1 year ago

0.0.243

1 year ago

0.0.242

1 year ago

0.0.252

10 months ago

0.0.251

11 months ago

0.0.250

11 months ago

0.0.253

10 months ago

0.0.236

1 year ago

0.0.235

1 year ago

0.0.234

1 year ago

0.0.233

1 year ago

0.0.232

1 year ago

0.0.231

1 year ago

0.0.230

1 year ago

0.0.229

1 year ago

0.0.228

1 year ago

0.0.227

1 year ago

0.0.226

1 year ago

0.0.225

1 year ago

0.0.224

1 year ago

0.0.223

1 year ago

0.0.222

1 year ago

0.0.221

1 year ago

0.0.220

1 year ago

0.0.219

1 year ago

0.0.216

1 year ago

0.0.218

1 year ago

0.0.217

1 year ago

0.0.215

1 year ago

0.0.214

1 year ago

0.0.213

1 year ago

0.0.212

1 year ago

0.0.211

1 year ago

0.0.209

1 year ago

0.0.210

1 year ago

0.0.208

1 year ago

0.0.207

2 years ago

0.0.205

2 years ago

0.0.206

2 years ago

0.0.204

2 years ago

0.0.203

2 years ago

0.0.202

2 years ago

0.0.201

2 years ago

0.0.200

2 years ago

0.0.199

2 years ago

0.0.198

2 years ago

0.0.197

2 years ago

0.0.196

2 years ago

0.0.195

2 years ago

0.0.194

2 years ago

0.0.193

2 years ago

0.0.192

2 years ago

0.0.191

2 years ago

0.0.190

2 years ago

0.0.159

2 years ago

0.0.158

2 years ago

0.0.153

2 years ago

0.0.152

2 years ago

0.0.151

2 years ago

0.0.150

2 years ago

0.0.157

2 years ago

0.0.156

2 years ago

0.0.155

2 years ago

0.0.154

2 years ago

0.0.169

2 years ago

0.0.164

2 years ago

0.0.163

2 years ago

0.0.162

2 years ago

0.0.161

2 years ago

0.0.168

2 years ago

0.0.167

2 years ago

0.0.166

2 years ago

0.0.165

2 years ago

0.0.160

2 years ago

0.0.175

2 years ago

0.0.174

2 years ago

0.0.173

2 years ago

0.0.172

2 years ago

0.0.179

2 years ago

0.0.178

2 years ago

0.0.177

2 years ago

0.0.176

2 years ago

0.0.171

2 years ago

0.0.170

2 years ago

0.0.186

2 years ago

0.0.185

2 years ago

0.0.184

2 years ago

0.0.183

2 years ago

0.0.189

2 years ago

0.0.188

2 years ago

0.0.187

2 years ago

0.0.182

2 years ago

0.0.181

2 years ago

0.0.180

2 years ago

0.0.139

2 years ago

0.0.138

2 years ago

0.0.149

2 years ago

0.0.148

2 years ago

0.0.147

2 years ago

0.0.142

2 years ago

0.0.141

2 years ago

0.0.140

2 years ago

0.0.146

2 years ago

0.0.145

2 years ago

0.0.144

2 years ago

0.0.143

2 years ago

0.0.137

2 years ago

0.0.136

2 years ago

0.0.135

2 years ago

0.0.128

2 years ago

0.0.127

2 years ago

0.0.126

2 years ago

0.0.125

2 years ago

0.0.129

2 years ago

0.0.124

2 years ago

0.0.123

2 years ago

0.0.131

2 years ago

0.0.130

2 years ago

0.0.134

2 years ago

0.0.133

2 years ago

0.0.132

2 years ago

0.0.120

2 years ago

0.0.122

2 years ago

0.0.121

2 years ago

0.0.119

2 years ago

0.0.118

2 years ago

0.0.117

2 years ago

0.0.116

2 years ago

0.0.115

2 years ago

0.0.114

2 years ago

0.0.113

2 years ago

0.0.112

2 years ago

0.0.84

3 years ago

0.0.85

3 years ago

0.0.86

3 years ago

0.0.87

3 years ago

0.0.88

3 years ago

0.0.89

3 years ago

0.0.80

3 years ago

0.0.81

3 years ago

0.0.82

3 years ago

0.0.83

3 years ago

0.0.73

3 years ago

0.0.74

3 years ago

0.0.75

3 years ago

0.0.76

3 years ago

0.0.77

3 years ago

0.0.78

3 years ago

0.0.79

3 years ago

0.0.70

3 years ago

0.0.71

3 years ago

0.0.72

3 years ago

0.0.64

3 years ago

0.0.65

3 years ago

0.0.66

3 years ago

0.0.67

3 years ago

0.0.68

3 years ago

0.0.69

3 years ago

0.0.106

2 years ago

0.0.105

2 years ago

0.0.104

2 years ago

0.0.103

2 years ago

0.0.109

2 years ago

0.0.108

2 years ago

0.0.107

2 years ago

0.0.102

3 years ago

0.0.101

3 years ago

0.0.100

3 years ago

0.0.111

2 years ago

0.0.110

2 years ago

0.0.95

3 years ago

0.0.96

3 years ago

0.0.97

3 years ago

0.0.98

3 years ago

0.0.99

3 years ago

0.0.90

3 years ago

0.0.91

3 years ago

0.0.92

3 years ago

0.0.93

3 years ago

0.0.94

3 years ago

0.0.40

3 years ago

0.0.41

3 years ago

0.0.42

3 years ago

0.0.43

3 years ago

0.0.44

3 years ago

0.0.45

3 years ago

0.0.46

3 years ago

0.0.47

3 years ago

0.0.37

3 years ago

0.0.38

3 years ago

0.0.39

3 years ago

0.0.35

3 years ago

0.0.36

3 years ago

0.0.62

3 years ago

0.0.63

3 years ago

0.0.60

3 years ago

0.0.61

3 years ago

0.0.59

3 years ago

0.0.51

3 years ago

0.0.52

3 years ago

0.0.53

3 years ago

0.0.54

3 years ago

0.0.55

3 years ago

0.0.56

3 years ago

0.0.57

3 years ago

0.0.58

3 years ago

0.0.50

3 years ago

0.0.48

3 years ago

0.0.49

3 years ago

0.0.34

3 years ago

0.0.30

3 years ago

0.0.31

3 years ago

0.0.32

3 years ago

0.0.33

3 years ago

0.0.29

3 years ago

0.0.23

3 years ago

0.0.24

3 years ago

0.0.25

3 years ago

0.0.26

3 years ago

0.0.27

3 years ago

0.0.28

3 years ago

0.0.20

3 years ago

0.0.21

3 years ago

0.0.22

3 years ago

0.0.16

3 years ago

0.0.17

3 years ago

0.0.18

3 years ago

0.0.19

3 years ago

0.0.15

3 years ago

0.0.10

3 years ago

0.0.11

3 years ago

0.0.12

3 years ago

0.0.13

3 years ago

0.0.14

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.5

3 years ago

0.0.4

3 years ago

0.0.7

3 years ago

0.0.6

3 years ago

0.0.3

3 years ago

0.0.1-1646812798

3 years ago

0.0.1-1646793114

3 years ago

0.0.1-1646789936

3 years ago

0.0.1-1646727625

3 years ago

0.0.1-1646384108

3 years ago

0.0.1-1646361421

3 years ago

0.0.1-1646299688

3 years ago

0.0.1-1646291328

3 years ago

0.0.1-1646286081

3 years ago

0.0.1-1646284786

3 years ago

0.0.1-1646284878

3 years ago

0.0.1-1646131492

3 years ago

0.0.1-1646124671

3 years ago

0.0.1-1646121838

3 years ago

0.0.1-1646120691

3 years ago