2019-09-26 13:59:33 +02:00
|
|
|
import * as plugins from './bunq.plugins';
|
2025-07-18 10:31:12 +00:00
|
|
|
import { BunqApiContext } from './bunq.classes.apicontext';
|
2020-08-21 01:33:30 +00:00
|
|
|
import { BunqMonetaryAccount } from './bunq.classes.monetaryaccount';
|
2025-07-18 10:31:12 +00:00
|
|
|
import { BunqUser } from './bunq.classes.user';
|
|
|
|
import { IBunqSessionServerResponse } from './bunq.interfaces';
|
2019-09-26 13:59:33 +02:00
|
|
|
|
|
|
|
export interface IBunqConstructorOptions {
|
2019-10-02 23:34:05 +02:00
|
|
|
deviceName: string;
|
|
|
|
apiKey: string;
|
|
|
|
environment: 'SANDBOX' | 'PRODUCTION';
|
2025-07-18 10:31:12 +00:00
|
|
|
permittedIps?: string[];
|
2019-09-26 13:59:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* the main bunq account
|
|
|
|
*/
|
|
|
|
export class BunqAccount {
|
2019-10-02 23:34:05 +02:00
|
|
|
public options: IBunqConstructorOptions;
|
2025-07-18 10:31:12 +00:00
|
|
|
public apiContext: BunqApiContext;
|
2019-10-02 23:34:05 +02:00
|
|
|
public userId: number;
|
2025-07-18 10:31:12 +00:00
|
|
|
public userType: 'UserPerson' | 'UserCompany' | 'UserApiKey';
|
|
|
|
|
|
|
|
private bunqUser: BunqUser;
|
2019-10-02 23:34:05 +02:00
|
|
|
|
|
|
|
constructor(optionsArg: IBunqConstructorOptions) {
|
|
|
|
this.options = optionsArg;
|
2019-09-26 13:59:33 +02:00
|
|
|
}
|
|
|
|
|
2025-07-18 10:31:12 +00:00
|
|
|
/**
|
|
|
|
* Initialize the bunq account
|
|
|
|
*/
|
2019-10-02 23:34:05 +02:00
|
|
|
public async init() {
|
2025-07-18 10:31:12 +00:00
|
|
|
// Create API context
|
|
|
|
this.apiContext = new BunqApiContext({
|
|
|
|
apiKey: this.options.apiKey,
|
|
|
|
environment: this.options.environment,
|
|
|
|
deviceDescription: this.options.deviceName,
|
|
|
|
permittedIps: this.options.permittedIps
|
|
|
|
});
|
|
|
|
|
|
|
|
// Initialize API context (handles installation, device registration, session)
|
|
|
|
await this.apiContext.init();
|
|
|
|
|
|
|
|
// Create user instance
|
|
|
|
this.bunqUser = new BunqUser(this.apiContext);
|
|
|
|
|
|
|
|
// Get user info
|
|
|
|
await this.getUserInfo();
|
|
|
|
}
|
2019-10-02 23:34:05 +02:00
|
|
|
|
2025-07-18 10:31:12 +00:00
|
|
|
/**
|
|
|
|
* Get user information and ID
|
|
|
|
*/
|
|
|
|
private async getUserInfo() {
|
|
|
|
const userInfo = await this.bunqUser.getInfo();
|
|
|
|
|
|
|
|
if (userInfo.UserPerson) {
|
|
|
|
this.userId = userInfo.UserPerson.id;
|
|
|
|
this.userType = 'UserPerson';
|
|
|
|
} else if (userInfo.UserCompany) {
|
|
|
|
this.userId = userInfo.UserCompany.id;
|
|
|
|
this.userType = 'UserCompany';
|
|
|
|
} else if (userInfo.UserApiKey) {
|
|
|
|
this.userId = userInfo.UserApiKey.id;
|
|
|
|
this.userType = 'UserApiKey';
|
2019-10-03 14:04:15 +02:00
|
|
|
} else {
|
2025-07-18 10:31:12 +00:00
|
|
|
throw new Error('Could not determine user type');
|
2019-10-03 14:04:15 +02:00
|
|
|
}
|
2025-07-18 10:31:12 +00:00
|
|
|
}
|
2019-10-02 23:34:05 +02:00
|
|
|
|
2025-07-18 10:31:12 +00:00
|
|
|
/**
|
|
|
|
* Get all monetary accounts
|
|
|
|
*/
|
|
|
|
public async getAccounts(): Promise<BunqMonetaryAccount[]> {
|
|
|
|
await this.apiContext.ensureValidSession();
|
|
|
|
|
|
|
|
const response = await this.apiContext.getHttpClient().list(
|
|
|
|
`/v1/user/${this.userId}/monetary-account`
|
2019-10-02 23:34:05 +02:00
|
|
|
);
|
|
|
|
|
2025-07-18 10:31:12 +00:00
|
|
|
const accountsArray: BunqMonetaryAccount[] = [];
|
|
|
|
|
|
|
|
if (response.Response) {
|
|
|
|
for (const apiAccount of response.Response) {
|
|
|
|
accountsArray.push(BunqMonetaryAccount.fromAPIObject(this, apiAccount));
|
|
|
|
}
|
|
|
|
}
|
2019-09-26 13:59:33 +02:00
|
|
|
|
2025-07-18 10:31:12 +00:00
|
|
|
return accountsArray;
|
2019-09-26 13:59:33 +02:00
|
|
|
}
|
2019-10-02 23:34:05 +02:00
|
|
|
|
|
|
|
/**
|
2025-07-18 10:31:12 +00:00
|
|
|
* Get a specific monetary account
|
2019-10-02 23:34:05 +02:00
|
|
|
*/
|
2025-07-18 10:31:12 +00:00
|
|
|
public async getAccount(accountId: number): Promise<BunqMonetaryAccount> {
|
|
|
|
await this.apiContext.ensureValidSession();
|
|
|
|
|
|
|
|
const response = await this.apiContext.getHttpClient().get(
|
|
|
|
`/v1/user/${this.userId}/monetary-account/${accountId}`
|
|
|
|
);
|
|
|
|
|
|
|
|
if (response.Response && response.Response[0]) {
|
|
|
|
return BunqMonetaryAccount.fromAPIObject(this, response.Response[0]);
|
2019-10-02 23:34:05 +02:00
|
|
|
}
|
2025-07-18 10:31:12 +00:00
|
|
|
|
|
|
|
throw new Error('Account not found');
|
2019-10-02 23:34:05 +02:00
|
|
|
}
|
|
|
|
|
2025-07-18 10:31:12 +00:00
|
|
|
/**
|
|
|
|
* Create a sandbox user (only works in sandbox environment)
|
|
|
|
*/
|
|
|
|
public async createSandboxUser(): Promise<string> {
|
|
|
|
if (this.options.environment !== 'SANDBOX') {
|
|
|
|
throw new Error('Creating sandbox users only works in sandbox environment');
|
2019-10-02 23:34:05 +02:00
|
|
|
}
|
2025-07-18 10:31:12 +00:00
|
|
|
|
|
|
|
const response = await this.apiContext.getHttpClient().post(
|
|
|
|
'/v1/sandbox-user-person',
|
|
|
|
{}
|
|
|
|
);
|
|
|
|
|
|
|
|
if (response.Response && response.Response[0] && response.Response[0].ApiKey) {
|
|
|
|
return response.Response[0].ApiKey.api_key;
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('Failed to create sandbox user');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the user instance
|
|
|
|
*/
|
|
|
|
public getUser(): BunqUser {
|
|
|
|
return this.bunqUser;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the HTTP client
|
|
|
|
*/
|
|
|
|
public getHttpClient() {
|
|
|
|
return this.apiContext.getHttpClient();
|
2019-10-02 23:34:05 +02:00
|
|
|
}
|
2019-10-03 14:04:15 +02:00
|
|
|
|
2019-12-15 17:21:23 +00:00
|
|
|
/**
|
2025-07-18 10:31:12 +00:00
|
|
|
* Stop the bunq account and clean up
|
2019-12-15 17:21:23 +00:00
|
|
|
*/
|
2019-10-03 14:04:15 +02:00
|
|
|
public async stop() {
|
2025-07-18 10:31:12 +00:00
|
|
|
if (this.apiContext) {
|
|
|
|
await this.apiContext.destroy();
|
|
|
|
this.apiContext = null;
|
2019-10-03 14:04:15 +02:00
|
|
|
}
|
|
|
|
}
|
2019-10-02 23:34:05 +02:00
|
|
|
}
|