@inkress/admin-sdk 1.1.42 → 1.1.44
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/README.md +244 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +404 -7
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +404 -6
- package/dist/index.js.map +1 -1
- package/dist/resources/kyc.d.ts +107 -0
- package/dist/resources/kyc.d.ts.map +1 -1
- package/dist/resources/public.d.ts +1 -1
- package/dist/resources/public.d.ts.map +1 -1
- package/dist/resources/webhook-urls.d.ts +85 -1
- package/dist/resources/webhook-urls.d.ts.map +1 -1
- package/dist/types/resources.d.ts +15 -17
- package/dist/types/resources.d.ts.map +1 -1
- package/dist/types.d.ts +25 -22
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1913,7 +1913,7 @@ const ORDER_FIELD_TYPES = {
|
|
|
1913
1913
|
status_on: 'number',
|
|
1914
1914
|
uid: 'string',
|
|
1915
1915
|
cart_id: 'number',
|
|
1916
|
-
|
|
1916
|
+
currency_code: 'string',
|
|
1917
1917
|
customer_id: 'number',
|
|
1918
1918
|
payment_link_id: 'number',
|
|
1919
1919
|
billing_plan_id: 'number',
|
|
@@ -1941,7 +1941,7 @@ const PRODUCT_FIELD_TYPES = {
|
|
|
1941
1941
|
tag_ids: 'array',
|
|
1942
1942
|
uid: 'string',
|
|
1943
1943
|
category_id: 'number',
|
|
1944
|
-
|
|
1944
|
+
currency_code: 'string',
|
|
1945
1945
|
user_id: 'number',
|
|
1946
1946
|
inserted_at: 'date',
|
|
1947
1947
|
updated_at: 'date',
|
|
@@ -2033,7 +2033,7 @@ const BILLING_PLAN_FIELD_TYPES = {
|
|
|
2033
2033
|
payout_value_limit: 'number',
|
|
2034
2034
|
payout_percentage_limit: 'number',
|
|
2035
2035
|
uid: 'string',
|
|
2036
|
-
|
|
2036
|
+
currency_code: 'string',
|
|
2037
2037
|
payment_provider_id: 'number',
|
|
2038
2038
|
inserted_at: 'date',
|
|
2039
2039
|
updated_at: 'date',
|
|
@@ -2074,7 +2074,7 @@ const PAYMENT_LINK_FIELD_TYPES = {
|
|
|
2074
2074
|
status: 'number',
|
|
2075
2075
|
kind: 'number',
|
|
2076
2076
|
customer_id: 'number',
|
|
2077
|
-
|
|
2077
|
+
currency_code: 'string',
|
|
2078
2078
|
order_id: 'number',
|
|
2079
2079
|
inserted_at: 'date',
|
|
2080
2080
|
updated_at: 'date',
|
|
@@ -2118,7 +2118,7 @@ const FINANCIAL_REQUEST_FIELD_TYPES = {
|
|
|
2118
2118
|
merchant_id: 'number',
|
|
2119
2119
|
requester_id: 'number',
|
|
2120
2120
|
reviewer_id: 'number',
|
|
2121
|
-
|
|
2121
|
+
currency_code: 'string',
|
|
2122
2122
|
evidence_file_id: 'number',
|
|
2123
2123
|
inserted_at: 'date',
|
|
2124
2124
|
updated_at: 'date',
|
|
@@ -2212,7 +2212,6 @@ const FEE_FIELD_TYPES = {
|
|
|
2212
2212
|
currency_code: 'string',
|
|
2213
2213
|
hash: 'string',
|
|
2214
2214
|
fee_set_id: 'number',
|
|
2215
|
-
currency_id: 'number',
|
|
2216
2215
|
user_id: 'number',
|
|
2217
2216
|
inserted_at: 'date',
|
|
2218
2217
|
updated_at: 'date',
|
|
@@ -3470,6 +3469,62 @@ class PublicResource {
|
|
|
3470
3469
|
}
|
|
3471
3470
|
}
|
|
3472
3471
|
|
|
3472
|
+
/**
|
|
3473
|
+
* KYC document requirements by entity type
|
|
3474
|
+
* These are the standard documents required for each type of business entity
|
|
3475
|
+
*/
|
|
3476
|
+
const KYC_DOCUMENT_REQUIREMENTS = {
|
|
3477
|
+
personal: [
|
|
3478
|
+
'Proof of Identity',
|
|
3479
|
+
'Proof of Address',
|
|
3480
|
+
'Proof of Bank Account Ownership',
|
|
3481
|
+
],
|
|
3482
|
+
'sole-trader': [
|
|
3483
|
+
'Proof of Identity',
|
|
3484
|
+
'Proof of Address',
|
|
3485
|
+
'Proof of Bank Account Ownership',
|
|
3486
|
+
'Business Certificate',
|
|
3487
|
+
'Articles of Incorporation',
|
|
3488
|
+
],
|
|
3489
|
+
llc: [
|
|
3490
|
+
'Proof of Identity',
|
|
3491
|
+
'Proof of Address',
|
|
3492
|
+
'Proof of Bank Account Ownership',
|
|
3493
|
+
'Business Certificate',
|
|
3494
|
+
'Articles of Incorporation',
|
|
3495
|
+
'Annual Return',
|
|
3496
|
+
'Notice of Directors',
|
|
3497
|
+
'Notice of Secretary',
|
|
3498
|
+
'Tax Compliance Certificate',
|
|
3499
|
+
],
|
|
3500
|
+
'non-profit': [
|
|
3501
|
+
'Proof of Identity',
|
|
3502
|
+
'Proof of Address',
|
|
3503
|
+
'Proof of Bank Account Ownership',
|
|
3504
|
+
'Business Certificate',
|
|
3505
|
+
'Articles of Incorporation',
|
|
3506
|
+
'Annual Return',
|
|
3507
|
+
],
|
|
3508
|
+
alumni: [
|
|
3509
|
+
'Proof of Identity',
|
|
3510
|
+
'Proof of Address',
|
|
3511
|
+
'Proof of Bank Account Ownership',
|
|
3512
|
+
'Business Certificate',
|
|
3513
|
+
'Articles of Incorporation',
|
|
3514
|
+
'Annual Return',
|
|
3515
|
+
],
|
|
3516
|
+
other: [
|
|
3517
|
+
'Proof of Identity',
|
|
3518
|
+
'Proof of Address',
|
|
3519
|
+
'Proof of Bank Account Ownership',
|
|
3520
|
+
'Business Certificate',
|
|
3521
|
+
'Articles of Incorporation',
|
|
3522
|
+
'Annual Return',
|
|
3523
|
+
'Notice of Directors',
|
|
3524
|
+
'Notice of Secretary',
|
|
3525
|
+
'Tax Compliance Certificate',
|
|
3526
|
+
],
|
|
3527
|
+
};
|
|
3473
3528
|
// Field type definitions for query validation
|
|
3474
3529
|
const KYC_FIELD_TYPES = {
|
|
3475
3530
|
id: 'number',
|
|
@@ -3550,6 +3605,185 @@ class KycResource {
|
|
|
3550
3605
|
async updateBankInfo(data) {
|
|
3551
3606
|
return this.client.post('/legal_requests', data);
|
|
3552
3607
|
}
|
|
3608
|
+
// ============================================================================
|
|
3609
|
+
// KYC DOCUMENT REQUIREMENTS & STATUS
|
|
3610
|
+
// ============================================================================
|
|
3611
|
+
/**
|
|
3612
|
+
* Get required KYC documents for a specific entity type
|
|
3613
|
+
* This is a client-side method that doesn't make an API call
|
|
3614
|
+
*
|
|
3615
|
+
* @param entityType - The type of business entity
|
|
3616
|
+
* @returns Array of required document types
|
|
3617
|
+
*
|
|
3618
|
+
* @example
|
|
3619
|
+
* const docs = kyc.getRequiredDocuments('llc');
|
|
3620
|
+
* // Returns: ['Proof of Identity', 'Proof of Address', ...]
|
|
3621
|
+
*/
|
|
3622
|
+
getRequiredDocuments(entityType) {
|
|
3623
|
+
return [...KYC_DOCUMENT_REQUIREMENTS[entityType]];
|
|
3624
|
+
}
|
|
3625
|
+
/**
|
|
3626
|
+
* Get all KYC document requirements (without making an API call)
|
|
3627
|
+
* Useful for displaying the full list in your application
|
|
3628
|
+
*
|
|
3629
|
+
* @returns Complete mapping of entity types to required documents
|
|
3630
|
+
*
|
|
3631
|
+
* @example
|
|
3632
|
+
* const allRequirements = kyc.getAllRequirements();
|
|
3633
|
+
* console.log(allRequirements.llc); // ['Proof of Identity', ...]
|
|
3634
|
+
*/
|
|
3635
|
+
getAllRequirements() {
|
|
3636
|
+
return { ...KYC_DOCUMENT_REQUIREMENTS };
|
|
3637
|
+
}
|
|
3638
|
+
/**
|
|
3639
|
+
* Get KYC requirements and submission status for the authenticated merchant
|
|
3640
|
+
* Fetches all KYC requests and maps them to required documents
|
|
3641
|
+
*
|
|
3642
|
+
* @param entityType - The merchant's business entity type
|
|
3643
|
+
* @returns Complete KYC requirements with submission status
|
|
3644
|
+
*
|
|
3645
|
+
* @example
|
|
3646
|
+
* const status = await kyc.getRequirementsStatus('llc');
|
|
3647
|
+
* console.log(`Completion: ${status.completion_percentage}%`);
|
|
3648
|
+
* console.log(`Approved: ${status.total_approved}/${status.total_required}`);
|
|
3649
|
+
*
|
|
3650
|
+
* // Check individual document status
|
|
3651
|
+
* status.document_statuses.forEach(doc => {
|
|
3652
|
+
* console.log(`${doc.document_type}: ${doc.status || 'not submitted'}`);
|
|
3653
|
+
* });
|
|
3654
|
+
*/
|
|
3655
|
+
async getRequirementsStatus(entityType) {
|
|
3656
|
+
// Get required documents for this entity type
|
|
3657
|
+
const requiredDocuments = this.getRequiredDocuments(entityType);
|
|
3658
|
+
// Fetch all KYC requests for the authenticated merchant
|
|
3659
|
+
const params = {
|
|
3660
|
+
kind: 'document_submission',
|
|
3661
|
+
};
|
|
3662
|
+
const response = await this.list(params);
|
|
3663
|
+
if (response.state === 'error' || !response.result) {
|
|
3664
|
+
return {
|
|
3665
|
+
state: 'error',
|
|
3666
|
+
};
|
|
3667
|
+
}
|
|
3668
|
+
const kycRequests = response.result.entries || [];
|
|
3669
|
+
// Map submitted documents
|
|
3670
|
+
const submittedDocs = new Map();
|
|
3671
|
+
kycRequests.forEach(request => {
|
|
3672
|
+
var _a;
|
|
3673
|
+
const docType = (_a = request.data) === null || _a === void 0 ? void 0 : _a.document_type;
|
|
3674
|
+
if (docType && requiredDocuments.includes(docType)) {
|
|
3675
|
+
// Keep the most recent submission for each document type
|
|
3676
|
+
const existing = submittedDocs.get(docType);
|
|
3677
|
+
if (!existing || new Date(request.inserted_at) > new Date(existing.inserted_at)) {
|
|
3678
|
+
submittedDocs.set(docType, request);
|
|
3679
|
+
}
|
|
3680
|
+
}
|
|
3681
|
+
});
|
|
3682
|
+
// Build document statuses
|
|
3683
|
+
const documentStatuses = requiredDocuments.map(docType => {
|
|
3684
|
+
var _a;
|
|
3685
|
+
const submission = submittedDocs.get(docType);
|
|
3686
|
+
if (!submission) {
|
|
3687
|
+
return {
|
|
3688
|
+
document_type: docType,
|
|
3689
|
+
required: true,
|
|
3690
|
+
submitted: false,
|
|
3691
|
+
};
|
|
3692
|
+
}
|
|
3693
|
+
// Convert integer status to string using translator
|
|
3694
|
+
// The API returns status as a number, but the type says it's a string
|
|
3695
|
+
const statusString = StatusTranslator.toStringWithoutContext(submission.status, 'legal_request');
|
|
3696
|
+
// Map to our simplified status types
|
|
3697
|
+
let status;
|
|
3698
|
+
if (statusString) {
|
|
3699
|
+
if (statusString === 'pending' || statusString === 'in_review') {
|
|
3700
|
+
status = 'pending';
|
|
3701
|
+
}
|
|
3702
|
+
else if (statusString === 'approved') {
|
|
3703
|
+
status = 'approved';
|
|
3704
|
+
}
|
|
3705
|
+
else if (statusString === 'rejected') {
|
|
3706
|
+
status = 'rejected';
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
const reviewedAt = submission.updated_at !== submission.inserted_at
|
|
3710
|
+
? submission.updated_at
|
|
3711
|
+
: undefined;
|
|
3712
|
+
return {
|
|
3713
|
+
document_type: docType,
|
|
3714
|
+
required: true,
|
|
3715
|
+
submitted: true,
|
|
3716
|
+
status,
|
|
3717
|
+
submitted_at: submission.inserted_at,
|
|
3718
|
+
reviewed_at: reviewedAt,
|
|
3719
|
+
rejection_reason: (_a = submission.data) === null || _a === void 0 ? void 0 : _a.rejection_reason,
|
|
3720
|
+
};
|
|
3721
|
+
});
|
|
3722
|
+
// Calculate statistics
|
|
3723
|
+
const totalRequired = requiredDocuments.length;
|
|
3724
|
+
const totalSubmitted = documentStatuses.filter(d => d.submitted).length;
|
|
3725
|
+
const totalApproved = documentStatuses.filter(d => d.status === 'approved').length;
|
|
3726
|
+
const totalRejected = documentStatuses.filter(d => d.status === 'rejected').length;
|
|
3727
|
+
const totalPending = documentStatuses.filter(d => d.status === 'pending').length;
|
|
3728
|
+
const completionPercentage = totalRequired > 0
|
|
3729
|
+
? Math.round((totalApproved / totalRequired) * 100)
|
|
3730
|
+
: 0;
|
|
3731
|
+
const isComplete = totalApproved === totalRequired;
|
|
3732
|
+
const requirements = {
|
|
3733
|
+
entity_type: entityType,
|
|
3734
|
+
required_documents: requiredDocuments,
|
|
3735
|
+
document_statuses: documentStatuses,
|
|
3736
|
+
total_required: totalRequired,
|
|
3737
|
+
total_submitted: totalSubmitted,
|
|
3738
|
+
total_approved: totalApproved,
|
|
3739
|
+
total_rejected: totalRejected,
|
|
3740
|
+
total_pending: totalPending,
|
|
3741
|
+
completion_percentage: completionPercentage,
|
|
3742
|
+
is_complete: isComplete,
|
|
3743
|
+
};
|
|
3744
|
+
return {
|
|
3745
|
+
state: 'ok',
|
|
3746
|
+
result: requirements,
|
|
3747
|
+
};
|
|
3748
|
+
}
|
|
3749
|
+
/**
|
|
3750
|
+
* Check if all required documents have been approved for the authenticated merchant
|
|
3751
|
+
*
|
|
3752
|
+
* @param entityType - The merchant's business entity type
|
|
3753
|
+
* @returns True if all required documents are approved
|
|
3754
|
+
*
|
|
3755
|
+
* @example
|
|
3756
|
+
* const isComplete = await kyc.isKycComplete('llc');
|
|
3757
|
+
* if (isComplete) {
|
|
3758
|
+
* console.log('Merchant is fully verified!');
|
|
3759
|
+
* }
|
|
3760
|
+
*/
|
|
3761
|
+
async isKycComplete(entityType) {
|
|
3762
|
+
var _a;
|
|
3763
|
+
const response = await this.getRequirementsStatus(entityType);
|
|
3764
|
+
return ((_a = response.result) === null || _a === void 0 ? void 0 : _a.is_complete) || false;
|
|
3765
|
+
}
|
|
3766
|
+
/**
|
|
3767
|
+
* Get list of missing (not submitted or rejected) documents for the authenticated merchant
|
|
3768
|
+
*
|
|
3769
|
+
* @param entityType - The merchant's business entity type
|
|
3770
|
+
* @returns Array of document types that need to be submitted or resubmitted
|
|
3771
|
+
*
|
|
3772
|
+
* @example
|
|
3773
|
+
* const missing = await kyc.getMissingDocuments('llc');
|
|
3774
|
+
* if (missing.length > 0) {
|
|
3775
|
+
* console.log('Please submit:', missing.join(', '));
|
|
3776
|
+
* }
|
|
3777
|
+
*/
|
|
3778
|
+
async getMissingDocuments(entityType) {
|
|
3779
|
+
const response = await this.getRequirementsStatus(entityType);
|
|
3780
|
+
if (response.state === 'error' || !response.result) {
|
|
3781
|
+
return [];
|
|
3782
|
+
}
|
|
3783
|
+
return response.result.document_statuses
|
|
3784
|
+
.filter(doc => !doc.submitted || doc.status === 'rejected')
|
|
3785
|
+
.map(doc => doc.document_type);
|
|
3786
|
+
}
|
|
3553
3787
|
}
|
|
3554
3788
|
|
|
3555
3789
|
class PaymentLinksResource {
|
|
@@ -3838,6 +4072,15 @@ class FinancialRequestsResource {
|
|
|
3838
4072
|
}
|
|
3839
4073
|
}
|
|
3840
4074
|
|
|
4075
|
+
let crypto;
|
|
4076
|
+
try {
|
|
4077
|
+
if (typeof require !== 'undefined') {
|
|
4078
|
+
crypto = require('crypto');
|
|
4079
|
+
}
|
|
4080
|
+
}
|
|
4081
|
+
catch (_a) {
|
|
4082
|
+
// Fallback for environments without Node.js crypto
|
|
4083
|
+
}
|
|
3841
4084
|
class WebhookUrlsResource {
|
|
3842
4085
|
constructor(client) {
|
|
3843
4086
|
this.client = client;
|
|
@@ -3897,6 +4140,160 @@ class WebhookUrlsResource {
|
|
|
3897
4140
|
createQueryBuilder() {
|
|
3898
4141
|
return new WebhookUrlQueryBuilder(this);
|
|
3899
4142
|
}
|
|
4143
|
+
// ============================================================================
|
|
4144
|
+
// WEBHOOK VERIFICATION METHODS
|
|
4145
|
+
// ============================================================================
|
|
4146
|
+
/**
|
|
4147
|
+
* Verify webhook signature using HMAC SHA256
|
|
4148
|
+
* Inkress webhooks use the format: crypto.mac(:hmac, :sha256, secret, body) |> Base.encode64()
|
|
4149
|
+
*/
|
|
4150
|
+
verifySignature(body, signature, secret) {
|
|
4151
|
+
if (!crypto) {
|
|
4152
|
+
throw new Error('Node.js crypto module not available. Cannot verify webhook signature.');
|
|
4153
|
+
}
|
|
4154
|
+
try {
|
|
4155
|
+
// Generate expected signature using HMAC SHA256
|
|
4156
|
+
const expectedSignature = crypto
|
|
4157
|
+
.createHmac('sha256', secret)
|
|
4158
|
+
.update(body, 'utf8')
|
|
4159
|
+
.digest('base64');
|
|
4160
|
+
// Use constant-time comparison to prevent timing attacks
|
|
4161
|
+
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));
|
|
4162
|
+
}
|
|
4163
|
+
catch (error) {
|
|
4164
|
+
return false;
|
|
4165
|
+
}
|
|
4166
|
+
}
|
|
4167
|
+
/**
|
|
4168
|
+
* Parse webhook payload from a string
|
|
4169
|
+
*/
|
|
4170
|
+
parsePayload(payload) {
|
|
4171
|
+
try {
|
|
4172
|
+
const parsed = JSON.parse(payload);
|
|
4173
|
+
if (!parsed.id || !parsed.timestamp || !parsed.event) {
|
|
4174
|
+
throw new Error('Invalid webhook payload structure: missing required fields (id, timestamp, or event)');
|
|
4175
|
+
}
|
|
4176
|
+
return parsed;
|
|
4177
|
+
}
|
|
4178
|
+
catch (error) {
|
|
4179
|
+
if (error instanceof Error) {
|
|
4180
|
+
throw new Error(`Failed to parse webhook payload: ${error.message}`);
|
|
4181
|
+
}
|
|
4182
|
+
throw new Error('Failed to parse webhook payload');
|
|
4183
|
+
}
|
|
4184
|
+
}
|
|
4185
|
+
/**
|
|
4186
|
+
* Verify and parse an incoming webhook request
|
|
4187
|
+
* This method clones the request body, validates the signature, and returns the parsed payload
|
|
4188
|
+
*
|
|
4189
|
+
* @param request - The incoming HTTP request object with headers and body
|
|
4190
|
+
* @param secret - Your webhook secret for signature verification
|
|
4191
|
+
* @param options - Optional verification options (e.g., timestamp tolerance)
|
|
4192
|
+
* @returns Promise that resolves to the parsed webhook payload
|
|
4193
|
+
* @throws Error if signature verification fails or payload is invalid
|
|
4194
|
+
*
|
|
4195
|
+
* @example
|
|
4196
|
+
* ```typescript
|
|
4197
|
+
* // Express.js example
|
|
4198
|
+
* app.post('/webhooks', async (req, res) => {
|
|
4199
|
+
* try {
|
|
4200
|
+
* const payload = await sdk.webhookUrls.verifyRequest(
|
|
4201
|
+
* { headers: req.headers, body: req.body },
|
|
4202
|
+
* 'your-webhook-secret'
|
|
4203
|
+
* );
|
|
4204
|
+
*
|
|
4205
|
+
* // Process the webhook
|
|
4206
|
+
* console.log('Received webhook:', payload.event.type);
|
|
4207
|
+
*
|
|
4208
|
+
* res.status(200).json({ received: true });
|
|
4209
|
+
* } catch (error) {
|
|
4210
|
+
* console.error('Webhook verification failed:', error);
|
|
4211
|
+
* res.status(400).json({ error: error.message });
|
|
4212
|
+
* }
|
|
4213
|
+
* });
|
|
4214
|
+
* ```
|
|
4215
|
+
*/
|
|
4216
|
+
async verifyRequest(request, secret, options) {
|
|
4217
|
+
// Extract signature from headers (case-insensitive)
|
|
4218
|
+
const signature = request.headers['x-inkress-webhook-signature'] ||
|
|
4219
|
+
request.headers['X-Inkress-Webhook-Signature'];
|
|
4220
|
+
if (!signature || typeof signature !== 'string') {
|
|
4221
|
+
throw new Error('Missing X-Inkress-Webhook-Signature header');
|
|
4222
|
+
}
|
|
4223
|
+
// Clone and ensure body is a string
|
|
4224
|
+
let body;
|
|
4225
|
+
if (typeof request.body === 'string') {
|
|
4226
|
+
body = request.body;
|
|
4227
|
+
}
|
|
4228
|
+
else if (request.body && typeof request.body === 'object') {
|
|
4229
|
+
body = JSON.stringify(request.body);
|
|
4230
|
+
}
|
|
4231
|
+
else {
|
|
4232
|
+
throw new Error('Invalid request body format: body must be a string or object');
|
|
4233
|
+
}
|
|
4234
|
+
// Verify signature
|
|
4235
|
+
const isValid = this.verifySignature(body, signature, secret);
|
|
4236
|
+
if (!isValid) {
|
|
4237
|
+
throw new Error('Webhook signature verification failed: signature does not match');
|
|
4238
|
+
}
|
|
4239
|
+
// Parse the payload
|
|
4240
|
+
const payload = this.parsePayload(body);
|
|
4241
|
+
// Optional: Verify timestamp tolerance
|
|
4242
|
+
if (options === null || options === void 0 ? void 0 : options.tolerance) {
|
|
4243
|
+
const currentTimestamp = Math.floor(Date.now() / 1000);
|
|
4244
|
+
const timeDifference = Math.abs(currentTimestamp - payload.timestamp);
|
|
4245
|
+
if (timeDifference > options.tolerance) {
|
|
4246
|
+
throw new Error(`Webhook timestamp outside tolerance window: ${timeDifference}s (max: ${options.tolerance}s)`);
|
|
4247
|
+
}
|
|
4248
|
+
}
|
|
4249
|
+
return payload;
|
|
4250
|
+
}
|
|
4251
|
+
/**
|
|
4252
|
+
* Verify webhook signature only (without parsing)
|
|
4253
|
+
* Useful for custom verification flows
|
|
4254
|
+
*
|
|
4255
|
+
* @param body - The raw webhook request body as a string
|
|
4256
|
+
* @param signature - The signature from X-Inkress-Webhook-Signature header
|
|
4257
|
+
* @param secret - Your webhook secret
|
|
4258
|
+
* @returns Promise that resolves to true if valid, rejects with error if invalid
|
|
4259
|
+
*/
|
|
4260
|
+
async verify(body, signature, secret) {
|
|
4261
|
+
if (!this.verifySignature(body, signature, secret)) {
|
|
4262
|
+
throw new Error('Webhook signature verification failed');
|
|
4263
|
+
}
|
|
4264
|
+
return true;
|
|
4265
|
+
}
|
|
4266
|
+
/**
|
|
4267
|
+
* Generate webhook signature for testing
|
|
4268
|
+
* Matches Inkress signature generation: crypto.mac(:hmac, :sha256, secret, body) |> Base.encode64()
|
|
4269
|
+
*
|
|
4270
|
+
* @example
|
|
4271
|
+
* ```typescript
|
|
4272
|
+
* const testBody = JSON.stringify({ id: '123', timestamp: Date.now(), event: {...} });
|
|
4273
|
+
* const signature = sdk.webhookUrls.generateSignature(testBody, 'your-secret');
|
|
4274
|
+
* ```
|
|
4275
|
+
*/
|
|
4276
|
+
generateSignature(body, secret) {
|
|
4277
|
+
if (!crypto) {
|
|
4278
|
+
throw new Error('Node.js crypto module not available. Cannot generate signature.');
|
|
4279
|
+
}
|
|
4280
|
+
return crypto
|
|
4281
|
+
.createHmac('sha256', secret)
|
|
4282
|
+
.update(body, 'utf8')
|
|
4283
|
+
.digest('base64');
|
|
4284
|
+
}
|
|
4285
|
+
/**
|
|
4286
|
+
* Extract event data from webhook payload with type safety
|
|
4287
|
+
*
|
|
4288
|
+
* @example
|
|
4289
|
+
* ```typescript
|
|
4290
|
+
* const payload = await sdk.webhookUrls.verifyRequest(request, secret);
|
|
4291
|
+
* const orderData = sdk.webhookUrls.extractEventData<Order>(payload);
|
|
4292
|
+
* ```
|
|
4293
|
+
*/
|
|
4294
|
+
extractEventData(payload) {
|
|
4295
|
+
return payload.event.data;
|
|
4296
|
+
}
|
|
3900
4297
|
}
|
|
3901
4298
|
|
|
3902
4299
|
/**
|
|
@@ -4538,5 +4935,5 @@ class InkressSDK {
|
|
|
4538
4935
|
}
|
|
4539
4936
|
}
|
|
4540
4937
|
|
|
4541
|
-
export { ADDRESS_FIELD_TYPES, AddressQueryBuilder, BILLING_PLAN_FIELD_TYPES, BillingPlanQueryBuilder, CATEGORY_FIELD_TYPES, CURRENCY_FIELD_TYPES, CategoryQueryBuilder, CurrencyQueryBuilder, EXCHANGE_RATE_FIELD_TYPES, ExchangeRateQueryBuilder, FEE_FIELD_TYPES, FINANCIAL_ACCOUNT_FIELD_TYPES, FINANCIAL_REQUEST_FIELD_TYPES, FeeQueryBuilder, FinancialAccountQueryBuilder, FinancialRequestQueryBuilder, HttpClient, InkressApiError, InkressSDK, MERCHANT_FIELD_TYPES, MerchantQueryBuilder, ORDER_FIELD_TYPES, OrderQueryBuilder, PAYMENT_LINK_FIELD_TYPES, PAYMENT_METHOD_FIELD_TYPES, PRODUCT_FIELD_TYPES, PaymentLinkQueryBuilder, PaymentMethodQueryBuilder, ProductQueryBuilder, QueryBuilder, SUBSCRIPTION_FIELD_TYPES, SubscriptionQueryBuilder, TOKEN_FIELD_TYPES, TRANSACTION_ENTRY_FIELD_TYPES, TokenQueryBuilder, TransactionEntryQueryBuilder, USER_FIELD_TYPES, UserQueryBuilder, WEBHOOK_URL_FIELD_TYPES, WebhookUrlQueryBuilder, InkressSDK as default, processQuery };
|
|
4938
|
+
export { ADDRESS_FIELD_TYPES, AddressQueryBuilder, BILLING_PLAN_FIELD_TYPES, BillingPlanQueryBuilder, CATEGORY_FIELD_TYPES, CURRENCY_FIELD_TYPES, CategoryQueryBuilder, CurrencyQueryBuilder, EXCHANGE_RATE_FIELD_TYPES, ExchangeRateQueryBuilder, FEE_FIELD_TYPES, FINANCIAL_ACCOUNT_FIELD_TYPES, FINANCIAL_REQUEST_FIELD_TYPES, FeeQueryBuilder, FinancialAccountQueryBuilder, FinancialRequestQueryBuilder, HttpClient, InkressApiError, InkressSDK, KYC_DOCUMENT_REQUIREMENTS, MERCHANT_FIELD_TYPES, MerchantQueryBuilder, ORDER_FIELD_TYPES, OrderQueryBuilder, PAYMENT_LINK_FIELD_TYPES, PAYMENT_METHOD_FIELD_TYPES, PRODUCT_FIELD_TYPES, PaymentLinkQueryBuilder, PaymentMethodQueryBuilder, ProductQueryBuilder, QueryBuilder, SUBSCRIPTION_FIELD_TYPES, SubscriptionQueryBuilder, TOKEN_FIELD_TYPES, TRANSACTION_ENTRY_FIELD_TYPES, TokenQueryBuilder, TransactionEntryQueryBuilder, USER_FIELD_TYPES, UserQueryBuilder, WEBHOOK_URL_FIELD_TYPES, WebhookUrlQueryBuilder, InkressSDK as default, processQuery };
|
|
4542
4939
|
//# sourceMappingURL=index.esm.js.map
|