@paykit-sdk/monnify 1.3.0 → 1.3.2
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/dist/index.js +79 -41
- package/dist/index.mjs +80 -42
- package/dist/monnify-provider.d.mts +20 -1
- package/dist/monnify-provider.d.ts +20 -1
- package/dist/monnify-provider.js +79 -41
- package/dist/monnify-provider.mjs +80 -42
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -211,6 +211,48 @@ var MonnifyProvider = class extends core.AbstractPayKitProvider {
|
|
|
211
211
|
}
|
|
212
212
|
return altResponse.value.responseBody;
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Monnify only has one way to move money: a hosted redirect
|
|
216
|
+
* transaction. createCheckout and createPayment both boil down to
|
|
217
|
+
* this same call - only the input validation and the response
|
|
218
|
+
* mapper differ between the two.
|
|
219
|
+
*/
|
|
220
|
+
async initializeTransaction(params) {
|
|
221
|
+
const paymentReference = crypto.randomUUID();
|
|
222
|
+
const body = {
|
|
223
|
+
amount: params.amount,
|
|
224
|
+
paymentReference,
|
|
225
|
+
paymentDescription: params.description,
|
|
226
|
+
currencyCode: params.currency,
|
|
227
|
+
redirectUrl: params.redirectUrl,
|
|
228
|
+
paymentMethods: ["CARD", "ACCOUNT_TRANSFER"],
|
|
229
|
+
metadata: params.metadata,
|
|
230
|
+
customerEmail: params.email
|
|
231
|
+
};
|
|
232
|
+
const response = await this._client.post(
|
|
233
|
+
"/v1/merchant/transactions/init-transaction",
|
|
234
|
+
{
|
|
235
|
+
body: JSON.stringify(body),
|
|
236
|
+
headers: await this.tokenManager.getAuthHeaders()
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
const responseBody = this.ensureResponse(
|
|
240
|
+
response,
|
|
241
|
+
"initializeTransaction"
|
|
242
|
+
);
|
|
243
|
+
const transactionReference = responseBody.transactionReference;
|
|
244
|
+
const checkoutUrl = responseBody.checkoutUrl;
|
|
245
|
+
const transactionResponse = await this._client.get(
|
|
246
|
+
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
247
|
+
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
248
|
+
);
|
|
249
|
+
const transactionData = this.ensureResponse(
|
|
250
|
+
transactionResponse,
|
|
251
|
+
"initializeTransaction",
|
|
252
|
+
"Failed to retrieve transaction details"
|
|
253
|
+
);
|
|
254
|
+
return { ...transactionData, checkoutUrl, transactionReference };
|
|
255
|
+
}
|
|
214
256
|
createCheckout = async (params) => {
|
|
215
257
|
const data = this.validateSchema(
|
|
216
258
|
core.createCheckoutSchema,
|
|
@@ -233,50 +275,21 @@ var MonnifyProvider = class extends core.AbstractPayKitProvider {
|
|
|
233
275
|
data.provider_metadata ?? { currency: "NGN" },
|
|
234
276
|
"The following fields must be present in the provider_metadata of createCheckout: {keys}"
|
|
235
277
|
);
|
|
236
|
-
const
|
|
237
|
-
|
|
278
|
+
const transactionData = await this.initializeTransaction({
|
|
279
|
+
email: data.customer.email,
|
|
238
280
|
amount,
|
|
239
|
-
|
|
240
|
-
paymentDescription: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
241
|
-
currencyCode: currency,
|
|
281
|
+
currency,
|
|
242
282
|
redirectUrl: data.success_url,
|
|
243
|
-
|
|
283
|
+
description: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
244
284
|
metadata: {
|
|
245
285
|
...params.metadata,
|
|
246
286
|
[core.PAYKIT_METADATA_KEY]: JSON.stringify({
|
|
247
287
|
item: data.item_id,
|
|
248
288
|
qty: data.quantity
|
|
249
289
|
})
|
|
250
|
-
},
|
|
251
|
-
customerEmail: data.customer.email
|
|
252
|
-
};
|
|
253
|
-
const response = await this._client.post(
|
|
254
|
-
"/v1/merchant/transactions/init-transaction",
|
|
255
|
-
{
|
|
256
|
-
body: JSON.stringify(body),
|
|
257
|
-
headers: await this.tokenManager.getAuthHeaders()
|
|
258
290
|
}
|
|
259
|
-
);
|
|
260
|
-
const responseBody = this.ensureResponse(
|
|
261
|
-
response,
|
|
262
|
-
"createCheckout"
|
|
263
|
-
);
|
|
264
|
-
const transactionReference = responseBody.transactionReference;
|
|
265
|
-
const checkoutUrl = responseBody.checkoutUrl;
|
|
266
|
-
const checkoutResponse = await this._client.get(
|
|
267
|
-
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
268
|
-
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
269
|
-
);
|
|
270
|
-
const checkoutData = this.ensureResponse(
|
|
271
|
-
checkoutResponse,
|
|
272
|
-
"createCheckout",
|
|
273
|
-
"Failed to retrieve checkout details"
|
|
274
|
-
);
|
|
275
|
-
return Checkout$inboundSchema({
|
|
276
|
-
...checkoutData,
|
|
277
|
-
checkoutUrl,
|
|
278
|
-
transactionReference
|
|
279
291
|
});
|
|
292
|
+
return Checkout$inboundSchema(transactionData);
|
|
280
293
|
};
|
|
281
294
|
retrieveCheckout = async (id) => {
|
|
282
295
|
const transactionData = await this.queryTransaction(
|
|
@@ -395,14 +408,39 @@ var MonnifyProvider = class extends core.AbstractPayKitProvider {
|
|
|
395
408
|
);
|
|
396
409
|
};
|
|
397
410
|
createPayment = async (params) => {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
411
|
+
const data = this.validateSchema(
|
|
412
|
+
core.createPaymentSchema,
|
|
413
|
+
params,
|
|
414
|
+
"createPayment"
|
|
415
|
+
);
|
|
416
|
+
if (!core.isEmailCustomer(data.customer)) {
|
|
417
|
+
throw new core.InvalidTypeError(
|
|
418
|
+
"customer",
|
|
419
|
+
"object (customer) with email",
|
|
420
|
+
"string (customer ID)",
|
|
421
|
+
{
|
|
422
|
+
provider: this.providerName,
|
|
423
|
+
method: "createPayment"
|
|
424
|
+
}
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
const { success_url } = core.validateRequiredKeys(
|
|
428
|
+
["success_url"],
|
|
429
|
+
data.provider_metadata ?? {},
|
|
430
|
+
"The following fields must be present in the provider_metadata of createPayment: {keys}"
|
|
405
431
|
);
|
|
432
|
+
const transactionData = await this.initializeTransaction({
|
|
433
|
+
email: data.customer.email,
|
|
434
|
+
amount: data.amount.toString(),
|
|
435
|
+
currency: data.currency,
|
|
436
|
+
redirectUrl: success_url,
|
|
437
|
+
description: `Payment for ${data.item_id}`,
|
|
438
|
+
metadata: {
|
|
439
|
+
...data.metadata,
|
|
440
|
+
[core.PAYKIT_METADATA_KEY]: JSON.stringify({ item: data.item_id })
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
return Payment$inboundSchema(transactionData);
|
|
406
444
|
};
|
|
407
445
|
retrievePayment = async (id) => {
|
|
408
446
|
try {
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { schema, Schema, validateRequiredKeys, AbstractPayKitProvider, HTTPClient, OAuth2TokenManager, ValidationError, OperationFailedError, createCheckoutSchema, isEmailCustomer, InvalidTypeError, PAYKIT_METADATA_KEY, ProviderNotSupportedError, createRefundSchema, WebhookError, parseJSON, omitInternalMetadata } from '@paykit-sdk/core';
|
|
1
|
+
import { schema, Schema, validateRequiredKeys, AbstractPayKitProvider, HTTPClient, OAuth2TokenManager, ValidationError, OperationFailedError, createCheckoutSchema, isEmailCustomer, InvalidTypeError, PAYKIT_METADATA_KEY, ProviderNotSupportedError, createPaymentSchema, createRefundSchema, WebhookError, parseJSON, omitInternalMetadata } from '@paykit-sdk/core';
|
|
2
2
|
import { timingSafeEqual } from 'crypto';
|
|
3
3
|
import { sha512 } from 'js-sha512';
|
|
4
4
|
|
|
@@ -209,6 +209,48 @@ var MonnifyProvider = class extends AbstractPayKitProvider {
|
|
|
209
209
|
}
|
|
210
210
|
return altResponse.value.responseBody;
|
|
211
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Monnify only has one way to move money: a hosted redirect
|
|
214
|
+
* transaction. createCheckout and createPayment both boil down to
|
|
215
|
+
* this same call - only the input validation and the response
|
|
216
|
+
* mapper differ between the two.
|
|
217
|
+
*/
|
|
218
|
+
async initializeTransaction(params) {
|
|
219
|
+
const paymentReference = crypto.randomUUID();
|
|
220
|
+
const body = {
|
|
221
|
+
amount: params.amount,
|
|
222
|
+
paymentReference,
|
|
223
|
+
paymentDescription: params.description,
|
|
224
|
+
currencyCode: params.currency,
|
|
225
|
+
redirectUrl: params.redirectUrl,
|
|
226
|
+
paymentMethods: ["CARD", "ACCOUNT_TRANSFER"],
|
|
227
|
+
metadata: params.metadata,
|
|
228
|
+
customerEmail: params.email
|
|
229
|
+
};
|
|
230
|
+
const response = await this._client.post(
|
|
231
|
+
"/v1/merchant/transactions/init-transaction",
|
|
232
|
+
{
|
|
233
|
+
body: JSON.stringify(body),
|
|
234
|
+
headers: await this.tokenManager.getAuthHeaders()
|
|
235
|
+
}
|
|
236
|
+
);
|
|
237
|
+
const responseBody = this.ensureResponse(
|
|
238
|
+
response,
|
|
239
|
+
"initializeTransaction"
|
|
240
|
+
);
|
|
241
|
+
const transactionReference = responseBody.transactionReference;
|
|
242
|
+
const checkoutUrl = responseBody.checkoutUrl;
|
|
243
|
+
const transactionResponse = await this._client.get(
|
|
244
|
+
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
245
|
+
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
246
|
+
);
|
|
247
|
+
const transactionData = this.ensureResponse(
|
|
248
|
+
transactionResponse,
|
|
249
|
+
"initializeTransaction",
|
|
250
|
+
"Failed to retrieve transaction details"
|
|
251
|
+
);
|
|
252
|
+
return { ...transactionData, checkoutUrl, transactionReference };
|
|
253
|
+
}
|
|
212
254
|
createCheckout = async (params) => {
|
|
213
255
|
const data = this.validateSchema(
|
|
214
256
|
createCheckoutSchema,
|
|
@@ -231,50 +273,21 @@ var MonnifyProvider = class extends AbstractPayKitProvider {
|
|
|
231
273
|
data.provider_metadata ?? { currency: "NGN" },
|
|
232
274
|
"The following fields must be present in the provider_metadata of createCheckout: {keys}"
|
|
233
275
|
);
|
|
234
|
-
const
|
|
235
|
-
|
|
276
|
+
const transactionData = await this.initializeTransaction({
|
|
277
|
+
email: data.customer.email,
|
|
236
278
|
amount,
|
|
237
|
-
|
|
238
|
-
paymentDescription: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
239
|
-
currencyCode: currency,
|
|
279
|
+
currency,
|
|
240
280
|
redirectUrl: data.success_url,
|
|
241
|
-
|
|
281
|
+
description: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
242
282
|
metadata: {
|
|
243
283
|
...params.metadata,
|
|
244
284
|
[PAYKIT_METADATA_KEY]: JSON.stringify({
|
|
245
285
|
item: data.item_id,
|
|
246
286
|
qty: data.quantity
|
|
247
287
|
})
|
|
248
|
-
},
|
|
249
|
-
customerEmail: data.customer.email
|
|
250
|
-
};
|
|
251
|
-
const response = await this._client.post(
|
|
252
|
-
"/v1/merchant/transactions/init-transaction",
|
|
253
|
-
{
|
|
254
|
-
body: JSON.stringify(body),
|
|
255
|
-
headers: await this.tokenManager.getAuthHeaders()
|
|
256
288
|
}
|
|
257
|
-
);
|
|
258
|
-
const responseBody = this.ensureResponse(
|
|
259
|
-
response,
|
|
260
|
-
"createCheckout"
|
|
261
|
-
);
|
|
262
|
-
const transactionReference = responseBody.transactionReference;
|
|
263
|
-
const checkoutUrl = responseBody.checkoutUrl;
|
|
264
|
-
const checkoutResponse = await this._client.get(
|
|
265
|
-
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
266
|
-
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
267
|
-
);
|
|
268
|
-
const checkoutData = this.ensureResponse(
|
|
269
|
-
checkoutResponse,
|
|
270
|
-
"createCheckout",
|
|
271
|
-
"Failed to retrieve checkout details"
|
|
272
|
-
);
|
|
273
|
-
return Checkout$inboundSchema({
|
|
274
|
-
...checkoutData,
|
|
275
|
-
checkoutUrl,
|
|
276
|
-
transactionReference
|
|
277
289
|
});
|
|
290
|
+
return Checkout$inboundSchema(transactionData);
|
|
278
291
|
};
|
|
279
292
|
retrieveCheckout = async (id) => {
|
|
280
293
|
const transactionData = await this.queryTransaction(
|
|
@@ -393,14 +406,39 @@ var MonnifyProvider = class extends AbstractPayKitProvider {
|
|
|
393
406
|
);
|
|
394
407
|
};
|
|
395
408
|
createPayment = async (params) => {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
409
|
+
const data = this.validateSchema(
|
|
410
|
+
createPaymentSchema,
|
|
411
|
+
params,
|
|
412
|
+
"createPayment"
|
|
413
|
+
);
|
|
414
|
+
if (!isEmailCustomer(data.customer)) {
|
|
415
|
+
throw new InvalidTypeError(
|
|
416
|
+
"customer",
|
|
417
|
+
"object (customer) with email",
|
|
418
|
+
"string (customer ID)",
|
|
419
|
+
{
|
|
420
|
+
provider: this.providerName,
|
|
421
|
+
method: "createPayment"
|
|
422
|
+
}
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
const { success_url } = validateRequiredKeys(
|
|
426
|
+
["success_url"],
|
|
427
|
+
data.provider_metadata ?? {},
|
|
428
|
+
"The following fields must be present in the provider_metadata of createPayment: {keys}"
|
|
403
429
|
);
|
|
430
|
+
const transactionData = await this.initializeTransaction({
|
|
431
|
+
email: data.customer.email,
|
|
432
|
+
amount: data.amount.toString(),
|
|
433
|
+
currency: data.currency,
|
|
434
|
+
redirectUrl: success_url,
|
|
435
|
+
description: `Payment for ${data.item_id}`,
|
|
436
|
+
metadata: {
|
|
437
|
+
...data.metadata,
|
|
438
|
+
[PAYKIT_METADATA_KEY]: JSON.stringify({ item: data.item_id })
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
return Payment$inboundSchema(transactionData);
|
|
404
442
|
};
|
|
405
443
|
retrievePayment = async (id) => {
|
|
406
444
|
try {
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { PaykitProviderOptions, AbstractPayKitProvider, PayKitProvider, ProviderMetadataRegistry, CreateCheckoutSchema, Checkout, UpdateCheckoutSchema, CreateCustomerParams, Customer, UpdateCustomerParams, CreateSubscriptionSchema, Subscription, UpdateSubscriptionSchema, CreatePaymentSchema, Payment, UpdatePaymentSchema, CapturePaymentSchema, CreateRefundSchema, Refund, WebhookHandlerConfig, WebhookEventPayload } from '@paykit-sdk/core';
|
|
2
2
|
|
|
3
3
|
interface MonnifyMetadata extends ProviderMetadataRegistry {
|
|
4
|
+
checkout?: {
|
|
5
|
+
amount?: string;
|
|
6
|
+
currency?: string;
|
|
7
|
+
};
|
|
8
|
+
payment?: {
|
|
9
|
+
/**
|
|
10
|
+
* Monnify only supports hosted/redirect transactions - a
|
|
11
|
+
* direct createPayment call still needs somewhere to send the
|
|
12
|
+
* customer, same as createCheckout's success_url.
|
|
13
|
+
*/
|
|
14
|
+
success_url?: string;
|
|
15
|
+
};
|
|
4
16
|
}
|
|
5
17
|
interface MonnifyRawEvents extends Record<string, any> {
|
|
6
18
|
}
|
|
@@ -39,6 +51,13 @@ declare class MonnifyProvider extends AbstractPayKitProvider implements PayKitPr
|
|
|
39
51
|
* Queries transaction by transactionReference or paymentReference (with fallback)
|
|
40
52
|
*/
|
|
41
53
|
private queryTransaction;
|
|
54
|
+
/**
|
|
55
|
+
* Monnify only has one way to move money: a hosted redirect
|
|
56
|
+
* transaction. createCheckout and createPayment both boil down to
|
|
57
|
+
* this same call - only the input validation and the response
|
|
58
|
+
* mapper differ between the two.
|
|
59
|
+
*/
|
|
60
|
+
private initializeTransaction;
|
|
42
61
|
createCheckout: (params: CreateCheckoutSchema) => Promise<Checkout>;
|
|
43
62
|
retrieveCheckout: (id: string) => Promise<Checkout>;
|
|
44
63
|
updateCheckout: (id: string, params: UpdateCheckoutSchema) => Promise<Checkout>;
|
|
@@ -52,7 +71,7 @@ declare class MonnifyProvider extends AbstractPayKitProvider implements PayKitPr
|
|
|
52
71
|
cancelSubscription: (id: string) => Promise<Subscription>;
|
|
53
72
|
deleteSubscription: (id: string) => Promise<null>;
|
|
54
73
|
retrieveSubscription: (id: string) => Promise<Subscription | null>;
|
|
55
|
-
createPayment: (params: CreatePaymentSchema) => Promise<Payment>;
|
|
74
|
+
createPayment: (params: CreatePaymentSchema<MonnifyMetadata["payment"]>) => Promise<Payment>;
|
|
56
75
|
retrievePayment: (id: string) => Promise<Payment | null>;
|
|
57
76
|
updatePayment: (id: string, params: UpdatePaymentSchema) => Promise<Payment>;
|
|
58
77
|
deletePayment: (id: string) => Promise<null>;
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { PaykitProviderOptions, AbstractPayKitProvider, PayKitProvider, ProviderMetadataRegistry, CreateCheckoutSchema, Checkout, UpdateCheckoutSchema, CreateCustomerParams, Customer, UpdateCustomerParams, CreateSubscriptionSchema, Subscription, UpdateSubscriptionSchema, CreatePaymentSchema, Payment, UpdatePaymentSchema, CapturePaymentSchema, CreateRefundSchema, Refund, WebhookHandlerConfig, WebhookEventPayload } from '@paykit-sdk/core';
|
|
2
2
|
|
|
3
3
|
interface MonnifyMetadata extends ProviderMetadataRegistry {
|
|
4
|
+
checkout?: {
|
|
5
|
+
amount?: string;
|
|
6
|
+
currency?: string;
|
|
7
|
+
};
|
|
8
|
+
payment?: {
|
|
9
|
+
/**
|
|
10
|
+
* Monnify only supports hosted/redirect transactions - a
|
|
11
|
+
* direct createPayment call still needs somewhere to send the
|
|
12
|
+
* customer, same as createCheckout's success_url.
|
|
13
|
+
*/
|
|
14
|
+
success_url?: string;
|
|
15
|
+
};
|
|
4
16
|
}
|
|
5
17
|
interface MonnifyRawEvents extends Record<string, any> {
|
|
6
18
|
}
|
|
@@ -39,6 +51,13 @@ declare class MonnifyProvider extends AbstractPayKitProvider implements PayKitPr
|
|
|
39
51
|
* Queries transaction by transactionReference or paymentReference (with fallback)
|
|
40
52
|
*/
|
|
41
53
|
private queryTransaction;
|
|
54
|
+
/**
|
|
55
|
+
* Monnify only has one way to move money: a hosted redirect
|
|
56
|
+
* transaction. createCheckout and createPayment both boil down to
|
|
57
|
+
* this same call - only the input validation and the response
|
|
58
|
+
* mapper differ between the two.
|
|
59
|
+
*/
|
|
60
|
+
private initializeTransaction;
|
|
42
61
|
createCheckout: (params: CreateCheckoutSchema) => Promise<Checkout>;
|
|
43
62
|
retrieveCheckout: (id: string) => Promise<Checkout>;
|
|
44
63
|
updateCheckout: (id: string, params: UpdateCheckoutSchema) => Promise<Checkout>;
|
|
@@ -52,7 +71,7 @@ declare class MonnifyProvider extends AbstractPayKitProvider implements PayKitPr
|
|
|
52
71
|
cancelSubscription: (id: string) => Promise<Subscription>;
|
|
53
72
|
deleteSubscription: (id: string) => Promise<null>;
|
|
54
73
|
retrieveSubscription: (id: string) => Promise<Subscription | null>;
|
|
55
|
-
createPayment: (params: CreatePaymentSchema) => Promise<Payment>;
|
|
74
|
+
createPayment: (params: CreatePaymentSchema<MonnifyMetadata["payment"]>) => Promise<Payment>;
|
|
56
75
|
retrievePayment: (id: string) => Promise<Payment | null>;
|
|
57
76
|
updatePayment: (id: string, params: UpdatePaymentSchema) => Promise<Payment>;
|
|
58
77
|
deletePayment: (id: string) => Promise<null>;
|
package/dist/monnify-provider.js
CHANGED
|
@@ -211,6 +211,48 @@ var MonnifyProvider = class extends core.AbstractPayKitProvider {
|
|
|
211
211
|
}
|
|
212
212
|
return altResponse.value.responseBody;
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Monnify only has one way to move money: a hosted redirect
|
|
216
|
+
* transaction. createCheckout and createPayment both boil down to
|
|
217
|
+
* this same call - only the input validation and the response
|
|
218
|
+
* mapper differ between the two.
|
|
219
|
+
*/
|
|
220
|
+
async initializeTransaction(params) {
|
|
221
|
+
const paymentReference = crypto.randomUUID();
|
|
222
|
+
const body = {
|
|
223
|
+
amount: params.amount,
|
|
224
|
+
paymentReference,
|
|
225
|
+
paymentDescription: params.description,
|
|
226
|
+
currencyCode: params.currency,
|
|
227
|
+
redirectUrl: params.redirectUrl,
|
|
228
|
+
paymentMethods: ["CARD", "ACCOUNT_TRANSFER"],
|
|
229
|
+
metadata: params.metadata,
|
|
230
|
+
customerEmail: params.email
|
|
231
|
+
};
|
|
232
|
+
const response = await this._client.post(
|
|
233
|
+
"/v1/merchant/transactions/init-transaction",
|
|
234
|
+
{
|
|
235
|
+
body: JSON.stringify(body),
|
|
236
|
+
headers: await this.tokenManager.getAuthHeaders()
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
const responseBody = this.ensureResponse(
|
|
240
|
+
response,
|
|
241
|
+
"initializeTransaction"
|
|
242
|
+
);
|
|
243
|
+
const transactionReference = responseBody.transactionReference;
|
|
244
|
+
const checkoutUrl = responseBody.checkoutUrl;
|
|
245
|
+
const transactionResponse = await this._client.get(
|
|
246
|
+
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
247
|
+
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
248
|
+
);
|
|
249
|
+
const transactionData = this.ensureResponse(
|
|
250
|
+
transactionResponse,
|
|
251
|
+
"initializeTransaction",
|
|
252
|
+
"Failed to retrieve transaction details"
|
|
253
|
+
);
|
|
254
|
+
return { ...transactionData, checkoutUrl, transactionReference };
|
|
255
|
+
}
|
|
214
256
|
createCheckout = async (params) => {
|
|
215
257
|
const data = this.validateSchema(
|
|
216
258
|
core.createCheckoutSchema,
|
|
@@ -233,50 +275,21 @@ var MonnifyProvider = class extends core.AbstractPayKitProvider {
|
|
|
233
275
|
data.provider_metadata ?? { currency: "NGN" },
|
|
234
276
|
"The following fields must be present in the provider_metadata of createCheckout: {keys}"
|
|
235
277
|
);
|
|
236
|
-
const
|
|
237
|
-
|
|
278
|
+
const transactionData = await this.initializeTransaction({
|
|
279
|
+
email: data.customer.email,
|
|
238
280
|
amount,
|
|
239
|
-
|
|
240
|
-
paymentDescription: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
241
|
-
currencyCode: currency,
|
|
281
|
+
currency,
|
|
242
282
|
redirectUrl: data.success_url,
|
|
243
|
-
|
|
283
|
+
description: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
244
284
|
metadata: {
|
|
245
285
|
...params.metadata,
|
|
246
286
|
[core.PAYKIT_METADATA_KEY]: JSON.stringify({
|
|
247
287
|
item: data.item_id,
|
|
248
288
|
qty: data.quantity
|
|
249
289
|
})
|
|
250
|
-
},
|
|
251
|
-
customerEmail: data.customer.email
|
|
252
|
-
};
|
|
253
|
-
const response = await this._client.post(
|
|
254
|
-
"/v1/merchant/transactions/init-transaction",
|
|
255
|
-
{
|
|
256
|
-
body: JSON.stringify(body),
|
|
257
|
-
headers: await this.tokenManager.getAuthHeaders()
|
|
258
290
|
}
|
|
259
|
-
);
|
|
260
|
-
const responseBody = this.ensureResponse(
|
|
261
|
-
response,
|
|
262
|
-
"createCheckout"
|
|
263
|
-
);
|
|
264
|
-
const transactionReference = responseBody.transactionReference;
|
|
265
|
-
const checkoutUrl = responseBody.checkoutUrl;
|
|
266
|
-
const checkoutResponse = await this._client.get(
|
|
267
|
-
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
268
|
-
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
269
|
-
);
|
|
270
|
-
const checkoutData = this.ensureResponse(
|
|
271
|
-
checkoutResponse,
|
|
272
|
-
"createCheckout",
|
|
273
|
-
"Failed to retrieve checkout details"
|
|
274
|
-
);
|
|
275
|
-
return Checkout$inboundSchema({
|
|
276
|
-
...checkoutData,
|
|
277
|
-
checkoutUrl,
|
|
278
|
-
transactionReference
|
|
279
291
|
});
|
|
292
|
+
return Checkout$inboundSchema(transactionData);
|
|
280
293
|
};
|
|
281
294
|
retrieveCheckout = async (id) => {
|
|
282
295
|
const transactionData = await this.queryTransaction(
|
|
@@ -395,14 +408,39 @@ var MonnifyProvider = class extends core.AbstractPayKitProvider {
|
|
|
395
408
|
);
|
|
396
409
|
};
|
|
397
410
|
createPayment = async (params) => {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
411
|
+
const data = this.validateSchema(
|
|
412
|
+
core.createPaymentSchema,
|
|
413
|
+
params,
|
|
414
|
+
"createPayment"
|
|
415
|
+
);
|
|
416
|
+
if (!core.isEmailCustomer(data.customer)) {
|
|
417
|
+
throw new core.InvalidTypeError(
|
|
418
|
+
"customer",
|
|
419
|
+
"object (customer) with email",
|
|
420
|
+
"string (customer ID)",
|
|
421
|
+
{
|
|
422
|
+
provider: this.providerName,
|
|
423
|
+
method: "createPayment"
|
|
424
|
+
}
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
const { success_url } = core.validateRequiredKeys(
|
|
428
|
+
["success_url"],
|
|
429
|
+
data.provider_metadata ?? {},
|
|
430
|
+
"The following fields must be present in the provider_metadata of createPayment: {keys}"
|
|
405
431
|
);
|
|
432
|
+
const transactionData = await this.initializeTransaction({
|
|
433
|
+
email: data.customer.email,
|
|
434
|
+
amount: data.amount.toString(),
|
|
435
|
+
currency: data.currency,
|
|
436
|
+
redirectUrl: success_url,
|
|
437
|
+
description: `Payment for ${data.item_id}`,
|
|
438
|
+
metadata: {
|
|
439
|
+
...data.metadata,
|
|
440
|
+
[core.PAYKIT_METADATA_KEY]: JSON.stringify({ item: data.item_id })
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
return Payment$inboundSchema(transactionData);
|
|
406
444
|
};
|
|
407
445
|
retrievePayment = async (id) => {
|
|
408
446
|
try {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { schema, Schema, AbstractPayKitProvider, HTTPClient, OAuth2TokenManager, ValidationError, OperationFailedError, createCheckoutSchema, isEmailCustomer, InvalidTypeError, validateRequiredKeys, PAYKIT_METADATA_KEY, ProviderNotSupportedError, createRefundSchema, WebhookError, parseJSON, omitInternalMetadata } from '@paykit-sdk/core';
|
|
1
|
+
import { schema, Schema, AbstractPayKitProvider, HTTPClient, OAuth2TokenManager, ValidationError, OperationFailedError, createCheckoutSchema, isEmailCustomer, InvalidTypeError, validateRequiredKeys, PAYKIT_METADATA_KEY, ProviderNotSupportedError, createPaymentSchema, createRefundSchema, WebhookError, parseJSON, omitInternalMetadata } from '@paykit-sdk/core';
|
|
2
2
|
import { timingSafeEqual } from 'crypto';
|
|
3
3
|
import { sha512 } from 'js-sha512';
|
|
4
4
|
|
|
@@ -209,6 +209,48 @@ var MonnifyProvider = class extends AbstractPayKitProvider {
|
|
|
209
209
|
}
|
|
210
210
|
return altResponse.value.responseBody;
|
|
211
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Monnify only has one way to move money: a hosted redirect
|
|
214
|
+
* transaction. createCheckout and createPayment both boil down to
|
|
215
|
+
* this same call - only the input validation and the response
|
|
216
|
+
* mapper differ between the two.
|
|
217
|
+
*/
|
|
218
|
+
async initializeTransaction(params) {
|
|
219
|
+
const paymentReference = crypto.randomUUID();
|
|
220
|
+
const body = {
|
|
221
|
+
amount: params.amount,
|
|
222
|
+
paymentReference,
|
|
223
|
+
paymentDescription: params.description,
|
|
224
|
+
currencyCode: params.currency,
|
|
225
|
+
redirectUrl: params.redirectUrl,
|
|
226
|
+
paymentMethods: ["CARD", "ACCOUNT_TRANSFER"],
|
|
227
|
+
metadata: params.metadata,
|
|
228
|
+
customerEmail: params.email
|
|
229
|
+
};
|
|
230
|
+
const response = await this._client.post(
|
|
231
|
+
"/v1/merchant/transactions/init-transaction",
|
|
232
|
+
{
|
|
233
|
+
body: JSON.stringify(body),
|
|
234
|
+
headers: await this.tokenManager.getAuthHeaders()
|
|
235
|
+
}
|
|
236
|
+
);
|
|
237
|
+
const responseBody = this.ensureResponse(
|
|
238
|
+
response,
|
|
239
|
+
"initializeTransaction"
|
|
240
|
+
);
|
|
241
|
+
const transactionReference = responseBody.transactionReference;
|
|
242
|
+
const checkoutUrl = responseBody.checkoutUrl;
|
|
243
|
+
const transactionResponse = await this._client.get(
|
|
244
|
+
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
245
|
+
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
246
|
+
);
|
|
247
|
+
const transactionData = this.ensureResponse(
|
|
248
|
+
transactionResponse,
|
|
249
|
+
"initializeTransaction",
|
|
250
|
+
"Failed to retrieve transaction details"
|
|
251
|
+
);
|
|
252
|
+
return { ...transactionData, checkoutUrl, transactionReference };
|
|
253
|
+
}
|
|
212
254
|
createCheckout = async (params) => {
|
|
213
255
|
const data = this.validateSchema(
|
|
214
256
|
createCheckoutSchema,
|
|
@@ -231,50 +273,21 @@ var MonnifyProvider = class extends AbstractPayKitProvider {
|
|
|
231
273
|
data.provider_metadata ?? { currency: "NGN" },
|
|
232
274
|
"The following fields must be present in the provider_metadata of createCheckout: {keys}"
|
|
233
275
|
);
|
|
234
|
-
const
|
|
235
|
-
|
|
276
|
+
const transactionData = await this.initializeTransaction({
|
|
277
|
+
email: data.customer.email,
|
|
236
278
|
amount,
|
|
237
|
-
|
|
238
|
-
paymentDescription: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
239
|
-
currencyCode: currency,
|
|
279
|
+
currency,
|
|
240
280
|
redirectUrl: data.success_url,
|
|
241
|
-
|
|
281
|
+
description: `Checkout for ${data.item_id} x ${data.quantity} item${data.quantity > 1 ? "s" : ""}`,
|
|
242
282
|
metadata: {
|
|
243
283
|
...params.metadata,
|
|
244
284
|
[PAYKIT_METADATA_KEY]: JSON.stringify({
|
|
245
285
|
item: data.item_id,
|
|
246
286
|
qty: data.quantity
|
|
247
287
|
})
|
|
248
|
-
},
|
|
249
|
-
customerEmail: data.customer.email
|
|
250
|
-
};
|
|
251
|
-
const response = await this._client.post(
|
|
252
|
-
"/v1/merchant/transactions/init-transaction",
|
|
253
|
-
{
|
|
254
|
-
body: JSON.stringify(body),
|
|
255
|
-
headers: await this.tokenManager.getAuthHeaders()
|
|
256
288
|
}
|
|
257
|
-
);
|
|
258
|
-
const responseBody = this.ensureResponse(
|
|
259
|
-
response,
|
|
260
|
-
"createCheckout"
|
|
261
|
-
);
|
|
262
|
-
const transactionReference = responseBody.transactionReference;
|
|
263
|
-
const checkoutUrl = responseBody.checkoutUrl;
|
|
264
|
-
const checkoutResponse = await this._client.get(
|
|
265
|
-
`/v2/merchant/transactions/query?paymentReference=${paymentReference}`,
|
|
266
|
-
{ headers: await this.tokenManager.getAuthHeaders() }
|
|
267
|
-
);
|
|
268
|
-
const checkoutData = this.ensureResponse(
|
|
269
|
-
checkoutResponse,
|
|
270
|
-
"createCheckout",
|
|
271
|
-
"Failed to retrieve checkout details"
|
|
272
|
-
);
|
|
273
|
-
return Checkout$inboundSchema({
|
|
274
|
-
...checkoutData,
|
|
275
|
-
checkoutUrl,
|
|
276
|
-
transactionReference
|
|
277
289
|
});
|
|
290
|
+
return Checkout$inboundSchema(transactionData);
|
|
278
291
|
};
|
|
279
292
|
retrieveCheckout = async (id) => {
|
|
280
293
|
const transactionData = await this.queryTransaction(
|
|
@@ -393,14 +406,39 @@ var MonnifyProvider = class extends AbstractPayKitProvider {
|
|
|
393
406
|
);
|
|
394
407
|
};
|
|
395
408
|
createPayment = async (params) => {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
409
|
+
const data = this.validateSchema(
|
|
410
|
+
createPaymentSchema,
|
|
411
|
+
params,
|
|
412
|
+
"createPayment"
|
|
413
|
+
);
|
|
414
|
+
if (!isEmailCustomer(data.customer)) {
|
|
415
|
+
throw new InvalidTypeError(
|
|
416
|
+
"customer",
|
|
417
|
+
"object (customer) with email",
|
|
418
|
+
"string (customer ID)",
|
|
419
|
+
{
|
|
420
|
+
provider: this.providerName,
|
|
421
|
+
method: "createPayment"
|
|
422
|
+
}
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
const { success_url } = validateRequiredKeys(
|
|
426
|
+
["success_url"],
|
|
427
|
+
data.provider_metadata ?? {},
|
|
428
|
+
"The following fields must be present in the provider_metadata of createPayment: {keys}"
|
|
403
429
|
);
|
|
430
|
+
const transactionData = await this.initializeTransaction({
|
|
431
|
+
email: data.customer.email,
|
|
432
|
+
amount: data.amount.toString(),
|
|
433
|
+
currency: data.currency,
|
|
434
|
+
redirectUrl: success_url,
|
|
435
|
+
description: `Payment for ${data.item_id}`,
|
|
436
|
+
metadata: {
|
|
437
|
+
...data.metadata,
|
|
438
|
+
[PAYKIT_METADATA_KEY]: JSON.stringify({ item: data.item_id })
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
return Payment$inboundSchema(transactionData);
|
|
404
442
|
};
|
|
405
443
|
retrievePayment = async (id) => {
|
|
406
444
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paykit-sdk/monnify",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Moniepoint provider for PayKit",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"tsup": "^8.5.0",
|
|
29
29
|
"typescript": "^5.9.2",
|
|
30
|
-
"@paykit-sdk/core": "1.3.
|
|
30
|
+
"@paykit-sdk/core": "1.3.2"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"js-sha512": "^0.9.0"
|