Skip to content

Commit 69f2598

Browse files
Merge pull request #6 from Fintecture/connect-v2-migration
Migrate to use Connect V2 for both AIS and PIS
2 parents 112090f + 6fe741a commit 69f2598

File tree

9 files changed

+55
-126
lines changed

9 files changed

+55
-126
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ let config = {
144144
country: 'fr'
145145
}
146146

147-
let connect = client.getAisConnect(null, config)
147+
let connect = await client.getAisConnect(null, config)
148148
window.href.location = connect.url;
149149
```
150150

fintecture-client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export class FintectureClient {
105105
return this.connect.getPisConnect(accessToken, connectConfig);
106106
}
107107

108-
public getAisConnect(accessToken: string, connectConfig: any): IAisConnect {
108+
public async getAisConnect(accessToken: string, connectConfig: any): Promise<IAisConnect> {
109109
return this.connect.getAisConnect(accessToken, connectConfig);
110110
}
111111

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fintecture-client",
3-
"version": "1.0.27",
3+
"version": "2.0.0",
44
"description": "Fintecture Open Banking API Gateway enabling secure bank connections and payments",
55
"main": "lib/fintecture-client.js",
66
"types": "lib/fintecture-client.d.ts",

spec/connect.spec.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { FintectureClient } from '../fintecture-client';
2-
import { BaseUrls } from './../src/utils/URLBuilders/BaseUrls';
32
import { IPisSetup, IAisSetup } from './../src/interfaces/connect/ConnectInterface';
43
import { TestConfig } from './constants/config';
54

@@ -34,20 +33,17 @@ const client = new FintectureClient({ app_id: TestConfig.appIdMerchant, app_secr
3433

3534
describe('Connect', () => {
3635
it('#PIS getPisConnect', async (done) => {
37-
const mockConnectUrl = BaseUrls.FINTECTURECONNECTURL_SBX + '/pis?config=';
3836
const tokens: any = await client.getAccessToken();
3937
const connectMin = await client.getPisConnect(tokens.access_token, connectPisConfigMin);
40-
expect(connectMin.url).toContain(mockConnectUrl);
4138
expect(!!connectMin.session_id).toBe(true);
4239
const connectFull = await client.getPisConnect(tokens.access_token, connectPisConfigFull);
43-
expect(connectFull.url).toContain(mockConnectUrl);
4440
expect(!!connectFull.session_id).toBe(true);
4541
expect(connectFull.url.length).toBeGreaterThan(connectMin.url.length)
4642
done();
4743
});
4844

49-
it('#AIS getAisConnectUrl', (done) => {
50-
const connect = client.getAisConnect(null, connectAisMin);
45+
it('#AIS getAisConnectUrl', async (done) => {
46+
const connect = await client.getAisConnect(null, connectAisMin);
5147
expect(!!connect.url).toBe(true);
5248
done();
5349
});

src/Connect.ts

Lines changed: 41 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
1-
import * as UtilsCrypto from './utils/Crypto.js';
2-
import { BaseUrls } from './utils/URLBuilders/BaseUrls';
3-
import * as connectService from './services/ConnectService';
4-
import { IPisSetup, IPisConnectConfig, IAisConnectConfig, IPaymentPayload, IData, IAttributes, IMeta } from './interfaces/connect/ConnectInterface';
5-
import { ISessionPayload } from './interfaces/pis/PisInterface';
1+
import qs from 'qs';
2+
3+
import { Endpoints } from './utils/URLBuilders/Endpoints';
4+
import { IPisSetup, IPaymentPayload, IData, IAttributes, IMeta } from './interfaces/connect/ConnectInterface';
65
import { IFintectureConfig } from './interfaces/ConfigInterface';
76
import { Constants } from './utils/Constants.js';
87
import { PIS } from './Pis';
98
import * as apiService from './services/ApiService';
109

1110
export class Connect {
1211
public pis: PIS;
13-
public axios: any;
12+
public axiosInstance: any;
1413
public config: IFintectureConfig;
1514
public connectConfig: IPisSetup;
1615

17-
private signatureType: string;
18-
1916
constructor(config: IFintectureConfig) {
2017
this.pis = new PIS(config);
21-
this.axios = connectService;
18+
this.axiosInstance = apiService.getInstance(config.env);
2219
this.config = config;
23-
this.signatureType = 'rsa-sha256';
2420
}
2521

2622
/**
@@ -29,44 +25,30 @@ export class Connect {
2925
* @param {string} accessTOken
3026
* @param {payment} State
3127
*/
32-
public getAisConnect(accessToken: string, connectConfig: any) {
28+
public async getAisConnect(accessToken: string, connectConfig: any) {
3329
this.config = this._validateConfigIntegrity(this.config);
3430

35-
const headers: any = this._buildHeaders(accessToken, 'get', null, this.config.private_key, this.signatureType);
36-
37-
const config: IAisConnectConfig = {
38-
app_id: this.config.app_id,
39-
signature_type: this.signatureType,
40-
signature: headers['Signature'],
31+
const queryParameters = qs.stringify({
4132
redirect_uri: connectConfig.redirect_uri,
42-
origin_uri: connectConfig.origin_uri,
43-
state: connectConfig.state,
44-
psu_type: connectConfig.psu_type,
45-
country: connectConfig.country,
46-
date: headers['Date'],
47-
request_id: headers['X-Request-ID'],
48-
provider: connectConfig.provider
33+
state: connectConfig.state
34+
});
35+
const url = `${Endpoints.AISCONNECT}?${queryParameters}`;
36+
37+
// Extend the headers with Connect specific headers if they are defined
38+
const extraHeaders = {
39+
'x-provider': connectConfig.provider,
40+
'x-psu-type': connectConfig.psu_type,
41+
'x-country': connectConfig.country,
42+
'x-language': connectConfig.language,
4943
};
5044

51-
if (accessToken) {
52-
config.access_token = accessToken;
53-
}
54-
55-
const psuType = connectConfig.psu_type ? connectConfig.psu_type : 'retail';
56-
const country = connectConfig.country ? connectConfig.country : 'fr';
57-
58-
const url = `${
59-
this.config.env === Constants.SANDBOXENVIRONMENT
60-
? BaseUrls.FINTECTURECONNECTURL_SBX
61-
: BaseUrls.FINTECTURECONNECTURL_PRD
62-
}/ais/${psuType}/${country}`;
45+
const headers = apiService.getHeaders('get', url, null, this.config, null, extraHeaders);
6346

64-
const connect = {
65-
url: `${url}?config=${Buffer.from(JSON.stringify(config)).toString('base64')}`,
66-
}
67-
68-
return connect;
47+
const { data } = await this.axiosInstance.get(url, { headers });
6948

49+
return {
50+
url: data.meta.url
51+
};
7052
}
7153

7254
/**
@@ -81,40 +63,29 @@ export class Connect {
8163

8264
const paymentPayload: IPaymentPayload = this._buildPaymentPayload(connectConfig);
8365

84-
const prepare: any = await this.pis.prepare(accessToken, paymentPayload);
85-
86-
const sessionPayload: ISessionPayload = this._buildSessionPayload(prepare);
87-
88-
const headers: any = this._buildHeaders(accessToken, 'post', sessionPayload, this.config.private_key, this.signatureType);
89-
90-
const config: IPisConnectConfig = {
91-
app_id: this.config.app_id,
92-
access_token: accessToken,
93-
signature_type: this.signatureType,
94-
signature: headers['Signature'],
95-
redirect_uri: connectConfig.redirect_uri,
66+
const queryParameters = qs.stringify({
9667
origin_uri: connectConfig.origin_uri,
97-
state: connectConfig.state,
98-
payload: sessionPayload,
99-
psu_type: connectConfig.psu_type,
100-
country: connectConfig.country,
101-
date: headers['Date'],
102-
request_id: headers['X-Request-ID'],
103-
provider: connectConfig.provider
68+
redirect_uri: connectConfig.redirect_uri,
69+
state: connectConfig.state
70+
});
71+
const url = `${Endpoints.PISCONNECT}?${queryParameters}`;
72+
73+
// Extend the headers with Connect specific headers if they are defined
74+
const extraHeaders = {
75+
'x-provider': connectConfig.provider,
76+
'x-psu-type': connectConfig.psu_type,
77+
'x-country': connectConfig.country,
78+
'x-language': connectConfig.language,
10479
};
10580

106-
const url = `${
107-
this.config.env === Constants.SANDBOXENVIRONMENT
108-
? BaseUrls.FINTECTURECONNECTURL_SBX
109-
: BaseUrls.FINTECTURECONNECTURL_PRD
110-
}/pis`;
81+
const headers = apiService.getHeaders('post', url, accessToken, this.config, paymentPayload, extraHeaders);
11182

112-
const connect = {
113-
url: `${url}?config=${Buffer.from(JSON.stringify(config)).toString('base64')}`,
114-
session_id: prepare.meta.session_id
115-
}
83+
const { data } = await this.axiosInstance.post(url, paymentPayload, { headers });
11684

117-
return connect;
85+
return {
86+
session_id: data.meta.session_id,
87+
url: data.meta.url,
88+
};
11889
}
11990

12091
private _validatePisConnectConfigIntegrity(connectConfig: any) {
@@ -143,14 +114,6 @@ export class Connect {
143114
return connectConfig as IPisSetup;
144115
}
145116

146-
147-
private _buildHeaders(accessToken: string, method: string, payload: any, privateKey: string, algorithm: string): any {
148-
const headers = apiService.getHeaders(method, '', accessToken, this.config, payload);
149-
const signingString = UtilsCrypto.buildSigningString(headers, Constants.CONNECTHEADERPARAMETERLIST)
150-
headers["Signature"] = UtilsCrypto.signPayload(signingString, this.config.private_key);
151-
return headers;
152-
}
153-
154117
private _buildPaymentPayload(payment: any) {
155118
const attributes: IAttributes = {
156119
amount: payment.amount,
@@ -184,30 +147,6 @@ export class Connect {
184147
return payload;
185148
}
186149

187-
private _buildSessionPayload(payment) {
188-
const payload = {
189-
meta: {
190-
session_id: payment.meta.session_id,
191-
},
192-
data: {
193-
attributes: {
194-
amount: payment.data.attributes.amount,
195-
currency: payment.data.attributes.currency
196-
}
197-
}
198-
} as ISessionPayload;
199-
200-
if (payment.data.attributes.beneficiary) {
201-
payload.data.attributes.beneficiary = {name: payment.data.attributes.beneficiary.name};
202-
}
203-
204-
if (payment.data.attributes.execution_date) {
205-
payload.data.attributes.execution_date = payment.data.attributes.execution_date;
206-
}
207-
208-
return payload;
209-
}
210-
211150
private _validateConfigIntegrity(config) {
212151
if (!config.private_key) {
213152
throw Error('private_key must be set to use this function');

src/services/ApiService.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,14 @@ export const getHeaders = (method: string, url: string, accessToken: string, con
4646
headers['Signature'] = Crypto.createSignatureHeader(headers, config, Constants.SIGNEDHEADERPARAMETERLIST);
4747
delete headers['(request-target)'];
4848

49+
// Extend with extra headers in case they are not undefined. `undefined` as value of a header
50+
// is not allowed by Node.js
4951
if (extraHeaders) {
50-
Object.assign(headers, extraHeaders);
52+
Object.entries(extraHeaders).forEach(([headerName, headerValue]) => {
53+
if (headerValue !== undefined) {
54+
headers[headerName] = headerValue;
55+
}
56+
})
5157
}
5258

5359
return headers;

src/services/ConnectService.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/utils/URLBuilders/BaseUrls.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,8 @@ export class BaseUrls {
1414
process.env.FINTECTUREOAUTHURL_DEV || 'https://oauth-sandbox.fintecture.com';
1515
public static readonly FINTECTUREAPIURL_SBX: string =
1616
process.env.FINTECTUREAPIURL_DEV || 'https://api-sandbox.fintecture.com';
17-
public static readonly FINTECTURECONNECTURL_SBX: string =
18-
process.env.FINTECTURECONNECTURL_DEV || 'https://connect-sandbox.fintecture.com';
1917
public static readonly FINTECTUREOAUTHURL_PRD: string =
2018
process.env.FINTECTUREOAUTHURL_DEV || 'https://oauth.fintecture.com';
2119
public static readonly FINTECTUREAPIURL_PRD: string =
2220
process.env.FINTECTUREAPIURL_DEV || 'https://api.fintecture.com';
23-
public static readonly FINTECTURECONNECTURL_PRD: string =
24-
process.env.FINTECTURECONNECTURL_DEV || 'https://connect.fintecture.com';
2521
}

src/utils/URLBuilders/Endpoints.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ export class Endpoints {
1616
public static readonly PIS: string = '/pis/v1';
1717
public static readonly AISPROVIDER: string = '/ais/v1/provider';
1818
public static readonly AISCUSTOMER: string = '/ais/v1/customer';
19+
public static readonly AISCONNECT: string = '/ais/v2/connect';
20+
public static readonly PISCONNECT: string = '/pis/v2/connect';
1921
}

0 commit comments

Comments
 (0)