0.0.269 • Published 9 months ago

@finverse/sdk-typescript v0.0.269

Weekly downloads
-
License
MIT
Repository
github
Last release
9 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

9 months ago

0.0.268

9 months ago

0.0.267

10 months ago

0.0.266

10 months ago

0.0.259

10 months ago

0.0.258

10 months ago

0.0.263

10 months ago

0.0.262

10 months ago

0.0.261

10 months ago

0.0.260

10 months ago

0.0.265

10 months ago

0.0.264

10 months ago

0.0.257

11 months ago

0.0.256

11 months ago

0.0.255

11 months ago

0.0.254

11 months ago

0.0.238

1 year ago

0.0.237

1 year ago

0.0.239

1 year ago

0.0.249

1 year ago

0.0.248

1 year ago

0.0.247

1 year ago

0.0.246

1 year 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

12 months ago

0.0.251

1 year ago

0.0.250

1 year ago

0.0.253

11 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

2 years ago

0.0.221

2 years ago

0.0.220

2 years ago

0.0.219

2 years ago

0.0.216

2 years ago

0.0.218

2 years ago

0.0.217

2 years ago

0.0.215

2 years ago

0.0.214

2 years ago

0.0.213

2 years ago

0.0.212

2 years ago

0.0.211

2 years ago

0.0.209

2 years ago

0.0.210

2 years ago

0.0.208

2 years 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

3 years ago

0.0.112

3 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

3 years ago

0.0.105

3 years ago

0.0.104

3 years ago

0.0.103

3 years ago

0.0.109

3 years ago

0.0.108

3 years ago

0.0.107

3 years ago

0.0.102

3 years ago

0.0.101

3 years ago

0.0.100

3 years ago

0.0.111

3 years ago

0.0.110

3 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