├── .gitignore ├── DEVELOPING.md ├── README.md ├── __tests__ ├── client.ts ├── errors.ts ├── fixtures │ ├── test_webhook_rsa │ └── test_webhook_rsa.pub └── webhooks.ts ├── babel.config.js ├── docs ├── README.md ├── classes │ ├── AccountsResource.md │ ├── AkahuClient.md │ ├── AkahuErrorResponse.md │ ├── AkahuWebhookValidationError.md │ ├── AuthResource.md │ ├── CategoriesResource.md │ ├── ConnectionsResource.md │ ├── IdentitiesResource.md │ ├── PartiesResource.md │ ├── PaymentsResource.md │ ├── TransactionsResource.md │ ├── TransfersResource.md │ ├── UsersResource.md │ └── WebhooksResource.md ├── interfaces │ └── WebhookSigningKeyCache.md └── type-aliases │ ├── Account.md │ ├── AccountHolderNameVerificationSource.md │ ├── AccountPayload.md │ ├── AkahuClientConfig.md │ ├── AuthorizationToken.md │ ├── BasePayload.md │ ├── CancelledPayload.md │ ├── Category.md │ ├── Connection.md │ ├── CurrencyConversion.md │ ├── Cursor.md │ ├── EnrichedTransaction.md │ ├── IdentityResult.md │ ├── IdentityVerifyNameQuery.md │ ├── IdentityVerifyNameResult.md │ ├── IrdPaymentCreateParams.md │ ├── Paginated.md │ ├── Party.md │ ├── PartyAddress.md │ ├── PartyDob.md │ ├── PartyEmail.md │ ├── PartyName.md │ ├── PartyNameVerificationSource.md │ ├── PartyPhoneNumber.md │ ├── PartyTaxNumber.md │ ├── Payment.md │ ├── PaymentCreateParams.md │ ├── PaymentPayload.md │ ├── PaymentQueryParams.md │ ├── PaymentStatus.md │ ├── PaymentStatusCode.md │ ├── PendingTransaction.md │ ├── PostRequestOptions.md │ ├── Protocol.md │ ├── RawTransaction.md │ ├── TokenPayload.md │ ├── Transaction.md │ ├── TransactionPayload.md │ ├── TransactionQueryParams.md │ ├── TransactionType.md │ ├── Transfer.md │ ├── TransferCreateParams.md │ ├── TransferPayload.md │ ├── TransferQueryParams.md │ ├── TransferStatus.md │ ├── User.md │ ├── Webhook.md │ ├── WebhookCacheConfig.md │ ├── WebhookCreateParams.md │ ├── WebhookEvent.md │ ├── WebhookEventQueryParams.md │ ├── WebhookPayload.md │ ├── WebhookStatus.md │ └── WebhookType.md ├── example ├── README.md ├── index.ts ├── package-lock.json ├── package.json └── tsconfig.json ├── package-lock.json ├── package.json ├── rollup.config.js ├── scripts └── version.js ├── src ├── client.ts ├── errors.ts ├── index.ts ├── models │ ├── accounts.ts │ ├── auth.ts │ ├── categories.ts │ ├── connections.ts │ ├── generic.ts │ ├── identities.ts │ ├── index.ts │ ├── parties.ts │ ├── payments.ts │ ├── transactions.ts │ ├── transfers.ts │ ├── users.ts │ └── webhooks.ts ├── resources │ ├── accounts.ts │ ├── auth.ts │ ├── base.ts │ ├── categories.ts │ ├── connections.ts │ ├── identities.ts │ ├── parties.ts │ ├── payments.ts │ ├── transactions.ts │ ├── transfers.ts │ ├── users.ts │ └── webhooks.ts ├── utils.ts └── version.ts ├── tsconfig.build.json ├── tsconfig.json └── typedoc.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | coverage 4 | .env 5 | -------------------------------------------------------------------------------- /DEVELOPING.md: -------------------------------------------------------------------------------- 1 | # Developing guide 2 | This document is intended to assist in the continued maintenance and development of this SDK. 3 | It is used to document the dev, build, and deploy workflow and configurations for this project. 4 | 5 | - [Command reference](#command-reference) 6 | - [Build and packaging](#build-and-packaging) 7 | - [Documentation build](#documentation-build) 8 | - [Publishing to npm](#publishing-to-npm) 9 | 10 | ## Command reference 11 | 12 | | Command | Description | 13 | |:------------------|:--------------------------------------------------------------------------| 14 | | `npm run build` | Runs a full production build of the project. Output is written to `dist/` | 15 | | `npm run test` | Runs the test suite located under `__tests__/` | 16 | | `npm run docs` | Builds the API documentation. Output is written to `docs/` | 17 | 18 | 19 | ## Build and packaging 20 | The build process consists of two stages that involve both the typescript compiler and 21 | [rollup](https://rollupjs.org). This process allows us to output both CommonJS and ES Modules, as 22 | well as simplify selection of an appropriate build target (currently `ES2019` for compat with 23 | Node.js v12.x.x). 24 | 25 | ### 1. `build:package` 26 | 1. The typescript compiler `tsc` is used to pre-compile the typescript source code to vanilla ES 27 | modules (`ES2015` spec) that are compatible with the chosen build target (`ES2019`). This stage is 28 | performed by [`@rollup/plugin-typescript`](https://github.com/rollup/plugins/tree/master/packages/typescript) 29 | during invocation of `rollup -c`. 30 | 2. Rollup bundles the output from stage 1 into single-file modules in both CommonJS and ES Module 31 | format. The resulting bundles are written to `dist/`. 32 | 33 | ### 2. `build:types` 34 | 1. `tsc` is manually invoked again with different configuration to emit only the type definitions. 35 | These are also output to `dist/`. 36 | 37 | 38 | ## Documentation build 39 | Source code documentation is written using the [tsdoc](https://tsdoc.org/) commenting standard. The 40 | [typedoc](https://github.com/TypeStrong/typedoc) documentation generator combines these tsdoc style 41 | comments with type information emitted by `tsc` to produce full API docs with type defs included 42 | "for free". 43 | 44 | However, both the `tsdoc` standard and `typedoc` documentation generator are fairly immature, so 45 | they come with some quirks. 46 | 47 | ### Plugins 48 | The following plugins have been installed to help improve output quality: 49 | 50 | #### [typedoc-plugin-markdown](https://www.npmjs.com/package/typedoc-plugin-markdown) 51 | Used to emit output in markdown so it can be easily viewed directly on github. In the future it may be 52 | nicer to revert usage of this plugin and publish the 'default' HTML output from typedoc to something 53 | like github pages. 54 | 55 | #### [typedoc-plugin-no-inherit](https://www.npmjs.com/package/typedoc-plugin-no-inherit) 56 | Enables usage of the `@noInheritDoc` tag on class docstrings to stop `typedoc` from including 57 | documentation for methods/properties/etc. inherited from a base class. Of particular use for custom 58 | error classes that inherit from `Error`. 59 | 60 | #### [typedoc-plugin-merge-modules](https://www.npmjs.com/package/typedoc-plugin-merge-modules) 61 | One limitation of `typedoc` is that it only generates documentation for definitions that are 62 | exported from the project 'entrypoint'. This means that in order to document functionality that is 63 | not directly exported from `src/index.ts` (for example the contents of each 'resource' class), we have 64 | to list these modules as additional entrypoints for typedoc to gather documentation from. When 65 | working with multiple entrypoints, typedoc separates each entrypoint into a new 'module' in the 66 | documentation. In our case, this is not what we want, as in reality all of our code is part of just 67 | a single module. This plugin removes this spurious module grouping and merges all 'modules' into a 68 | single top-level grouping. 69 | 70 | ### Known issues 71 | The design decision by typedoc to only document exported definitions is a source of contention. A 72 | plugin exists [typedoc-plugin-not-supported](https://www.npmjs.com/package/typedoc-plugin-not-exported) 73 | that purports to fix this behaviour, but it doesn't seem to be maintained or functional with the most 74 | recent typedoc release. Some relevant discussions: 75 | 76 | - https://github.com/TypeStrong/typedoc/issues/1569 77 | - https://github.com/TypeStrong/typedoc/issues/1657 78 | - https://github.com/TypeStrong/typedoc/issues/1577 79 | 80 | In addition, typedoc is as of yet unable to produce clean type definitions for intersection and union 81 | types. Relevant discussions: 82 | 83 | - https://github.com/TypeStrong/typedoc/issues/1540 84 | - https://github.com/TypeStrong/typedoc/issues/1021 85 | - https://github.com/TypeStrong/typedoc/issues/1258 86 | 87 | 88 | ## Publishing to npm 89 | Use the following process to publish a new SDK version to npm: 90 | - Checkout latest `master` branch 91 | - Run [`npm version [major | minor | patch]`](https://docs.npmjs.com/cli/v7/commands/npm-version) 92 | - Add relevant changelog entries to README 93 | - Run [`npm publish`](https://docs.npmjs.com/cli/v7/commands/npm-publish) (requires `npm login`) 94 | - Create a PR for the new version changes 95 | -------------------------------------------------------------------------------- /__tests__/client.ts: -------------------------------------------------------------------------------- 1 | // import MockAdapter from "axios-mock-adapter"; 2 | import { AkahuClient } from '../src'; 3 | 4 | 5 | describe("AkahuClient", () => { 6 | let client: any; // `any` allows access to private methods 7 | 8 | beforeEach(() => { 9 | client = new AkahuClient({ 10 | appToken: "app_token_123", 11 | appSecret: "hunter2", 12 | }); 13 | }); 14 | 15 | describe("_authorizeRequest()", () => { 16 | it("does nothing when no auth method specified", async () => { 17 | const request = { url: "/test", method: "post", headers: { DNT: "1" } }; 18 | 19 | const authenticatedRequest = client._authorizeRequest(request, undefined); 20 | 21 | // Request config is unchanged 22 | expect(authenticatedRequest).toEqual(request); 23 | }); 24 | 25 | it("correctly adds auth token header when specified", async () => { 26 | const request = { url: "/test", method: "post", headers: { DNT: "1" } }; 27 | 28 | const token = "user_token_123"; 29 | const authenticatedRequest = client._authorizeRequest(request, { token }); 30 | 31 | // Authorization header was merged with the request config 32 | expect(authenticatedRequest.headers.Authorization).toBe( 33 | "Bearer user_token_123" 34 | ); 35 | // All other config values remain untouched 36 | expect(authenticatedRequest).toMatchObject(request); 37 | }); 38 | 39 | it("correctly adds basic auth when specified", async () => { 40 | const request = { url: "/test", method: "post", headers: { DNT: "1" } }; 41 | 42 | const authenticatedRequest = client._authorizeRequest(request, { 43 | basic: true, 44 | }); 45 | 46 | // Authorization header was merged with the request config 47 | expect(authenticatedRequest.auth).toEqual({ 48 | username: "app_token_123", 49 | password: "hunter2", 50 | }); 51 | 52 | // All other config values remain untouched 53 | expect(authenticatedRequest).toMatchObject(request); 54 | }); 55 | }); 56 | 57 | describe("_makeIdempotent()", () => { 58 | it("adds an Itempotency-Key to all POST requests", () => { 59 | const request = { url: "/test", method: "post", headers: { DNT: "1" } }; 60 | 61 | const idempotentRequest = client._makeIdempotent(request, {}); 62 | 63 | // Idempotency-Key header has been set 64 | expect(idempotentRequest.headers["Idempotency-Key"]).toBeTruthy(); 65 | 66 | // All other config values remain untouched 67 | expect(idempotentRequest).toMatchObject(request); 68 | }); 69 | 70 | it("adds the proveded Itempotency-Key to a POST request", () => { 71 | const request = { url: "/test", method: "post", headers: { DNT: "1" } }; 72 | 73 | const idempotentRequest = client._makeIdempotent(request, { 74 | idempotencyKey: "my-idempotency-key", 75 | }); 76 | 77 | // Idempotency-Key header has been set 78 | expect(idempotentRequest.headers["Idempotency-Key"]).toBe( 79 | "my-idempotency-key" 80 | ); 81 | 82 | // All other config values remain untouched 83 | expect(idempotentRequest).toMatchObject(request); 84 | }); 85 | 86 | it("does not add an Itempotency-Key to all other requests", () => { 87 | const request = { url: "/test", method: "get", headers: { DNT: "1" } }; 88 | 89 | const idempotentRequest = client._makeIdempotent(request, {}); 90 | 91 | // Idempotency-Key header has not been set 92 | expect(idempotentRequest.headers["Idempotency-Key"]).toBeUndefined(); 93 | 94 | // All other config values remain untouched 95 | expect(idempotentRequest).toMatchObject(request); 96 | }); 97 | }); 98 | }); 99 | 100 | describe("AkahuClient._apiCall", () => { 101 | // let client: AkahuClient; 102 | // let mockApi: MockAdapter; 103 | // beforeEach(() => { 104 | // // Setup a new AkahuClient instance and attach an adapter to mock out axios calls. 105 | // client = new AkahuClient({ appToken: 'app_token_123', appSecret: 'hunter2' }); 106 | // mockApi = new MockAdapter((client as any).axios); 107 | // }); 108 | }); 109 | -------------------------------------------------------------------------------- /__tests__/errors.ts: -------------------------------------------------------------------------------- 1 | import type { AxiosResponse } from "axios"; 2 | import { AkahuErrorResponse } from "../src/errors"; 3 | 4 | function mockResponse(overrides?: object) { 5 | return { 6 | status: 400, 7 | statusText: "Bad request", 8 | ...overrides, 9 | } as AxiosResponse; 10 | } 11 | 12 | describe("AkahuErrorResponse", () => { 13 | it("handles OAuth errors with an error_description", () => { 14 | const response = mockResponse({ 15 | data: { error: "invalid_grant", error_description: "This code has already been used." }, 16 | }); 17 | 18 | const error = new AkahuErrorResponse(response); 19 | expect(error.message).toBe("This code has already been used."); 20 | }); 21 | 22 | it("handles OAuth errors without an error_description", () => { 23 | const response = mockResponse({ data: { error: "invalid_request" } }); 24 | const error = new AkahuErrorResponse(response); 25 | expect(error.message).toBe("Invalid OAuth request."); 26 | }); 27 | 28 | it("handles generic error responses from the API", () => { 29 | const response = mockResponse({ data: { message: "Something went wrong." } }); 30 | const error = new AkahuErrorResponse(response); 31 | expect(error.message).toBe("Something went wrong."); 32 | }); 33 | 34 | it("falls back to HTTP status if no other message is available", () => { 35 | const response = mockResponse({ statusText: "Not found." }); 36 | const error = new AkahuErrorResponse(response); 37 | expect(error.message).toBe("Not found."); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /__tests__/fixtures/test_webhook_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG5QIBAAKCAYEAujyk8O5MfmavdgnG2PRgikSh5Dotl8y3jmGSnC/z9HGMd64f 3 | hCwhI9oiHGAGMajMk9tHTYWGA8aBxCXO1G5su/CJxoOB5Y7zygD6muDv47dfKylk 4 | 0GcroDWpjfbVGlkcqoYUcxma2MBadt3euk2nx/PmJ1+My7H7ptD6eDCXfmQj/ONt 5 | fsmfK09m8OQFmB22VSP3gb+6tN2PJ7RVf7iAjG6uKqnnRKTQn4/6zW0IjEpJlUrq 6 | NWZYp4Pnl1Q/WgC1BBVSJ8eDTJJ+Sy2SObM+8gmp2T5d0XjFNuJWw165U3gZ1NR2 7 | sXrfdE+gKtpCrI5GvCxT+av5wEesHok3rzZ5tf0OBm8PPu26wLqqslnXbBeGO7Px 8 | mVjiYSv+FqY6IM5/TIrHhgxZFxxsvKzXRNhokhlHsJJe+31OFdMfscF2U8JS5YGY 9 | N32qjpZ57nzwt8ubn+N7x1XLGzOF0U+GwOiZoNl0G3red4HDkpfdXxSr0yEHKIYB 10 | xSuRVG9K86Y5A3YLAgMBAAECggGBALSaDtHeJawGZG0xefX2tpAfkmdCy+gDjJW0 11 | pXp1Pjx0yOVepA2GxfSAmsetjxQlP466/OB+dcG/hSP0DikPlL6EuvcZnKRDBsOE 12 | Q4JiVAAeWVn/4FYBVtscbvrOvUW52QS81aPw1qsPjirragx9NhG/whe4n08BoKra 13 | yao4ZREah5O78PkdCQ/1Bjzgw1QKrEDQijr29VZj7WlxheA/ydllk9ynuzBkLDQw 14 | aeVAsSNq/wSaC5oRUDPSxImKF41uVHGVNSrFRXnXvfrcEUhof9SIbCMRRr4+ECeZ 15 | 8VYtRwQ0bDlt9eF4+HZuM5X5ZkZ3g6QWsUjpbMa6gGfk0sp2w4T6rQctzt+PnwO+ 16 | UVPrNp1qSpumjmosGkTzcwDg0eRxfuByFV6wMLAZJLYbLeTUSuIBvBuID375U6Fq 17 | SINQSnQzMao8k19PpTPQCnSRtv8qP0yC0+jU2ULNnVqlofCINg+sF5lGDvOCGBKc 18 | fpn/AJ4gu6tEWxx3momEKTExyAIZYQKBwQD2+wXBYs84Jyn1KpMhZUoe9WBmg59F 19 | DesrLIR4KVOlPRuCFEAZuwpHCRYShCxDiloE7HVkMlQzV7NbjvtMe/IHyMY39KMo 20 | ggX5jwf4QTLKLVaaTMqTxLAXO7r9maHZhT4Nq8WaoxVIHZetbinX6jbLqD6LNXlq 21 | 8m2V9ISQaMExrpdc+2xMB7PlsIS3K19B3X/ShzJ2xgMjUZLenzBdIwnuPzpkHMpv 22 | Egh23OnIVSA2sac3Qwv7zbCnvP6DuRpaNAMCgcEAwQm9c68qVNTNGFmNEw+ToY6f 23 | 8OII7su1iWK6BShwJ9kkTvzlF1CeMjQGvz1MO9yLusK4R023wb2A5IjPisDaqOcJ 24 | xlzAUSwTkbJMPDmVHzNDYmYzmDDGGUGjKn/gB4hF0lvtQKF9v0dRcwt03QG5Qxub 25 | ojt96P7f+QzlmESd0RDhl8HegC5d1DHtG/Fzvv6KkCIgnc8V/lDhpoGHZxL6e3cx 26 | NigLeJTvkzuYW/CjEvWp1VbApRx3PUb4yOskI8tZAoHBALZ5WBM9EaSHKvS78+Bk 27 | mZKt7/9Nl8rJMcrAJU8yGV6n+z7r/0ADdOBu0iP0C1ALU973ZPQWSydz0EwBI6Gq 28 | oXMm32xQDovLJObwyg6c/Q1q2eU+fx0V4JQJyWm8rFutmd833dMWUo7pbjrwfXHM 29 | 1Zc6QptPctmVK2nzMk4PV02BlMtZ5vV1a3B0Llm2bbaYE+xTfvFJ8t+RUVWxf2YQ 30 | kTG4/UciDl5pkF9hcEhWvGosb0LhAmWT3sTPWauwgsvKSQKBwBCWxbErXHft0bJF 31 | /9mjfQxlNVl+E0ZyOyeTVGkdEIZcIsKm+QkH5JBr6CiHHAYI7fkewrdd9myv3GPH 32 | Xg6OhDv/ntdtIRnYr9XVfLewOyBzR1ctcUGi72M8QMlmM9px2444WCs1tZi6iEVa 33 | trBHdaROuxE2C5v6S0Ub1p8/RlCxIrHn9zcMxQN3Rukf1tKTDVVVmXf2U+2HBd1J 34 | RFmXR+9UTuZYiqPSKMR+WpmMFHeMpQuwaN3HlHevobGig3iQAQKBwQChFhEp4l6k 35 | M6xFev9aZqgyMM697kHe2QbxBvOgDHVE6MZVVVlPH+u42ztuE5H089r8ClYq5cHD 36 | QogWbbNwSLevJRi4mQXRptIWLNhjpCyb4zWJlgbTOJM9VAKljT7LNxwog3RYAXww 37 | GASGSl0p2syI98MWnX5U/KpSJMp4+aR6mWsP81zhnj7DYbjgPDD5tJu/vGiJRjBh 38 | WT6xzjmznkgfY8LDubKYDwTdB440jifm97DJMWGdmTR8Ib2tWCVrI1A= 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /__tests__/fixtures/test_webhook_rsa.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PUBLIC KEY----- 2 | MIIBigKCAYEAujyk8O5MfmavdgnG2PRgikSh5Dotl8y3jmGSnC/z9HGMd64fhCwh 3 | I9oiHGAGMajMk9tHTYWGA8aBxCXO1G5su/CJxoOB5Y7zygD6muDv47dfKylk0Gcr 4 | oDWpjfbVGlkcqoYUcxma2MBadt3euk2nx/PmJ1+My7H7ptD6eDCXfmQj/ONtfsmf 5 | K09m8OQFmB22VSP3gb+6tN2PJ7RVf7iAjG6uKqnnRKTQn4/6zW0IjEpJlUrqNWZY 6 | p4Pnl1Q/WgC1BBVSJ8eDTJJ+Sy2SObM+8gmp2T5d0XjFNuJWw165U3gZ1NR2sXrf 7 | dE+gKtpCrI5GvCxT+av5wEesHok3rzZ5tf0OBm8PPu26wLqqslnXbBeGO7PxmVji 8 | YSv+FqY6IM5/TIrHhgxZFxxsvKzXRNhokhlHsJJe+31OFdMfscF2U8JS5YGYN32q 9 | jpZ57nzwt8ubn+N7x1XLGzOF0U+GwOiZoNl0G3red4HDkpfdXxSr0yEHKIYBxSuR 10 | VG9K86Y5A3YLAgMBAAE= 11 | -----END RSA PUBLIC KEY----- 12 | -------------------------------------------------------------------------------- /__tests__/webhooks.ts: -------------------------------------------------------------------------------- 1 | import { createSign } from 'crypto'; 2 | import { readFileSync } from "fs"; 3 | import MockAdapter from "axios-mock-adapter"; 4 | 5 | import { AkahuClient } from '../src'; 6 | import { WebhookPayload } from '../src'; 7 | 8 | /* Initialize fixtures */ 9 | const testPrivKey = readFileSync(`${__dirname}/fixtures/test_webhook_rsa`, 'utf-8') 10 | const testPubKey = readFileSync(`${__dirname}/fixtures/test_webhook_rsa.pub`, 'utf-8') 11 | 12 | const sign = (payload: string) => { 13 | const signer = createSign("sha256"); 14 | signer.update(payload).end(); 15 | return signer.sign(testPrivKey, 'base64'); 16 | } 17 | 18 | const testWebhookPayload: WebhookPayload = { 19 | webhook_type: 'TOKEN', 20 | webhook_code: 'DELETE', 21 | state: '', 22 | item_id: 'user_token_1234', 23 | } 24 | 25 | const testWebhookBody = JSON.stringify(testWebhookPayload); 26 | const testWebhookSignature = sign(testWebhookBody); 27 | 28 | 29 | describe("AkahuClient.webhooks.validateWebhook()", () => { 30 | let client: AkahuClient; 31 | let mockApi: MockAdapter; 32 | const testKeyId = 2; 33 | 34 | beforeEach(() => { 35 | // Setup a new AkahuClient instance and attach an adapter to mock out axios calls. 36 | client = new AkahuClient({ appToken: 'app_token_123', appSecret: 'hunter2' }); 37 | mockApi = new MockAdapter((client as any).axios); 38 | 39 | // Mock API response with public key 40 | mockApi.onGet(`/keys/${testKeyId}`) 41 | .reply(200, { success: true, item: testPubKey }); 42 | }); 43 | 44 | test("validateWebhook() returns deserialized payload for valid webhook request", async () => { 45 | const result = await client.webhooks.validateWebhook(testKeyId, 46 | testWebhookSignature, 47 | testWebhookBody); 48 | expect(result).toEqual(testWebhookPayload); 49 | }); 50 | 51 | test("validateWebhook() throws an error for invalid webhook signature", async () => { 52 | await expect( 53 | () => client.webhooks.validateWebhook( 54 | testKeyId, 55 | sign('abcd'), 56 | testWebhookBody 57 | ) 58 | ).rejects.toThrow(/Webhook signature verificaton failed\./); 59 | }); 60 | 61 | test("validateWebhook() caches the public key using the default cache", async () => { 62 | // WebhooksResource caches using a local object by default 63 | const cacheStore = (client.webhooks as any).defaultKeyCache._cache; 64 | 65 | // Cache is initially empty 66 | expect(cacheStore.akahu__webhook_key).toBeUndefined() 67 | 68 | // Perform webhook validation 69 | await client.webhooks.validateWebhook(testKeyId, testWebhookSignature, testWebhookBody); 70 | 71 | // The public key was retrieved from API 72 | expect(mockApi.history.get.length).toBe(1); 73 | 74 | // Cache is populated with key data 75 | const { id, key } = JSON.parse(cacheStore.akahu__webhook_key); 76 | expect(id).toEqual(testKeyId); 77 | expect(key).toEqual(testPubKey); 78 | 79 | // Perform webhook validation a second time 80 | await client.webhooks.validateWebhook(testKeyId, testWebhookSignature, testWebhookBody); 81 | 82 | // The public key was retrieved from cache (no increase in request count) 83 | expect(mockApi.history.get.length).toBe(1); 84 | }); 85 | 86 | test("validateWebhook() caches the public key using the configured cache", async () => { 87 | // Implement our own cache 88 | let cachedValue: string | null = null; 89 | 90 | // Keep track of get and set calls 91 | const calls: Record = { 92 | get: [], 93 | set: [], 94 | } 95 | 96 | // Custom cache interface 97 | const cache = { 98 | get: (k: string) => { 99 | calls.get.push([k]); 100 | return cachedValue; 101 | }, 102 | set: (k: string, v: string) => { 103 | calls.set.push([k, v]); 104 | cachedValue = v 105 | }, 106 | }; 107 | 108 | const testCacheConfig = { cache, key: 'customCacheKey' }; 109 | 110 | // Perform webhook validation passing in custom cache 111 | await client.webhooks.validateWebhook( 112 | testKeyId, 113 | testWebhookSignature, 114 | testWebhookBody, 115 | testCacheConfig 116 | ); 117 | 118 | // The public key was retrieved from API 119 | expect(mockApi.history.get.length).toBe(1); 120 | 121 | // Verify that our custom cache is populated with key data 122 | let id, key; 123 | if (cachedValue !== null) { 124 | ({ id, key } = JSON.parse(cachedValue)); 125 | } 126 | 127 | expect(id).toEqual(testKeyId); 128 | expect(key).toEqual(testPubKey); 129 | expect(calls.get).toEqual([['customCacheKey']]) 130 | expect(calls.set).toEqual([['customCacheKey', cachedValue]]) 131 | 132 | // Perform webhook validation a second time 133 | await client.webhooks.validateWebhook( 134 | testKeyId, 135 | testWebhookSignature, 136 | testWebhookBody, 137 | testCacheConfig 138 | ); 139 | 140 | // API was not hit (no increase in request count) 141 | expect(mockApi.history.get.length).toBe(1); 142 | 143 | // Key was retreived from cache 144 | expect(calls.get).toEqual([['customCacheKey'], ['customCacheKey']]) 145 | }); 146 | 147 | 148 | test("validateWebhook() throws an error if requested key id is older than cached key id", async () => { 149 | const cache = { 150 | // get() returns key with id > than testKeyId 151 | get: (_: string) => JSON.stringify({ id: 3, key: 'abc', lastRefreshed: new Date() }), 152 | // set() is a no-op 153 | set: (_: string, __: string) => undefined, 154 | }; 155 | 156 | await expect( 157 | () => 158 | client.webhooks.validateWebhook( 159 | testKeyId, 160 | testWebhookSignature, 161 | testWebhookBody, 162 | { cache } 163 | ) 164 | ).rejects.toThrow(/Webhook signing key \(id: 2\) has expired\..+/); 165 | }); 166 | 167 | 168 | test("validateWebhook() ignores cached keys more than maxAgeMs old", async () => { 169 | const maxAgeMs = 1000 * 60 * 60; // 1 hour 170 | const justExpired = new Date(Date.now() - maxAgeMs - 1).toISOString(); 171 | let wasGetCalled = false; 172 | 173 | // Cached value is 'expired': lastRefreshed timestamp is more than maxAgeMs ago. 174 | let cachedValue = JSON.stringify({ id: 2, key: 'test', lastRefreshed: justExpired }); 175 | 176 | const testCacheConfig = { 177 | cache: { 178 | get: (_: string) => { wasGetCalled = true; return cachedValue }, 179 | // set() is a no-op 180 | set: (_: string, v: string) => { cachedValue = v }, 181 | }, 182 | maxAgeMs, 183 | } 184 | 185 | // Run webhook validation - pass in our custom cacheConfig 186 | await client.webhooks.validateWebhook(testKeyId, testWebhookSignature, 187 | testWebhookBody, testCacheConfig); 188 | 189 | // Sanity check - cache.get() was called 190 | expect(wasGetCalled).toBe(true); 191 | // But key was rejected and instead updated from the API 192 | expect(mockApi.history.get.length).toBe(1); 193 | // Then the cache was updated with the refreshed value 194 | const { id, key, lastRefreshed } = JSON.parse(cachedValue); 195 | expect(id).toBe(testKeyId); 196 | expect(key).toEqual(testPubKey); 197 | expect(Date.now() - Date.parse(lastRefreshed)).toBeLessThan(10); 198 | }); 199 | }); -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | ["@babel/preset-env", { targets: { node: "current" } }], 4 | "@babel/preset-typescript", 5 | ], 6 | }; 7 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | **akahu v2.1.0** • **Docs** 2 | 3 | *** 4 | 5 | # akahu v2.1.0 6 | 7 | ## Classes 8 | 9 | ### API client 10 | 11 | - [AkahuClient](classes/AkahuClient.md) 12 | 13 | ### Error 14 | 15 | - [AkahuErrorResponse](classes/AkahuErrorResponse.md) 16 | - [AkahuWebhookValidationError](classes/AkahuWebhookValidationError.md) 17 | 18 | ### Resource 19 | 20 | - [AccountsResource](classes/AccountsResource.md) 21 | - [AuthResource](classes/AuthResource.md) 22 | - [CategoriesResource](classes/CategoriesResource.md) 23 | - [ConnectionsResource](classes/ConnectionsResource.md) 24 | - [IdentitiesResource](classes/IdentitiesResource.md) 25 | - [PartiesResource](classes/PartiesResource.md) 26 | - [PaymentsResource](classes/PaymentsResource.md) 27 | - [TransactionsResource](classes/TransactionsResource.md) 28 | - [TransfersResource](classes/TransfersResource.md) 29 | - [UsersResource](classes/UsersResource.md) 30 | - [WebhooksResource](classes/WebhooksResource.md) 31 | 32 | ## Interfaces 33 | 34 | ### API client 35 | 36 | - [WebhookSigningKeyCache](interfaces/WebhookSigningKeyCache.md) 37 | 38 | ## Type Aliases 39 | 40 | ### API client config 41 | 42 | - [AkahuClientConfig](type-aliases/AkahuClientConfig.md) 43 | - [WebhookCacheConfig](type-aliases/WebhookCacheConfig.md) 44 | 45 | ### Generic 46 | 47 | - [Paginated](type-aliases/Paginated.md) 48 | - [Cursor](type-aliases/Cursor.md) 49 | 50 | ### Other 51 | 52 | - [Account](type-aliases/Account.md) 53 | - [AuthorizationToken](type-aliases/AuthorizationToken.md) 54 | - [Category](type-aliases/Category.md) 55 | - [Connection](type-aliases/Connection.md) 56 | - [PostRequestOptions](type-aliases/PostRequestOptions.md) 57 | - [IdentityResult](type-aliases/IdentityResult.md) 58 | - [IdentityVerifyNameQuery](type-aliases/IdentityVerifyNameQuery.md) 59 | - [AccountHolderNameVerificationSource](type-aliases/AccountHolderNameVerificationSource.md) 60 | - [PartyNameVerificationSource](type-aliases/PartyNameVerificationSource.md) 61 | - [IdentityVerifyNameResult](type-aliases/IdentityVerifyNameResult.md) 62 | - [PaymentStatus](type-aliases/PaymentStatus.md) 63 | - [PaymentStatusCode](type-aliases/PaymentStatusCode.md) 64 | - [Payment](type-aliases/Payment.md) 65 | - [PaymentCreateParams](type-aliases/PaymentCreateParams.md) 66 | - [IrdPaymentCreateParams](type-aliases/IrdPaymentCreateParams.md) 67 | - [PaymentQueryParams](type-aliases/PaymentQueryParams.md) 68 | - [TransactionType](type-aliases/TransactionType.md) 69 | - [RawTransaction](type-aliases/RawTransaction.md) 70 | - [PendingTransaction](type-aliases/PendingTransaction.md) 71 | - [CurrencyConversion](type-aliases/CurrencyConversion.md) 72 | - [EnrichedTransaction](type-aliases/EnrichedTransaction.md) 73 | - [Transaction](type-aliases/Transaction.md) 74 | - [TransactionQueryParams](type-aliases/TransactionQueryParams.md) 75 | - [TransferStatus](type-aliases/TransferStatus.md) 76 | - [Transfer](type-aliases/Transfer.md) 77 | - [TransferCreateParams](type-aliases/TransferCreateParams.md) 78 | - [TransferQueryParams](type-aliases/TransferQueryParams.md) 79 | - [User](type-aliases/User.md) 80 | - [WebhookType](type-aliases/WebhookType.md) 81 | - [WebhookStatus](type-aliases/WebhookStatus.md) 82 | - [Webhook](type-aliases/Webhook.md) 83 | - [WebhookCreateParams](type-aliases/WebhookCreateParams.md) 84 | - [BasePayload](type-aliases/BasePayload.md) 85 | - [CancelledPayload](type-aliases/CancelledPayload.md) 86 | - [TokenPayload](type-aliases/TokenPayload.md) 87 | - [AccountPayload](type-aliases/AccountPayload.md) 88 | - [TransactionPayload](type-aliases/TransactionPayload.md) 89 | - [TransferPayload](type-aliases/TransferPayload.md) 90 | - [PaymentPayload](type-aliases/PaymentPayload.md) 91 | - [WebhookPayload](type-aliases/WebhookPayload.md) 92 | - [WebhookEvent](type-aliases/WebhookEvent.md) 93 | - [WebhookEventQueryParams](type-aliases/WebhookEventQueryParams.md) 94 | - [Protocol](type-aliases/Protocol.md) 95 | 96 | ### Parties 97 | 98 | - [PartyName](type-aliases/PartyName.md) 99 | - [PartyDob](type-aliases/PartyDob.md) 100 | - [PartyPhoneNumber](type-aliases/PartyPhoneNumber.md) 101 | - [PartyEmail](type-aliases/PartyEmail.md) 102 | - [PartyAddress](type-aliases/PartyAddress.md) 103 | - [PartyTaxNumber](type-aliases/PartyTaxNumber.md) 104 | - [Party](type-aliases/Party.md) 105 | -------------------------------------------------------------------------------- /docs/classes/AccountsResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AccountsResource 6 | 7 | # Class: AccountsResource 8 | 9 | Utilities for managing Akahu accounts that have been linked by users. 10 | 11 | [https://developers.akahu.nz/docs/accessing-account-data](https://developers.akahu.nz/docs/accessing-account-data) 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### list() 20 | 21 | > **list**(`token`): `Promise`\<[`Account`](../type-aliases/Account.md)[]\> 22 | 23 | List all accounts that have been connected by the user associated with the specified `token`. 24 | 25 | [https://developers.akahu.nz/reference/get_accounts](https://developers.akahu.nz/reference/get_accounts) 26 | 27 | #### Parameters 28 | 29 | • **token**: `string` 30 | 31 | #### Returns 32 | 33 | `Promise`\<[`Account`](../type-aliases/Account.md)[]\> 34 | 35 | *** 36 | 37 | ### get() 38 | 39 | > **get**(`token`, `accountId`): `Promise`\<[`Account`](../type-aliases/Account.md)\> 40 | 41 | Get a single account that has been connected by the user associated with the specified `token`. 42 | 43 | [https://developers.akahu.nz/reference/get_accounts-id](https://developers.akahu.nz/reference/get_accounts-id) 44 | 45 | #### Parameters 46 | 47 | • **token**: `string` 48 | 49 | • **accountId**: `string` 50 | 51 | #### Returns 52 | 53 | `Promise`\<[`Account`](../type-aliases/Account.md)\> 54 | 55 | *** 56 | 57 | ### listTransactions() 58 | 59 | > **listTransactions**(`token`, `accountId`, `query`): `Promise`\<[`Paginated`](../type-aliases/Paginated.md)\<[`Transaction`](../type-aliases/Transaction.md)\>\> 60 | 61 | List transactions for a specified account. 62 | 63 | [https://developers.akahu.nz/reference/get_accounts-id-transactions](https://developers.akahu.nz/reference/get_accounts-id-transactions) 64 | 65 | #### Parameters 66 | 67 | • **token**: `string` 68 | 69 | • **accountId**: `string` 70 | 71 | • **query**: [`TransactionQueryParams`](../type-aliases/TransactionQueryParams.md)= `{}` 72 | 73 | #### Returns 74 | 75 | `Promise`\<[`Paginated`](../type-aliases/Paginated.md)\<[`Transaction`](../type-aliases/Transaction.md)\>\> 76 | 77 | *** 78 | 79 | ### listPendingTransactions() 80 | 81 | > **listPendingTransactions**(`token`, `accountId`): `Promise`\<[`PendingTransaction`](../type-aliases/PendingTransaction.md)[]\> 82 | 83 | List pending transactions for a specified account. 84 | 85 | [https://developers.akahu.nz/reference/get_accounts-id-transactions-pending](https://developers.akahu.nz/reference/get_accounts-id-transactions-pending) 86 | 87 | #### Parameters 88 | 89 | • **token**: `string` 90 | 91 | • **accountId**: `string` 92 | 93 | #### Returns 94 | 95 | `Promise`\<[`PendingTransaction`](../type-aliases/PendingTransaction.md)[]\> 96 | 97 | *** 98 | 99 | ### revoke() 100 | 101 | > **revoke**(`token`, `accountId`): `Promise`\<`void`\> 102 | 103 | Revoke a single account from the specified `token`. 104 | 105 | After this call the token will no longer have access to the specified account or it's associated data, 106 | including transactions. 107 | 108 | [https://developers.akahu.nz/reference/delete_accounts-id](https://developers.akahu.nz/reference/delete_accounts-id) 109 | 110 | #### Parameters 111 | 112 | • **token**: `string` 113 | 114 | • **accountId**: `string` 115 | 116 | #### Returns 117 | 118 | `Promise`\<`void`\> 119 | 120 | *** 121 | 122 | ### refresh() 123 | 124 | > **refresh**(`token`, `accountId`): `Promise`\<`void`\> 125 | 126 | Refresh a single account that has been connected by the user associated with the specified `token`. 127 | 128 | [https://developers.akahu.nz/reference/post_refresh-id](https://developers.akahu.nz/reference/post_refresh-id) 129 | 130 | #### Parameters 131 | 132 | • **token**: `string` 133 | 134 | • **accountId**: `string` 135 | 136 | #### Returns 137 | 138 | `Promise`\<`void`\> 139 | 140 | *** 141 | 142 | ### refreshAll() 143 | 144 | > **refreshAll**(`token`): `Promise`\<`void`\> 145 | 146 | Refresh all accounts that have been connected by the user associated with the specified `token`. 147 | 148 | [https://developers.akahu.nz/reference/post_refresh](https://developers.akahu.nz/reference/post_refresh) 149 | 150 | #### Parameters 151 | 152 | • **token**: `string` 153 | 154 | #### Returns 155 | 156 | `Promise`\<`void`\> 157 | -------------------------------------------------------------------------------- /docs/classes/AkahuClient.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AkahuClient 6 | 7 | # Class: AkahuClient 8 | 9 | The AkahuClient provides a simple interface to the Akahu API and utilities 10 | that assist with common usage patterns. 11 | 12 | AkahuClient uses [axios](https://axios-http.com/docs/intro) under the hood to make 13 | API requests. A subset of axios request options can be passed through to the underlying axios 14 | instance using the options available in [AkahuClientConfig](../type-aliases/AkahuClientConfig.md). 15 | 16 | In the case of an error while making an API request, you can expect to handle one of the 17 | following two exceptions: 18 | 19 | - [AkahuErrorResponse](AkahuErrorResponse.md) When an error response is returned from the API 20 | - [AxiosError](https://github.com/axios/axios/blob/v0.21.1/index.d.ts#L85) when an error 21 | occurred during the request process, but no response was received (i.e. due to network issues). 22 | 23 | ## Constructors 24 | 25 | ### new AkahuClient() 26 | 27 | > **new AkahuClient**(`config`): [`AkahuClient`](AkahuClient.md) 28 | 29 | #### Parameters 30 | 31 | • **config**: [`AkahuClientConfig`](../type-aliases/AkahuClientConfig.md) 32 | 33 | #### Returns 34 | 35 | [`AkahuClient`](AkahuClient.md) 36 | 37 | ## Properties 38 | 39 | ### Resource 40 | 41 | #### auth 42 | 43 | > **auth**: [`AuthResource`](AuthResource.md) 44 | 45 | Utilities for authorizing users using OAuth2. 46 | 47 | [https://developers.akahu.nz/docs/authorizing-with-oauth2](https://developers.akahu.nz/docs/authorizing-with-oauth2) 48 | 49 | *** 50 | 51 | #### identities 52 | 53 | > **identities**: [`IdentitiesResource`](IdentitiesResource.md) 54 | 55 | Utilities for requesting identity verification using OAuth2. 56 | 57 | [https://developers.akahu.nz/docs/identity-verification](https://developers.akahu.nz/docs/identity-verification) 58 | 59 | *** 60 | 61 | #### users 62 | 63 | > **users**: [`UsersResource`](UsersResource.md) 64 | 65 | Utilities for retrieving information about the Akahu user. 66 | 67 | *** 68 | 69 | #### connections 70 | 71 | > **connections**: [`ConnectionsResource`](ConnectionsResource.md) 72 | 73 | Utilities to view connections that are available to your app, and refresh 74 | accounts under a given connection. 75 | 76 | *** 77 | 78 | #### categories 79 | 80 | > **categories**: [`CategoriesResource`](CategoriesResource.md) 81 | 82 | Utilities to view categories that are available to your app. 83 | 84 | *** 85 | 86 | #### accounts 87 | 88 | > **accounts**: [`AccountsResource`](AccountsResource.md) 89 | 90 | Utilities for managing Akahu accounts that have been linked by users. 91 | 92 | [https://developers.akahu.nz/docs/accessing-account-data](https://developers.akahu.nz/docs/accessing-account-data) 93 | 94 | *** 95 | 96 | #### payments 97 | 98 | > **payments**: [`PaymentsResource`](PaymentsResource.md) 99 | 100 | Utilities for managing bank account payments on behalf of users. 101 | 102 | [https://developers.akahu.nz/docs/making-a-payment](https://developers.akahu.nz/docs/making-a-payment) 103 | 104 | *** 105 | 106 | #### transfers 107 | 108 | > **transfers**: [`TransfersResource`](TransfersResource.md) 109 | 110 | Utilities for managing bank account transfers on behalf of users. 111 | 112 | [https://developers.akahu.nz/docs/making-a-transfer](https://developers.akahu.nz/docs/making-a-transfer) 113 | 114 | *** 115 | 116 | #### transactions 117 | 118 | > **transactions**: [`TransactionsResource`](TransactionsResource.md) 119 | 120 | Utilities for retrieving bank transactions from connected user accounts. 121 | 122 | [https://developers.akahu.nz/docs/accessing-transactional-data](https://developers.akahu.nz/docs/accessing-transactional-data) 123 | 124 | *** 125 | 126 | #### webhooks 127 | 128 | > **webhooks**: [`WebhooksResource`](WebhooksResource.md) 129 | 130 | Utilities for managing, retrieving, and validating webhooks. 131 | 132 | [https://developers.akahu.nz/docs/reference-webhooks](https://developers.akahu.nz/docs/reference-webhooks) 133 | 134 | *** 135 | 136 | #### parties 137 | 138 | > **parties**: [`PartiesResource`](PartiesResource.md) 139 | 140 | Fetch identity data relating to the party that the user has logged-in to 141 | their institution as when connecting accounts to Akahu. i.e. the user's 142 | "profile" information at the connected institution. 143 | -------------------------------------------------------------------------------- /docs/classes/AkahuErrorResponse.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AkahuErrorResponse 6 | 7 | # Class: AkahuErrorResponse 8 | 9 | Error type for error responses received from the Akahu API. 10 | An error response is characterised by a non 2XX status code and/or a body 11 | payload that contains `success: false` along with an accompanying error message. 12 | 13 | ## Extends 14 | 15 | - `AkahuError` 16 | 17 | ## Properties 18 | 19 | ### status 20 | 21 | > **status**: `number` 22 | 23 | The response status code. 24 | 25 | *** 26 | 27 | ### response 28 | 29 | > **response**: `AxiosResponse`\<`any`, `any`\> 30 | 31 | The full [AxiosReponse](https://axios-http.com/docs/res_schema) 32 | object from axios. 33 | -------------------------------------------------------------------------------- /docs/classes/AkahuWebhookValidationError.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AkahuWebhookValidationError 6 | 7 | # Class: AkahuWebhookValidationError 8 | 9 | Error type for errors that occur during the webhook validation process. 10 | 11 | ## Extends 12 | 13 | - `AkahuError` 14 | -------------------------------------------------------------------------------- /docs/classes/AuthResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AuthResource 6 | 7 | # Class: AuthResource 8 | 9 | Utilities for authorizing users using OAuth2. 10 | 11 | [https://developers.akahu.nz/docs/authorizing-with-oauth2](https://developers.akahu.nz/docs/authorizing-with-oauth2) 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### buildAuthorizationUrl() 20 | 21 | > **buildAuthorizationUrl**(`options`): `string` 22 | 23 | Build the OAuth Authorization URL 24 | 25 | #### Parameters 26 | 27 | • **options** 28 | 29 | Options for customising the generated URL. 30 | 31 | [https://developers.akahu.nz/docs/authorizing-with-oauth2#the-authorization-request](https://developers.akahu.nz/docs/authorizing-with-oauth2#the-authorization-request) 32 | 33 | • **options.redirect\_uri**: `string` 34 | 35 | Where to redirect the user once they have accepted or rejected the access request. 36 | This **must** match one of your app's Redirect URIs. 37 | 38 | • **options.response\_type?**: `string` 39 | 40 | The type of OAuth response. Currently `code` is the only supported option. 41 | 42 | **Default** 43 | `code` 44 | 45 | • **options.scope?**: `string` 46 | 47 | • **options.email?**: `string` 48 | 49 | • **options.connection?**: `string` 50 | 51 | • **options.state?**: `string` 52 | 53 | • **options.protocol?**: [`Protocol`](../type-aliases/Protocol.md) 54 | 55 | • **options.host?**: `string` 56 | 57 | • **options.port?**: `number` 58 | 59 | • **options.path?**: `string` 60 | 61 | #### Returns 62 | 63 | `string` 64 | 65 | *** 66 | 67 | ### exchange() 68 | 69 | > **exchange**(`code`, `redirect_uri`, `grant_type`): `Promise`\<[`AuthorizationToken`](../type-aliases/AuthorizationToken.md)\> 70 | 71 | Exchange an OAuth authorization code for an access token. 72 | 73 | [https://developers.akahu.nz/docs/authorizing-with-oauth2#exchanging-the-authorization-code](https://developers.akahu.nz/docs/authorizing-with-oauth2#exchanging-the-authorization-code) 74 | [https://developers.akahu.nz/reference/post_token](https://developers.akahu.nz/reference/post_token) 75 | 76 | #### Parameters 77 | 78 | • **code**: `string` 79 | 80 | • **redirect\_uri**: `string` 81 | 82 | • **grant\_type**: `string`= `"authorization_code"` 83 | 84 | #### Returns 85 | 86 | `Promise`\<[`AuthorizationToken`](../type-aliases/AuthorizationToken.md)\> 87 | 88 | *** 89 | 90 | ### revoke() 91 | 92 | > **revoke**(`token`): `Promise`\<`void`\> 93 | 94 | Revoke the specified user auth token: 95 | 96 | [https://developers.akahu.nz/reference/delete_token](https://developers.akahu.nz/reference/delete_token) 97 | 98 | #### Parameters 99 | 100 | • **token**: `string` 101 | 102 | #### Returns 103 | 104 | `Promise`\<`void`\> 105 | -------------------------------------------------------------------------------- /docs/classes/CategoriesResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / CategoriesResource 6 | 7 | # Class: CategoriesResource 8 | 9 | Utilities to view categories that are available to your app. 10 | 11 | ## Extends 12 | 13 | - `BaseResource` 14 | 15 | ## Methods 16 | 17 | ### list() 18 | 19 | > **list**(): `Promise`\<[`Category`](../type-aliases/Category.md)[]\> 20 | 21 | List all categories that the app has access to. 22 | 23 | [https://developers.akahu.nz/reference/get_categories](https://developers.akahu.nz/reference/get_categories) 24 | 25 | #### Returns 26 | 27 | `Promise`\<[`Category`](../type-aliases/Category.md)[]\> 28 | 29 | *** 30 | 31 | ### get() 32 | 33 | > **get**(`categoryId`): `Promise`\<[`Category`](../type-aliases/Category.md)\> 34 | 35 | Get an individual category. 36 | 37 | [https://developers.akahu.nz/reference/get_categories-id](https://developers.akahu.nz/reference/get_categories-id) 38 | 39 | #### Parameters 40 | 41 | • **categoryId**: `string` 42 | 43 | #### Returns 44 | 45 | `Promise`\<[`Category`](../type-aliases/Category.md)\> 46 | -------------------------------------------------------------------------------- /docs/classes/ConnectionsResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / ConnectionsResource 6 | 7 | # Class: ConnectionsResource 8 | 9 | Utilities to view connections that are available to your app, and refresh 10 | accounts under a given connection. 11 | 12 | ## Extends 13 | 14 | - `BaseResource` 15 | 16 | ## Methods 17 | 18 | ### list() 19 | 20 | > **list**(): `Promise`\<[`Connection`](../type-aliases/Connection.md)[]\> 21 | 22 | List all connections that the app has access to. 23 | 24 | [https://developers.akahu.nz/reference/get_connections](https://developers.akahu.nz/reference/get_connections) 25 | 26 | #### Returns 27 | 28 | `Promise`\<[`Connection`](../type-aliases/Connection.md)[]\> 29 | 30 | *** 31 | 32 | ### get() 33 | 34 | > **get**(`connectionId`): `Promise`\<[`Connection`](../type-aliases/Connection.md)\> 35 | 36 | Get an individual connection detail. 37 | 38 | [https://developers.akahu.nz/reference/get_connections-id](https://developers.akahu.nz/reference/get_connections-id) 39 | 40 | #### Parameters 41 | 42 | • **connectionId**: `string` 43 | 44 | #### Returns 45 | 46 | `Promise`\<[`Connection`](../type-aliases/Connection.md)\> 47 | 48 | *** 49 | 50 | ### refresh() 51 | 52 | > **refresh**(`token`, `connectionId`): `Promise`\<`void`\> 53 | 54 | Refresh all accounts that are made using the given connection and have been 55 | connected by the user associated with the specified `token`. 56 | 57 | [https://developers.akahu.nz/reference/post_refresh-id](https://developers.akahu.nz/reference/post_refresh-id) 58 | 59 | #### Parameters 60 | 61 | • **token**: `string` 62 | 63 | • **connectionId**: `string` 64 | 65 | #### Returns 66 | 67 | `Promise`\<`void`\> 68 | -------------------------------------------------------------------------------- /docs/classes/IdentitiesResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / IdentitiesResource 6 | 7 | # Class: IdentitiesResource 8 | 9 | Utilities for requesting identity verification using OAuth2. 10 | 11 | [https://developers.akahu.nz/docs/identity-verification](https://developers.akahu.nz/docs/identity-verification) 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### buildAuthorizationUrl() 20 | 21 | > **buildAuthorizationUrl**(`params`): `string` 22 | 23 | Build the Identity OAuth Authorization URL. 24 | 25 | [https://developers.akahu.nz/docs/identity-verification#the-authorization-request](https://developers.akahu.nz/docs/identity-verification#the-authorization-request) 26 | 27 | #### Parameters 28 | 29 | • **params** 30 | 31 | • **params.redirect\_uri**: `string` 32 | 33 | • **params.protocol?**: [`Protocol`](../type-aliases/Protocol.md) 34 | 35 | • **params.host?**: `string` 36 | 37 | • **params.port?**: `number` 38 | 39 | • **params.path?**: `string` 40 | 41 | • **params.response\_type?**: `string` 42 | 43 | • **params.scope?**: `string` 44 | 45 | • **params.state?**: `string` 46 | 47 | #### Returns 48 | 49 | `string` 50 | 51 | *** 52 | 53 | ### get() 54 | 55 | > **get**(`code`): `Promise`\<[`IdentityResult`](../type-aliases/IdentityResult.md)\> 56 | 57 | Retrieve an identity result using the code/id returned after successful authorization using the 58 | OAuth identity verification flow. 59 | 60 | [https://developers.akahu.nz/docs/identity-verification#retrieving-identity-results-with-the-oauth-result-code](https://developers.akahu.nz/docs/identity-verification#retrieving-identity-results-with-the-oauth-result-code) 61 | 62 | #### Parameters 63 | 64 | • **code**: `string` 65 | 66 | #### Returns 67 | 68 | `Promise`\<[`IdentityResult`](../type-aliases/IdentityResult.md)\> 69 | 70 | *** 71 | 72 | ### verifyName() 73 | 74 | > **verifyName**(`code`, `query`): `Promise`\<[`IdentityVerifyNameResult`](../type-aliases/IdentityVerifyNameResult.md)\> 75 | 76 | (**BETA**) Verify the user's name against an identity result. 77 | 78 | [https://developers.akahu.nz/docs/oneoff-verify-name](https://developers.akahu.nz/docs/oneoff-verify-name) 79 | 80 | #### Parameters 81 | 82 | • **code**: `string` 83 | 84 | • **query**: [`IdentityVerifyNameQuery`](../type-aliases/IdentityVerifyNameQuery.md) 85 | 86 | #### Returns 87 | 88 | `Promise`\<[`IdentityVerifyNameResult`](../type-aliases/IdentityVerifyNameResult.md)\> 89 | -------------------------------------------------------------------------------- /docs/classes/PartiesResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartiesResource 6 | 7 | # Class: PartiesResource 8 | 9 | Fetch identity data relating to the party that the user has logged-in to 10 | their institution as when connecting accounts to Akahu. i.e. the user's 11 | "profile" information at the connected institution. 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### list() 20 | 21 | > **list**(`token`): `Promise`\<[`Party`](../type-aliases/Party.md)[]\> 22 | 23 | List all parties related to accounts which the user has shared with your 24 | app. 25 | 26 | [https://developers.akahu.nz/reference/get_parties](https://developers.akahu.nz/reference/get_parties) 27 | 28 | #### Parameters 29 | 30 | • **token**: `string` 31 | 32 | #### Returns 33 | 34 | `Promise`\<[`Party`](../type-aliases/Party.md)[]\> 35 | -------------------------------------------------------------------------------- /docs/classes/PaymentsResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PaymentsResource 6 | 7 | # Class: PaymentsResource 8 | 9 | Utilities for managing bank account payments on behalf of users. 10 | 11 | [https://developers.akahu.nz/docs/making-a-payment](https://developers.akahu.nz/docs/making-a-payment) 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### get() 20 | 21 | > **get**(`token`, `paymentId`): `Promise`\<[`Payment`](../type-aliases/Payment.md)\> 22 | 23 | Get a single payment made by the user associated with the specified `token`. 24 | 25 | [https://developers.akahu.nz/reference/get_payments-id](https://developers.akahu.nz/reference/get_payments-id) 26 | 27 | #### Parameters 28 | 29 | • **token**: `string` 30 | 31 | • **paymentId**: `string` 32 | 33 | #### Returns 34 | 35 | `Promise`\<[`Payment`](../type-aliases/Payment.md)\> 36 | 37 | *** 38 | 39 | ### list() 40 | 41 | > **list**(`token`, `query`): `Promise`\<[`Payment`](../type-aliases/Payment.md)[]\> 42 | 43 | List all payments made in the provided date range by the user associated 44 | with the specified `token`. Defaults to the last 30 days if no date range 45 | is provided. 46 | 47 | [https://developers.akahu.nz/reference/get_payments](https://developers.akahu.nz/reference/get_payments) 48 | 49 | #### Parameters 50 | 51 | • **token**: `string` 52 | 53 | • **query**: [`PaymentQueryParams`](../type-aliases/PaymentQueryParams.md)= `{}` 54 | 55 | #### Returns 56 | 57 | `Promise`\<[`Payment`](../type-aliases/Payment.md)[]\> 58 | 59 | *** 60 | 61 | ### create() 62 | 63 | > **create**(`token`, `payment`, `requestOptions`?): `Promise`\<[`Payment`](../type-aliases/Payment.md)\> 64 | 65 | Initiate a payment to an external bank account on behalf of the user associated 66 | with the specified `token`. 67 | 68 | [https://developers.akahu.nz/reference/post_payments](https://developers.akahu.nz/reference/post_payments) 69 | 70 | #### Parameters 71 | 72 | • **token**: `string` 73 | 74 | • **payment**: [`PaymentCreateParams`](../type-aliases/PaymentCreateParams.md) 75 | 76 | • **requestOptions?**: [`PostRequestOptions`](../type-aliases/PostRequestOptions.md) 77 | 78 | #### Returns 79 | 80 | `Promise`\<[`Payment`](../type-aliases/Payment.md)\> 81 | 82 | *** 83 | 84 | ### createToIrd() 85 | 86 | > **createToIrd**(`token`, `payment`, `requestOptions`?): `Promise`\<[`Payment`](../type-aliases/Payment.md)\> 87 | 88 | Initiate a payment to the Inland Revenue Department on behalf of the user 89 | associated with the specified `token`. 90 | 91 | [https://developers.akahu.nz/reference/post_payments-ird](https://developers.akahu.nz/reference/post_payments-ird) 92 | 93 | #### Parameters 94 | 95 | • **token**: `string` 96 | 97 | • **payment**: [`IrdPaymentCreateParams`](../type-aliases/IrdPaymentCreateParams.md) 98 | 99 | • **requestOptions?**: [`PostRequestOptions`](../type-aliases/PostRequestOptions.md) 100 | 101 | #### Returns 102 | 103 | `Promise`\<[`Payment`](../type-aliases/Payment.md)\> 104 | 105 | *** 106 | 107 | ### cancel() 108 | 109 | > **cancel**(`token`, `paymentId`): `Promise`\<`void`\> 110 | 111 | Cancel a payment that has a status of `PENDING_APPROVAL`. 112 | 113 | [https://developers.akahu.nz/reference/put_payments-id-cancel](https://developers.akahu.nz/reference/put_payments-id-cancel) 114 | [https://developers.akahu.nz/docs/making-a-payment#manual-payment-approval](https://developers.akahu.nz/docs/making-a-payment#manual-payment-approval) 115 | 116 | #### Parameters 117 | 118 | • **token**: `string` 119 | 120 | • **paymentId**: `string` 121 | 122 | #### Returns 123 | 124 | `Promise`\<`void`\> 125 | -------------------------------------------------------------------------------- /docs/classes/TransactionsResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransactionsResource 6 | 7 | # Class: TransactionsResource 8 | 9 | Utilities for retrieving bank transactions from connected user accounts. 10 | 11 | [https://developers.akahu.nz/docs/accessing-transactional-data](https://developers.akahu.nz/docs/accessing-transactional-data) 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### list() 20 | 21 | > **list**(`token`, `query`): `Promise`\<[`Paginated`](../type-aliases/Paginated.md)\<[`Transaction`](../type-aliases/Transaction.md)\>\> 22 | 23 | List all transactions for all accounts that have been connected by the user associated with the 24 | specified `token`. 25 | 26 | [https://developers.akahu.nz/reference/get_transactions](https://developers.akahu.nz/reference/get_transactions) 27 | 28 | #### Parameters 29 | 30 | • **token**: `string` 31 | 32 | • **query**: [`TransactionQueryParams`](../type-aliases/TransactionQueryParams.md)= `{}` 33 | 34 | #### Returns 35 | 36 | `Promise`\<[`Paginated`](../type-aliases/Paginated.md)\<[`Transaction`](../type-aliases/Transaction.md)\>\> 37 | 38 | *** 39 | 40 | ### listPending() 41 | 42 | > **listPending**(`token`): `Promise`\<[`PendingTransaction`](../type-aliases/PendingTransaction.md)[]\> 43 | 44 | List all pending transactions for all accounts that have been connected by the user associated with the 45 | specified `token`. 46 | 47 | [https://developers.akahu.nz/reference/get_transactions-pending](https://developers.akahu.nz/reference/get_transactions-pending) 48 | 49 | #### Parameters 50 | 51 | • **token**: `string` 52 | 53 | #### Returns 54 | 55 | `Promise`\<[`PendingTransaction`](../type-aliases/PendingTransaction.md)[]\> 56 | 57 | *** 58 | 59 | ### get() 60 | 61 | > **get**(`token`, `transactionId`): `Promise`\<[`Transaction`](../type-aliases/Transaction.md)\> 62 | 63 | Get a single transaction from an account that has been connected by the user associated with 64 | the specified `token`. 65 | 66 | [https://developers.akahu.nz/reference/get_transactions-id](https://developers.akahu.nz/reference/get_transactions-id) 67 | 68 | #### Parameters 69 | 70 | • **token**: `string` 71 | 72 | • **transactionId**: `string` 73 | 74 | #### Returns 75 | 76 | `Promise`\<[`Transaction`](../type-aliases/Transaction.md)\> 77 | 78 | *** 79 | 80 | ### getMany() 81 | 82 | > **getMany**(`token`, `transactionIds`): `Promise`\<[`Transaction`](../type-aliases/Transaction.md)[]\> 83 | 84 | Get multiple transactions by id. 85 | 86 | All transactions must belong to the user associated with the specified `token`. 87 | 88 | This method may be useful to bulk refresh changed transaction data 89 | in response to a webhook event. 90 | 91 | [https://developers.akahu.nz/reference/post_transactions-ids](https://developers.akahu.nz/reference/post_transactions-ids) 92 | 93 | #### Parameters 94 | 95 | • **token**: `string` 96 | 97 | • **transactionIds**: `string`[] 98 | 99 | #### Returns 100 | 101 | `Promise`\<[`Transaction`](../type-aliases/Transaction.md)[]\> 102 | -------------------------------------------------------------------------------- /docs/classes/TransfersResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransfersResource 6 | 7 | # Class: TransfersResource 8 | 9 | Utilities for managing bank account transfers on behalf of users. 10 | 11 | [https://developers.akahu.nz/docs/making-a-transfer](https://developers.akahu.nz/docs/making-a-transfer) 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### get() 20 | 21 | > **get**(`token`, `transferId`): `Promise`\<[`Transfer`](../type-aliases/Transfer.md)\> 22 | 23 | Get a single transfer made by the user associated with the specified `token`. 24 | 25 | [https://developers.akahu.nz/reference/get_transfers-id](https://developers.akahu.nz/reference/get_transfers-id) 26 | 27 | #### Parameters 28 | 29 | • **token**: `string` 30 | 31 | • **transferId**: `string` 32 | 33 | #### Returns 34 | 35 | `Promise`\<[`Transfer`](../type-aliases/Transfer.md)\> 36 | 37 | *** 38 | 39 | ### list() 40 | 41 | > **list**(`token`, `query`): `Promise`\<[`Transfer`](../type-aliases/Transfer.md)[]\> 42 | 43 | List all transfers made in the provided date range by the user associated 44 | with the specified `token`. Defaults to the last 30 days if no date range 45 | is provided. 46 | 47 | [https://developers.akahu.nz/reference/get_transfers](https://developers.akahu.nz/reference/get_transfers) 48 | 49 | #### Parameters 50 | 51 | • **token**: `string` 52 | 53 | • **query**: [`TransferQueryParams`](../type-aliases/TransferQueryParams.md)= `{}` 54 | 55 | #### Returns 56 | 57 | `Promise`\<[`Transfer`](../type-aliases/Transfer.md)[]\> 58 | 59 | *** 60 | 61 | ### create() 62 | 63 | > **create**(`token`, `transfer`, `requestOptions`?): `Promise`\<[`Transfer`](../type-aliases/Transfer.md)\> 64 | 65 | Initiate a transfer between two of the users bank accounts. 66 | 67 | [https://developers.akahu.nz/reference/post_transfers](https://developers.akahu.nz/reference/post_transfers) 68 | 69 | #### Parameters 70 | 71 | • **token**: `string` 72 | 73 | • **transfer**: [`TransferCreateParams`](../type-aliases/TransferCreateParams.md) 74 | 75 | • **requestOptions?**: [`PostRequestOptions`](../type-aliases/PostRequestOptions.md) 76 | 77 | #### Returns 78 | 79 | `Promise`\<[`Transfer`](../type-aliases/Transfer.md)\> 80 | -------------------------------------------------------------------------------- /docs/classes/UsersResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / UsersResource 6 | 7 | # Class: UsersResource 8 | 9 | Utilities for retrieving information about the Akahu user. 10 | 11 | ## Extends 12 | 13 | - `BaseResource` 14 | 15 | ## Methods 16 | 17 | ### get() 18 | 19 | > **get**(`token`): `Promise`\<[`User`](../type-aliases/User.md)\> 20 | 21 | Get the user associated with the specified `token`. 22 | 23 | [https://developers.akahu.nz/reference/get_me](https://developers.akahu.nz/reference/get_me) 24 | 25 | #### Parameters 26 | 27 | • **token**: `string` 28 | 29 | #### Returns 30 | 31 | `Promise`\<[`User`](../type-aliases/User.md)\> 32 | -------------------------------------------------------------------------------- /docs/classes/WebhooksResource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhooksResource 6 | 7 | # Class: WebhooksResource 8 | 9 | Utilities for managing, retrieving, and validating webhooks. 10 | 11 | [https://developers.akahu.nz/docs/reference-webhooks](https://developers.akahu.nz/docs/reference-webhooks) 12 | 13 | ## Extends 14 | 15 | - `BaseResource` 16 | 17 | ## Methods 18 | 19 | ### list() 20 | 21 | > **list**(`token`): `Promise`\<[`Webhook`](../type-aliases/Webhook.md)[]\> 22 | 23 | Gets active webhooks for the user associated with the specified `token`. 24 | 25 | [https://developers.akahu.nz/reference/get_webhooks](https://developers.akahu.nz/reference/get_webhooks) 26 | 27 | #### Parameters 28 | 29 | • **token**: `string` 30 | 31 | #### Returns 32 | 33 | `Promise`\<[`Webhook`](../type-aliases/Webhook.md)[]\> 34 | 35 | *** 36 | 37 | ### subscribe() 38 | 39 | > **subscribe**(`token`, `webhook`, `requestOptions`?): `Promise`\<`string`\> 40 | 41 | Subscribe to a webhook. 42 | 43 | #### Parameters 44 | 45 | • **token**: `string` 46 | 47 | • **webhook**: [`WebhookCreateParams`](../type-aliases/WebhookCreateParams.md) 48 | 49 | • **requestOptions?**: [`PostRequestOptions`](../type-aliases/PostRequestOptions.md) 50 | 51 | #### Returns 52 | 53 | `Promise`\<`string`\> 54 | 55 | The newly created webhook id. 56 | 57 | [https://developers.akahu.nz/reference/post_webhooks](https://developers.akahu.nz/reference/post_webhooks) 58 | 59 | *** 60 | 61 | ### unsubscribe() 62 | 63 | > **unsubscribe**(`token`, `webhookId`): `Promise`\<`void`\> 64 | 65 | Unsubscribe from a previously created webhook. 66 | 67 | [https://developers.akahu.nz/reference/delete_webhooks-id](https://developers.akahu.nz/reference/delete_webhooks-id) 68 | 69 | #### Parameters 70 | 71 | • **token**: `string` 72 | 73 | • **webhookId**: `string` 74 | 75 | #### Returns 76 | 77 | `Promise`\<`void`\> 78 | 79 | *** 80 | 81 | ### listEvents() 82 | 83 | > **listEvents**(`query`): `Promise`\<[`WebhookEvent`](../type-aliases/WebhookEvent.md)[]\> 84 | 85 | List all webhook events with the specified status in the specified date 86 | range (defaults to last 30 days). 87 | 88 | [https://developers.akahu.nz/reference/get_webhook-events](https://developers.akahu.nz/reference/get_webhook-events) 89 | 90 | #### Parameters 91 | 92 | • **query**: [`WebhookEventQueryParams`](../type-aliases/WebhookEventQueryParams.md) 93 | 94 | #### Returns 95 | 96 | `Promise`\<[`WebhookEvent`](../type-aliases/WebhookEvent.md)[]\> 97 | 98 | *** 99 | 100 | ### getPublicKey() 101 | 102 | > **getPublicKey**(`keyId`): `Promise`\<`string`\> 103 | 104 | Get a webhook signing public-key by id. 105 | 106 | [https://developers.akahu.nz/reference/get_keys-id](https://developers.akahu.nz/reference/get_keys-id) 107 | 108 | #### Parameters 109 | 110 | • **keyId**: `string` \| `number` 111 | 112 | #### Returns 113 | 114 | `Promise`\<`string`\> 115 | 116 | *** 117 | 118 | ### validateWebhook() 119 | 120 | > **validateWebhook**(`keyId`, `signature`, `webhookRequestBody`, `cacheConfig`): `Promise`\<[`WebhookPayload`](../type-aliases/WebhookPayload.md)\> 121 | 122 | Helper to validate a webhook request payload. 123 | 124 | See the project README for example usage. 125 | 126 | #### Parameters 127 | 128 | • **keyId**: `string` \| `number` 129 | 130 | • **signature**: `string` 131 | 132 | • **webhookRequestBody**: `string` 133 | 134 | • **cacheConfig**: `Partial`\<[`WebhookCacheConfig`](../type-aliases/WebhookCacheConfig.md)\>= `{}` 135 | 136 | #### Returns 137 | 138 | `Promise`\<[`WebhookPayload`](../type-aliases/WebhookPayload.md)\> 139 | 140 | The deserialized webhook payload after successful validation 141 | 142 | #### Throws 143 | 144 | [AkahuWebhookValidationError](AkahuWebhookValidationError.md) 145 | if validation of the webhook fails due to invalid signature or expired signing key. 146 | 147 | #### Throws 148 | 149 | [AkahuErrorResponse](AkahuErrorResponse.md) 150 | if the client fails to fetch the specified signing key from the Akahu API. 151 | 152 | [https://developers.akahu.nz/docs/reference-webhooks](https://developers.akahu.nz/docs/reference-webhooks) 153 | -------------------------------------------------------------------------------- /docs/interfaces/WebhookSigningKeyCache.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookSigningKeyCache 6 | 7 | # Interface: WebhookSigningKeyCache 8 | 9 | Setter and getter interface to enable external/shared caching of webhook 10 | signing keys. 11 | 12 | Accessor functions may be async (by returning a Promise) or sync (by returning a value). 13 | 14 | See the project README for example usage. 15 | 16 | ## Methods 17 | 18 | ### get() 19 | 20 | > **get**(`key`): `null` \| `string` \| `Promise`\<`null` \| `string`\> 21 | 22 | #### Parameters 23 | 24 | • **key**: `string` 25 | 26 | #### Returns 27 | 28 | `null` \| `string` \| `Promise`\<`null` \| `string`\> 29 | 30 | *** 31 | 32 | ### set() 33 | 34 | > **set**(`key`, `value`): `void` \| `Promise`\<`void`\> 35 | 36 | #### Parameters 37 | 38 | • **key**: `string` 39 | 40 | • **value**: `string` 41 | 42 | #### Returns 43 | 44 | `void` \| `Promise`\<`void`\> 45 | -------------------------------------------------------------------------------- /docs/type-aliases/Account.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Account 6 | 7 | # Type alias: Account 8 | 9 | > **Account**: `object` 10 | 11 | Account data returned by Akahu /account endpoints. 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | A unique identifier for the account in the Akahu system. It is always be prefixed by `acc_` so that you can tell that it belongs to an account. 20 | 21 | ### \_authorisation 22 | 23 | > **\_authorisation**: `string` 24 | 25 | The authorisation identifier. Financial accounts are connected to Akahu via 26 | an authorisation with the user's financial institution. Multiple accounts 27 | can be connected during a single authorisation, causing them to have the 28 | same authorisation identifier. This identifier can also be used to link a 29 | specific account to identity data for the 30 | [party](https://developers.akahu.nz/reference/get_parties) who completed 31 | the authorisation. 32 | 33 | ### ~~\_credentials~~ 34 | 35 | > **\_credentials**: `string` 36 | 37 | #### Deprecated 38 | 39 | Please use `_authorisation` instead. 40 | 41 | ### connection 42 | 43 | > **connection**: [`Connection`](Connection.md) 44 | 45 | Information about the financial institution where the account is held (eg. ANZ bank). 46 | 47 | ### name 48 | 49 | > **name**: `string` 50 | 51 | The name of this account. If the connection allows customisation, the name will be the custom name (or nickname), eg. "Spending Account". Otherwise Akahu falls back to the product name, eg. "Super Saver". 52 | 53 | ### status 54 | 55 | > **status**: `"ACTIVE"` \| `"INACTIVE"` 56 | 57 | This tells you whether Akahu can currently sign in to the account to refresh it's data. It can be one of: 58 | 59 | - `ACTIVE` → Akahu can sign in and refresh this account. 60 | 61 | - `INACTIVE` → Akahu no longer has access to this account. This may be caused by the user revoking Akahu's access at the institution or changing their login credentials. When an account becomes `INACTIVE` your application should direct the the user back to the OAuth flow or to my.akahu.nz where they will be prompted to to re-establish this connection. 62 | 63 | ### type 64 | 65 | > **type**: `AccountType` 66 | 67 | Type of account, Akahu provides specific bank account types, and falls back to more general types for other types of connection. 68 | - `CHECKING` → An everyday spending account. 69 | - `SAVINGS` → A savings account. 70 | - `CREDITCARD` → A credit card. 71 | - `LOAN` → A loan account. 72 | - `KIWISAVER` → A KiwiSaver investment product. 73 | - `INVESTMENT` → A general investment product. 74 | - `TERMDEPOSIT` → A term deposit. 75 | - `FOREIGN` → An account holding a foreign currency. 76 | - `TAX` → An account with tax authorities. 77 | - `REWARDS` → An account for rewards points, e.g. Fly Buys or True Rewards. 78 | - `WALLET` → Available cash for investment or withdrawal from an investment provider. 79 | 80 | ### attributes 81 | 82 | > **attributes**: `AccountAttribute`[] 83 | 84 | The list of attributes indicates which abilities an account has. A list of: 85 | - `TRANSACTIONS` → account has transactions and supports retrieval of these via Akahu. 86 | - `TRANSFER_TO` → account can receive transfers from other accounts belonging to same set of credentials. 87 | - `TRANSFER_FROM` → account can initiate transfers to other accounts belonging to the same set of credentials. 88 | - `PAYMENT_TO` → account can receive payments from any Akahu account with the `PAYMENT_FROM` attribute. 89 | - `PAYMENT_FROM` → account can initiate payments to any Akahu account with the `PAYMENT_TO` attribute. 90 | 91 | ### formatted\_account? 92 | 93 | > `optional` **formatted\_account**: `string` 94 | 95 | If the account has a well defined account number (eg. a bank account number, or credit card number) this will be defined here with a standard format across connections. Credit cards will have at least 8 digits redacted. 96 | 97 | ### balance? 98 | 99 | > `optional` **balance**: `AccountBalance` 100 | 101 | The account balance 102 | 103 | ### refreshed? 104 | 105 | > `optional` **refreshed**: `AccountRefreshState` 106 | 107 | Akahu can refresh different parts of an account's data at different rates. The timestamps in the `refreshed` object tell you when that account data was last updated. This can be thought of as "Akahu's view of the account (balance/metadata/transactions) is up to date as of \$TIME". 108 | 109 | ### meta? 110 | 111 | > `optional` **meta**: `AccountMeta` 112 | 113 | Metadata regarding this account 114 | -------------------------------------------------------------------------------- /docs/type-aliases/AccountHolderNameVerificationSource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AccountHolderNameVerificationSource 6 | 7 | # Type alias: AccountHolderNameVerificationSource 8 | 9 | > **AccountHolderNameVerificationSource**: `object` 10 | 11 | Name verification match where the source data is the account holder name. 12 | 13 | ## Type declaration 14 | 15 | ### type 16 | 17 | > **type**: `"HOLDER_NAME"` 18 | 19 | ### match\_result 20 | 21 | > **match\_result**: `"MATCH"` \| `"PARTIAL_MATCH"` 22 | 23 | ### meta 24 | 25 | > **meta**: `object` 26 | 27 | Metadata from the matched account 28 | 29 | ### meta.name 30 | 31 | > **name**: `string` 32 | 33 | The account name 34 | 35 | ### meta.holder 36 | 37 | > **holder**: `string` 38 | 39 | The account holder name 40 | 41 | ### meta.account\_number 42 | 43 | > **account\_number**: `string` 44 | 45 | Formatted account number 46 | 47 | ### meta.bank 48 | 49 | > **bank**: `string` 50 | 51 | The name of the bank 52 | 53 | ### meta.address? 54 | 55 | > `optional` **address**: `string` 56 | 57 | The address associated with the account 58 | 59 | ### meta.branch? 60 | 61 | > `optional` **branch**: `object` 62 | 63 | Branch details (if available) 64 | 65 | ### meta.branch.\_id 66 | 67 | > **\_id**: `string` 68 | 69 | ### meta.branch.description 70 | 71 | > **description**: `string` 72 | 73 | ### meta.branch.phone 74 | 75 | > **phone**: `string` 76 | 77 | ### meta.branch.address 78 | 79 | > **address**: `object` 80 | 81 | ### meta.branch.address.line1 82 | 83 | > **line1**: `string` 84 | 85 | ### meta.branch.address.city 86 | 87 | > **city**: `string` 88 | 89 | ### meta.branch.address.country 90 | 91 | > **country**: `"New Zealand"` 92 | 93 | ### meta.branch.address.postcode 94 | 95 | > **postcode**: `string` 96 | 97 | ### meta.branch.address.line2? 98 | 99 | > `optional` **line2**: `string` 100 | 101 | ### meta.branch.address.line3? 102 | 103 | > `optional` **line3**: `string` 104 | 105 | ### verification 106 | 107 | > **verification**: `object` 108 | 109 | ### verification.given\_name 110 | 111 | > **given\_name**: `boolean` 112 | 113 | ### verification.given\_initial 114 | 115 | > **given\_initial**: `boolean` 116 | 117 | ### verification.middle\_name 118 | 119 | > **middle\_name**: `boolean` 120 | 121 | ### verification.middle\_initial 122 | 123 | > **middle\_initial**: `boolean` 124 | 125 | ### verification.family\_name 126 | 127 | > **family\_name**: `boolean` 128 | -------------------------------------------------------------------------------- /docs/type-aliases/AccountPayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AccountPayload 6 | 7 | # Type alias: AccountPayload 8 | 9 | > **AccountPayload**: [`BasePayload`](BasePayload.md) & `object` & `object` \| `object` 10 | 11 | ACCOUNT 12 | 13 | An event has occurred relating to a users linked account. 14 | 15 | [https://developers.akahu.nz/docs/reference-webhooks#account](https://developers.akahu.nz/docs/reference-webhooks#account) 16 | 17 | ## Type declaration 18 | 19 | ### webhook\_type 20 | 21 | > **webhook\_type**: `"ACCOUNT"` 22 | -------------------------------------------------------------------------------- /docs/type-aliases/AkahuClientConfig.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AkahuClientConfig 6 | 7 | # Type alias: AkahuClientConfig 8 | 9 | > **AkahuClientConfig**: `object` 10 | 11 | Authentication and API endpoint configuration for [AkahuClient](../classes/AkahuClient.md). 12 | 13 | ## Type declaration 14 | 15 | ### appToken 16 | 17 | > **appToken**: `string` 18 | 19 | appToken is required to access the Akahu API. 20 | 21 | ### appSecret? 22 | 23 | > `optional` **appSecret**: `string` 24 | 25 | appSecret is only required for completing an OAuth code exchange, or to 26 | access app-specific endpoints. 27 | 28 | For security reasons, this option must not be used client-side in the browser. 29 | 30 | [https://developers.akahu.nz/reference](https://developers.akahu.nz/reference) 31 | 32 | #### Default Value 33 | 34 | `undefined` 35 | 36 | ### apiVersion? 37 | 38 | > `optional` **apiVersion**: `ApiVersion` 39 | 40 | The Akahu API version. Currently the only supported value is "v1". 41 | 42 | #### Default Value 43 | 44 | `v1` 45 | 46 | ### protocol? 47 | 48 | > `optional` **protocol**: [`Protocol`](Protocol.md) 49 | 50 | The protocol used for Akahu API calls. 51 | The Akahu API only supports connections over HTTPS, so this option is only 52 | useful for test environments etc. 53 | 54 | #### Default Value 55 | 56 | `https` 57 | 58 | ### host? 59 | 60 | > `optional` **host**: `string` 61 | 62 | The Akahu API hostname. 63 | It may be useful to override this in staging / testing environments. 64 | 65 | #### Default Value 66 | 67 | `api.akahu.io` 68 | 69 | ### port? 70 | 71 | > `optional` **port**: `number` 72 | 73 | The Akahu API port. 74 | It may be useful to override this in staging / testing environments. 75 | 76 | #### Default Value 77 | 78 | `undefined` 79 | 80 | ### headers? 81 | 82 | > `optional` **headers**: `Record`\<`string`, `string`\> 83 | 84 | Additional headers that will be included in each request. 85 | 86 | ### timeout? 87 | 88 | > `optional` **timeout**: `number` 89 | 90 | Timeout in ms for each request to the Akahu API. 91 | 92 | If used in combination with `retries`, the timeout will be applied to 93 | each retried request. This means that the total time until an error is 94 | thrown due to a timeout will be `timeout * (retries + 1)` milliseconds. 95 | 96 | #### Default Value 97 | 98 | `0` (no timeout) 99 | 100 | ### retries? 101 | 102 | > `optional` **retries**: `number` 103 | 104 | The number of times that API requests will be retried in the case of 105 | network errors. Error responses from the Akahu API will not result in 106 | a retry. 107 | 108 | #### Default Value 109 | 110 | `0` 111 | 112 | ### proxy? 113 | 114 | > `optional` **proxy**: `object` 115 | 116 | Optional configuration for an HTTP proxy. 117 | 118 | See the proxy section of the axios [request config](https://axios-http.com/docs/req_config) 119 | for more details. 120 | 121 | ### proxy.host 122 | 123 | > **host**: `string` 124 | 125 | ### proxy.port 126 | 127 | > **port**: `number` 128 | 129 | ### proxy.auth? 130 | 131 | > `optional` **auth**: `object` 132 | 133 | ### proxy.auth.username 134 | 135 | > **username**: `string` 136 | 137 | ### proxy.auth.password 138 | 139 | > **password**: `string` 140 | 141 | ### proxy.protocol? 142 | 143 | > `optional` **protocol**: `string` 144 | 145 | ### adapter? 146 | 147 | > `optional` **adapter**: `AxiosRequestConfig`\[`"adapter"`\] 148 | 149 | Optional adapter function which will be passed through to the underlying 150 | Axios instance. 151 | 152 | See [https://github.com/axios/axios/tree/v1.8.3/lib/adapters](https://github.com/axios/axios/tree/v1.8.3/lib/adapters). 153 | -------------------------------------------------------------------------------- /docs/type-aliases/AuthorizationToken.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / AuthorizationToken 6 | 7 | # Type alias: AuthorizationToken 8 | 9 | > **AuthorizationToken**: `object` 10 | 11 | OAuth2 token authorization response. 12 | 13 | ## Type declaration 14 | 15 | ### access\_token 16 | 17 | > **access\_token**: `string` 18 | 19 | ### token\_type 20 | 21 | > **token\_type**: `"bearer"` 22 | 23 | ### scope 24 | 25 | > **scope**: `string` 26 | -------------------------------------------------------------------------------- /docs/type-aliases/BasePayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / BasePayload 6 | 7 | # Type alias: BasePayload 8 | 9 | > **BasePayload**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### webhook\_type 14 | 15 | > **webhook\_type**: [`WebhookType`](WebhookType.md) 16 | 17 | ### webhook\_code 18 | 19 | > **webhook\_code**: `string` 20 | 21 | ### state 22 | 23 | > **state**: `string` 24 | -------------------------------------------------------------------------------- /docs/type-aliases/CancelledPayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / CancelledPayload 6 | 7 | # Type alias: CancelledPayload 8 | 9 | > **CancelledPayload**: [`BasePayload`](BasePayload.md) & `object` 10 | 11 | WEBHOOK_CANCELLED 12 | 13 | Webhook payload to indicate that the specified webhook has been cancelled. 14 | For example, if the user revokes access to your app. 15 | 16 | ## Type declaration 17 | 18 | ### webhook\_code 19 | 20 | > **webhook\_code**: `"WEBHOOK_CANCELLED"` 21 | -------------------------------------------------------------------------------- /docs/type-aliases/Category.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Category 6 | 7 | # Type alias: Category 8 | 9 | > **Category**: `object` 10 | 11 | Akahu category metadata returned by /categories endpoints. 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | ### name 20 | 21 | > **name**: `string` 22 | 23 | ### groups 24 | 25 | > **groups**: `object` 26 | 27 | #### Index signature 28 | 29 | \[`groupingKey`: `string`\]: `object` 30 | -------------------------------------------------------------------------------- /docs/type-aliases/Connection.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Connection 6 | 7 | # Type alias: Connection 8 | 9 | > **Connection**: `object` 10 | 11 | Akahu connection metadata returned by /connections endpoints. 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | ### name 20 | 21 | > **name**: `string` 22 | 23 | ### logo 24 | 25 | > **logo**: `string` 26 | -------------------------------------------------------------------------------- /docs/type-aliases/CurrencyConversion.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / CurrencyConversion 6 | 7 | # Type alias: CurrencyConversion 8 | 9 | > **CurrencyConversion**: `object` 10 | 11 | Represents the conversion details of a transaction. 12 | 13 | ## Type declaration 14 | 15 | ### rate 16 | 17 | > **rate**: `number` 18 | 19 | The conversion rate used for the transaction. 20 | 21 | ### amount 22 | 23 | > **amount**: `number` 24 | 25 | The converted amount in the transaction. 26 | 27 | ### currency 28 | 29 | > **currency**: `string` 30 | 31 | The foreign currency in which the transaction was converted to/from. 32 | -------------------------------------------------------------------------------- /docs/type-aliases/Cursor.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Cursor 6 | 7 | # Type alias: Cursor 8 | 9 | > **Cursor**: `string` \| `null` \| `undefined` 10 | 11 | Convenience type alias, useful when paging through multiple pages of results. 12 | 13 | ## Example 14 | 15 | ```typescript 16 | import type { Cursor, Transaction } from "akahu"; 17 | const transactions: Transaction[] = []; 18 | let cursor: Cursor; 19 | 20 | do { 21 | const page = await akahu.transactions.list(userToken, { cursor }); 22 | transactions.push(...page.items); 23 | cursor = page.cursor.next; 24 | } while (cursor !== null); 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/type-aliases/EnrichedTransaction.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / EnrichedTransaction 6 | 7 | # Type alias: EnrichedTransaction 8 | 9 | > **EnrichedTransaction**: [`RawTransaction`](RawTransaction.md) & `object` 10 | 11 | A basic transaction with additional enrichment data. 12 | 13 | An enriched transaction includes structured data describing the merchant 14 | that was party to the transaction. 15 | 16 | ## Type declaration 17 | 18 | ### merchant 19 | 20 | > **merchant**: `object` 21 | 22 | ### merchant.\_id 23 | 24 | > **\_id**: `string` 25 | 26 | ### merchant.name 27 | 28 | > **name**: `string` 29 | 30 | ### merchant.website? 31 | 32 | > `optional` **website**: `string` 33 | 34 | ### category 35 | 36 | > **category**: `object` 37 | 38 | ### category.\_id 39 | 40 | > **\_id**: `string` 41 | 42 | ### category.name 43 | 44 | > **name**: `string` 45 | 46 | ### category.groups 47 | 48 | > **groups**: `object` 49 | 50 | #### Index signature 51 | 52 | \[`groupKey`: `string`\]: `object` 53 | 54 | ### meta 55 | 56 | > **meta**: `object` 57 | 58 | ### meta.particulars? 59 | 60 | > `optional` **particulars**: `string` 61 | 62 | ### meta.code? 63 | 64 | > `optional` **code**: `string` 65 | 66 | ### meta.reference? 67 | 68 | > `optional` **reference**: `string` 69 | 70 | ### meta.other\_account? 71 | 72 | > `optional` **other\_account**: `string` 73 | 74 | ### meta.conversion? 75 | 76 | > `optional` **conversion**: [`CurrencyConversion`](CurrencyConversion.md) 77 | 78 | ### meta.logo? 79 | 80 | > `optional` **logo**: `string` 81 | 82 | ### meta.card\_suffix? 83 | 84 | > `optional` **card\_suffix**: `string` 85 | 86 | If this transaction was made with a credit or debit card, this field may 87 | contain the last four digits of the card number. 88 | -------------------------------------------------------------------------------- /docs/type-aliases/IdentityResult.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / IdentityResult 6 | 7 | # Type alias: IdentityResult 8 | 9 | > **IdentityResult**: `object` 10 | 11 | The result of an Akahu identity verification request. 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | ### status 20 | 21 | > **status**: `"PROCESSING"` \| `"COMPLETE"` \| `"ERROR"` 22 | 23 | ### created\_at 24 | 25 | > **created\_at**: `string` 26 | 27 | ### updated\_at 28 | 29 | > **updated\_at**: `string` 30 | 31 | ### expires\_at 32 | 33 | > **expires\_at**: `string` 34 | 35 | ### source 36 | 37 | > **source**: `Record`\<`string`, `any`\> 38 | 39 | ### errors? 40 | 41 | > `optional` **errors**: `string`[] 42 | 43 | ### identities? 44 | 45 | > `optional` **identities**: `Record`\<`string`, `any`\>[] 46 | 47 | ### addresses? 48 | 49 | > `optional` **addresses**: `Record`\<`string`, `any`\>[] 50 | 51 | ### accounts? 52 | 53 | > `optional` **accounts**: `Record`\<`string`, `any`\>[] 54 | -------------------------------------------------------------------------------- /docs/type-aliases/IdentityVerifyNameQuery.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / IdentityVerifyNameQuery 6 | 7 | # Type alias: IdentityVerifyNameQuery 8 | 9 | > **IdentityVerifyNameQuery**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### family\_name 14 | 15 | > **family\_name**: `string` 16 | 17 | The user's family name which will be verified against the Akahu identity 18 | result. 19 | 20 | ### given\_name? 21 | 22 | > `optional` **given\_name**: `string` 23 | 24 | The user's given name which will be verified against the Akahu identity 25 | result. 26 | 27 | ### middle\_name? 28 | 29 | > `optional` **middle\_name**: `string` 30 | 31 | The user's middle name which will be verified against the Akahu identity 32 | result. If the user has multiple middle names, provide them all separated 33 | by a space. 34 | -------------------------------------------------------------------------------- /docs/type-aliases/IdentityVerifyNameResult.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / IdentityVerifyNameResult 6 | 7 | # Type alias: IdentityVerifyNameResult 8 | 9 | > **IdentityVerifyNameResult**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### sources 14 | 15 | > **sources**: ([`AccountHolderNameVerificationSource`](AccountHolderNameVerificationSource.md) \| [`PartyNameVerificationSource`](PartyNameVerificationSource.md))[] 16 | -------------------------------------------------------------------------------- /docs/type-aliases/IrdPaymentCreateParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / IrdPaymentCreateParams 6 | 7 | # Type alias: IrdPaymentCreateParams 8 | 9 | > **IrdPaymentCreateParams**: `object` 10 | 11 | Parameters for initiating a new payment from a bank account to IRD. 12 | 13 | ## Type declaration 14 | 15 | ### from 16 | 17 | > **from**: `string` 18 | 19 | The Akahu account id from which the payment will be made. The `from` 20 | account id **must** refer to an account that has been linked by the user 21 | for which this request is authenticated. 22 | 23 | An account id starts with `acc_...`. 24 | 25 | ### amount 26 | 27 | > **amount**: `number` 28 | 29 | The dollar amount for the payment. This must be a numeric value with no more 30 | than 2 decimal places. 31 | 32 | ### meta 33 | 34 | > **meta**: `object` 35 | 36 | Required tax payment metadata to send with the payment. 37 | 38 | ### meta.tax\_number 39 | 40 | > **tax\_number**: `string` 41 | 42 | The IRD/GST number associated with the payment. 43 | 44 | ### meta.tax\_type 45 | 46 | > **tax\_type**: `string` 47 | 48 | The 3 character IRD tax type code that tells IRD what type of tax the 49 | payment is for. 50 | [https://www.ird.govt.nz/managing-my-tax/make-a-payment/choosing-the-right-account-type](https://www.ird.govt.nz/managing-my-tax/make-a-payment/choosing-the-right-account-type) 51 | 52 | ### meta.tax\_period? 53 | 54 | > `optional` **tax\_period**: `string` 55 | 56 | The end date of the tax period which this payment is for, formatted as an 57 | ISO 8601 date e.g. 1970-01-01. 58 | 59 | This is required by IRD for _most_ tax payments, however there are certain 60 | payment types that do not require it (e.g. ARR, KSS, LGL). For the complete 61 | list of exclusions see: 62 | [https://www.ird.govt.nz/managing-my-tax/make-a-payment/ways-of-paying/paying-electronically](https://www.ird.govt.nz/managing-my-tax/make-a-payment/ways-of-paying/paying-electronically) 63 | -------------------------------------------------------------------------------- /docs/type-aliases/Paginated.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Paginated 6 | 7 | # Type alias: Paginated\ 8 | 9 | > **Paginated**\<`T`\>: `object` 10 | 11 | A "page" of results returned by paginated API endpoints. 12 | 13 | Each page contains an array of zero-or-more returned objects nested under the 14 | `items` key. In some cases - even if the returned `items` array is empty - 15 | there may still be further pages available. Because if this it is important 16 | to always check the value of `cursor.next` in the response. 17 | 18 | The cursor pointing to the next page of results can be found nested under 19 | `cursor.next`. If there are no further results available, `cursor.next` will 20 | be `null`. 21 | 22 | ## Type parameters 23 | 24 | • **T** 25 | 26 | ## Type declaration 27 | 28 | ### items 29 | 30 | > **items**: `T`[] 31 | 32 | ### cursor 33 | 34 | > **cursor**: `object` 35 | 36 | ### cursor.next 37 | 38 | > **next**: `string` \| `null` 39 | -------------------------------------------------------------------------------- /docs/type-aliases/Party.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Party 6 | 7 | # Type alias: Party 8 | 9 | > **Party**: `object` 10 | 11 | Identity data relating to the party that the user has logged-in to their 12 | institution as when connecting accounts to Akahu. i.e. the user's "profile" 13 | information at the connected institution. 14 | 15 | All keys are optional depending on the scopes granted to your app. 16 | 17 | ## Type declaration 18 | 19 | ### \_id 20 | 21 | > **\_id**: `string` 22 | 23 | ### \_authorisation 24 | 25 | > **\_authorisation**: `string` 26 | 27 | The authorisation identifier. Financial accounts are connected to Akahu via 28 | an authorisation with the user's financial institution. This identifier can 29 | be used to link specific financial accounts to the party who completed the 30 | authorisation by matching records with the same `_authorisation` value. 31 | 32 | ### \_connection 33 | 34 | > **\_connection**: `string` 35 | 36 | The connection id identifying the institution that the data was sourced from 37 | 38 | ### \_user 39 | 40 | > **\_user**: `string` 41 | 42 | ### type 43 | 44 | > **type**: `"INDIVIDUAL"` \| `"JOINT"` \| `"TRUST"` \| `"LLC"` 45 | 46 | ### name? 47 | 48 | > `optional` **name**: [`PartyName`](PartyName.md) 49 | 50 | ### dob? 51 | 52 | > `optional` **dob**: [`PartyDob`](PartyDob.md) 53 | 54 | ### tax\_number? 55 | 56 | > `optional` **tax\_number**: [`PartyTaxNumber`](PartyTaxNumber.md) 57 | 58 | ### phone\_numbers? 59 | 60 | > `optional` **phone\_numbers**: [`PartyPhoneNumber`](PartyPhoneNumber.md)[] 61 | 62 | ### email\_addresses? 63 | 64 | > `optional` **email\_addresses**: [`PartyEmail`](PartyEmail.md)[] 65 | 66 | ### addresses? 67 | 68 | > `optional` **addresses**: [`PartyAddress`](PartyAddress.md)[] 69 | -------------------------------------------------------------------------------- /docs/type-aliases/PartyAddress.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartyAddress 6 | 7 | # Type alias: PartyAddress 8 | 9 | > **PartyAddress**: `object` 10 | 11 | The user's address as sourced from the connected institution. 12 | 13 | ## Type declaration 14 | 15 | ### subtype 16 | 17 | > **subtype**: `"RESIDENTIAL"` \| `"POSTAL"` 18 | 19 | ### value 20 | 21 | > **value**: `string` 22 | 23 | The raw address value from the connected institution. 24 | 25 | ### formatted 26 | 27 | > **formatted**: `string` 28 | 29 | A consistently formatted/normalised version of the address. 30 | 31 | ### components 32 | 33 | > **components**: `object` 34 | 35 | Individual components of the normalised address. 36 | 37 | ### components.street 38 | 39 | > **street**: `string` 40 | 41 | ### components.suburb 42 | 43 | > **suburb**: `string` 44 | 45 | ### components.city 46 | 47 | > **city**: `string` 48 | 49 | ### components.region 50 | 51 | > **region**: `string` 52 | 53 | ### components.postal\_code 54 | 55 | > **postal\_code**: `string` 56 | 57 | ### components.country 58 | 59 | > **country**: `string` 60 | 61 | ### google\_maps\_place\_id 62 | 63 | > **google\_maps\_place\_id**: `string` 64 | 65 | Google Maps API Place ID for this address. 66 | 67 | [https://developers.google.com/maps/documentation/places/web-service/place-id](https://developers.google.com/maps/documentation/places/web-service/place-id) 68 | -------------------------------------------------------------------------------- /docs/type-aliases/PartyDob.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartyDob 6 | 7 | # Type alias: PartyDob 8 | 9 | > **PartyDob**: `object` 10 | 11 | The user's date of birth as sourced from the connected institution. 12 | 13 | ## Type declaration 14 | 15 | ### value 16 | 17 | > **value**: `string` 18 | 19 | The user's date of birth in the format YYYY-MM-DD. 20 | -------------------------------------------------------------------------------- /docs/type-aliases/PartyEmail.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartyEmail 6 | 7 | # Type alias: PartyEmail 8 | 9 | > **PartyEmail**: `object` 10 | 11 | The user's email address as sourced from the connected institution. 12 | 13 | ## Type declaration 14 | 15 | ### subtype 16 | 17 | > **subtype**: `"PRIMARY"` 18 | 19 | ### verified 20 | 21 | > **verified**: `boolean` 22 | 23 | ### value 24 | 25 | > **value**: `string` 26 | 27 | The value of the email address. 28 | -------------------------------------------------------------------------------- /docs/type-aliases/PartyName.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartyName 6 | 7 | # Type alias: PartyName 8 | 9 | > **PartyName**: `object` 10 | 11 | The user's name as sourced from the connected institution. 12 | 13 | ## Type declaration 14 | 15 | ### value 16 | 17 | > **value**: `string` 18 | 19 | The name value in the format provided by the connected institution. 20 | e.g. John Smith, Mr John Smith, MR JOHN SMITH 21 | -------------------------------------------------------------------------------- /docs/type-aliases/PartyNameVerificationSource.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartyNameVerificationSource 6 | 7 | # Type alias: PartyNameVerificationSource 8 | 9 | > **PartyNameVerificationSource**: `object` 10 | 11 | Name verification match where the source data is the registered name of the 12 | party who has authenticated with the financial institution. 13 | 14 | This data is sourced from the profile information held by connected institution 15 | rather than any specific account held within. 16 | 17 | ## Type declaration 18 | 19 | ### type 20 | 21 | > **type**: `"PARTY_NAME"` 22 | 23 | ### match\_result 24 | 25 | > **match\_result**: `"MATCH"` \| `"PARTIAL_MATCH"` 26 | 27 | ### meta 28 | 29 | > **meta**: `object` 30 | 31 | The matched party name data 32 | 33 | ### meta.type 34 | 35 | > **type**: `"INDIVIDUAL"` \| `"JOINT"` \| `"TRUST"` \| `"LLC"` 36 | 37 | ### meta.family\_name 38 | 39 | > **family\_name**: `string` 40 | 41 | ### meta.full\_name 42 | 43 | > **full\_name**: `string` 44 | 45 | ### meta.initials? 46 | 47 | > `optional` **initials**: `string`[] 48 | 49 | ### meta.given\_name? 50 | 51 | > `optional` **given\_name**: `string` 52 | 53 | ### meta.middle\_name? 54 | 55 | > `optional` **middle\_name**: `string` 56 | 57 | ### meta.prefix? 58 | 59 | > `optional` **prefix**: `string` 60 | 61 | ### meta.gender? 62 | 63 | > `optional` **gender**: `string` 64 | 65 | ### verification 66 | 67 | > **verification**: `object` 68 | 69 | ### verification.given\_name 70 | 71 | > **given\_name**: `boolean` 72 | 73 | ### verification.given\_initial 74 | 75 | > **given\_initial**: `boolean` 76 | 77 | ### verification.middle\_name 78 | 79 | > **middle\_name**: `boolean` 80 | 81 | ### verification.middle\_initial 82 | 83 | > **middle\_initial**: `boolean` 84 | 85 | ### verification.family\_name 86 | 87 | > **family\_name**: `boolean` 88 | -------------------------------------------------------------------------------- /docs/type-aliases/PartyPhoneNumber.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartyPhoneNumber 6 | 7 | # Type alias: PartyPhoneNumber 8 | 9 | > **PartyPhoneNumber**: `object` 10 | 11 | The user's phone number as sourced from the connected institution. 12 | 13 | ## Type declaration 14 | 15 | ### subtype 16 | 17 | > **subtype**: `"MOBILE"` \| `"HOME"` \| `"WORK"` 18 | 19 | ### verified 20 | 21 | > **verified**: `boolean` 22 | 23 | ### value 24 | 25 | > **value**: `string` 26 | 27 | The value of the phone number. 28 | -------------------------------------------------------------------------------- /docs/type-aliases/PartyTaxNumber.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PartyTaxNumber 6 | 7 | # Type alias: PartyTaxNumber 8 | 9 | > **PartyTaxNumber**: `object` 10 | 11 | The user's tax (IRD) number as sourced from the connected institution. 12 | 13 | ## Type declaration 14 | 15 | ### value 16 | 17 | > **value**: `string` 18 | 19 | The IRD number in the format XXX-XXX-XXX 20 | -------------------------------------------------------------------------------- /docs/type-aliases/Payment.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Payment 6 | 7 | # Type alias: Payment 8 | 9 | > **Payment**: `object` 10 | 11 | Payment object returned by the /payments endpoint. 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | ### from 20 | 21 | > **from**: `string` 22 | 23 | ### to 24 | 25 | > **to**: `object` 26 | 27 | ### to.name 28 | 29 | > **name**: `string` 30 | 31 | ### to.account\_number 32 | 33 | > **account\_number**: `string` 34 | 35 | ### amount 36 | 37 | > **amount**: `number` 38 | 39 | ### meta 40 | 41 | > **meta**: `object` 42 | 43 | ### meta.source 44 | 45 | > **source**: `object` 46 | 47 | ### meta.source.code? 48 | 49 | > `optional` **code**: `string` 50 | 51 | ### meta.source.reference? 52 | 53 | > `optional` **reference**: `string` 54 | 55 | ### meta.destination 56 | 57 | > **destination**: `object` 58 | 59 | ### meta.destination.particulars? 60 | 61 | > `optional` **particulars**: `string` 62 | 63 | ### meta.destination.code? 64 | 65 | > `optional` **code**: `string` 66 | 67 | ### meta.destination.reference? 68 | 69 | > `optional` **reference**: `string` 70 | 71 | ### sid 72 | 73 | > **sid**: `string` 74 | 75 | ### status 76 | 77 | > **status**: [`PaymentStatus`](PaymentStatus.md) 78 | 79 | ### final 80 | 81 | > **final**: `boolean` 82 | 83 | ### timeline 84 | 85 | > **timeline**: `object`[] 86 | 87 | ### created\_at 88 | 89 | > **created\_at**: `string` 90 | 91 | ### updated\_at 92 | 93 | > **updated\_at**: `string` 94 | 95 | ### status\_code? 96 | 97 | > `optional` **status\_code**: [`PaymentStatusCode`](PaymentStatusCode.md) 98 | 99 | ### status\_text? 100 | 101 | > `optional` **status\_text**: `string` 102 | 103 | ### approval\_type? 104 | 105 | > `optional` **approval\_type**: `"BANK"` \| `"USER"` 106 | 107 | ### received\_at? 108 | 109 | > `optional` **received\_at**: `string` 110 | 111 | ### ~~timeout\_at?~~ 112 | 113 | > `optional` **timeout\_at**: `string` 114 | 115 | #### Deprecated 116 | 117 | this field is unused 118 | -------------------------------------------------------------------------------- /docs/type-aliases/PaymentCreateParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PaymentCreateParams 6 | 7 | # Type alias: PaymentCreateParams 8 | 9 | > **PaymentCreateParams**: `object` 10 | 11 | Parameters for initiating a new bank account payment using Akahu. 12 | 13 | ## Type declaration 14 | 15 | ### from 16 | 17 | > **from**: `string` 18 | 19 | The Akahu account id from which the payment will be made. The `from` 20 | account id **must** refer to an account that has been linked by the user 21 | for which this request is authenticated. 22 | 23 | An account id starts with `acc_...`. 24 | 25 | ### amount 26 | 27 | > **amount**: `number` 28 | 29 | The dollar amount for the payment. This must be a numeric value with no more 30 | than 2 decimal places. 31 | 32 | ### to 33 | 34 | > **to**: `object` 35 | 36 | The details of the payee bank account to which the payment will be made. 37 | 38 | ### to.name 39 | 40 | > **name**: `string` 41 | 42 | The payee account holder name 43 | 44 | ### to.account\_number 45 | 46 | > **account\_number**: `string` 47 | 48 | The full payee account number. 49 | 50 | ### meta? 51 | 52 | > `optional` **meta**: `object` 53 | 54 | Optional metadata to send with the payment. 55 | 56 | ### meta.source? 57 | 58 | > `optional` **source**: `object` 59 | 60 | Metadata which will appear on the payers account statement. 61 | 62 | #### Remarks 63 | 64 | **Note:** `particulars` is not an accepted field. Akahu reserves this 65 | field on the source/payer statement for support and transaction verification. 66 | 67 | ### meta.source.code? 68 | 69 | > `optional` **code**: `string` 70 | 71 | ### meta.source.reference? 72 | 73 | > `optional` **reference**: `string` 74 | 75 | ### meta.destination? 76 | 77 | > `optional` **destination**: `object` 78 | 79 | Metadata which will appear on the payees account statement 80 | 81 | ### meta.destination.particulars? 82 | 83 | > `optional` **particulars**: `string` 84 | 85 | ### meta.destination.code? 86 | 87 | > `optional` **code**: `string` 88 | 89 | ### meta.destination.reference? 90 | 91 | > `optional` **reference**: `string` 92 | -------------------------------------------------------------------------------- /docs/type-aliases/PaymentPayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PaymentPayload 6 | 7 | # Type alias: PaymentPayload 8 | 9 | > **PaymentPayload**: [`BasePayload`](BasePayload.md) & `object` & `object` \| `object` 10 | 11 | PAYMENT 12 | 13 | An event has occurred relating to a payment from a users linked bank account. 14 | 15 | [https://developers.akahu.nz/docs/reference-webhooks#payment](https://developers.akahu.nz/docs/reference-webhooks#payment) 16 | 17 | ## Type declaration 18 | 19 | ### webhook\_type 20 | 21 | > **webhook\_type**: `"PAYMENT"` 22 | -------------------------------------------------------------------------------- /docs/type-aliases/PaymentQueryParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PaymentQueryParams 6 | 7 | # Type alias: PaymentQueryParams 8 | 9 | > **PaymentQueryParams**: `object` 10 | 11 | The date range that will be used to filter payment results. 12 | 13 | ## Type declaration 14 | 15 | ### start? 16 | 17 | > `optional` **start**: `string` 18 | 19 | The start date of the query as an ISO 8601 string. 20 | 21 | #### Default Value 22 | 23 | `30 days ago` 24 | 25 | ### end? 26 | 27 | > `optional` **end**: `string` 28 | 29 | The end date of the query as an ISO 8601 string. 30 | 31 | #### Default Value 32 | 33 | `today` 34 | -------------------------------------------------------------------------------- /docs/type-aliases/PaymentStatus.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PaymentStatus 6 | 7 | # Type alias: PaymentStatus 8 | 9 | > **PaymentStatus**: `"READY"` \| `"PENDING_APPROVAL"` \| `"PAUSED"` \| `"SENT"` \| `"DECLINED"` \| `"ERROR"` \| `"CANCELLED"` 10 | -------------------------------------------------------------------------------- /docs/type-aliases/PaymentStatusCode.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PaymentStatusCode 6 | 7 | # Type alias: PaymentStatusCode 8 | 9 | > **PaymentStatusCode**: `"INTERNAL_ERROR"` \| `"BANK_ERROR"` \| `"UNAVAILABLE"` \| `"INVALID_ACCOUNT"` \| `"INSUFFICIENT_FUNDS"` \| `"SINGLE_LIMIT_EXCEEDED"` \| `"DAILY_LIMIT_EXCEEDED"` \| `"AKAHU_LIMIT_EXCEEDED"` \| `"MFA_UNSUPPORTED"` \| `"MULTISIG_UNSUPPORTED"` \| `"AUTHENTICATION_FAILED"` \| `"MFA_FAILED"` \| `"AFTER_HOURS"` \| `"USER_CANCELLED"` \| `"APP_CANCELLED"` \| `"AKAHU_CANCELLED"` 10 | -------------------------------------------------------------------------------- /docs/type-aliases/PendingTransaction.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PendingTransaction 6 | 7 | # Type alias: PendingTransaction 8 | 9 | > **PendingTransaction**: `object` 10 | 11 | A pending transaction as returned by /transactions/pending 12 | 13 | ## Type declaration 14 | 15 | ### \_user 16 | 17 | > **\_user**: `string` 18 | 19 | The unique id of the user that the pending transaction is associated with. 20 | 21 | ### \_account 22 | 23 | > **\_account**: `string` 24 | 25 | The unique id of the account that the pending transaction is associated with. 26 | 27 | ### \_connection 28 | 29 | > **\_connection**: `string` 30 | 31 | The unique id of the account that the pending transaction is associated with. 32 | 33 | ### updated\_at 34 | 35 | > **updated\_at**: `string` 36 | 37 | The time at which the transaction was updated by Akahu. Formatted as an ISO 8601 timestamp. 38 | 39 | ### date 40 | 41 | > **date**: `string` 42 | 43 | The date that the transaction was posted as reported by the bank integration. Formatted as an 44 | ISO 8601 timestamp. 45 | 46 | ### description 47 | 48 | > **description**: `string` 49 | 50 | ### amount 51 | 52 | > **amount**: `number` 53 | 54 | ### type 55 | 56 | > **type**: [`TransactionType`](TransactionType.md) 57 | -------------------------------------------------------------------------------- /docs/type-aliases/PostRequestOptions.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / PostRequestOptions 6 | 7 | # Type alias: PostRequestOptions 8 | 9 | > **PostRequestOptions**: `object` 10 | 11 | Additional options for a POST request 12 | 13 | ## Type declaration 14 | 15 | ### idempotencyKey? 16 | 17 | > `optional` **idempotencyKey**: `string` 18 | 19 | Specifying this key allows you to safely retry POST requests without the 20 | risk of taking the same action twice. This is useful when an API call is 21 | disrupted in transit and you do not receive a response or you wish to 22 | protect against your application issuing duplicate requests. 23 | 24 | #### Default 25 | 26 | ```ts 27 | auto generated uuid 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/type-aliases/Protocol.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Protocol 6 | 7 | # Type alias: Protocol 8 | 9 | > **Protocol**: `"http"` \| `"https"` 10 | -------------------------------------------------------------------------------- /docs/type-aliases/RawTransaction.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / RawTransaction 6 | 7 | # Type alias: RawTransaction 8 | 9 | > **RawTransaction**: `object` 10 | 11 | A raw, unenriched transaction object returned by /transactions 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | The unique id for the transaction 20 | 21 | ### \_user 22 | 23 | > **\_user**: `string` 24 | 25 | The unique id of the user that the transaction is associated with. 26 | 27 | ### \_account 28 | 29 | > **\_account**: `string` 30 | 31 | The unique id of the account that the transaction is associated with. 32 | 33 | ### \_connection 34 | 35 | > **\_connection**: `string` 36 | 37 | The unique id of the connection that the transaction is associated with. 38 | 39 | ### created\_at 40 | 41 | > **created\_at**: `string` 42 | 43 | The time at which the transaction was retrieved by Akahu. Formatted as an ISO 8601 timestamp. 44 | 45 | ### updated\_at 46 | 47 | > **updated\_at**: `string` 48 | 49 | The time at which the transaction was last updated by Akahu. Formatted as an ISO 8601 timestamp. 50 | 51 | ### date 52 | 53 | > **date**: `string` 54 | 55 | The date that the transaction was posted as reported by the bank integration. Formatted as an 56 | ISO 8601 timestamp. 57 | 58 | ### ~~hash~~ 59 | 60 | > **hash**: `string` 61 | 62 | An identification string based on the contents of the transaction and the account from 63 | which the transaction was fetched. 64 | 65 | #### Deprecated 66 | 67 | Prefer `_id` to uniquely identify transactions. 68 | 69 | ### description 70 | 71 | > **description**: `string` 72 | 73 | The transaction description as reported by the bank integration. 74 | 75 | ### amount 76 | 77 | > **amount**: `number` 78 | 79 | The monetary value of the transaction. 80 | 81 | ### type 82 | 83 | > **type**: [`TransactionType`](TransactionType.md) 84 | 85 | The type of the transaction. 86 | 87 | ### balance? 88 | 89 | > `optional` **balance**: `number` 90 | 91 | The account balance after receipt of this transaction (when available). 92 | -------------------------------------------------------------------------------- /docs/type-aliases/TokenPayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TokenPayload 6 | 7 | # Type alias: TokenPayload 8 | 9 | > **TokenPayload**: [`BasePayload`](BasePayload.md) & `object` 10 | 11 | TOKEN 12 | 13 | An event has occurred relating to a user token. 14 | 15 | [https://developers.akahu.nz/docs/reference-webhooks#token](https://developers.akahu.nz/docs/reference-webhooks#token) 16 | 17 | ## Type declaration 18 | 19 | ### webhook\_type 20 | 21 | > **webhook\_type**: `"TOKEN"` 22 | 23 | ### webhook\_code 24 | 25 | > **webhook\_code**: `"DELETE"` 26 | 27 | ### item\_id 28 | 29 | > **item\_id**: `string` 30 | -------------------------------------------------------------------------------- /docs/type-aliases/Transaction.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Transaction 6 | 7 | # Type alias: Transaction 8 | 9 | > **Transaction**: [`RawTransaction`](RawTransaction.md) \| [`EnrichedTransaction`](EnrichedTransaction.md) 10 | 11 | A transaction object as returned by the /transactions endpoint. 12 | -------------------------------------------------------------------------------- /docs/type-aliases/TransactionPayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransactionPayload 6 | 7 | # Type alias: TransactionPayload 8 | 9 | > **TransactionPayload**: [`BasePayload`](BasePayload.md) & `object` & `object` \| `object` 10 | 11 | TRANSACTION 12 | 13 | An event has occurred relating to transactions on a users linked account. 14 | 15 | [https://developers.akahu.nz/docs/reference-webhooks#transaction](https://developers.akahu.nz/docs/reference-webhooks#transaction) 16 | 17 | ## Type declaration 18 | 19 | ### webhook\_type 20 | 21 | > **webhook\_type**: `"TRANSACTION"` 22 | -------------------------------------------------------------------------------- /docs/type-aliases/TransactionQueryParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransactionQueryParams 6 | 7 | # Type alias: TransactionQueryParams 8 | 9 | > **TransactionQueryParams**: `object` 10 | 11 | Query parameters that will be used to filter transaction results. 12 | 13 | ## Type declaration 14 | 15 | ### start? 16 | 17 | > `optional` **start**: `string` 18 | 19 | The start date of the query as an ISO 8601 string. 20 | 21 | #### Default Value 22 | 23 | `30 days ago` 24 | 25 | ### end? 26 | 27 | > `optional` **end**: `string` 28 | 29 | The end date of the query as an ISO 8601 string. 30 | 31 | #### Default Value 32 | 33 | `today` 34 | 35 | ### cursor? 36 | 37 | > `optional` **cursor**: [`Cursor`](Cursor.md) 38 | 39 | The pagination cursor received as part of a previous paginated response. 40 | 41 | If this query parameter is omitted, only the first page of transaction 42 | results will be retrieved. The cursor to fetch the next page of results can 43 | be retrieved from a given `page` of response data, nested under 44 | `page.cursor.next`. If this value is `undefined`, it means that the last 45 | page has been reached. 46 | -------------------------------------------------------------------------------- /docs/type-aliases/TransactionType.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransactionType 6 | 7 | # Type alias: TransactionType 8 | 9 | > **TransactionType**: `"CREDIT"` \| `"DEBIT"` \| `"PAYMENT"` \| `"TRANSFER"` \| `"STANDING ORDER"` \| `"EFTPOS"` \| `"INTEREST"` \| `"FEE"` \| `"CREDIT CARD"` \| `"TAX"` \| `"DIRECT DEBIT"` \| `"DIRECT CREDIT"` \| `"ATM"` \| `"LOAN"` 10 | -------------------------------------------------------------------------------- /docs/type-aliases/Transfer.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Transfer 6 | 7 | # Type alias: Transfer 8 | 9 | > **Transfer**: `object` 10 | 11 | Transfer object returned by the /transfers endpoint. 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | ### from 20 | 21 | > **from**: `string` 22 | 23 | ### to 24 | 25 | > **to**: `string` 26 | 27 | ### amount 28 | 29 | > **amount**: `number` 30 | 31 | ### sid 32 | 33 | > **sid**: `string` 34 | 35 | ### status 36 | 37 | > **status**: [`TransferStatus`](TransferStatus.md) 38 | 39 | ### final 40 | 41 | > **final**: `boolean` 42 | 43 | ### timeline 44 | 45 | > **timeline**: `object`[] 46 | 47 | ### created\_at 48 | 49 | > **created\_at**: `string` 50 | 51 | ### updated\_at 52 | 53 | > **updated\_at**: `string` 54 | 55 | ### status\_text? 56 | 57 | > `optional` **status\_text**: `string` 58 | -------------------------------------------------------------------------------- /docs/type-aliases/TransferCreateParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransferCreateParams 6 | 7 | # Type alias: TransferCreateParams 8 | 9 | > **TransferCreateParams**: `object` 10 | 11 | Parameters for initiating a new bank account transfer using Akahu. 12 | 13 | ## Type declaration 14 | 15 | ### from 16 | 17 | > **from**: `string` 18 | 19 | The Akahu account id from which the transfer will be made. The `from` 20 | account id **must** refer to an account that has been linked by the user 21 | for which this request is authenticated. 22 | 23 | An account id starts with `acc_...`. 24 | 25 | ### to 26 | 27 | > **to**: `string` 28 | 29 | The Akahu account id to which the transfer will be made. The `to` 30 | account id **must** refer to an account that has been linked by the user 31 | for which this request is authenticated. 32 | 33 | An account id starts with `acc_...`. 34 | 35 | ### amount 36 | 37 | > **amount**: `number` 38 | 39 | The dollar amount for the transfer. This must be a numeric value with no more 40 | than 2 decimal places. 41 | -------------------------------------------------------------------------------- /docs/type-aliases/TransferPayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransferPayload 6 | 7 | # Type alias: TransferPayload 8 | 9 | > **TransferPayload**: [`BasePayload`](BasePayload.md) & `object` & `object` \| `object` 10 | 11 | TRANSFER 12 | 13 | An event has occurred relating to a transfer between a users bank accounts. 14 | 15 | [https://developers.akahu.nz/docs/reference-webhooks#transfer](https://developers.akahu.nz/docs/reference-webhooks#transfer) 16 | 17 | ## Type declaration 18 | 19 | ### webhook\_type 20 | 21 | > **webhook\_type**: `"TRANSFER"` 22 | -------------------------------------------------------------------------------- /docs/type-aliases/TransferQueryParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransferQueryParams 6 | 7 | # Type alias: TransferQueryParams 8 | 9 | > **TransferQueryParams**: `object` 10 | 11 | The date range that will be used to filter transfer results. 12 | 13 | ## Type declaration 14 | 15 | ### start? 16 | 17 | > `optional` **start**: `string` 18 | 19 | The start date of the query as an ISO 8601 string. 20 | 21 | #### Default Value 22 | 23 | `30 days ago` 24 | 25 | ### end? 26 | 27 | > `optional` **end**: `string` 28 | 29 | The end date of the query as an ISO 8601 string. 30 | 31 | #### Default Value 32 | 33 | `today` 34 | -------------------------------------------------------------------------------- /docs/type-aliases/TransferStatus.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / TransferStatus 6 | 7 | # Type alias: TransferStatus 8 | 9 | > **TransferStatus**: `"READY"` \| `"PENDING_APPROVAL"` \| `"SENT"` \| `"DECLINED"` \| `"ERROR"` \| `"PAUSED"` \| `"CANCELLED"` 10 | -------------------------------------------------------------------------------- /docs/type-aliases/User.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / User 6 | 7 | # Type alias: User 8 | 9 | > **User**: `object` 10 | 11 | User data as returned from the /users/me endpoint 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | Akahu's unique identifier for this user. 20 | 21 | ### access\_granted\_at 22 | 23 | > **access\_granted\_at**: `string` 24 | 25 | The timestamp that the user first granted your app access to their accounts 26 | (i.e. the time at which your user token was issued). Formatted as an ISO 27 | 8601 timestamp. 28 | 29 | ### email? 30 | 31 | > `optional` **email**: `string` 32 | 33 | The email address that this user used to register with Akahu. 34 | 35 | This will always be present if your app has the `AKAHU` scope. 36 | 37 | ### preferred\_name? 38 | 39 | > `optional` **preferred\_name**: `string` 40 | 41 | The user's preferred name, if they have provided it by updating their 42 | profile at https://my.akahu.nz. This will not be available for most users. 43 | 44 | ### ~~first\_name?~~ 45 | 46 | > `optional` **first\_name**: `string` 47 | 48 | The user's first name, if they have provided it. 49 | 50 | #### Deprecated 51 | 52 | Only present on some legacy users. You probably want 53 | [party](https://developers.akahu.nz/reference/get_parties) data instead, 54 | which is sourced from the user's connected financial institution(s). 55 | 56 | ### ~~last\_name?~~ 57 | 58 | > `optional` **last\_name**: `string` 59 | 60 | The user's last name, if they have provided it. 61 | 62 | #### Deprecated 63 | 64 | Only present on some legacy users. You probably want 65 | [party](https://developers.akahu.nz/reference/get_parties) data instead, 66 | which is sourced from the user's connected financial institution(s). 67 | 68 | ### ~~mobile?~~ 69 | 70 | > `optional` **mobile**: `undefined` 71 | 72 | #### Deprecated 73 | 74 | This field is unused. You probably want 75 | [party](https://developers.akahu.nz/reference/get_parties) data instead, 76 | which is sourced from the user's connected financial institution(s). 77 | -------------------------------------------------------------------------------- /docs/type-aliases/Webhook.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / Webhook 6 | 7 | # Type alias: Webhook 8 | 9 | > **Webhook**: `object` 10 | 11 | Description of a single webhook subscription. 12 | 13 | ## Type declaration 14 | 15 | ### \_id 16 | 17 | > **\_id**: `string` 18 | 19 | ### type 20 | 21 | > **type**: [`WebhookType`](WebhookType.md) 22 | 23 | ### state 24 | 25 | > **state**: `string` 26 | 27 | ### url 28 | 29 | > **url**: `string` 30 | 31 | ### created\_at 32 | 33 | > **created\_at**: `string` 34 | 35 | ### updated\_at 36 | 37 | > **updated\_at**: `string` 38 | 39 | ### last\_called\_at 40 | 41 | > **last\_called\_at**: `string` 42 | -------------------------------------------------------------------------------- /docs/type-aliases/WebhookCacheConfig.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookCacheConfig 6 | 7 | # Type alias: WebhookCacheConfig 8 | 9 | > **WebhookCacheConfig**: `object` 10 | 11 | ## Type declaration 12 | 13 | ### cache 14 | 15 | > **cache**: [`WebhookSigningKeyCache`](../interfaces/WebhookSigningKeyCache.md) 16 | 17 | ### key 18 | 19 | > **key**: `string` 20 | 21 | ### maxAgeMs 22 | 23 | > **maxAgeMs**: `number` 24 | -------------------------------------------------------------------------------- /docs/type-aliases/WebhookCreateParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookCreateParams 6 | 7 | # Type alias: WebhookCreateParams 8 | 9 | > **WebhookCreateParams**: `object` 10 | 11 | Parameters used to subscribe to a new webhook event. 12 | 13 | ## Type declaration 14 | 15 | ### webhook\_type 16 | 17 | > **webhook\_type**: [`WebhookType`](WebhookType.md) 18 | 19 | ### state? 20 | 21 | > `optional` **state**: `string` 22 | 23 | The `state` value will be 24 | This value should allow you to uniquely iden 25 | -------------------------------------------------------------------------------- /docs/type-aliases/WebhookEvent.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookEvent 6 | 7 | # Type alias: WebhookEvent 8 | 9 | > **WebhookEvent**: `object` 10 | 11 | Metadata about a past webhook event, as retreived from /webhook-events 12 | 13 | [https://developers.akahu.nz/reference/get_webhook-events](https://developers.akahu.nz/reference/get_webhook-events) 14 | 15 | ## Type declaration 16 | 17 | ### \_id 18 | 19 | > **\_id**: `string` 20 | 21 | The unique identifier for this webhook event. 22 | 23 | ### \_hook 24 | 25 | > **\_hook**: `string` 26 | 27 | The unique identifier for this webhook subscription. 28 | This can be used with the `unsubscribe` method to remove this webhook 29 | subscription if it is no longer required. 30 | 31 | ### status 32 | 33 | > **status**: [`WebhookStatus`](WebhookStatus.md) 34 | 35 | The delivery status of this webhook event. 36 | 37 | ### payload 38 | 39 | > **payload**: [`WebhookPayload`](WebhookPayload.md) 40 | 41 | The main payload of the webhook event. 42 | 43 | ### created\_at 44 | 45 | > **created\_at**: `string` 46 | 47 | The timestamp at which this webhook event was created. 48 | 49 | ### updated\_at 50 | 51 | > **updated\_at**: `string` 52 | 53 | The timestamp at which this webhook event was last updated. 54 | 55 | ### last\_failed\_at? 56 | 57 | > `optional` **last\_failed\_at**: `string` 58 | 59 | If the webhook event has at any point failed to send, the timestamp at 60 | which the last attempt was made. 61 | -------------------------------------------------------------------------------- /docs/type-aliases/WebhookEventQueryParams.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookEventQueryParams 6 | 7 | # Type alias: WebhookEventQueryParams 8 | 9 | > **WebhookEventQueryParams**: `object` 10 | 11 | Query parameters to filter results from the /webhook-events endpoint. 12 | 13 | ## Type declaration 14 | 15 | ### status 16 | 17 | > **status**: [`WebhookStatus`](WebhookStatus.md) 18 | 19 | **Required:** The webhook delivery status. 20 | 21 | ### start? 22 | 23 | > `optional` **start**: `string` 24 | 25 | The start date of the query as an ISO 8601 string. 26 | 27 | #### Default Value 28 | 29 | `30 days ago` 30 | 31 | ### end? 32 | 33 | > `optional` **end**: `string` 34 | 35 | The end date of the query as an ISO 8601 string. 36 | 37 | #### Default Value 38 | 39 | `today` 40 | -------------------------------------------------------------------------------- /docs/type-aliases/WebhookPayload.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookPayload 6 | 7 | # Type alias: WebhookPayload 8 | 9 | > **WebhookPayload**: [`CancelledPayload`](CancelledPayload.md) \| [`TokenPayload`](TokenPayload.md) \| [`AccountPayload`](AccountPayload.md) \| [`TransactionPayload`](TransactionPayload.md) \| [`TransferPayload`](TransferPayload.md) \| [`PaymentPayload`](PaymentPayload.md) 10 | -------------------------------------------------------------------------------- /docs/type-aliases/WebhookStatus.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookStatus 6 | 7 | # Type alias: WebhookStatus 8 | 9 | > **WebhookStatus**: `"SENT"` \| `"FAILED"` \| `"RETRY"` 10 | -------------------------------------------------------------------------------- /docs/type-aliases/WebhookType.md: -------------------------------------------------------------------------------- 1 | [**akahu v2.1.0**](../README.md) • **Docs** 2 | 3 | *** 4 | 5 | [akahu v2.1.0](../README.md) / WebhookType 6 | 7 | # Type alias: WebhookType 8 | 9 | > **WebhookType**: `"TOKEN"` \| `"ACCOUNT"` \| `"TRANSACTION"` \| `"TRANSFER"` \| `"PAYMENT"` 10 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # akahu-sdk-example 2 | 3 | This project serves as a full integration test of the SDK as well as example code for SDK usage. Before running the script you will need to configure a `.env` file in this directory with your credentials as follows: 4 | 5 | **`.env`** 6 | ```sh 7 | # Your Akahu App Token 8 | AKAHU_APP_TOKEN=app_token_xxxxxx 9 | # Your Akahu App Secret 10 | AKAHU_APP_SECRET=xxxxxx 11 | # Email address to use to prefill the OAuth flow (optional) 12 | AKAHU_OAUTH_EMAIL=john.smith@example.com 13 | # The OAuth redirect location. Must be specified if you wish to test either of the auth flows. 14 | AKAHU_OAUTH_REDIRECT_URI=https://example.com/auth/akahu 15 | # If you don't include the manual auth flow, you must provide a valid PREFETCHED_USER_TOKEN instead 16 | # If you wish to test transfers, the user token must have at least 2x connected accounts with the TRANSFER attribute. 17 | # If you wish to test payments, the user token must have at least 1 connected account with the PAYMENT_FROM attribute. 18 | PREFETCHED_USER_TOKEN=user_token_xxxxxx 19 | # Holder name of the bank account that a test payment ($0.01) will be made to 20 | TEST_PAYEE_NAME=John Smith 21 | # Account number of the bank account that a test payment ($0.01) will be made to 22 | # WARNING: Make sure this is an account number that you control. 23 | TEST_PAYEE_ACCOUNT=XX-XXXX-XXXXXXX-XX 24 | ``` 25 | 26 | Once you have all that sorted, run the test with: 27 | 28 | ```sh 29 | npm run it 30 | ``` 31 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "akahu-sdk-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.ts", 6 | "dependencies": { 7 | "akahu": "file:../src", 8 | "dotenv": "^10.0.0", 9 | "open": "^8.2.1", 10 | "ts-node": "^10.7.0" 11 | }, 12 | "scripts": { 13 | "it": "ts-node -T index.ts" 14 | }, 15 | "author": "", 16 | "license": "ISC" 17 | } 18 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["index.ts"], 3 | "compilerOptions": { 4 | "target": "es2019", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "noImplicitAny": true, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "akahu", 3 | "version": "2.1.0", 4 | "description": "Javascript SDK for Akahu", 5 | "main": "dist/index.js", 6 | "module": "dist/index.mjs", 7 | "types": "dist/index.d.ts", 8 | "files": [ 9 | "/dist" 10 | ], 11 | "scripts": { 12 | "build": "npm run build:clean && npm run build:package && npm run build:types", 13 | "build:clean": "rm -rf dist", 14 | "build:package": "rollup -c", 15 | "build:types": "tsc --project tsconfig.build.json", 16 | "docs": "rm -rf docs/* && npx typedoc", 17 | "prettier": "prettier --write src/", 18 | "test": "jest", 19 | "preversion": "npm run test", 20 | "version": "node scripts/version.js && npm run build && npm run docs && git add -A docs src/version.ts", 21 | "postversion": "git push -u origin HEAD && git push --tags" 22 | }, 23 | "prettier": { 24 | "arrowParens": "always", 25 | "bracketSpacing": true, 26 | "embeddedLanguageFormatting": "auto", 27 | "htmlWhitespaceSensitivity": "css", 28 | "jsxBracketSameLine": false, 29 | "parser": "typescript", 30 | "printWidth": 80, 31 | "proseWrap": "preserve", 32 | "quoteProps": "as-needed", 33 | "requirePragma": false, 34 | "semi": true, 35 | "singleQuote": false, 36 | "tabWidth": 2, 37 | "trailingComma": "es5" 38 | }, 39 | "repository": { 40 | "type": "git", 41 | "url": "git+https://github.com/akahu-io/akahu-sdk-js.git" 42 | }, 43 | "keywords": [ 44 | "node", 45 | "js", 46 | "javascript", 47 | "sdk", 48 | "akahu" 49 | ], 50 | "author": "Akahu", 51 | "license": "ISC", 52 | "bugs": { 53 | "url": "https://github.com/akahu-io/akahu-sdk-js/issues" 54 | }, 55 | "homepage": "https://github.com/akahu-io/akahu-sdk-js#readme", 56 | "jest": { 57 | "collectCoverage": true, 58 | "coverageDirectory": "coverage" 59 | }, 60 | "devDependencies": { 61 | "@babel/preset-env": "^7.24.5", 62 | "@babel/preset-typescript": "^7.24.1", 63 | "@rollup/plugin-typescript": "^8.2.3", 64 | "@types/jest": "^29.5.12", 65 | "@types/node": "^18.19.33", 66 | "@types/uuid": "^8.3.1", 67 | "axios-mock-adapter": "^1.22.0", 68 | "jest": "^29.7.0", 69 | "prettier": "^2.8.8", 70 | "rollup": "^2.55.0", 71 | "typedoc": "^0.25.13", 72 | "typedoc-plugin-markdown": "^4.0.1", 73 | "typedoc-plugin-merge-modules": "^5.1.0", 74 | "typedoc-plugin-no-inherit": "^1.4.0", 75 | "typescript": "^5.4.5" 76 | }, 77 | "dependencies": { 78 | "axios": "^1.8.3", 79 | "uuid": "^8.3.2" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from "@rollup/plugin-typescript"; 2 | 3 | const packageJson = require("./package.json"); 4 | 5 | export default { 6 | input: "src/index.ts", 7 | output: [ 8 | { 9 | file: packageJson.main, 10 | format: "cjs", // Output CommonJS to support node.js v12 11 | sourcemap: true, 12 | }, 13 | { 14 | file: packageJson.module, 15 | format: "esm", // Output ES Module to take advantage of newer tooling 16 | sourcemap: true, 17 | }, 18 | ], 19 | plugins: [ 20 | // Run source files through tsc prior to bundling. 21 | // The typescript plugin inherits config from `tsconfig.json`. 22 | // https://github.com/rollup/plugins/blob/master/packages/typescript/README.md 23 | typescript({ 24 | // Compilation targeting node.js v18 and above as per: 25 | // https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping#recommended-node-tsconfig-settings 26 | // but using `module: "ES2015"` which is then bundled by Rollup: https://stackoverflow.com/a/66812779/3175260 27 | target: "ES2015", 28 | module: "ES2015", 29 | outDir: "./dist", 30 | exclude: ["__tests__/**/*.ts"], 31 | }), 32 | ], 33 | // Mark external dependencies to avoid 'Unresolved dependencies' warnings. 34 | external: Object.keys(packageJson.dependencies), 35 | }; 36 | -------------------------------------------------------------------------------- /scripts/version.js: -------------------------------------------------------------------------------- 1 | // Could be a bash one-liner but this works cross platform 2 | require("fs").writeFileSync( 3 | "src/version.ts", 4 | `export const version = "${process.env.npm_package_version}";` 5 | ); 6 | require("child_process").exec( 7 | `git checkout -b ${process.env.npm_package_version}` 8 | ); 9 | -------------------------------------------------------------------------------- /src/errors.ts: -------------------------------------------------------------------------------- 1 | import type { AxiosResponse } from "axios"; 2 | 3 | class AkahuError extends Error { 4 | /** 5 | * Flag that can be used to detect exceptions thrown by the Akahu SDK. 6 | */ 7 | isAkahuError = true; 8 | /** 9 | * Legacy static property for backwards compatibility. Prefer the instance 10 | * property `isAkahuError` instead. 11 | * @deprecated 12 | */ 13 | static isAkahuError = true; 14 | } 15 | 16 | /** 17 | * Error type for error responses received from the Akahu API. 18 | * An error response is characterised by a non 2XX status code and/or a body 19 | * payload that contains `success: false` along with an accompanying error message. 20 | * 21 | * @noInheritDoc 22 | * @category Error 23 | */ 24 | export class AkahuErrorResponse extends AkahuError { 25 | /** 26 | * The response status code. 27 | */ 28 | status: number; 29 | /** 30 | * The full {@link https://axios-http.com/docs/res_schema AxiosReponse} 31 | * object from axios. 32 | */ 33 | response: AxiosResponse; 34 | 35 | /** @internal */ 36 | static oAuthErrorCodeMap: Record = { 37 | invalid_request: "Invalid OAuth request.", 38 | unauthorized_client: 39 | "This application is not authorized to make this request.", 40 | unsupported_response_type: "Unsupported OAuth response type.", 41 | invalid_scope: "Unknown or invalid scope.", 42 | server_error: "Unknown server error.", 43 | temporarily_unavailable: 44 | "The authorization server is temporarily unavailable.", 45 | invalid_grant: "Invalid OAuth request.", 46 | }; 47 | 48 | /** @internal */ 49 | constructor(response: AxiosResponse) { 50 | const { status, statusText, data = {} } = response; 51 | const { message, error, error_description } = data; 52 | let _message: string; 53 | 54 | // `error` and `error_description` are specific to the OAuth endpoints. 55 | // `error_description` is more user-friendly, but optional: 56 | // https://www.oauth.com/oauth2-servers/server-side-apps/possible-errors/ 57 | if (typeof error_description === "string") { 58 | _message = error_description; 59 | } else if (error in AkahuErrorResponse.oAuthErrorCodeMap) { 60 | _message = AkahuErrorResponse.oAuthErrorCodeMap[error]; 61 | } else { 62 | // Detail for other error responses are nested under the `message` key. 63 | // Include a fallback to statusText just in case things go really wrong. 64 | _message = message ?? statusText; 65 | } 66 | 67 | super(_message); 68 | this.status = status; 69 | this.response = response; 70 | } 71 | } 72 | 73 | /** 74 | * Error type for errors that occur during the webhook validation process. 75 | * 76 | * @noInheritDoc 77 | * @category Error 78 | */ 79 | export class AkahuWebhookValidationError extends AkahuError {} 80 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @packageDocumentation 4 | */ 5 | 6 | // Public API 7 | export { AkahuClient } from "./client"; 8 | export type { Protocol, AkahuClientConfig } from "./client"; 9 | 10 | // Exported mainly for the sake of the doc generator 11 | export type { AkahuErrorResponse, AkahuWebhookValidationError } from "./errors"; 12 | 13 | // Expose type defs for reference by consumers (and doc generator) 14 | export * from "./models"; 15 | -------------------------------------------------------------------------------- /src/models/accounts.ts: -------------------------------------------------------------------------------- 1 | import { Connection } from "./connections"; 2 | 3 | export type AccountType = 4 | | "CHECKING" 5 | | "SAVINGS" 6 | | "CREDITCARD" 7 | | "LOAN" 8 | | "KIWISAVER" 9 | | "INVESTMENT" 10 | | "TERMDEPOSIT" 11 | | "FOREIGN" 12 | | "TAX" 13 | | "REWARDS" 14 | | "WALLET"; 15 | 16 | export type AccountAttribute = 17 | | "PAYMENT_TO" 18 | | "PAYMENT_FROM" 19 | | "TRANSFER_TO" 20 | | "TRANSFER_FROM" 21 | | "TRANSACTIONS"; 22 | 23 | export type AccountBalance = { 24 | /** 25 | * The (3 letter ISO 4217 currency code)[https://www.xe.com/iso4217.php] that this balance is in. 26 | */ 27 | currency: string; 28 | /** 29 | * The current account balance. 30 | */ 31 | current: number; 32 | /** 33 | * The balance that is currently available to the account holder. 34 | */ 35 | available?: number; 36 | /** 37 | * The credit limit for this account. For example a credit card limit or an overdraft limit. This value is only present when provided directly by the connected financial institution. 38 | */ 39 | limit?: number; 40 | /** 41 | * A boolean indicating whether this account is in unarranged overdraft. 42 | */ 43 | overdrawn?: boolean; 44 | }; 45 | 46 | export type AccountLoanDetails = { 47 | /** 48 | * The purpose of the loan, if we can't determine the purpose, this will be `UNKNOWN` 49 | */ 50 | purpose: "HOME" | "PERSONAL" | "BUSINESS" | "UNKNOWN"; 51 | /** 52 | * The type of loan, if we can't determine the type, this will be `UNKNOWN` 53 | */ 54 | type: "TABLE" | "REDUCING" | "REVOLVING" | "UNKNOWN"; 55 | /** 56 | * Interest rate information for the loan. 57 | */ 58 | interest: { 59 | /** 60 | * The interest rate on the loan. 61 | */ 62 | rate: number; 63 | /** 64 | * The type of interest rate. 65 | */ 66 | type: "FIXED" | "FLOATING"; 67 | /** 68 | * When this interest rate expires, if available. 69 | */ 70 | expires_at?: string; 71 | }; 72 | /** 73 | * Is the loan currently in an interest only period? 74 | */ 75 | is_interest_only: boolean; 76 | /** 77 | * When the interest only period expires, if available. 78 | */ 79 | interest_only_expires_at?: string; 80 | /** 81 | * The duration/term of the loan for it to be paid to completion from the start date of the loan. 82 | */ 83 | term?: 84 | | { 85 | /** 86 | * The number of years the loan is for. 87 | */ 88 | years?: number; 89 | /** 90 | * The number of months the loan is for. 91 | */ 92 | months?: number; 93 | } 94 | | undefined; 95 | /** 96 | * When the loan matures, if available. 97 | */ 98 | matures_at?: string; 99 | /** 100 | * The loan initial principal amount, this was the original amount borrowed. 101 | */ 102 | initial_principal?: number; 103 | /** 104 | * Loan repayment information if available. 105 | */ 106 | repayment?: 107 | | { 108 | /** 109 | * The frequency of the loan repayment. 110 | */ 111 | frequency?: 112 | | "WEEKLY" 113 | | "FORTNIGHTLY" 114 | | "MONTHLY" 115 | | "QUARTERLY" 116 | | "BIANNUALLY" 117 | | "ANNUALLY"; 118 | /** 119 | * The next repayment date, if available. 120 | */ 121 | next_date?: string; 122 | /** 123 | * The next instalment amount. 124 | */ 125 | next_amount: number; 126 | } 127 | | undefined; 128 | }; 129 | 130 | export type AccountRefreshState = { 131 | /** 132 | * The ISO 8601 timestamp when the balance was last retrieved 133 | */ 134 | balance?: string; 135 | /** 136 | * The ISO 8601 timestamp when other account metadata was last retrieved (any property apart from balance) 137 | */ 138 | meta?: string; 139 | /** 140 | * The ISO 8601 timestamp when we last checked for and processed any new transactions. This flag may be missing when an account has first connected, as it takes a few seconds for new transactions to be processed. 141 | */ 142 | transactions?: string; 143 | /** 144 | * The ISO 8601 timestamp when we last fetched identity data about the party who has authenticated with the financial institution when connecting this account. 145 | */ 146 | party?: string; 147 | }; 148 | 149 | export type AccountMeta = { 150 | /** 151 | * The account holder name 152 | */ 153 | holder?: string | undefined; 154 | 155 | /** 156 | * Details about a loan account, if available. 157 | */ 158 | loan_details?: AccountLoanDetails | undefined; 159 | 160 | [k: string]: any; // Catch-all for dynamic attributes 161 | }; 162 | 163 | /** 164 | * Account data returned by Akahu /account endpoints. 165 | */ 166 | export type Account = { 167 | /** 168 | * A unique identifier for the account in the Akahu system. It is always be prefixed by `acc_` so that you can tell that it belongs to an account. 169 | */ 170 | _id: string; 171 | 172 | /** 173 | * The authorisation identifier. Financial accounts are connected to Akahu via 174 | * an authorisation with the user's financial institution. Multiple accounts 175 | * can be connected during a single authorisation, causing them to have the 176 | * same authorisation identifier. This identifier can also be used to link a 177 | * specific account to identity data for the 178 | * [party](https://developers.akahu.nz/reference/get_parties) who completed 179 | * the authorisation. 180 | */ 181 | _authorisation: string; 182 | 183 | /** 184 | * @deprecated Please use `_authorisation` instead. 185 | */ 186 | _credentials: string; 187 | 188 | /** 189 | * Information about the financial institution where the account is held (eg. ANZ bank). 190 | */ 191 | connection: Connection; 192 | 193 | /** 194 | * The name of this account. If the connection allows customisation, the name will be the custom name (or nickname), eg. "Spending Account". Otherwise Akahu falls back to the product name, eg. "Super Saver". 195 | */ 196 | name: string; 197 | 198 | /** 199 | * This tells you whether Akahu can currently sign in to the account to refresh it's data. It can be one of: 200 | * 201 | * - `ACTIVE` → Akahu can sign in and refresh this account. 202 | * 203 | * - `INACTIVE` → Akahu no longer has access to this account. This may be caused by the user revoking Akahu's access at the institution or changing their login credentials. When an account becomes `INACTIVE` your application should direct the the user back to the OAuth flow or to my.akahu.nz where they will be prompted to to re-establish this connection. 204 | */ 205 | status: "ACTIVE" | "INACTIVE"; 206 | 207 | /** 208 | * If the account has a well defined account number (eg. a bank account number, or credit card number) this will be defined here with a standard format across connections. Credit cards will have at least 8 digits redacted. 209 | */ 210 | formatted_account?: string | undefined; 211 | 212 | /** 213 | * Type of account, Akahu provides specific bank account types, and falls back to more general types for other types of connection. 214 | * - `CHECKING` → An everyday spending account. 215 | * - `SAVINGS` → A savings account. 216 | * - `CREDITCARD` → A credit card. 217 | * - `LOAN` → A loan account. 218 | * - `KIWISAVER` → A KiwiSaver investment product. 219 | * - `INVESTMENT` → A general investment product. 220 | * - `TERMDEPOSIT` → A term deposit. 221 | * - `FOREIGN` → An account holding a foreign currency. 222 | * - `TAX` → An account with tax authorities. 223 | * - `REWARDS` → An account for rewards points, e.g. Fly Buys or True Rewards. 224 | * - `WALLET` → Available cash for investment or withdrawal from an investment provider. 225 | */ 226 | type: AccountType; 227 | 228 | /** 229 | * The list of attributes indicates which abilities an account has. A list of: 230 | * - `TRANSACTIONS` → account has transactions and supports retrieval of these via Akahu. 231 | * - `TRANSFER_TO` → account can receive transfers from other accounts belonging to same set of credentials. 232 | * - `TRANSFER_FROM` → account can initiate transfers to other accounts belonging to the same set of credentials. 233 | * - `PAYMENT_TO` → account can receive payments from any Akahu account with the `PAYMENT_FROM` attribute. 234 | * - `PAYMENT_FROM` → account can initiate payments to any Akahu account with the `PAYMENT_TO` attribute. 235 | */ 236 | attributes: AccountAttribute[]; 237 | 238 | /** 239 | * The account balance 240 | */ 241 | balance?: AccountBalance | undefined; 242 | 243 | /** 244 | * Akahu can refresh different parts of an account's data at different rates. The timestamps in the `refreshed` object tell you when that account data was last updated. This can be thought of as "Akahu's view of the account (balance/metadata/transactions) is up to date as of \$TIME". 245 | */ 246 | refreshed?: AccountRefreshState | undefined; 247 | 248 | /** 249 | * Metadata regarding this account 250 | */ 251 | meta?: AccountMeta | undefined; 252 | }; 253 | -------------------------------------------------------------------------------- /src/models/auth.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * OAuth2 token authorization response. 3 | */ 4 | export type AuthorizationToken = { 5 | access_token: string; 6 | token_type: "bearer"; 7 | scope: string; 8 | }; 9 | -------------------------------------------------------------------------------- /src/models/categories.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Akahu category metadata returned by /categories endpoints. 3 | */ 4 | export type Category = { 5 | _id: string; 6 | name: string; 7 | groups: { 8 | [groupingKey: string]: { 9 | _id: string; 10 | name: string; 11 | }; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /src/models/connections.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Akahu connection metadata returned by /connections endpoints. 3 | */ 4 | export type Connection = { 5 | _id: string; 6 | name: string; 7 | logo: string; 8 | }; 9 | -------------------------------------------------------------------------------- /src/models/generic.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A "page" of results returned by paginated API endpoints. 3 | * 4 | * Each page contains an array of zero-or-more returned objects nested under the 5 | * `items` key. In some cases - even if the returned `items` array is empty - 6 | * there may still be further pages available. Because if this it is important 7 | * to always check the value of `cursor.next` in the response. 8 | * 9 | * The cursor pointing to the next page of results can be found nested under 10 | * `cursor.next`. If there are no further results available, `cursor.next` will 11 | * be `null`. 12 | * 13 | * @category Generic 14 | * */ 15 | export type Paginated = { 16 | items: T[]; 17 | cursor: { next: string | null }; 18 | }; 19 | 20 | /** 21 | * Convenience type alias, useful when paging through multiple pages of results. 22 | * 23 | * @example 24 | * ```typescript 25 | * import type { Cursor, Transaction } from "akahu"; 26 | * const transactions: Transaction[] = []; 27 | * let cursor: Cursor; 28 | * 29 | * do { 30 | * const page = await akahu.transactions.list(userToken, { cursor }); 31 | * transactions.push(...page.items); 32 | * cursor = page.cursor.next; 33 | * } while (cursor !== null); 34 | * ``` 35 | * 36 | * @category Generic 37 | */ 38 | export type Cursor = string | null | undefined; 39 | 40 | 41 | /** 42 | * Additional options for a POST request 43 | */ 44 | export type PostRequestOptions = { 45 | /** 46 | * Specifying this key allows you to safely retry POST requests without the 47 | * risk of taking the same action twice. This is useful when an API call is 48 | * disrupted in transit and you do not receive a response or you wish to 49 | * protect against your application issuing duplicate requests. 50 | * 51 | * @default auto generated uuid 52 | */ 53 | idempotencyKey?: string; 54 | } 55 | -------------------------------------------------------------------------------- /src/models/identities.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The result of an Akahu identity verification request. 3 | */ 4 | export type IdentityResult = { 5 | _id: string; 6 | status: "PROCESSING" | "COMPLETE" | "ERROR"; 7 | created_at: string; 8 | updated_at: string; 9 | expires_at: string; 10 | source: Record; 11 | errors?: string[]; 12 | identities?: Record[]; 13 | addresses?: Record[]; 14 | accounts?: Record[]; 15 | }; 16 | 17 | export type IdentityVerifyNameQuery = { 18 | /** 19 | * The user's given name which will be verified against the Akahu identity 20 | * result. 21 | */ 22 | given_name?: string; 23 | /** 24 | * The user's middle name which will be verified against the Akahu identity 25 | * result. If the user has multiple middle names, provide them all separated 26 | * by a space. 27 | */ 28 | middle_name?: string; 29 | /** 30 | * The user's family name which will be verified against the Akahu identity 31 | * result. 32 | */ 33 | family_name: string; 34 | }; 35 | 36 | /** Name verification match where the source data is the account holder name. */ 37 | export type AccountHolderNameVerificationSource = { 38 | type: "HOLDER_NAME"; 39 | match_result: "MATCH" | "PARTIAL_MATCH"; 40 | /** Metadata from the matched account */ 41 | meta: { 42 | /** The account name */ 43 | name: string; 44 | /** The account holder name */ 45 | holder: string; 46 | /** Formatted account number */ 47 | account_number: string; 48 | /** The address associated with the account */ 49 | address?: string; 50 | /** The name of the bank */ 51 | bank: string; 52 | /** Branch details (if available) */ 53 | branch?: { 54 | _id: string; 55 | description: string; 56 | phone: string; 57 | address: { 58 | line1: string; 59 | line2?: string; 60 | line3?: string; 61 | city: string; 62 | country: "New Zealand"; 63 | postcode: string; 64 | }; 65 | }; 66 | }; 67 | verification: { 68 | given_name: boolean; 69 | given_initial: boolean; 70 | middle_name: boolean; 71 | middle_initial: boolean; 72 | family_name: boolean; 73 | }; 74 | }; 75 | 76 | /** 77 | * Name verification match where the source data is the registered name of the 78 | * party who has authenticated with the financial institution. 79 | * 80 | * This data is sourced from the profile information held by connected institution 81 | * rather than any specific account held within. 82 | */ 83 | export type PartyNameVerificationSource = { 84 | type: "PARTY_NAME"; 85 | match_result: "MATCH" | "PARTIAL_MATCH"; 86 | /** The matched party name data */ 87 | meta: { 88 | type: "INDIVIDUAL" | "JOINT" | "TRUST" | "LLC"; 89 | initials?: string[]; 90 | given_name?: string; 91 | middle_name?: string; 92 | family_name: string; 93 | full_name: string; 94 | prefix?: string; 95 | gender?: string; 96 | }; 97 | verification: { 98 | given_name: boolean; 99 | given_initial: boolean; 100 | middle_name: boolean; 101 | middle_initial: boolean; 102 | family_name: boolean; 103 | }; 104 | }; 105 | 106 | export type IdentityVerifyNameResult = { 107 | sources: ( 108 | | AccountHolderNameVerificationSource 109 | | PartyNameVerificationSource 110 | )[]; 111 | }; 112 | -------------------------------------------------------------------------------- /src/models/index.ts: -------------------------------------------------------------------------------- 1 | /** @category Account */ 2 | export { Account } from "./accounts"; 3 | 4 | /** @category Auth */ 5 | export { AuthorizationToken } from "./auth"; 6 | 7 | /** @category Connection */ 8 | export { Connection } from "./connections"; 9 | 10 | /** @category Category */ 11 | export { Category } from "./categories"; 12 | 13 | /** @category Identity */ 14 | export { 15 | IdentityResult, 16 | IdentityVerifyNameQuery, 17 | IdentityVerifyNameResult, 18 | AccountHolderNameVerificationSource, 19 | PartyNameVerificationSource, 20 | } from "./identities"; 21 | 22 | /** @category Payment */ 23 | export { 24 | PaymentStatus, 25 | PaymentStatusCode, 26 | Payment, 27 | IrdPaymentCreateParams, 28 | PaymentCreateParams, 29 | PaymentQueryParams, 30 | } from "./payments"; 31 | 32 | /** @category Transfer */ 33 | export { 34 | TransferStatus, 35 | Transfer, 36 | TransferCreateParams, 37 | TransferQueryParams, 38 | } from "./transfers"; 39 | 40 | /** @category Transaction */ 41 | export { 42 | TransactionType, 43 | Transaction, 44 | PendingTransaction, 45 | RawTransaction, 46 | CurrencyConversion, 47 | EnrichedTransaction, 48 | TransactionQueryParams, 49 | } from "./transactions"; 50 | 51 | /** @category User */ 52 | export { User } from "./users"; 53 | 54 | /** @category Webhook */ 55 | export { 56 | WebhookType, 57 | WebhookStatus, 58 | Webhook, 59 | WebhookCreateParams, 60 | BasePayload, 61 | CancelledPayload, 62 | TokenPayload, 63 | AccountPayload, 64 | TransactionPayload, 65 | TransferPayload, 66 | PaymentPayload, 67 | WebhookPayload, 68 | WebhookEvent, 69 | WebhookEventQueryParams, 70 | } from "./webhooks"; 71 | 72 | export { 73 | PartyName, 74 | PartyDob, 75 | PartyPhoneNumber, 76 | PartyEmail, 77 | PartyAddress, 78 | PartyTaxNumber, 79 | Party, 80 | } from "./parties"; 81 | 82 | export { Cursor, Paginated, PostRequestOptions } from "./generic"; 83 | -------------------------------------------------------------------------------- /src/models/parties.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The user's name as sourced from the connected institution. 3 | * 4 | * @category Parties 5 | */ 6 | export type PartyName = { 7 | /** 8 | * The name value in the format provided by the connected institution. 9 | * e.g. John Smith, Mr John Smith, MR JOHN SMITH 10 | */ 11 | value: string; 12 | }; 13 | 14 | /** 15 | * The user's date of birth as sourced from the connected institution. 16 | * 17 | * @category Parties 18 | */ 19 | export type PartyDob = { 20 | /** 21 | * The user's date of birth in the format YYYY-MM-DD. 22 | */ 23 | value: string; 24 | }; 25 | 26 | /** 27 | * The user's phone number as sourced from the connected institution. 28 | * 29 | * @category Parties 30 | */ 31 | export type PartyPhoneNumber = { 32 | subtype: "MOBILE" | "HOME" | "WORK"; 33 | verified: boolean; 34 | /** 35 | * The value of the phone number. 36 | */ 37 | value: string; 38 | }; 39 | 40 | /** 41 | * The user's email address as sourced from the connected institution. 42 | * 43 | * @category Parties 44 | */ 45 | export type PartyEmail = { 46 | subtype: "PRIMARY"; 47 | verified: boolean; 48 | /** 49 | * The value of the email address. 50 | */ 51 | value: string; 52 | }; 53 | 54 | /** 55 | * The user's address as sourced from the connected institution. 56 | * 57 | * @category Parties 58 | */ 59 | export type PartyAddress = { 60 | subtype: "RESIDENTIAL" | "POSTAL"; 61 | /** The raw address value from the connected institution. */ 62 | value: string; 63 | /** A consistently formatted/normalised version of the address. */ 64 | formatted: string; 65 | /** Individual components of the normalised address. */ 66 | components: { 67 | street: string; 68 | suburb: string; 69 | city: string; 70 | region: string; 71 | postal_code: string; 72 | country: string; 73 | }; 74 | /** 75 | * Google Maps API Place ID for this address. 76 | * 77 | * {@link https://developers.google.com/maps/documentation/places/web-service/place-id} 78 | */ 79 | google_maps_place_id: string; 80 | }; 81 | 82 | /** 83 | * The user's tax (IRD) number as sourced from the connected institution. 84 | * 85 | * @category Parties 86 | */ 87 | export type PartyTaxNumber = { 88 | /** The IRD number in the format XXX-XXX-XXX */ 89 | value: string; 90 | }; 91 | 92 | /** 93 | * Identity data relating to the party that the user has logged-in to their 94 | * institution as when connecting accounts to Akahu. i.e. the user's "profile" 95 | * information at the connected institution. 96 | * 97 | * All keys are optional depending on the scopes granted to your app. 98 | * 99 | * @category Parties 100 | */ 101 | export type Party = { 102 | _id: string; 103 | /** 104 | * The authorisation identifier. Financial accounts are connected to Akahu via 105 | * an authorisation with the user's financial institution. This identifier can 106 | * be used to link specific financial accounts to the party who completed the 107 | * authorisation by matching records with the same `_authorisation` value. 108 | */ 109 | _authorisation: string; 110 | /** The connection id identifying the institution that the data was sourced from */ 111 | _connection: string; 112 | _user: string; 113 | type: "INDIVIDUAL" | "JOINT" | "TRUST" | "LLC"; 114 | name?: PartyName; 115 | dob?: PartyDob; 116 | tax_number?: PartyTaxNumber; 117 | phone_numbers?: PartyPhoneNumber[]; 118 | email_addresses?: PartyEmail[]; 119 | addresses?: PartyAddress[]; 120 | }; 121 | -------------------------------------------------------------------------------- /src/models/payments.ts: -------------------------------------------------------------------------------- 1 | export type PaymentStatus = 2 | | "READY" 3 | | "PENDING_APPROVAL" 4 | | "PAUSED" 5 | | "SENT" 6 | | "DECLINED" 7 | | "ERROR" 8 | | "CANCELLED"; 9 | 10 | export type PaymentStatusCode = 11 | | "INTERNAL_ERROR" 12 | | "BANK_ERROR" 13 | | "UNAVAILABLE" 14 | | "INVALID_ACCOUNT" 15 | | "INSUFFICIENT_FUNDS" 16 | | "SINGLE_LIMIT_EXCEEDED" 17 | | "DAILY_LIMIT_EXCEEDED" 18 | | "AKAHU_LIMIT_EXCEEDED" 19 | | "MFA_UNSUPPORTED" 20 | | "MULTISIG_UNSUPPORTED" 21 | | "AUTHENTICATION_FAILED" 22 | | "MFA_FAILED" 23 | | "AFTER_HOURS" 24 | | "USER_CANCELLED" 25 | | "APP_CANCELLED" 26 | | "AKAHU_CANCELLED"; 27 | 28 | /** 29 | * Payment object returned by the /payments endpoint. 30 | */ 31 | export type Payment = { 32 | _id: string; 33 | from: string; 34 | to: { 35 | name: string; 36 | account_number: string; 37 | }; 38 | amount: number; 39 | meta: { 40 | source: { 41 | code?: string; 42 | reference?: string; 43 | }; 44 | destination: { 45 | particulars?: string; 46 | code?: string; 47 | reference?: string; 48 | }; 49 | }; 50 | sid: string; 51 | status: PaymentStatus; 52 | status_code?: PaymentStatusCode; 53 | status_text?: string; 54 | approval_type?: "BANK" | "USER"; 55 | final: boolean; 56 | timeline: { 57 | status: PaymentStatus; 58 | time: string; 59 | eta?: string; 60 | }[]; 61 | created_at: string; 62 | updated_at: string; 63 | received_at?: string; 64 | /** @deprecated this field is unused */ 65 | timeout_at?: string; 66 | }; 67 | 68 | /** 69 | * Parameters for initiating a new bank account payment using Akahu. 70 | */ 71 | export type PaymentCreateParams = { 72 | /** 73 | * The Akahu account id from which the payment will be made. The `from` 74 | * account id **must** refer to an account that has been linked by the user 75 | * for which this request is authenticated. 76 | * 77 | * An account id starts with `acc_...`. 78 | */ 79 | from: string; 80 | /** 81 | * The dollar amount for the payment. This must be a numeric value with no more 82 | * than 2 decimal places. 83 | */ 84 | amount: number; 85 | /** The details of the payee bank account to which the payment will be made. */ 86 | to: { 87 | /** The payee account holder name */ 88 | name: string; 89 | /** The full payee account number. */ 90 | account_number: string; 91 | }; 92 | /** Optional metadata to send with the payment. */ 93 | meta?: { 94 | /** 95 | * Metadata which will appear on the payers account statement. 96 | * 97 | * @remarks 98 | * **Note:** `particulars` is not an accepted field. Akahu reserves this 99 | * field on the source/payer statement for support and transaction verification. 100 | */ 101 | source?: { 102 | code?: string; 103 | reference?: string; 104 | }; 105 | /** Metadata which will appear on the payees account statement */ 106 | destination?: { 107 | particulars?: string; 108 | code?: string; 109 | reference?: string; 110 | }; 111 | }; 112 | }; 113 | 114 | /** 115 | * Parameters for initiating a new payment from a bank account to IRD. 116 | */ 117 | export type IrdPaymentCreateParams = { 118 | /** 119 | * The Akahu account id from which the payment will be made. The `from` 120 | * account id **must** refer to an account that has been linked by the user 121 | * for which this request is authenticated. 122 | * 123 | * An account id starts with `acc_...`. 124 | */ 125 | from: string; 126 | /** 127 | * The dollar amount for the payment. This must be a numeric value with no more 128 | * than 2 decimal places. 129 | */ 130 | amount: number; 131 | /** Required tax payment metadata to send with the payment. */ 132 | meta: { 133 | /** The IRD/GST number associated with the payment. */ 134 | tax_number: string; 135 | /** 136 | * The 3 character IRD tax type code that tells IRD what type of tax the 137 | * payment is for. 138 | * {@link https://www.ird.govt.nz/managing-my-tax/make-a-payment/choosing-the-right-account-type} 139 | */ 140 | tax_type: string; 141 | /** 142 | * The end date of the tax period which this payment is for, formatted as an 143 | * ISO 8601 date e.g. 1970-01-01. 144 | * 145 | * This is required by IRD for _most_ tax payments, however there are certain 146 | * payment types that do not require it (e.g. ARR, KSS, LGL). For the complete 147 | * list of exclusions see: 148 | * {@link https://www.ird.govt.nz/managing-my-tax/make-a-payment/ways-of-paying/paying-electronically} 149 | */ 150 | tax_period?: string; 151 | }; 152 | }; 153 | 154 | /** 155 | * The date range that will be used to filter payment results. 156 | */ 157 | export type PaymentQueryParams = { 158 | /** 159 | * The start date of the query as an ISO 8601 string. 160 | * 161 | * @defaultValue `30 days ago` 162 | */ 163 | start?: string; 164 | /** 165 | * The end date of the query as an ISO 8601 string. 166 | * 167 | * @defaultValue `today` 168 | */ 169 | end?: string; 170 | }; 171 | -------------------------------------------------------------------------------- /src/models/transactions.ts: -------------------------------------------------------------------------------- 1 | import { Cursor } from "./generic"; 2 | 3 | export type TransactionType = 4 | | "CREDIT" 5 | | "DEBIT" 6 | | "PAYMENT" 7 | | "TRANSFER" 8 | | "STANDING ORDER" 9 | | "EFTPOS" 10 | | "INTEREST" 11 | | "FEE" 12 | | "CREDIT CARD" 13 | | "TAX" 14 | | "DIRECT DEBIT" 15 | | "DIRECT CREDIT" 16 | | "ATM" 17 | | "LOAN"; 18 | 19 | /** 20 | * A raw, unenriched transaction object returned by /transactions 21 | */ 22 | export type RawTransaction = { 23 | /** 24 | * The unique id for the transaction 25 | */ 26 | _id: string; 27 | /** 28 | * The unique id of the user that the transaction is associated with. 29 | */ 30 | _user: string; 31 | /** 32 | * The unique id of the account that the transaction is associated with. 33 | */ 34 | _account: string; 35 | /** 36 | * The unique id of the connection that the transaction is associated with. 37 | */ 38 | _connection: string; 39 | /** 40 | * The time at which the transaction was retrieved by Akahu. Formatted as an ISO 8601 timestamp. 41 | */ 42 | created_at: string; 43 | /** 44 | * The time at which the transaction was last updated by Akahu. Formatted as an ISO 8601 timestamp. 45 | */ 46 | updated_at: string; 47 | /** 48 | * The date that the transaction was posted as reported by the bank integration. Formatted as an 49 | * ISO 8601 timestamp. 50 | */ 51 | date: string; 52 | /** 53 | * An identification string based on the contents of the transaction and the account from 54 | * which the transaction was fetched. 55 | * 56 | * @deprecated Prefer {@link RawTransaction._id `_id`} to uniquely identify transactions. 57 | */ 58 | hash: string; 59 | /** 60 | * The transaction description as reported by the bank integration. 61 | */ 62 | description: string; 63 | /** 64 | * The monetary value of the transaction. 65 | */ 66 | amount: number; 67 | /** 68 | * The account balance after receipt of this transaction (when available). 69 | */ 70 | balance?: number; 71 | /** 72 | * The type of the transaction. 73 | */ 74 | type: TransactionType; 75 | }; 76 | 77 | /** 78 | * A pending transaction as returned by /transactions/pending 79 | */ 80 | export type PendingTransaction = { 81 | /** 82 | * The unique id of the user that the pending transaction is associated with. 83 | */ 84 | _user: string; 85 | /** 86 | * The unique id of the account that the pending transaction is associated with. 87 | */ 88 | _account: string; 89 | /** 90 | * The unique id of the account that the pending transaction is associated with. 91 | */ 92 | _connection: string; 93 | /** 94 | * The time at which the transaction was updated by Akahu. Formatted as an ISO 8601 timestamp. 95 | */ 96 | updated_at: string; 97 | /** 98 | * The date that the transaction was posted as reported by the bank integration. Formatted as an 99 | * ISO 8601 timestamp. 100 | */ 101 | date: string; 102 | description: string; 103 | 104 | amount: number; 105 | 106 | type: TransactionType; 107 | }; 108 | 109 | /** 110 | * Represents the conversion details of a transaction. 111 | */ 112 | export type CurrencyConversion = { 113 | /** 114 | * The conversion rate used for the transaction. 115 | */ 116 | rate: number, 117 | /** 118 | * The converted amount in the transaction. 119 | */ 120 | amount: number, 121 | /** 122 | * The foreign currency in which the transaction was converted to/from. 123 | */ 124 | currency: string 125 | }; 126 | 127 | /** 128 | * A basic transaction with additional enrichment data. 129 | * 130 | * An enriched transaction includes structured data describing the merchant 131 | * that was party to the transaction. 132 | */ 133 | export type EnrichedTransaction = RawTransaction & { 134 | merchant: { _id: string; name: string; website?: string }; 135 | category: { 136 | _id: string; 137 | name: string; 138 | groups: { 139 | [groupKey: string]: { 140 | _id: string; 141 | name: string; 142 | }; 143 | }; 144 | }; 145 | meta: { 146 | particulars?: string; 147 | code?: string; 148 | reference?: string; 149 | other_account?: string; 150 | conversion?: CurrencyConversion; 151 | logo?: string; 152 | /** 153 | * If this transaction was made with a credit or debit card, this field may 154 | * contain the last four digits of the card number. 155 | */ 156 | card_suffix?: string; 157 | }; 158 | }; 159 | 160 | /** 161 | * A transaction object as returned by the /transactions endpoint. 162 | */ 163 | export type Transaction = RawTransaction | EnrichedTransaction; 164 | 165 | /** 166 | * Query parameters that will be used to filter transaction results. 167 | */ 168 | export type TransactionQueryParams = { 169 | /** 170 | * The start date of the query as an ISO 8601 string. 171 | * 172 | * @defaultValue `30 days ago` 173 | */ 174 | start?: string; 175 | /** 176 | * The end date of the query as an ISO 8601 string. 177 | * 178 | * @defaultValue `today` 179 | */ 180 | end?: string; 181 | /** 182 | * The pagination cursor received as part of a previous paginated response. 183 | * 184 | * If this query parameter is omitted, only the first page of transaction 185 | * results will be retrieved. The cursor to fetch the next page of results can 186 | * be retrieved from a given `page` of response data, nested under 187 | * `page.cursor.next`. If this value is `undefined`, it means that the last 188 | * page has been reached. 189 | */ 190 | cursor?: Cursor; 191 | }; 192 | -------------------------------------------------------------------------------- /src/models/transfers.ts: -------------------------------------------------------------------------------- 1 | export type TransferStatus = 2 | | "READY" 3 | | "PENDING_APPROVAL" 4 | | "SENT" 5 | | "DECLINED" 6 | | "ERROR" 7 | | "PAUSED" 8 | | "CANCELLED"; 9 | 10 | /** 11 | * Transfer object returned by the /transfers endpoint. 12 | */ 13 | export type Transfer = { 14 | _id: string; 15 | from: string; 16 | to: string; 17 | amount: number; 18 | sid: string; 19 | status: TransferStatus; 20 | status_text?: string; 21 | final: boolean; 22 | timeline: { status: TransferStatus; time: string }[]; 23 | created_at: string; 24 | updated_at: string; 25 | }; 26 | 27 | /** 28 | * Parameters for initiating a new bank account transfer using Akahu. 29 | */ 30 | export type TransferCreateParams = { 31 | /** 32 | * The Akahu account id from which the transfer will be made. The `from` 33 | * account id **must** refer to an account that has been linked by the user 34 | * for which this request is authenticated. 35 | * 36 | * An account id starts with `acc_...`. 37 | */ 38 | from: string; 39 | /** 40 | * The Akahu account id to which the transfer will be made. The `to` 41 | * account id **must** refer to an account that has been linked by the user 42 | * for which this request is authenticated. 43 | * 44 | * An account id starts with `acc_...`. 45 | */ 46 | to: string; 47 | /** 48 | * The dollar amount for the transfer. This must be a numeric value with no more 49 | * than 2 decimal places. 50 | */ 51 | amount: number; 52 | }; 53 | 54 | /** 55 | * The date range that will be used to filter transfer results. 56 | */ 57 | export type TransferQueryParams = { 58 | /** 59 | * The start date of the query as an ISO 8601 string. 60 | * 61 | * @defaultValue `30 days ago` 62 | */ 63 | start?: string; 64 | /** 65 | * The end date of the query as an ISO 8601 string. 66 | * 67 | * @defaultValue `today` 68 | */ 69 | end?: string; 70 | }; 71 | -------------------------------------------------------------------------------- /src/models/users.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * User data as returned from the /users/me endpoint 3 | */ 4 | export type User = { 5 | /** 6 | * Akahu's unique identifier for this user. 7 | */ 8 | _id: string; 9 | /** 10 | * The email address that this user used to register with Akahu. 11 | * 12 | * This will always be present if your app has the `AKAHU` scope. 13 | */ 14 | email?: string; 15 | /** 16 | * The user's preferred name, if they have provided it by updating their 17 | * profile at https://my.akahu.nz. This will not be available for most users. 18 | */ 19 | preferred_name?: string; 20 | /** 21 | * The timestamp that the user first granted your app access to their accounts 22 | * (i.e. the time at which your user token was issued). Formatted as an ISO 23 | * 8601 timestamp. 24 | */ 25 | access_granted_at: string; 26 | /** 27 | * The user's first name, if they have provided it. 28 | * 29 | * @deprecated Only present on some legacy users. You probably want 30 | * [party](https://developers.akahu.nz/reference/get_parties) data instead, 31 | * which is sourced from the user's connected financial institution(s). 32 | */ 33 | first_name?: string; 34 | /** 35 | * The user's last name, if they have provided it. 36 | * 37 | * @deprecated Only present on some legacy users. You probably want 38 | * [party](https://developers.akahu.nz/reference/get_parties) data instead, 39 | * which is sourced from the user's connected financial institution(s). 40 | */ 41 | last_name?: string; 42 | /** 43 | * @deprecated This field is unused. You probably want 44 | * [party](https://developers.akahu.nz/reference/get_parties) data instead, 45 | * which is sourced from the user's connected financial institution(s). 46 | */ 47 | mobile?: undefined; 48 | }; 49 | -------------------------------------------------------------------------------- /src/models/webhooks.ts: -------------------------------------------------------------------------------- 1 | import { TransferStatus } from "./transfers"; 2 | 3 | export type WebhookType = "TOKEN" | "ACCOUNT" | "TRANSACTION" | "TRANSFER" | "PAYMENT"; 4 | export type WebhookStatus = "SENT" | "FAILED" | "RETRY"; 5 | 6 | /** 7 | * Description of a single webhook subscription. 8 | */ 9 | export type Webhook = { 10 | _id: string; 11 | type: WebhookType; 12 | state: string; 13 | url: string; 14 | created_at: string; 15 | updated_at: string; 16 | last_called_at: string; 17 | }; 18 | 19 | /** 20 | * Parameters used to subscribe to a new webhook event. 21 | */ 22 | export type WebhookCreateParams = { 23 | webhook_type: WebhookType; 24 | /** 25 | * The `state` value will be 26 | * This value should allow you to uniquely iden 27 | */ 28 | state?: string; 29 | }; 30 | 31 | // *Webhook event payloads 32 | export type BasePayload = { 33 | webhook_type: WebhookType; 34 | webhook_code: string; 35 | state: string; 36 | }; 37 | 38 | /** 39 | * WEBHOOK_CANCELLED 40 | * 41 | * Webhook payload to indicate that the specified webhook has been cancelled. 42 | * For example, if the user revokes access to your app. 43 | */ 44 | export type CancelledPayload = BasePayload & { 45 | // Applies to all webhook_types 46 | webhook_code: "WEBHOOK_CANCELLED"; 47 | }; 48 | 49 | /** 50 | * TOKEN 51 | * 52 | * An event has occurred relating to a user token. 53 | * 54 | * {@link https://developers.akahu.nz/docs/reference-webhooks#token} 55 | */ 56 | export type TokenPayload = BasePayload & { 57 | webhook_type: "TOKEN"; 58 | webhook_code: "DELETE"; 59 | item_id: string; 60 | }; 61 | 62 | /** 63 | * ACCOUNT 64 | * 65 | * An event has occurred relating to a users linked account. 66 | * 67 | * {@link https://developers.akahu.nz/docs/reference-webhooks#account} 68 | */ 69 | export type AccountPayload = BasePayload & { 70 | webhook_type: "ACCOUNT"; 71 | } & ( 72 | | { 73 | // CREATE / DELETE events 74 | webhook_code: "CREATE" | "DELETE"; 75 | item_id: string; 76 | } 77 | | { 78 | // UPDATE event 79 | webhook_code: "UPDATE"; 80 | item_id: string; 81 | updated_fields: string[]; 82 | } 83 | ); 84 | 85 | /** 86 | * TRANSACTION 87 | * 88 | * An event has occurred relating to transactions on a users linked account. 89 | * 90 | * {@link https://developers.akahu.nz/docs/reference-webhooks#transaction} 91 | */ 92 | export type TransactionPayload = BasePayload & { 93 | webhook_type: "TRANSACTION"; 94 | } & ( 95 | | { 96 | // UPDATE events 97 | webhook_code: "INITIAL_UPDATE" | "DEFAULT_UPDATE"; 98 | item_id: string; 99 | new_transactions: number; 100 | new_transaction_ids: string[]; 101 | } 102 | | { 103 | // DELETE event 104 | webhook_code: "DELETE"; 105 | item_id: string; 106 | removed_transactions: string[]; 107 | } 108 | ); 109 | 110 | /** 111 | * TRANSFER 112 | * 113 | * An event has occurred relating to a transfer between a users bank accounts. 114 | * 115 | * {@link https://developers.akahu.nz/docs/reference-webhooks#transfer} 116 | */ 117 | export type TransferPayload = BasePayload & { 118 | webhook_type: "TRANSFER"; 119 | } & ( 120 | | { 121 | // UPDATE event 122 | webhook_code: "UPDATE"; 123 | item_id: string; 124 | status: TransferStatus; 125 | status_text?: string; 126 | } 127 | | { 128 | // RECEIVED event 129 | webhook_code: "RECEIVED"; 130 | item_id: string; 131 | received_at: string; 132 | } 133 | ); 134 | 135 | /** 136 | * PAYMENT 137 | * 138 | * An event has occurred relating to a payment from a users linked bank account. 139 | * 140 | * {@link https://developers.akahu.nz/docs/reference-webhooks#payment} 141 | */ 142 | export type PaymentPayload = BasePayload & { 143 | webhook_type: "PAYMENT"; 144 | } & ( 145 | | { 146 | // UPDATE event 147 | webhook_code: "UPDATE"; 148 | item_id: string; 149 | status: TransferStatus; 150 | status_text?: string; 151 | status_code?: string; 152 | } 153 | | { 154 | // RECEIVED event 155 | webhook_code: "RECEIVED"; 156 | item_id: string; 157 | received_at: string; 158 | } 159 | ); 160 | 161 | // Combined union type 162 | export type WebhookPayload = 163 | | CancelledPayload 164 | | TokenPayload 165 | | AccountPayload 166 | | TransactionPayload 167 | | TransferPayload 168 | | PaymentPayload; 169 | 170 | /** 171 | * Metadata about a past webhook event, as retreived from /webhook-events 172 | * 173 | * {@link https://developers.akahu.nz/reference/get_webhook-events} 174 | */ 175 | export type WebhookEvent = { 176 | /** 177 | * The unique identifier for this webhook event. 178 | */ 179 | _id: string; 180 | /** 181 | * The unique identifier for this webhook subscription. 182 | * This can be used with the `unsubscribe` method to remove this webhook 183 | * subscription if it is no longer required. 184 | */ 185 | _hook: string; 186 | /** 187 | * The delivery status of this webhook event. 188 | */ 189 | status: WebhookStatus; 190 | /** 191 | * The main payload of the webhook event. 192 | */ 193 | payload: WebhookPayload; 194 | /** 195 | * The timestamp at which this webhook event was created. 196 | */ 197 | created_at: string; 198 | /** 199 | * The timestamp at which this webhook event was last updated. 200 | */ 201 | updated_at: string; 202 | /** 203 | * If the webhook event has at any point failed to send, the timestamp at 204 | * which the last attempt was made. 205 | */ 206 | last_failed_at?: string; 207 | }; 208 | 209 | /** 210 | * Query parameters to filter results from the /webhook-events endpoint. 211 | */ 212 | export type WebhookEventQueryParams = { 213 | /** 214 | * **Required:** The webhook delivery status. 215 | */ 216 | status: WebhookStatus; 217 | /** 218 | * The start date of the query as an ISO 8601 string. 219 | * 220 | * @defaultValue `30 days ago` 221 | */ 222 | start?: string; 223 | /** 224 | * The end date of the query as an ISO 8601 string. 225 | * 226 | * @defaultValue `today` 227 | */ 228 | end?: string; 229 | }; 230 | -------------------------------------------------------------------------------- /src/resources/accounts.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | 3 | import { 4 | Account, 5 | Transaction, 6 | PendingTransaction, 7 | TransactionQueryParams, 8 | Paginated, 9 | } from "../models"; 10 | 11 | /** 12 | * Utilities for managing Akahu accounts that have been linked by users. 13 | * 14 | * {@link https://developers.akahu.nz/docs/accessing-account-data} 15 | * 16 | * @category Resource 17 | */ 18 | export class AccountsResource extends BaseResource { 19 | /** 20 | * List all accounts that have been connected by the user associated with the specified `token`. 21 | * 22 | * {@link https://developers.akahu.nz/reference/get_accounts} 23 | */ 24 | public async list(token: string): Promise { 25 | return await this._client._apiCall({ 26 | path: "/accounts", 27 | auth: { token }, 28 | }); 29 | } 30 | 31 | /** 32 | * Get a single account that has been connected by the user associated with the specified `token`. 33 | * 34 | * {@link https://developers.akahu.nz/reference/get_accounts-id} 35 | */ 36 | public async get(token: string, accountId: string): Promise { 37 | return await this._client._apiCall({ 38 | path: `/accounts/${accountId}`, 39 | auth: { token }, 40 | }); 41 | } 42 | 43 | /** 44 | * List transactions for a specified account. 45 | * 46 | * {@link https://developers.akahu.nz/reference/get_accounts-id-transactions} 47 | */ 48 | public async listTransactions( 49 | token: string, 50 | accountId: string, 51 | query: TransactionQueryParams = {} 52 | ): Promise> { 53 | return await this._client._apiCall>({ 54 | path: `/accounts/${accountId}/transactions`, 55 | auth: { token }, 56 | query, 57 | }); 58 | } 59 | 60 | /** 61 | * List pending transactions for a specified account. 62 | * 63 | * {@link https://developers.akahu.nz/reference/get_accounts-id-transactions-pending} 64 | */ 65 | public async listPendingTransactions( 66 | token: string, 67 | accountId: string 68 | ): Promise { 69 | return await this._client._apiCall({ 70 | path: `/accounts/${accountId}/transactions/pending`, 71 | auth: { token }, 72 | }); 73 | } 74 | 75 | /** 76 | * Revoke a single account from the specified `token`. 77 | * 78 | * After this call the token will no longer have access to the specified account or it's associated data, 79 | * including transactions. 80 | * 81 | * {@link https://developers.akahu.nz/reference/delete_accounts-id} 82 | */ 83 | public async revoke(token: string, accountId: string): Promise { 84 | return await this._client._apiCall({ 85 | path: `/accounts/${accountId}`, 86 | method: "DELETE", 87 | auth: { token }, 88 | }); 89 | } 90 | 91 | /** 92 | * Refresh a single account that has been connected by the user associated with the specified `token`. 93 | * 94 | * {@link https://developers.akahu.nz/reference/post_refresh-id} 95 | */ 96 | public async refresh(token: string, accountId: string): Promise { 97 | return await this._client._apiCall({ 98 | path: `/refresh/${accountId}`, 99 | method: "POST", 100 | auth: { token }, 101 | }); 102 | } 103 | 104 | /** 105 | * Refresh all accounts that have been connected by the user associated with the specified `token`. 106 | * 107 | * {@link https://developers.akahu.nz/reference/post_refresh} 108 | */ 109 | public async refreshAll(token: string): Promise { 110 | return await this._client._apiCall({ 111 | path: "/refresh", 112 | method: "POST", 113 | auth: { token }, 114 | }); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/resources/auth.ts: -------------------------------------------------------------------------------- 1 | import { Protocol, buildUrl } from "../utils"; 2 | import { BaseResource } from "./base"; 3 | import { AuthorizationToken } from "../models"; 4 | 5 | /** 6 | * Utilities for authorizing users using OAuth2. 7 | * 8 | * {@link https://developers.akahu.nz/docs/authorizing-with-oauth2} 9 | * 10 | * @category Resource 11 | */ 12 | export class AuthResource extends BaseResource { 13 | /** 14 | * Build the OAuth Authorization URL 15 | * 16 | * @param options Options for customising the generated URL. 17 | * 18 | * {@link https://developers.akahu.nz/docs/authorizing-with-oauth2#the-authorization-request} 19 | */ 20 | public buildAuthorizationUrl(options: { 21 | /** 22 | * Where to redirect the user once they have accepted or rejected the access request. 23 | * This **must** match one of your app's Redirect URIs. 24 | */ 25 | redirect_uri: string; 26 | /** 27 | * The type of OAuth response. Currently `code` is the only supported option. 28 | * 29 | * @default `code` 30 | */ 31 | response_type?: string; 32 | scope?: string; 33 | email?: string; 34 | connection?: string; 35 | state?: string; 36 | protocol?: Protocol; 37 | host?: string; 38 | port?: number; 39 | path?: string; 40 | }) { 41 | // Unpack options with defaults 42 | const { 43 | protocol, 44 | host, 45 | port, 46 | path, 47 | response_type, 48 | scope, 49 | redirect_uri, 50 | state, 51 | email, 52 | connection, 53 | } = { 54 | protocol: "https" as const, 55 | host: "oauth.akahu.nz", 56 | path: "", 57 | response_type: "code", 58 | scope: "ENDURING_CONSENT", 59 | ...options, 60 | }; 61 | 62 | // Construct main OAuth query params 63 | const { appToken: client_id } = this._client.authConfig; 64 | const query: Record = { 65 | response_type, 66 | redirect_uri, 67 | scope, 68 | client_id, 69 | }; 70 | 71 | // Include optional params if specified in options 72 | if (email) query.email = email; 73 | if (connection) query.connection = connection; 74 | if (state) query.state = state; 75 | 76 | return buildUrl({ protocol, host, port, path, query }); 77 | } 78 | 79 | /** 80 | * Exchange an OAuth authorization code for an access token. 81 | * 82 | * {@link https://developers.akahu.nz/docs/authorizing-with-oauth2#exchanging-the-authorization-code} 83 | * {@link https://developers.akahu.nz/reference/post_token} 84 | */ 85 | public async exchange( 86 | code: string, 87 | redirect_uri: string, 88 | grant_type: string = "authorization_code" 89 | ): Promise { 90 | // POST parameters for OAuth code exchange 91 | const { appToken: client_id, appSecret: client_secret } = 92 | this._client.authConfig; 93 | const data = { code, redirect_uri, grant_type, client_id, client_secret }; 94 | 95 | return await this._client._apiCall({ 96 | path: "/token", 97 | method: "POST", 98 | data, 99 | }); 100 | } 101 | 102 | /** 103 | * Revoke the specified user auth token: 104 | * 105 | * {@link https://developers.akahu.nz/reference/delete_token} 106 | */ 107 | public async revoke(token: string) { 108 | return await this._client._apiCall({ 109 | path: "/token", 110 | method: "DELETE", 111 | auth: { token }, 112 | }); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/resources/base.ts: -------------------------------------------------------------------------------- 1 | import type { AkahuClient } from "../client"; 2 | 3 | /** 4 | * @internal 5 | */ 6 | export class BaseResource { 7 | protected readonly _client: AkahuClient; 8 | 9 | /** 10 | * @internal 11 | */ 12 | constructor(client: AkahuClient) { 13 | this._client = client; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/resources/categories.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { Category } from "../models"; 3 | 4 | /** 5 | * Utilities to view categories that are available to your app. 6 | * 7 | * @category Resource 8 | */ 9 | export class CategoriesResource extends BaseResource { 10 | /** 11 | * List all categories that the app has access to. 12 | * 13 | * {@link https://developers.akahu.nz/reference/get_categories} 14 | */ 15 | public async list(): Promise { 16 | return await this._client._apiCall({ 17 | path: "/categories", 18 | auth: { basic: true }, 19 | }); 20 | } 21 | 22 | /** 23 | * Get an individual category. 24 | * 25 | * {@link https://developers.akahu.nz/reference/get_categories-id} 26 | */ 27 | public async get(categoryId: string): Promise { 28 | return await this._client._apiCall({ 29 | path: `/categories/${categoryId}`, 30 | auth: { basic: true }, 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/resources/connections.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { Connection } from "../models"; 3 | 4 | /** 5 | * Utilities to view connections that are available to your app, and refresh 6 | * accounts under a given connection. 7 | * 8 | * @category Resource 9 | */ 10 | export class ConnectionsResource extends BaseResource { 11 | /** 12 | * List all connections that the app has access to. 13 | * 14 | * {@link https://developers.akahu.nz/reference/get_connections} 15 | */ 16 | public async list(): Promise { 17 | return await this._client._apiCall({ 18 | path: "/connections", 19 | auth: { basic: true }, 20 | }); 21 | } 22 | 23 | /** 24 | * Get an individual connection detail. 25 | * 26 | * {@link https://developers.akahu.nz/reference/get_connections-id} 27 | */ 28 | public async get(connectionId: string): Promise { 29 | return await this._client._apiCall({ 30 | path: `/connections/${connectionId}`, 31 | auth: { basic: true }, 32 | }); 33 | } 34 | 35 | /** 36 | * Refresh all accounts that are made using the given connection and have been 37 | * connected by the user associated with the specified `token`. 38 | * 39 | * {@link https://developers.akahu.nz/reference/post_refresh-id} 40 | */ 41 | public async refresh(token: string, connectionId: string): Promise { 42 | return await this._client._apiCall({ 43 | path: `/refresh/${connectionId}`, 44 | method: "POST", 45 | auth: { token }, 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/resources/identities.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { Protocol } from "../utils"; 3 | import { 4 | IdentityResult, 5 | IdentityVerifyNameQuery, 6 | IdentityVerifyNameResult, 7 | } from "../models"; 8 | 9 | /** 10 | * Utilities for requesting identity verification using OAuth2. 11 | * 12 | * {@link https://developers.akahu.nz/docs/identity-verification} 13 | * 14 | * @category Resource 15 | */ 16 | export class IdentitiesResource extends BaseResource { 17 | /** 18 | * Build the Identity OAuth Authorization URL. 19 | * 20 | * {@link https://developers.akahu.nz/docs/identity-verification#the-authorization-request} 21 | */ 22 | public buildAuthorizationUrl(params: { 23 | protocol?: Protocol; 24 | host?: string; 25 | port?: number; 26 | path?: string; 27 | response_type?: string; 28 | redirect_uri: string; 29 | scope?: string; 30 | state?: string; 31 | }) { 32 | // Borrow implementation from `OAuthResource.buildAuthorizationUrl` 33 | return this._client.auth.buildAuthorizationUrl({ 34 | scope: "ONEOFF", 35 | ...params, 36 | }); 37 | } 38 | 39 | /** 40 | * Retrieve an identity result using the code/id returned after successful authorization using the 41 | * OAuth identity verification flow. 42 | * 43 | * {@link https://developers.akahu.nz/docs/identity-verification#retrieving-identity-results-with-the-oauth-result-code} 44 | */ 45 | public async get(code: string) { 46 | return this._client._apiCall({ 47 | path: `/identity/${code}`, 48 | auth: { basic: true }, 49 | }); 50 | } 51 | 52 | /** 53 | * (**BETA**) Verify the user's name against an identity result. 54 | * 55 | * {@link https://developers.akahu.nz/docs/oneoff-verify-name} 56 | */ 57 | public async verifyName(code: string, query: IdentityVerifyNameQuery) { 58 | return this._client._apiCall({ 59 | path: `/identity/${code}/verify/name`, 60 | method: "POST", 61 | data: query, 62 | auth: { basic: true }, 63 | }); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/resources/parties.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | 3 | import { Party } from "../models"; 4 | 5 | /** 6 | * Fetch identity data relating to the party that the user has logged-in to 7 | * their institution as when connecting accounts to Akahu. i.e. the user's 8 | * "profile" information at the connected institution. 9 | * @category Resource 10 | */ 11 | export class PartiesResource extends BaseResource { 12 | /** 13 | * List all parties related to accounts which the user has shared with your 14 | * app. 15 | * 16 | * {@link https://developers.akahu.nz/reference/get_parties} 17 | */ 18 | public async list(token: string): Promise { 19 | return await this._client._apiCall({ 20 | path: "/parties", 21 | auth: { token }, 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/resources/payments.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { 3 | Payment, 4 | PaymentCreateParams, 5 | PaymentQueryParams, 6 | PostRequestOptions, 7 | } from "../models"; 8 | import { IrdPaymentCreateParams } from "../models/payments"; 9 | 10 | /** 11 | * Utilities for managing bank account payments on behalf of users. 12 | * 13 | * {@link https://developers.akahu.nz/docs/making-a-payment} 14 | * 15 | * @category Resource 16 | */ 17 | export class PaymentsResource extends BaseResource { 18 | /** 19 | * Get a single payment made by the user associated with the specified `token`. 20 | * 21 | * {@link https://developers.akahu.nz/reference/get_payments-id} 22 | */ 23 | public async get(token: string, paymentId: string): Promise { 24 | return await this._client._apiCall({ 25 | path: `/payments/${paymentId}`, 26 | auth: { token }, 27 | }); 28 | } 29 | 30 | /** 31 | * List all payments made in the provided date range by the user associated 32 | * with the specified `token`. Defaults to the last 30 days if no date range 33 | * is provided. 34 | * 35 | * {@link https://developers.akahu.nz/reference/get_payments} 36 | */ 37 | public async list( 38 | token: string, 39 | query: PaymentQueryParams = {} 40 | ): Promise { 41 | // List endpoint with optional query params for date range 42 | return await this._client._apiCall({ 43 | path: "/payments", 44 | auth: { token }, 45 | query, 46 | }); 47 | } 48 | 49 | /** 50 | * Initiate a payment to an external bank account on behalf of the user associated 51 | * with the specified `token`. 52 | * 53 | * {@link https://developers.akahu.nz/reference/post_payments} 54 | */ 55 | public async create( 56 | token: string, 57 | payment: PaymentCreateParams, 58 | requestOptions?: PostRequestOptions 59 | ): Promise { 60 | return await this._client._apiCall({ 61 | path: "/payments", 62 | method: "POST", 63 | auth: { token }, 64 | data: payment, 65 | options: requestOptions, 66 | }); 67 | } 68 | 69 | /** 70 | * Initiate a payment to the Inland Revenue Department on behalf of the user 71 | * associated with the specified `token`. 72 | * 73 | * {@link https://developers.akahu.nz/reference/post_payments-ird} 74 | */ 75 | public async createToIrd( 76 | token: string, 77 | payment: IrdPaymentCreateParams, 78 | requestOptions?: PostRequestOptions 79 | ): Promise { 80 | return await this._client._apiCall({ 81 | path: "/payments/ird", 82 | method: "POST", 83 | auth: { token }, 84 | data: payment, 85 | options: requestOptions, 86 | }); 87 | } 88 | 89 | /** 90 | * Cancel a payment that has a status of `PENDING_APPROVAL`. 91 | * 92 | * {@link https://developers.akahu.nz/reference/put_payments-id-cancel} 93 | * {@link https://developers.akahu.nz/docs/making-a-payment#manual-payment-approval} 94 | */ 95 | public async cancel(token: string, paymentId: string) { 96 | return this._client._apiCall({ 97 | path: `/payments/${paymentId}`, 98 | method: "PUT", 99 | auth: { token }, 100 | }); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/resources/transactions.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { 3 | Transaction, 4 | PendingTransaction, 5 | TransactionQueryParams, 6 | Paginated, 7 | } from "../models"; 8 | 9 | /** 10 | * Utilities for retrieving bank transactions from connected user accounts. 11 | * 12 | * {@link https://developers.akahu.nz/docs/accessing-transactional-data} 13 | * 14 | * @category Resource 15 | */ 16 | export class TransactionsResource extends BaseResource { 17 | /** 18 | * List all transactions for all accounts that have been connected by the user associated with the 19 | * specified `token`. 20 | * 21 | * {@link https://developers.akahu.nz/reference/get_transactions} 22 | */ 23 | public async list( 24 | token: string, 25 | query: TransactionQueryParams = {} 26 | ): Promise> { 27 | // Paginated list endpoint with optional query params for date range & cursor 28 | return await this._client._apiCall>({ 29 | path: "/transactions", 30 | auth: { token }, 31 | query, 32 | }); 33 | } 34 | 35 | /** 36 | * List all pending transactions for all accounts that have been connected by the user associated with the 37 | * specified `token`. 38 | * 39 | * {@link https://developers.akahu.nz/reference/get_transactions-pending} 40 | */ 41 | public async listPending(token: string): Promise { 42 | // Non-paginated list endpoint of pending transactions 43 | return await this._client._apiCall({ 44 | path: "/transactions/pending", 45 | auth: { token }, 46 | }); 47 | } 48 | 49 | /** 50 | * Get a single transaction from an account that has been connected by the user associated with 51 | * the specified `token`. 52 | * 53 | * {@link https://developers.akahu.nz/reference/get_transactions-id} 54 | */ 55 | public async get(token: string, transactionId: string): Promise { 56 | return await this._client._apiCall({ 57 | path: `/transactions/${transactionId}`, 58 | auth: { token }, 59 | }); 60 | } 61 | 62 | /** 63 | * Get multiple transactions by id. 64 | * 65 | * All transactions must belong to the user associated with the specified `token`. 66 | * 67 | * This method may be useful to bulk refresh changed transaction data 68 | * in response to a webhook event. 69 | * 70 | * {@link https://developers.akahu.nz/reference/post_transactions-ids} 71 | */ 72 | public async getMany( 73 | token: string, 74 | transactionIds: string[] 75 | ): Promise { 76 | // Non-paginated list endpoint subset by transaction id 77 | return this._client._apiCall({ 78 | path: "/transactions/ids", 79 | method: "POST", 80 | auth: { token }, 81 | data: transactionIds, 82 | }); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/resources/transfers.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { 3 | Transfer, 4 | TransferCreateParams, 5 | TransferQueryParams, 6 | PostRequestOptions, 7 | } from "../models"; 8 | 9 | /** 10 | * Utilities for managing bank account transfers on behalf of users. 11 | * 12 | * {@link https://developers.akahu.nz/docs/making-a-transfer} 13 | * 14 | * @category Resource 15 | */ 16 | export class TransfersResource extends BaseResource { 17 | /** 18 | * Get a single transfer made by the user associated with the specified `token`. 19 | * 20 | * {@link https://developers.akahu.nz/reference/get_transfers-id} 21 | */ 22 | public async get(token: string, transferId: string): Promise { 23 | return await this._client._apiCall({ 24 | path: `/transfers/${transferId}`, 25 | auth: { token }, 26 | }); 27 | } 28 | 29 | /** 30 | * List all transfers made in the provided date range by the user associated 31 | * with the specified `token`. Defaults to the last 30 days if no date range 32 | * is provided. 33 | * 34 | * {@link https://developers.akahu.nz/reference/get_transfers} 35 | */ 36 | public async list( 37 | token: string, 38 | query: TransferQueryParams = {} 39 | ): Promise { 40 | // List endpoint with optional query params for date range 41 | return await this._client._apiCall({ 42 | path: "/transfers", 43 | auth: { token }, 44 | query, 45 | }); 46 | } 47 | 48 | /** 49 | * Initiate a transfer between two of the users bank accounts. 50 | * 51 | * {@link https://developers.akahu.nz/reference/post_transfers} 52 | */ 53 | public async create( 54 | token: string, 55 | transfer: TransferCreateParams, 56 | requestOptions?: PostRequestOptions 57 | ): Promise { 58 | return await this._client._apiCall({ 59 | path: "/transfers", 60 | method: "POST", 61 | auth: { token }, 62 | data: transfer, 63 | options: requestOptions, 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/resources/users.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { User } from "../models"; 3 | 4 | /** 5 | * Utilities for retrieving information about the Akahu user. 6 | * 7 | * @category Resource 8 | */ 9 | export class UsersResource extends BaseResource { 10 | /** 11 | * Get the user associated with the specified `token`. 12 | * 13 | * {@link https://developers.akahu.nz/reference/get_me} 14 | */ 15 | public async get(token: string): Promise { 16 | return await this._client._apiCall({ path: "/me", auth: { token } }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/resources/webhooks.ts: -------------------------------------------------------------------------------- 1 | import { BaseResource } from "./base"; 2 | import { AkahuWebhookValidationError } from "../errors"; 3 | 4 | import type { 5 | Webhook, 6 | WebhookPayload, 7 | WebhookEvent, 8 | WebhookCreateParams, 9 | WebhookEventQueryParams, 10 | } from "../models/webhooks"; 11 | import { PostRequestOptions } from "../models"; 12 | 13 | type CryptoModule = typeof import("crypto"); 14 | 15 | // crypto may not be available on all platforms (e.g React Native). 16 | // This is ok as we only need it server side. We just need to handle the import conditionally. 17 | let crypto: CryptoModule | undefined; 18 | 19 | try { 20 | crypto = require("crypto"); 21 | } catch (e) {} 22 | 23 | /** 24 | * Setter and getter interface to enable external/shared caching of webhook 25 | * signing keys. 26 | * 27 | * Accessor functions may be async (by returning a Promise) or sync (by returning a value). 28 | * 29 | * See the project README for example usage. 30 | * 31 | * @category API client 32 | */ 33 | export interface WebhookSigningKeyCache { 34 | get(key: string): string | null | Promise; 35 | set(key: string, value: string): void | Promise; 36 | } 37 | 38 | /** 39 | * @category API client config 40 | */ 41 | export type WebhookCacheConfig = { 42 | cache: WebhookSigningKeyCache; 43 | key: string; 44 | maxAgeMs: number; 45 | }; 46 | 47 | type CachedKeyData = { 48 | id: number; 49 | key: string; 50 | lastRefreshed: string; 51 | }; 52 | 53 | /** 54 | * Default in-memory cache for caching the webhook signing key. 55 | */ 56 | class DefaultKeyCache implements WebhookSigningKeyCache { 57 | private readonly _cache: Record = {}; 58 | 59 | async get(key: string): Promise { 60 | return this._cache[key] ?? null; 61 | } 62 | 63 | async set(key: string, value: string): Promise { 64 | this._cache[key] = value; 65 | } 66 | } 67 | 68 | /** 69 | * Utilities for managing, retrieving, and validating webhooks. 70 | * 71 | * {@link https://developers.akahu.nz/docs/reference-webhooks} 72 | * 73 | * @category Resource 74 | */ 75 | export class WebhooksResource extends BaseResource { 76 | private defaultKeyCache = new DefaultKeyCache(); 77 | 78 | /** 79 | * Gets active webhooks for the user associated with the specified `token`. 80 | * 81 | * {@link https://developers.akahu.nz/reference/get_webhooks} 82 | */ 83 | public async list(token: string): Promise { 84 | return await this._client._apiCall({ 85 | path: "/webhooks", 86 | auth: { token }, 87 | }); 88 | } 89 | 90 | /** 91 | * Subscribe to a webhook. 92 | * 93 | * @returns The newly created webhook id. 94 | * 95 | * {@link https://developers.akahu.nz/reference/post_webhooks} 96 | */ 97 | public async subscribe( 98 | token: string, 99 | webhook: WebhookCreateParams, 100 | requestOptions?: PostRequestOptions 101 | ): Promise { 102 | return await this._client._apiCall({ 103 | path: "/webhooks", 104 | method: "POST", 105 | auth: { token }, 106 | data: webhook, 107 | options: requestOptions, 108 | }); 109 | } 110 | 111 | /** 112 | * Unsubscribe from a previously created webhook. 113 | * 114 | * {@link https://developers.akahu.nz/reference/delete_webhooks-id} 115 | */ 116 | public async unsubscribe(token: string, webhookId: string): Promise { 117 | return await this._client._apiCall({ 118 | path: `/webhooks/${webhookId}`, 119 | method: "DELETE", 120 | auth: { token }, 121 | }); 122 | } 123 | 124 | /** 125 | * List all webhook events with the specified status in the specified date 126 | * range (defaults to last 30 days). 127 | * 128 | * {@link https://developers.akahu.nz/reference/get_webhook-events} 129 | */ 130 | public async listEvents( 131 | query: WebhookEventQueryParams 132 | ): Promise { 133 | return await this._client._apiCall({ 134 | path: "/webhook-events", 135 | auth: { basic: true }, 136 | query, 137 | }); 138 | } 139 | 140 | /** 141 | * Get a webhook signing public-key by id. 142 | * 143 | * {@link https://developers.akahu.nz/reference/get_keys-id} 144 | */ 145 | public async getPublicKey(keyId: string | number): Promise { 146 | return await this._client._apiCall({ 147 | path: `/keys/${keyId}`, 148 | auth: { basic: true }, 149 | }); 150 | } 151 | 152 | /** 153 | * Helper to validate a webhook request payload. 154 | * 155 | * See the project README for example usage. 156 | * 157 | * @returns The deserialized webhook payload after successful validation 158 | * 159 | * @throws {@link AkahuWebhookValidationError} 160 | * if validation of the webhook fails due to invalid signature or expired signing key. 161 | * 162 | * @throws {@link AkahuErrorResponse} 163 | * if the client fails to fetch the specified signing key from the Akahu API. 164 | * 165 | * {@link https://developers.akahu.nz/docs/reference-webhooks} 166 | */ 167 | public async validateWebhook( 168 | keyId: string | number, 169 | signature: string, 170 | webhookRequestBody: string, 171 | cacheConfig: Partial = {} 172 | ): Promise { 173 | // Coerce keyId as a number 174 | const _keyId = Number(keyId); 175 | 176 | // Validate that keyId is an integer. Includes null check because Number(null) === 0 177 | if (!Number.isInteger(_keyId) || keyId === null) { 178 | throw new AkahuWebhookValidationError( 179 | `Can't validate webhook request. keyId must be an integer (received ${keyId}).` 180 | ); 181 | } 182 | 183 | // Initialize cache config with defaults 184 | const _cacheConfig = { 185 | cache: this.defaultKeyCache, 186 | key: "akahu__webhook_key", 187 | maxAgeMs: 24 * 60 * 60 * 1000, // 24 hours 188 | ...cacheConfig, 189 | }; 190 | 191 | // Get the public key matching keyId - either from cache or API lookup 192 | const publicKey = await this._getPublicKey(_keyId, _cacheConfig); 193 | 194 | // Validate the webhook signature using the retreived public key 195 | const isValid = this._validateWebhookSignature( 196 | publicKey, 197 | signature, 198 | webhookRequestBody 199 | ); 200 | 201 | if (!isValid) { 202 | throw new AkahuWebhookValidationError( 203 | "Webhook signature verificaton failed." 204 | ); 205 | } 206 | 207 | return JSON.parse(webhookRequestBody) as WebhookPayload; 208 | } 209 | 210 | /** 211 | * Get the public key (by id) to validate a webhook signature. 212 | * The key will be retrieved from cache if possible, falling back to API lookup. 213 | * If a cached key exists with a newer id, an error will be thrown, as the existence of a newer 214 | * key implies that the key has been rotated and the requested key is no longer valid. 215 | * 216 | * {@link https://developers.akahu.nz/docs/reference-webhooks#caching} 217 | */ 218 | private async _getPublicKey( 219 | keyId: number, 220 | cacheConfig: WebhookCacheConfig 221 | ): Promise { 222 | // Attempt to lookup key from cache 223 | const keyDataFromCache = await this._getPublicKeyFromCache(cacheConfig); 224 | 225 | // Validate the cached key matches 226 | if (keyDataFromCache !== null) { 227 | const { id, key } = keyDataFromCache; 228 | 229 | // Validate that the cached key has same id as requested key 230 | if (keyId === id) { 231 | return key; 232 | } 233 | 234 | // Throw an error if the requested key has been superseded 235 | if (keyId < id) { 236 | throw new AkahuWebhookValidationError( 237 | `Webhook signing key (id: ${keyId}) has expired. Unable to validate webhook.` 238 | ); 239 | } 240 | 241 | // Fallback to lookup via API 242 | } 243 | 244 | // Lookup key data from API 245 | const freshKeyData: CachedKeyData = { 246 | id: keyId, 247 | lastRefreshed: new Date().toISOString(), 248 | key: await this.getPublicKey(keyId), 249 | }; 250 | 251 | // Cache the updated key data 252 | await this._cacheKeyData(freshKeyData, cacheConfig); 253 | 254 | return freshKeyData.key; 255 | } 256 | 257 | /** 258 | * Lookup current active public key from the cache. 259 | * If the key has been in the cache for more than `maxAgeMs` milliseconds, it is considered 260 | * stale, and will be ignored - causing it to be re-fetched from Akahu. `maxAgeMs` defaults to 24 hours. 261 | * 262 | * {@link https://developers.akahu.nz/docs/reference-webhooks#caching} 263 | */ 264 | private async _getPublicKeyFromCache( 265 | cacheConfig: WebhookCacheConfig 266 | ): Promise { 267 | const { cache, key: cacheKey, maxAgeMs } = cacheConfig; 268 | 269 | // Lookup key data from cache 270 | const rawFromCache = await cache.get(cacheKey); 271 | 272 | // Cache hit 273 | if (typeof rawFromCache === "string") { 274 | let keyData: CachedKeyData | undefined; 275 | 276 | // Deserialize key data JSON from cache 277 | try { 278 | keyData = JSON.parse(rawFromCache); 279 | } catch (e) { 280 | // Warn but no error if invalid JSON in cache data 281 | console.warn( 282 | `akahu-sdk: Failed to deserialize webhook key data from cache (key: ${cacheKey}).` 283 | ); 284 | } 285 | 286 | // Validate the key data from cache 287 | if (typeof keyData !== "undefined") { 288 | // Ensure that the cache is at most `maxAgeMs` old 289 | const cacheAgeMs = Date.now() - Date.parse(keyData.lastRefreshed); 290 | // NaN check in case lastRefreshed is invalid date string or undefined somehow 291 | if (!Number.isNaN(cacheAgeMs) && cacheAgeMs < maxAgeMs) { 292 | return keyData; 293 | } 294 | } 295 | } 296 | 297 | // Cache miss or invalid cache data 298 | return null; 299 | } 300 | 301 | /** 302 | * Add the public key that has been fetched from the API to the cache. 303 | * 304 | * {@link https://developers.akahu.nz/docs/reference-webhooks#caching} 305 | */ 306 | private async _cacheKeyData( 307 | keyData: CachedKeyData, 308 | cacheConfig: WebhookCacheConfig 309 | ): Promise { 310 | const { cache, key } = cacheConfig; 311 | await cache.set(key, JSON.stringify(keyData)); 312 | } 313 | 314 | /** 315 | * Validate a webhook and associated signature using the public key fetched from the Akahu API. 316 | * 317 | * {@link https://developers.akahu.nz/docs/reference-webhooks#verification} 318 | */ 319 | private _validateWebhookSignature( 320 | publicKey: string, 321 | signature: string, 322 | webhookBody: string 323 | ): boolean { 324 | if (typeof crypto === "undefined") { 325 | throw new Error( 326 | "Webhook validation is only supported on Node.js environments." 327 | ); 328 | } 329 | 330 | const verify = crypto.createVerify("sha256"); 331 | verify.update(webhookBody); 332 | verify.end(); 333 | 334 | return verify.verify(publicKey, signature, "base64"); 335 | } 336 | } 337 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import type { AxiosResponse, AxiosError } from "axios"; 3 | export type Protocol = "http" | "https"; 4 | 5 | /** 6 | * Build a URL from constituent components. 7 | */ 8 | export function buildUrl({ 9 | protocol, 10 | host, 11 | port, 12 | path = "", 13 | query = {}, 14 | }: { 15 | protocol: Protocol; 16 | host: string; 17 | port?: number; 18 | path?: string; 19 | query?: Record; 20 | }): string { 21 | // If not specified, port will be chosen by browser based on protocol choice (http or https). 22 | const _port = port ? `:${port}` : ""; 23 | 24 | // Clean `undefined` values from the query params 25 | const cleanedQuery = Object.fromEntries( 26 | Object.entries(query || {}).filter(([_, v]) => typeof v !== "undefined") 27 | ) as Record; 28 | 29 | // Convert to URL encoded query string 30 | const queryString = 31 | Object.keys(cleanedQuery).length !== 0 32 | ? "?" + new URLSearchParams(cleanedQuery).toString() 33 | : ""; 34 | 35 | return `${protocol}://${host}${_port}/${path}${queryString}`; 36 | } 37 | 38 | export function pick, TKey extends keyof TObj>( 39 | obj: TObj, 40 | ...props: TKey[] 41 | ) { 42 | return Object.fromEntries( 43 | Object.entries(obj).filter(([k]) => props.includes(k as TKey)) 44 | ) as Pick; 45 | } 46 | 47 | /** 48 | * Axios error interceptor to retry on network failures. 49 | * Dormant by default - is activated by including `retries` in the axios config. 50 | */ 51 | export function axiosRetryOnNetworkError( 52 | error: AxiosError 53 | ): Promise { 54 | // Only handle axios errors. 55 | if (!error.isAxiosError) return Promise.reject(error); 56 | 57 | const { config }: any = error; 58 | const { method, headers, retries = 0, __retryCount = 0 } = config; 59 | 60 | // POST requests can only be retried if they include an idempotency key. 61 | // Other methods (i.e. get, patch, delete) are considered idempotent by default. 62 | const isIdempotent = 63 | method.toUpperCase() !== "POST" || 64 | typeof headers["Idempotency-Key"] === "string"; 65 | 66 | const shouldRetry = 67 | isIdempotent && 68 | __retryCount < retries && 69 | isNetworkError(error) && // Don't retry due to server errors 70 | isRetryAllowed(error); // Don't retry if the error is permanent (e.g. SSL related) 71 | 72 | if (!shouldRetry) { 73 | return Promise.reject(error); 74 | } 75 | 76 | config.__retryCount = __retryCount + 1; 77 | return axios(config); 78 | } 79 | 80 | /** 81 | * Determine whether an axios error instance was caused by network error 82 | * (and should therefore be retryable). 83 | * 84 | * Borrowed from {@link https://github.com/softonic/axios-retry/blob/master/es/index.js} 85 | * with minor changes as we want to retry on timeout. 86 | */ 87 | function isNetworkError(error: AxiosError): boolean { 88 | return ( 89 | error.isAxiosError && 90 | !error.response && // Network errors have no response 91 | !axios.isCancel(error) 92 | ); // Don't retry cancelled requests 93 | } 94 | 95 | /** 96 | * Inspect network error code from axios to determine if it makes sense to retry it. 97 | * 98 | * Borrowed from {@link https://github.com/sindresorhus/is-retry-allowed/blob/main/index.js} 99 | */ 100 | function isRetryAllowed(error: AxiosError): boolean { 101 | return ( 102 | error.code === undefined || // Errors due to timeout have no error code. 103 | !retryDenyList.has(error.code) 104 | ); 105 | } 106 | 107 | const retryDenyList = new Set([ 108 | "ENOTFOUND", 109 | "ENETUNREACH", 110 | "UNABLE_TO_GET_ISSUER_CERT", 111 | "UNABLE_TO_GET_CRL", 112 | "UNABLE_TO_DECRYPT_CERT_SIGNATURE", 113 | "UNABLE_TO_DECRYPT_CRL_SIGNATURE", 114 | "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY", 115 | "CERT_SIGNATURE_FAILURE", 116 | "CRL_SIGNATURE_FAILURE", 117 | "CERT_NOT_YET_VALID", 118 | "CERT_HAS_EXPIRED", 119 | "CRL_NOT_YET_VALID", 120 | "CRL_HAS_EXPIRED", 121 | "ERROR_IN_CERT_NOT_BEFORE_FIELD", 122 | "ERROR_IN_CERT_NOT_AFTER_FIELD", 123 | "ERROR_IN_CRL_LAST_UPDATE_FIELD", 124 | "ERROR_IN_CRL_NEXT_UPDATE_FIELD", 125 | "OUT_OF_MEM", 126 | "DEPTH_ZERO_SELF_SIGNED_CERT", 127 | "SELF_SIGNED_CERT_IN_CHAIN", 128 | "UNABLE_TO_GET_ISSUER_CERT_LOCALLY", 129 | "UNABLE_TO_VERIFY_LEAF_SIGNATURE", 130 | "CERT_CHAIN_TOO_LONG", 131 | "CERT_REVOKED", 132 | "INVALID_CA", 133 | "PATH_LENGTH_EXCEEDED", 134 | "INVALID_PURPOSE", 135 | "CERT_UNTRUSTED", 136 | "CERT_REJECTED", 137 | "HOSTNAME_MISMATCH", 138 | ]); 139 | 140 | // https://github.com/flexdinesh/browser-or-node/blob/master/src/index.js 141 | export const isBrowser = () => 142 | typeof window !== "undefined" && typeof window.document !== "undefined"; 143 | 144 | export const isNode = () => 145 | typeof process === "object" && 146 | Boolean(process.versions?.node) && 147 | !isReactNative(); 148 | 149 | // https://github.com/facebook/react-native/commit/3c65e62183ce05893be0822da217cb803b121c61 150 | export const isReactNative = () => 151 | typeof navigator === "object" && navigator.product === "ReactNative"; 152 | -------------------------------------------------------------------------------- /src/version.ts: -------------------------------------------------------------------------------- 1 | export const version = "2.1.0"; -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | // This config only used to generate the type definitions in index.d.ts 3 | // The actual options used to compile pre-bundling are included in rollup.config.js 4 | "extends": "./tsconfig.json", 5 | "include": ["src/**/*.ts"], 6 | "compilerOptions": { 7 | "outDir": "./dist", 8 | "declaration": true, 9 | "emitDeclarationOnly": true, 10 | } 11 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // This is all a bit fiddly. These options are consumed by and determine the behaviour of: 3 | // - Your IDE / editor 4 | // - npm run test (thanks to ts-jest plugin) 5 | // - npm run docs (to get type defs for typedoc) 6 | // - npm run build 7 | // - To build to plain JS for rollup (in combination with overrides in rollup.config.js) 8 | // - To output the index.d.ts (in combination with overrides in tsconfig.build.json) 9 | "include": [ 10 | "src/**/*.ts", 11 | "__tests__/**/*.ts" 12 | ], 13 | "compilerOptions": { 14 | "target": "ES2019", 15 | "module": "ES2015", 16 | "lib": [ 17 | "ES2019", 18 | "DOM" 19 | ], 20 | "moduleResolution": "node", 21 | "esModuleInterop": true, 22 | "strict": true, 23 | "noImplicitAny": true, 24 | "strictNullChecks": true, 25 | "strictFunctionTypes": true, 26 | "strictPropertyInitialization": true, 27 | "noImplicitThis": true, 28 | "alwaysStrict": true, 29 | "noUnusedLocals": true, 30 | "noUnusedParameters": true, 31 | "noImplicitReturns": true, 32 | "noFallthroughCasesInSwitch": true, 33 | } 34 | } -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": [ 3 | "src/index.ts", 4 | "src/resources" 5 | ], 6 | "plugin": [ 7 | "typedoc-plugin-markdown", 8 | "typedoc-plugin-no-inherit", 9 | "typedoc-plugin-merge-modules" 10 | ], 11 | "out": "docs", 12 | "readme": "none", 13 | "excludeExternals": false, 14 | "excludeProtected": true, 15 | "excludePrivate": true, 16 | "excludeInternal": true, 17 | "includeVersion": true, 18 | "disableSources": true, 19 | "sort": ["required-first", "source-order"], 20 | "categorizeByGroup": true, 21 | "cleanOutputDir": true, 22 | "entryPointStrategy": "expand" 23 | } 24 | --------------------------------------------------------------------------------