@vantagepay/vantagepay 0.17.3 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/LICENSE +21 -0
- package/README.md +267 -427
- package/dist/index.d.mts +12059 -0
- package/dist/index.d.ts +12039 -37
- package/dist/index.js +5992 -2
- package/dist/index.mjs +5697 -2
- package/package.json +25 -13
- package/dist/apiConfig.d.ts +0 -10
- package/dist/apiError.d.ts +0 -5
- package/dist/apiTokens.d.ts +0 -7
- package/dist/authentication/index.d.ts +0 -26
- package/dist/authentication/types.d.ts +0 -77
- package/dist/baseApi.d.ts +0 -10
- package/dist/common/types.d.ts +0 -115
- package/dist/consumers/index.d.ts +0 -21
- package/dist/consumers/types.d.ts +0 -588
- package/dist/content/index.d.ts +0 -7
- package/dist/devices/types.d.ts +0 -20
- package/dist/eventTypes.d.ts +0 -11
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/index.modern.mjs +0 -2
- package/dist/index.modern.mjs.map +0 -1
- package/dist/index.umd.js +0 -2
- package/dist/index.umd.js.map +0 -1
- package/dist/log/index.d.ts +0 -19
- package/dist/log/messageTemplate.d.ts +0 -10
- package/dist/log/types.d.ts +0 -20
- package/dist/lookups/index.d.ts +0 -31
- package/dist/lookups/types.d.ts +0 -1911
- package/dist/merchants/index.d.ts +0 -37
- package/dist/merchants/types.d.ts +0 -515
- package/dist/payments/index.d.ts +0 -38
- package/dist/payments/types.d.ts +0 -2028
- package/dist/qr/index.d.ts +0 -6
- package/dist/reports/index.d.ts +0 -10
- package/dist/reports/types.d.ts +0 -69
- package/dist/system/index.d.ts +0 -4
- package/dist/tokens/types.d.ts +0 -38
package/README.md
CHANGED
|
@@ -1,516 +1,356 @@
|
|
|
1
|
-
# VantagePay
|
|
1
|
+
# VantagePay SDK for TypeScript/JavaScript
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@vantagepay/vantagepay` is the official TypeScript/JavaScript SDK for integrating with VantagePay APIs.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It provides:
|
|
6
|
+
|
|
7
|
+
- typed API modules backed by VantagePay model types
|
|
8
|
+
- automatic HTTP retries for transient failures
|
|
9
|
+
- automatic token refresh using `refreshToken`
|
|
10
|
+
- real-time payment status updates via SignalR
|
|
11
|
+
- event publishing for session and payment lifecycle signals
|
|
12
|
+
|
|
13
|
+
This package is client-focused. Administrative API-key capabilities are available in the .NET SDK ([VantagePay.SDK](https://www.nuget.org/packages/VantagePay.SDK)) and are not part of this package.
|
|
6
14
|
|
|
7
15
|
---
|
|
8
|
-
# Installation
|
|
9
16
|
|
|
10
|
-
|
|
17
|
+
## Table of Contents
|
|
18
|
+
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Client Types](#client-types)
|
|
21
|
+
- [Basic Usage](#basic-usage)
|
|
22
|
+
- [Configuration and Construction](#configuration-and-construction)
|
|
23
|
+
- [Authentication and Tokens](#authentication-and-tokens)
|
|
24
|
+
- [Error Handling](#error-handling)
|
|
25
|
+
- [Public API Surface](#public-api-surface)
|
|
26
|
+
- [Payments and Signals](#payments-and-signals)
|
|
27
|
+
- [Server-side Admin Usage](#server-side-admin-usage)
|
|
28
|
+
- [Additional Modules](#additional-modules)
|
|
11
29
|
|
|
12
|
-
```ps
|
|
13
|
-
npm install @vantagepay/vantagepay --save
|
|
14
|
-
```
|
|
15
30
|
---
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Once imported you can create an instance with options specific to your environment.
|
|
22
|
-
```js
|
|
23
|
-
const VantagePayClient = new VantagePay({ baseUrl: 'https://sandbox-api.vantagepay.dev/' })
|
|
24
|
-
```
|
|
25
|
-
When you are done using the client or when the application exits, you can close the client to flush logs, unsubscribe to events and cancel active web requests.
|
|
26
|
-
```js
|
|
27
|
-
await VantagePayClient.close()
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npm install @vantagepay/vantagepay
|
|
28
36
|
```
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
```js
|
|
32
|
-
{
|
|
33
|
-
// The partner URL you are integrating with, this will point to the local development server by default.
|
|
34
|
-
baseUrl: 'https://sandbox-api.vantagepay.dev/',
|
|
38
|
+
---
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
headers: {
|
|
38
|
-
'X-EXAMPLE-HEADER': 'Test'
|
|
39
|
-
},
|
|
40
|
+
## Client Types
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
language: 'en',
|
|
42
|
+
This package exposes one top-level client:
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
retries: 3,
|
|
44
|
+
- `VantagePay` for client-facing integrations (web/mobile/POS-style app integrations).
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
consoleLogging: false,
|
|
46
|
+
Important:
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
- there is no `VantagePayAdminClient` in TypeScript.
|
|
49
|
+
- for server-side admin API-key workflows, use the [.NET SDK](https://www.nuget.org/packages/VantagePay.SDK).
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
logBatchInterval: 60000,
|
|
55
|
-
}
|
|
56
|
-
```
|
|
51
|
+
---
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
```js
|
|
60
|
-
// Do this when the application close to push final logs to the server.
|
|
61
|
-
VantagePayClient.log.flush()
|
|
53
|
+
## Basic Usage
|
|
62
54
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
```
|
|
55
|
+
```ts
|
|
56
|
+
import { VantagePay } from '@vantagepay/vantagepay'
|
|
66
57
|
|
|
67
|
-
|
|
58
|
+
const client = new VantagePay({
|
|
59
|
+
baseUrl: 'https://sandbox-api.vantagepay.dev/',
|
|
60
|
+
})
|
|
68
61
|
|
|
69
|
-
|
|
70
|
-
The API will respond with typical REST HTTP error status codes (4xx and 5xx) for errors that will trigger an exception. You can use the following generic error handling code for the typical exceptions that you may experience.
|
|
62
|
+
await client.auth.login('233548306110', 'Password123!')
|
|
71
63
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// First check if it's an API error.
|
|
77
|
-
if (error instanceof ApiError) {
|
|
78
|
-
// You can always display the `message` property to handle things generically.
|
|
79
|
-
console.error('\n%s\n', error.message)
|
|
80
|
-
|
|
81
|
-
// Or you can decide to handle things in a custom way depending on the status code.
|
|
82
|
-
if (error.statusCode === 400 || error.statusCode === 422) { // 400/422 - Validation Errors
|
|
83
|
-
if (Array.isArray(error.result)) {
|
|
84
|
-
// Multiple errors.
|
|
85
|
-
error.result.forEach(validationError => console.error(validationError))
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
// Single error message.
|
|
89
|
-
console.error(error.message || error.result)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
else if (error.statusCode === 401 || error.statusCode === 403) { // 401/403 - Auth Errors
|
|
93
|
-
// Login calls will contain extra information on failure (401).
|
|
94
|
-
// No access will not have any specific details on why (403).
|
|
95
|
-
}
|
|
96
|
-
else if (error.statusCode === 429) { // 429 - Too Many Requests
|
|
97
|
-
// Contains the limit.
|
|
98
|
-
console.error(error.message)
|
|
99
|
-
// This will also contain a standard 'Retry-After' header if you need to know how long to wait.
|
|
100
|
-
}
|
|
101
|
-
else if (error.statusCode === 500) { // 500 - Server Error
|
|
102
|
-
// General error message.
|
|
103
|
-
console.error(error.message)
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
console.error('Unknown status code from VantagePay client library: ' + error.statusCode)
|
|
107
|
-
throw error
|
|
108
|
-
}
|
|
109
|
-
} else {
|
|
110
|
-
// Not a client library error...
|
|
111
|
-
throw error
|
|
112
|
-
}
|
|
113
|
-
}
|
|
64
|
+
const currencies = await client.lookups.getCurrencies()
|
|
65
|
+
const summary = await client.reports.getTransactionSummary('GHS')
|
|
66
|
+
|
|
67
|
+
await client.close()
|
|
114
68
|
```
|
|
115
69
|
|
|
116
70
|
---
|
|
117
|
-
# Authentication
|
|
118
71
|
|
|
119
|
-
##
|
|
120
|
-
Use credentials to login and retrieve access and refresh tokens.
|
|
121
|
-
```js
|
|
122
|
-
try {
|
|
123
|
-
|
|
124
|
-
const testLogin = await VantagePayClient.auth.login('test', 'test@#$123abCD')
|
|
72
|
+
## Configuration and Construction
|
|
125
73
|
|
|
126
|
-
|
|
127
|
-
my_secure_storage.set('accessToken', testLogin.accessToken)
|
|
128
|
-
my_secure_storage.set('refreshToken', testLogin.refreshToken)
|
|
74
|
+
Available `VantagePay` constructor options:
|
|
129
75
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
my_secure_storage.set('refreshToken', ApiTokens.refreshToken)
|
|
76
|
+
```ts
|
|
77
|
+
import { VantagePay } from '@vantagepay/vantagepay'
|
|
133
78
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// }
|
|
145
|
-
|
|
146
|
-
const authError = error.result
|
|
147
|
-
|
|
148
|
-
if (authError.mustChangePassword) {
|
|
149
|
-
console.log('Navigate to a change password page, the token is internally set to allow calls to auth.changePassword()')
|
|
150
|
-
|
|
151
|
-
// A successful change will automatically log you in.
|
|
152
|
-
await VantagePayClient.auth.changePassword('NewComplexP@55word!')
|
|
153
|
-
}
|
|
79
|
+
const client = new VantagePay({
|
|
80
|
+
baseUrl: 'https://sandbox-api.vantagepay.dev/',
|
|
81
|
+
headers: { 'X-EXAMPLE-HEADER': 'Test' },
|
|
82
|
+
language: 'en',
|
|
83
|
+
retries: 3,
|
|
84
|
+
consoleLogging: false,
|
|
85
|
+
logBatchSize: 100,
|
|
86
|
+
logBatchInterval: 60000,
|
|
87
|
+
})
|
|
88
|
+
```
|
|
154
89
|
|
|
155
|
-
|
|
156
|
-
console.log('Navigate to the OTP page password page, the token is internally set to allow calls to auth.resendOtp() and auth.validateOtp()')
|
|
90
|
+
Notes:
|
|
157
91
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
92
|
+
- `baseUrl` defaults to `http://localhost:5000`.
|
|
93
|
+
- `close()` flushes logs, stops payment status checks, unsubscribes events, and aborts in-flight requests.
|
|
161
94
|
|
|
162
|
-
|
|
163
|
-
console.log('User account has been deactivated')
|
|
164
|
-
}
|
|
95
|
+
---
|
|
165
96
|
|
|
166
|
-
|
|
167
|
-
console.log('User is currently locked out')
|
|
168
|
-
}
|
|
97
|
+
## Authentication and Tokens
|
|
169
98
|
|
|
170
|
-
|
|
171
|
-
console.log('User credentials supplied are invalid')
|
|
172
|
-
}
|
|
173
|
-
}
|
|
99
|
+
### Login and token storage
|
|
174
100
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
101
|
+
```ts
|
|
102
|
+
import { ApiTokens } from '@vantagepay/vantagepay'
|
|
103
|
+
|
|
104
|
+
const tokenResponse = await client.auth.login('233548306110', 'Password123!')
|
|
105
|
+
|
|
106
|
+
console.log(tokenResponse.accessToken)
|
|
107
|
+
console.log(ApiTokens.accessToken)
|
|
108
|
+
console.log(ApiTokens.refreshToken)
|
|
181
109
|
```
|
|
182
110
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
111
|
+
### Restore existing tokens
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { ApiTokens } from '@vantagepay/vantagepay'
|
|
186
115
|
|
|
187
|
-
|
|
188
|
-
ApiTokens.
|
|
189
|
-
ApiTokens.refreshToken = my_secure_storage.get('refreshToken') || null
|
|
116
|
+
ApiTokens.accessToken = secureStore.get('accessToken') || null
|
|
117
|
+
ApiTokens.refreshToken = secureStore.get('refreshToken') || null
|
|
190
118
|
```
|
|
191
119
|
|
|
192
|
-
|
|
193
|
-
You can also use this to clear out tokens manually which is also used internally when `logout` is called.
|
|
120
|
+
### Session helpers
|
|
194
121
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
await
|
|
122
|
+
```ts
|
|
123
|
+
const isLoggedIn = client.auth.isLoggedIn()
|
|
124
|
+
await client.auth.refresh()
|
|
125
|
+
await client.auth.logout()
|
|
199
126
|
```
|
|
200
127
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
```
|
|
204
|
-
|
|
128
|
+
### Token claim helpers
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
client.auth.getCurrentUserReference()
|
|
132
|
+
client.auth.getCurrentConsumerReference()
|
|
133
|
+
client.auth.getCurrentMerchantReference()
|
|
134
|
+
client.auth.getCurrentBusinessReference()
|
|
135
|
+
client.auth.getCurrentTerminalReference()
|
|
136
|
+
client.auth.getCurrentUserName()
|
|
137
|
+
client.auth.getMobileNumber()
|
|
138
|
+
client.auth.getEmailAddress()
|
|
139
|
+
client.auth.getRedirectAction()
|
|
205
140
|
```
|
|
206
141
|
|
|
207
142
|
---
|
|
208
|
-
# Lookups
|
|
209
|
-
There are a number of lookup values that can be retrieved from the server. This is preferred over static client data because it allows for dynamic configuration and disabling of things from the server without redeploying the client.
|
|
210
143
|
|
|
211
|
-
##
|
|
212
|
-
Get a list of configured currencies for the partner. The `isAvailable` flag can be used to disable items from selection, the text will also indicate if it is currently available. Other properties can be useful for displaying currency values.
|
|
213
|
-
```js
|
|
214
|
-
var currencies = await VantagePayClient.lookups.getCurrencies()
|
|
215
|
-
```
|
|
144
|
+
## Error Handling
|
|
216
145
|
|
|
217
|
-
|
|
218
|
-
```js
|
|
219
|
-
[
|
|
220
|
-
{
|
|
221
|
-
isAvailable: true,
|
|
222
|
-
currency: 'GHS',
|
|
223
|
-
currencyName: 'Ghana Cedi',
|
|
224
|
-
currencyCode: 'GHS',
|
|
225
|
-
symbol: '¢',
|
|
226
|
-
numericIsoCode: 936
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
isAvailable: true,
|
|
230
|
-
currency: 'NGN',
|
|
231
|
-
currencyName: 'Nigeria Naira',
|
|
232
|
-
currencyCode: 'NGN',
|
|
233
|
-
symbol: '₦',
|
|
234
|
-
numericIsoCode: 566
|
|
235
|
-
},
|
|
236
|
-
{
|
|
237
|
-
isAvailable: true,
|
|
238
|
-
currency: 'ZAR',
|
|
239
|
-
currencyName: 'South Africa Rand',
|
|
240
|
-
currencyCode: 'ZAR',
|
|
241
|
-
symbol: 'R',
|
|
242
|
-
numericIsoCode: 710
|
|
243
|
-
}
|
|
244
|
-
]
|
|
245
|
-
```
|
|
146
|
+
All API methods throw `ApiError` for HTTP/API failures.
|
|
246
147
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
```js
|
|
250
|
-
var countries = await VantagePayClient.lookups.getCountries()
|
|
251
|
-
```
|
|
148
|
+
```ts
|
|
149
|
+
import { ApiError } from '@vantagepay/vantagepay'
|
|
252
150
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
{
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
longIsoCode: 'GHA',
|
|
261
|
-
shortIsoCode: 'GH',
|
|
262
|
-
numericIsoCode: 288,
|
|
263
|
-
diallingCode: '233'
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
isAvailable: true,
|
|
267
|
-
country: 'NGA',
|
|
268
|
-
countryName: 'Nigeria',
|
|
269
|
-
longIsoCode: 'NGA',
|
|
270
|
-
shortIsoCode: 'NG',
|
|
271
|
-
numericIsoCode: 566,
|
|
272
|
-
diallingCode: '234'
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
isAvailable: false,
|
|
276
|
-
country: 'ZAF',
|
|
277
|
-
countryName: 'South Africa (Currently Unavailable)',
|
|
278
|
-
longIsoCode: 'ZAF',
|
|
279
|
-
shortIsoCode: 'ZA',
|
|
280
|
-
numericIsoCode: 710,
|
|
281
|
-
diallingCode: '27'
|
|
282
|
-
}
|
|
283
|
-
]
|
|
284
|
-
```
|
|
151
|
+
try {
|
|
152
|
+
await client.auth.login('user', 'wrong-password')
|
|
153
|
+
} catch (error) {
|
|
154
|
+
if (error instanceof ApiError) {
|
|
155
|
+
console.error(error.statusCode)
|
|
156
|
+
console.error(error.message)
|
|
157
|
+
console.error(error.result)
|
|
285
158
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
var languages = await VantagePayClient.lookups.getLanguages()
|
|
290
|
-
```
|
|
159
|
+
if (error.statusCode === 401 && error.result?.mustChangePassword) {
|
|
160
|
+
await client.auth.changePassword('OldPassword', 'NewPassword123!')
|
|
161
|
+
}
|
|
291
162
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
163
|
+
if (error.statusCode === 401 && (error.result?.mustValidatePhoneNumber || error.result?.mustValidateEmailAddress)) {
|
|
164
|
+
await client.auth.resendOtp()
|
|
165
|
+
await client.auth.validateOtp('123456')
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
throw error
|
|
169
|
+
}
|
|
170
|
+
}
|
|
295
171
|
```
|
|
296
172
|
|
|
297
|
-
|
|
298
|
-
Get a list of configured mobile wallet operators for the partner. The `isAvailable` flag can be used to disable items from selection, the text will also indicate if it is currently available. This can be used when setting up mobile wallets for example by limiting the types to only what the partner supports. The `operatorCode` is what can be passed into payment request packets for mobile wallet sources or destinations.
|
|
299
|
-
```js
|
|
300
|
-
var mobileWalletOperators = await VantagePayClient.lookups.getMobileWalletOperators()
|
|
301
|
-
```
|
|
173
|
+
---
|
|
302
174
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
175
|
+
## Public API Surface
|
|
176
|
+
|
|
177
|
+
`VantagePay` modules:
|
|
178
|
+
|
|
179
|
+
| Module | Purpose |
|
|
180
|
+
|---|---|
|
|
181
|
+
| `auth` | Login/logout, refresh, OTP, password, face/liveness checks, token claim helpers |
|
|
182
|
+
| `lookups` | Countries, currencies, languages, banks, wallet operators, categories, product types, address resolution |
|
|
183
|
+
| `consumers` | Consumer profile operations, files, limits, debit orders, feedback/support |
|
|
184
|
+
| `merchants` | Merchant profile operations, OTP verify, merchant user flows, product catalog and merchant product management, POS setup/config |
|
|
185
|
+
| `payments` | Payment initiation, status monitoring, tokenization, interactive payment submissions |
|
|
186
|
+
| `notifications` | In-app message retrieval and lifecycle |
|
|
187
|
+
| `qrCodes` | QR decode and QR image generation |
|
|
188
|
+
| `reports` | Recent transactions, summaries, daily and detailed transaction reporting |
|
|
189
|
+
| `system` | Health ping |
|
|
190
|
+
| `content` | Client content and contact-details retrieval (cached) |
|
|
191
|
+
| `log` | Structured application logging with batching |
|
|
192
|
+
| `events` | PubSub event bus for session and payment signals |
|
|
193
|
+
|
|
194
|
+
Example API calls:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
const banks = await client.lookups.getBanks()
|
|
198
|
+
const consumer = await client.consumers.getConsumer()
|
|
199
|
+
const merchant = await client.merchants.getMerchant()
|
|
200
|
+
const productTypes = await client.merchants.getActiveProductTypes()
|
|
201
|
+
const messages = await client.notifications.getMessages()
|
|
202
|
+
const recent = await client.reports.getRecentTransactions(10, true)
|
|
203
|
+
await client.system.ping()
|
|
314
204
|
```
|
|
315
205
|
|
|
316
|
-
|
|
317
|
-
Get a list of configured banks for the partner. The `isAvailable` flag can be used to disable items from selection, the text will also indicate if it is currently available. This can be used when setting up bank accounts for example by limiting the types to only what the partner supports. The `bankCode` is what can be passed into payment request packets for bank account sources or destinations.
|
|
318
|
-
```js
|
|
319
|
-
var banks = await VantagePayClient.lookups.getBanks()
|
|
320
|
-
```
|
|
206
|
+
---
|
|
321
207
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
var banks = await VantagePayClient.lookups.getBanks('GHA')
|
|
326
|
-
```
|
|
208
|
+
## Payments and Signals
|
|
209
|
+
|
|
210
|
+
### Basic payment submission
|
|
327
211
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
{
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
212
|
+
```ts
|
|
213
|
+
const status = await client.payments.pay({
|
|
214
|
+
yourReference: 'ORDER-1001',
|
|
215
|
+
paymentSources: {
|
|
216
|
+
mobileWallets: [{
|
|
217
|
+
mobileWalletOperator: 'MTN',
|
|
218
|
+
msisdn: '233555666112',
|
|
219
|
+
amountInCents: 5000,
|
|
220
|
+
currency: 'GHS',
|
|
221
|
+
}],
|
|
337
222
|
},
|
|
338
|
-
{
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
223
|
+
paymentDestinations: {
|
|
224
|
+
merchants: [{
|
|
225
|
+
merchantReference: 'merchant-reference',
|
|
226
|
+
amountInCents: 5000,
|
|
227
|
+
currency: 'GHS',
|
|
228
|
+
paymentType: 'BuyingGoods',
|
|
229
|
+
}],
|
|
344
230
|
},
|
|
345
|
-
|
|
346
|
-
isAvailable: false,
|
|
347
|
-
bank: 'FNB',
|
|
348
|
-
bankCode: 'FNB',
|
|
349
|
-
bankName: 'First National Bank Ghana (Currently Unavailable)',
|
|
350
|
-
country: 'GHA'
|
|
351
|
-
}
|
|
352
|
-
]
|
|
231
|
+
})
|
|
353
232
|
```
|
|
354
233
|
|
|
355
|
-
|
|
356
|
-
It is sometimes necessary to determine which country a card was issued in, you can use the card issuer country lookup with a card number to lookup the country.
|
|
357
|
-
```js
|
|
358
|
-
var country = await VantagePayClient.lookups.getCardIssuerCountry('5200000000000114')
|
|
359
|
-
```
|
|
234
|
+
### Subscribing to payment/session signals
|
|
360
235
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
236
|
+
```ts
|
|
237
|
+
import {
|
|
238
|
+
OnSessionStarted,
|
|
239
|
+
OnSessionExpired,
|
|
240
|
+
OnAutomaticRefresh,
|
|
241
|
+
OnApiRetry,
|
|
242
|
+
OnPaymentStatusUpdate,
|
|
243
|
+
OnPaymentComplete,
|
|
244
|
+
OnRequiresPin,
|
|
245
|
+
OnRequiresConfirmation,
|
|
246
|
+
OnRequires3DSecure,
|
|
247
|
+
OnComplete3DSecure,
|
|
248
|
+
OnRequiresAddress,
|
|
249
|
+
} from '@vantagepay/vantagepay'
|
|
365
250
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
isAvailable: true,
|
|
370
|
-
country: 'MYS',
|
|
371
|
-
countryName: 'Malaysia',
|
|
372
|
-
longIsoCode: 'MYS',
|
|
373
|
-
shortIsoCode: 'MY',
|
|
374
|
-
numericIsoCode: 458,
|
|
375
|
-
diallingCode: '60'
|
|
376
|
-
}
|
|
377
|
-
```
|
|
251
|
+
const sub1 = client.events.subscribe(OnPaymentStatusUpdate, (_, data) => {
|
|
252
|
+
console.log('status update', data)
|
|
253
|
+
})
|
|
378
254
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
These events can be useful if your application needs to react to certain things happening behind the scenes. It is especially useful when used to automatically receive payment status updates during payment processing.
|
|
384
|
-
```js
|
|
385
|
-
import { VantagePay, OnApiRetry, OnAutomaticRefresh, OnSessionStarted, OnSessionExpired } from '@vantagepay/vantagepay'
|
|
386
|
-
...
|
|
387
|
-
const onApiRetrySub = VantagePayClient.events.subscribe(OnApiRetry, (_, retryInfo) => console.log('API performed an automatic retry', retryInfo))
|
|
388
|
-
const onAutoRefreshSub = VantagePayClient.events.subscribe(OnAutomaticRefresh, (_, tokenResponse) => console.log('Automatic refresh was triggered', tokenResponse))
|
|
389
|
-
const onSessionStartedSub = VantagePayClient.events.subscribe(OnSessionStarted, () => console.log('Session started'))
|
|
390
|
-
const onSessionExpiredSub = VantagePayClient.events.subscribe(OnSessionExpired, () => console.log('Session expired'))
|
|
391
|
-
...
|
|
392
|
-
// Unsubscribe if you no longer want to receive events.
|
|
393
|
-
VantagePayClient.events.unsubscribe(onApiRetrySub)
|
|
394
|
-
VantagePayClient.events.unsubscribe(onAutoRefreshSub)
|
|
395
|
-
VantagePayClient.events.unsubscribe(onSessionStartedSub)
|
|
396
|
-
VantagePayClient.events.unsubscribe(onSessionExpiredSub)
|
|
397
|
-
```
|
|
255
|
+
const sub2 = client.events.subscribe(OnPaymentComplete, (_, data) => {
|
|
256
|
+
console.log('payment complete', data.paymentReference)
|
|
257
|
+
})
|
|
398
258
|
|
|
399
|
-
|
|
400
|
-
|
|
259
|
+
client.events.subscribe(OnRequiresPin, async (_, data) => {
|
|
260
|
+
await client.payments.submitPinCode(data.transactionReference, '1234')
|
|
261
|
+
})
|
|
401
262
|
|
|
402
|
-
|
|
403
|
-
|
|
263
|
+
client.events.subscribe(OnRequiresConfirmation, async (_, data) => {
|
|
264
|
+
await client.payments.submitConfirmation(data.transactionReference, true)
|
|
265
|
+
})
|
|
404
266
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
267
|
+
client.events.subscribe(OnRequiresAddress, async (_, data) => {
|
|
268
|
+
await client.payments.submitAddress(data.transactionReference, {
|
|
269
|
+
addressType: 'BILL',
|
|
270
|
+
addressLine1: '10 Main Road',
|
|
271
|
+
city: 'Johannesburg',
|
|
272
|
+
countryIsoCode: 'ZAF',
|
|
273
|
+
postalCode: '2196',
|
|
274
|
+
})
|
|
275
|
+
})
|
|
411
276
|
|
|
412
|
-
|
|
413
|
-
|
|
277
|
+
client.events.subscribe(OnRequires3DSecure, (_, data) => {
|
|
278
|
+
window.open(data.url)
|
|
279
|
+
})
|
|
414
280
|
|
|
415
|
-
|
|
281
|
+
client.events.subscribe(OnComplete3DSecure, () => {
|
|
282
|
+
console.log('3DS completed')
|
|
283
|
+
})
|
|
416
284
|
|
|
417
|
-
|
|
418
|
-
|
|
285
|
+
client.events.subscribe(OnSessionStarted, () => console.log('session started'))
|
|
286
|
+
client.events.subscribe(OnSessionExpired, () => console.log('session expired'))
|
|
287
|
+
client.events.subscribe(OnAutomaticRefresh, (_, token) => console.log('refreshed', token))
|
|
288
|
+
client.events.subscribe(OnApiRetry, (_, data) => console.log('retry', data.retryCount))
|
|
419
289
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
The data will include the URL to launch.
|
|
423
|
-
```js
|
|
424
|
-
{ url: 'https://some_url_that_will_start-3ds' }
|
|
290
|
+
client.events.unsubscribe(sub1)
|
|
291
|
+
client.events.unsubscribe(sub2)
|
|
425
292
|
```
|
|
426
293
|
|
|
427
|
-
###
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
294
|
+
### Manual status-check control
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
await client.payments.startPaymentStatusChecking() // external/incoming payment listener
|
|
298
|
+
await client.payments.stopPaymentStatusChecking('payment-ref') // one payment
|
|
299
|
+
await client.payments.stopPaymentStatusChecking() // all payments
|
|
433
300
|
```
|
|
434
301
|
|
|
435
|
-
|
|
436
|
-
This will fire once 3DS has completed as an indication that you can close the browser or iFrame that was launched when `OnRequires3DSecure` was fired. There is no additional data included in this event.
|
|
302
|
+
### Tokenization and notifications
|
|
437
303
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
304
|
+
```ts
|
|
305
|
+
const cardToken = await client.payments.createCardToken({
|
|
306
|
+
cardNumber: '5200000000000114',
|
|
307
|
+
nameOnCard: 'John Doe',
|
|
308
|
+
expiryMonth: 9,
|
|
309
|
+
expiryYear: 2028,
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
await client.payments.sendEmailPaymentNotification('payment-reference', 'user@example.com')
|
|
313
|
+
await client.payments.sendSmsPaymentNotification('payment-reference', '233548306110')
|
|
446
314
|
```
|
|
447
315
|
|
|
448
|
-
|
|
316
|
+
### Payment helpers
|
|
449
317
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
const pin = prompt(signalData.message)
|
|
455
|
-
VantagePayClient.payments.submitPinCode(signalData.transactionReference, pin)
|
|
456
|
-
}
|
|
318
|
+
```ts
|
|
319
|
+
client.payments.getRequiredPinLength('VDF') // 6
|
|
320
|
+
client.payments.getRequiredPinLength('MTN') // 4
|
|
321
|
+
client.payments.luhnCheck('5200000000000114') // true
|
|
457
322
|
```
|
|
458
323
|
|
|
459
|
-
|
|
460
|
-
This will be fired if a transaction requires confirmation such as additional fees or even to verify account information. The event data will include the message to display to the user so they are aware of what they are confirming. The dialog to display can just have Yes/No buttons.
|
|
461
|
-
```js
|
|
462
|
-
{
|
|
463
|
-
message: 'The transaction requires an additional e-levy fee of GHS 3.00. Do you want to continue?',
|
|
464
|
-
transactionReference: '6FD502DE-20FF-4110-ABBE-8FE6D7733AAE',
|
|
465
|
-
confirmationData: {
|
|
466
|
-
amountInCents: 1025,
|
|
467
|
-
sourceAccountHolder: 'Steve Rogers',
|
|
468
|
-
destinationAccountHolder: 'Tony Stark',
|
|
469
|
-
fees: []
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
```
|
|
324
|
+
---
|
|
473
325
|
|
|
474
|
-
|
|
326
|
+
## Server-side Admin Usage
|
|
475
327
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
328
|
+
This TypeScript package does not expose admin API-key modules.
|
|
329
|
+
|
|
330
|
+
For administrative workflows (for example user administration, KYC/KYB administration, template management, and admin payment/refund orchestration), use the .NET SDK `VantagePay.SDK` with `VantagePayAdminClient`.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Additional Modules
|
|
335
|
+
|
|
336
|
+
### QR utilities
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
const decoded = await client.qrCodes.decode('000201010211...')
|
|
340
|
+
const qrBase64 = await client.qrCodes.generate('https://example.com/pay', 500)
|
|
483
341
|
```
|
|
484
342
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
transactionReference: '6F4F250E-BF64-4BC2-936C-02E5A2982969'
|
|
491
|
-
}
|
|
343
|
+
### Content
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
const clientContent = await client.content.getClientContent()
|
|
347
|
+
const contactDetails = await client.content.getContactDetails()
|
|
492
348
|
```
|
|
493
349
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
### Pseudo Code
|
|
497
|
-
```js
|
|
498
|
-
function handleRequiresAddress(signalData) {
|
|
499
|
-
// Let the user know what is required.
|
|
500
|
-
alert(signalData.message)
|
|
501
|
-
|
|
502
|
-
// You need to capture a PIN code and call `submitPinCode`.
|
|
503
|
-
const address = {
|
|
504
|
-
addressType: prompt('Type: ') || 'BILL',
|
|
505
|
-
addressLine1: prompt('Line 1: ') || '10 Whitley Road',
|
|
506
|
-
addressLine2: prompt('Line 2: ') || null,
|
|
507
|
-
addressLine3: prompt('Line 3: ') || null,
|
|
508
|
-
countryIsoCode: prompt('Country: ') || 'ZAF',
|
|
509
|
-
city: prompt('City: ') || 'Johannesburg',
|
|
510
|
-
state: prompt('State: ') || null,
|
|
511
|
-
postalCode: prompt('Postal Code: ') || '2196',
|
|
512
|
-
}
|
|
350
|
+
### Structured logging
|
|
513
351
|
|
|
514
|
-
|
|
515
|
-
}
|
|
352
|
+
```ts
|
|
353
|
+
client.log.info('User {Username} logged in from {Country}', 'john', 'GHA')
|
|
354
|
+
client.log.warn('Payment {PaymentRef} is delayed', 'PAY-123')
|
|
355
|
+
await client.log.flush()
|
|
516
356
|
```
|