Skip to content
This repository was archived by the owner on Apr 23, 2021. It is now read-only.

Commit 71c8d6c

Browse files
authored
Merge pull request #32 from smontiu/master
Feature direct debits and standing orders
2 parents 49217d4 + eb640e8 commit 71c8d6c

File tree

10 files changed

+207
-11
lines changed

10 files changed

+207
-11
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ This client library consists of two core pieces of functionality, each represent
155155

156156
* `getAccounts` - call to the */accounts* endpoint
157157
* `getAccount` - call to the */accounts/{account_id}* endpoint
158+
* `getDirectDebits` - call to the */accounts/{account_id}/direct_debits* endpoint
159+
* `getStandingOrders` - call to the */accounts/{account_id}/standing_orders* endpoint
158160
* `getTransactions` - call to the */accounts/{account_id}/transactions* endpoint
159161
* `getPendingTransactions` - call to the */accounts/{account_id}/transactions/pending* endpoint
160162
* `getBalance` - call to the */accounts/{account_id}/balance* endpoint

index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ export { StatusAPIClient } from "./src/v1/StatusAPIClient";
44
export { Constants } from "./src/v1/Constants";
55
export { IAccount } from "./src/v1/interfaces/data/IAccount";
66
export { IBalance } from "./src/v1/interfaces/data/IBalance";
7+
export { IDirectDebit } from "./src/v1/interfaces/data/IDirectDebit";
8+
export { IStandingOrder } from "./src/v1/interfaces/data/IStandingOrder";
79
export { IInfo } from "./src/v1/interfaces/data/IInfo";
810
export { IMe } from "./src/v1/interfaces/data/IMe";
911
export { IOptions } from "./src/v1/interfaces/auth/IOptions";

src/v1/AuthAPIClient.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,7 @@ export class AuthAPIClient {
115115
* @returns {boolean}
116116
*/
117117
private static isValidScope(grant: string): boolean {
118-
switch (grant) {
119-
case "offline_access":
120-
case "info":
121-
case "accounts":
122-
case "transactions":
123-
case "balance":
124-
case "cards":
125-
return true;
126-
default:
127-
return false;
128-
}
118+
return Constants.AVAILABLE_SCOPES.includes(grant);
129119
}
130120

131121
/**

src/v1/Constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ export class Constants {
88
public static readonly API_URL: string = "https://api.truelayer.com";
99
public static readonly STATUS_URL: string = "https://status-api.truelayer.com";
1010
public static readonly API_TIMEOUT: number = 60000;
11+
public static readonly AVAILABLE_SCOPES: Array<string> = ["offline_access", "info", "accounts", "transactions", "balance", "cards", "direct_debits", "standing_orders"];
1112
}

src/v1/DataAPIClient.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { ApiError } from "./APIError";
22
import { Constants } from "./Constants";
33
import { IAccount } from "./interfaces/data/IAccount";
44
import { IBalance } from "./interfaces/data/IBalance";
5+
import { IDirectDebit } from "./interfaces/data/IDirectDebit";
6+
import { IStandingOrder } from "./interfaces/data/IStandingOrder";
57
import { IInfo } from "./interfaces/data/IInfo";
68
import { IJWT } from "./interfaces/auth/IJWT";
79
import { IMe } from "./interfaces/data/IMe";
@@ -158,6 +160,28 @@ export class DataAPIClient {
158160
return await DataAPIClient.callAPI<IBalance>(accessToken, `${Constants.API_URL}/data/v1/accounts/${accountId}/balance`);
159161
}
160162

163+
/**
164+
* Call to /accounts/account_id/direct_debits API
165+
*
166+
* @param accessToken
167+
* @param accountId
168+
* @returns {Promise<IResult<IDirectDebit>>}
169+
*/
170+
public static async getDirectDebits(accessToken: string, accountId: string): Promise<IResult<IDirectDebit>> {
171+
return await DataAPIClient.callAPI<IDirectDebit>(accessToken, `${Constants.API_URL}/data/v1/accounts/${accountId}/direct_debits`);
172+
}
173+
174+
/**
175+
* Call to /accounts/account_id/standing_orders API
176+
*
177+
* @param accessToken
178+
* @param accountId
179+
* @returns {Promise<IResult<IStandingOrder>>}
180+
*/
181+
public static async getStandingOrders(accessToken: string, accountId: string): Promise<IResult<IStandingOrder>> {
182+
return await DataAPIClient.callAPI<IStandingOrder>(accessToken, `${Constants.API_URL}/data/v1/accounts/${accountId}/standing_orders`);
183+
}
184+
161185
/**
162186
* Call to /cards API.
163187
*

src/v1/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ Class responsible for calling to the Data endpoints
8484
* [.getInfo(accessToken)](#DataAPIClient.getInfo) ⇒ <code>Promise.&lt;IResponse.&lt;IInfo&gt;&gt;</code>
8585
* [.getAccounts(accessToken)](#DataAPIClient.getAccounts) ⇒ <code>Promise.&lt;IResponse.&lt;IAccount&gt;&gt;</code>
8686
* [.getAccount(accessToken, accountId)](#DataAPIClient.getAccount) ⇒ <code>Promise.&lt;IResponse.&lt;IAccount&gt;&gt;</code>
87+
* [.getDirectDebits(accessToken, accountId)](#DataAPIClient.getDirectDebits) ⇒ <code>Promise.&lt;IResponse.&lt;IDirectDebit&gt;&gt;</code>
88+
* [.getStandingOrders(accessToken, accountId)](#DataAPIClient.getStandingOrders) ⇒ <code>Promise.&lt;IResponse.&lt;IStandingOrder&gt;&gt;</code>
8789
* [.getTransactions(accessToken, accountId, from, to)](#DataAPIClient.getTransactions) ⇒ <code>Promise.&lt;IResponse.&lt;ITransaction&gt;&gt;</code>
8890
* [.getBalance(accessToken, accountId)](#DataAPIClient.getBalance) ⇒ <code>Promise.&lt;IResponse.&lt;IBalance&gt;&gt;</code>
8991
* [.validateToken(accessToken)](#DataAPIClient.isTokenExpired) ⇒ <code>boolean</code>
@@ -147,6 +149,26 @@ Call to /accounts/account_id API.
147149
| accessToken | <code>string</code> |
148150
| accountId | <code>string</code> |
149151

152+
### DataAPIClient.getDirectDebits(accessToken, accountId) ⇒ <code>Promise.&lt;IResponse.&lt;IDirectDebit&gt;&gt;</code>
153+
Call to /accounts/account_id/direct_debits API.
154+
155+
**Kind**: static method of [<code>DataAPIClient</code>](#DataAPIClient)
156+
157+
| Param | Type |
158+
| --- | --- |
159+
| accessToken | <code>string</code> |
160+
| accountId | <code>string</code> |
161+
162+
### DataAPIClient.getStandingOrders(accessToken, accountId) ⇒ <code>Promise.&lt;IResponse.&lt;IStandingOrder&gt;&gt;</code>
163+
Call to /accounts/account_id/standing_orders API.
164+
165+
**Kind**: static method of [<code>DataAPIClient</code>](#DataAPIClient)
166+
167+
| Param | Type |
168+
| --- | --- |
169+
| accessToken | <code>string</code> |
170+
| accountId | <code>string</code> |
171+
150172
<a name="DataAPIClient.getTransactions"></a>
151173

152174
### DataAPIClient.getTransactions(accessToken, accountId, from, to) ⇒ <code>Promise.&lt;IResponse.&lt;ITransaction&gt;&gt;</code>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Customer's direct debits and associated data - for use with /accounts endpoint
3+
* Docs: https://docs.truelayer.com/#retrieve-direct-debits
4+
*
5+
* @interface IDirectDebit
6+
*/
7+
export interface IDirectDebit {
8+
/** Unique identifier of the direct debit in a request. It may change between requests. */
9+
direct_debit_id: string;
10+
/** Name of the service or user returned by the Provider */
11+
name: string;
12+
/** This can either be Active or Inactive */
13+
status: string;
14+
/** Date of the latest payment */
15+
previous_payment_timestamp: string;
16+
/** Amount of the latest paymentt */
17+
previous_payment_amount: number;
18+
/** ISO 4217 alpha-3 currency code */
19+
currency: string;
20+
/** A collection of additional Provider specific transaction metadata * @type {IMeta} */
21+
meta?: IMeta;
22+
/** Date and time the request was made */
23+
timestamp: string;
24+
}
25+
26+
/**
27+
* Direct debit meta
28+
*
29+
* @interface IMeta
30+
*/
31+
export interface IMeta {
32+
/** Provider mandate identification */
33+
provider_mandate_identification: string;
34+
/** Provider account identifier */
35+
provider_account_id: string;
36+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Customer's standing orders - for use with /accounts endpoint
3+
* Docs: https://docs.truelayer.com/#retrieve-standing-orders
4+
*
5+
* @interface IStandingOrder
6+
*/
7+
export interface IStandingOrder {
8+
/** Frequency of the standing order.
9+
* Possible values:
10+
* EvryDay - every day
11+
* EvryWorkgDay - every working day
12+
* IntrvlDay:XX - every XX calendar day
13+
* IntrvlMnthDay:XX:YY - every XXth month on the YYth day of the month
14+
* IntrvlWkDay:XX:YY - every XXth week, on the YYth day of the week
15+
* QtrDay - quarterly -
16+
* WkInMnthDay:XX:YY - every month, on the XXth week of the month and on the YYth day of the week. */
17+
frequency: string;
18+
/** This can either be Active or Inactive */
19+
status: string;
20+
/** Date and time the request was made */
21+
timestamp: string;
22+
/** ISO 4217 alpha-3 currency code */
23+
currency: string;
24+
/** A collection of additional Provider specific transaction metadata * @type {IMeta} */
25+
meta?: IMeta;
26+
/** The date on which the next payment for the standing order schedule will be made */
27+
next_payment_date: string;
28+
/** Amount of the next payment for the standing order **/
29+
next_payment_amount: number;
30+
/** The date on which the first payment for the standing order schedule will be or was made */
31+
first_payment_date: string;
32+
/** Amount of the first payment for the standing order */
33+
first_payment_amount: number;
34+
/** The date on which the next payment for a Standing Order schedule will be made */
35+
final_payment_date: string;
36+
/** Amount of the last payment for the standing order */
37+
final_payment_amount: number;
38+
/** Reference of the standing order set by the user */
39+
reference: string;
40+
/** Date of the latest payment */
41+
previous_payment_timestamp: string;
42+
/** Amount of the latest payment */
43+
previous_payment_amount: number;
44+
}
45+
46+
/**
47+
* Direct debit meta
48+
*
49+
* @interface IMeta
50+
*/
51+
export interface IMeta {
52+
/** Provider account identifier */
53+
provider_account_id: string;
54+
}

test/unit/data.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ test("buildRequestOptions() - returns well formed request options - all params",
4444
// Get access token from environment variable
4545
const access_token: string = (process.env.access_token as string);
4646

47+
4748
// Only run the below stubbed tests with a valid access token
4849
if (DataAPIClient.validateToken(access_token)) {
4950

@@ -101,6 +102,22 @@ if (DataAPIClient.validateToken(access_token)) {
101102
t.deepEqual(actual, expected);
102103
});
103104

105+
test.serial("stubbed request body for /Accounts/{id}/DirectDebits endpoint is correctly parsed", async (t) => {
106+
const expected = fixtures.accountDirectDebitResponse;
107+
mock.stub(request, "get").returns(JSON.stringify(expected));
108+
const actual = await DataAPIClient.getDirectDebits(access_token, "test_account_id");
109+
t.plan(1);
110+
t.deepEqual(actual, expected);
111+
});
112+
113+
test.serial("stubbed request body for /Accounts/{id}/StandingOrders endpoint is correctly parsed", async (t) => {
114+
const expected = fixtures.accountStandingOrderResponse;
115+
mock.stub(request, "get").returns(JSON.stringify(expected));
116+
const actual = await DataAPIClient.getStandingOrders(access_token, "test_account_id");
117+
t.plan(1);
118+
t.deepEqual(actual, expected);
119+
});
120+
104121
test.serial("stubbed request body for /Cards endpoint is correctly parsed", async (t) => {
105122
const expected = fixtures.cardsResponse;
106123
mock.stub(request, "get").returns(JSON.stringify(expected));

test/unit/fixtures.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { ICardBalance } from "../../src/v1/interfaces/data/ICardBalance";
1111
import { ICardTransaction } from "../../src/v1/interfaces/data/ICardTransaction";
1212
import { IProviderInfo } from '../../src/v1/interfaces/auth/IProviderInfo';
1313
import { IStatusInfo } from "../../src/v1/interfaces/status/IStatusInfo";
14+
import { IStandingOrder } from "../../src/v1/interfaces/data/IStandingOrder";
15+
import { IDirectDebit } from "../../src/v1/interfaces/data/IDirectDebit";
1416

1517
export class Fixtures {
1618

@@ -386,6 +388,52 @@ export class Fixtures {
386388
]
387389
};
388390

391+
// Expected /Accounts/{id}/StandingOrders json response
392+
public readonly accountStandingOrderResponse: IResult<IStandingOrder> =
393+
{
394+
results: [
395+
{
396+
currency: "GBP",
397+
frequency: "DD",
398+
next_payment_date: "2017-10-12T07:17:54.8144949Z",
399+
next_payment_amount: 123,
400+
first_payment_date: "2017-10-12T07:17:54.8144949Z",
401+
status: "Active",
402+
first_payment_amount: 123,
403+
final_payment_date: "2017-10-12T07:17:54.8144949Z",
404+
final_payment_amount: 123,
405+
timestamp: "2017-10-12T07:17:54.8144949Z",
406+
reference: "Savings",
407+
previous_payment_timestamp: "2017-10-12T07:17:54.8144949Z",
408+
previous_payment_amount: 123,
409+
meta: {
410+
provider_account_id: "234234-123"
411+
}
412+
}
413+
]
414+
};
415+
416+
// Expected /Accounts/{id}/DirectDebits json response
417+
public readonly accountDirectDebitResponse: IResult<IDirectDebit> =
418+
{
419+
results: [
420+
{
421+
direct_debit_id: "123",
422+
name: "Netflic",
423+
status: "Active",
424+
previous_payment_timestamp: "2017-10-12T07:17:54.8144949Z",
425+
previous_payment_amount: 123,
426+
currency: "GBP",
427+
timestamp: "2017-10-12T07:17:54.8144949Z",
428+
meta: {
429+
provider_mandate_identification: "Lacsitos",
430+
provider_account_id: "234234-123"
431+
}
432+
}
433+
]
434+
};
435+
436+
// Expected /Cards/{id}/Transactions json response
389437
public readonly cardTransactionsResponse: IResult<ICardTransaction> =
390438
{
391439
results: [

0 commit comments

Comments
 (0)