Skip to content

Commit 010a1f4

Browse files
authored
Merge branch 'master' into fix-bump-workflow
2 parents bff6159 + dfbbff7 commit 010a1f4

File tree

20 files changed

+1482
-376
lines changed

20 files changed

+1482
-376
lines changed

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hawk.api",
3-
"version": "1.1.29",
3+
"version": "1.1.36",
44
"main": "index.ts",
55
"license": "UNLICENSED",
66
"scripts": {
@@ -37,13 +37,16 @@
3737
"@graphql-tools/schema": "^8.5.1",
3838
"@graphql-tools/utils": "^8.9.0",
3939
"@hawk.so/nodejs": "^3.1.1",
40-
"@hawk.so/types": "^0.1.31",
40+
"@hawk.so/types": "^0.1.33",
41+
"@n1ru4l/json-patch-plus": "^0.2.0",
4142
"@types/amqp-connection-manager": "^2.0.4",
4243
"@types/bson": "^4.0.5",
4344
"@types/debug": "^4.1.5",
4445
"@types/escape-html": "^1.0.0",
4546
"@types/graphql-upload": "^8.0.11",
4647
"@types/jsonwebtoken": "^8.3.5",
48+
"@types/lodash.clonedeep": "^4.5.9",
49+
"@types/lodash.mergewith": "^4.6.9",
4750
"@types/mime-types": "^2.1.0",
4851
"@types/mongodb": "^3.6.20",
4952
"@types/node": "^16.11.46",
@@ -70,6 +73,8 @@
7073
"graphql-upload": "^13",
7174
"jsonwebtoken": "^8.5.1",
7275
"lodash": "^4.17.15",
76+
"lodash.clonedeep": "^4.5.0",
77+
"lodash.mergewith": "^4.6.2",
7378
"migrate-mongo": "^7.0.1",
7479
"mime-types": "^2.1.25",
7580
"mongodb": "^3.7.3",

src/billing/cloudpayments.ts

Lines changed: 19 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,9 @@ import { PaymentData } from './types/paymentData';
4242
import cloudPaymentsApi from '../utils/cloudPaymentsApi';
4343
import PlanModel from '../models/plan';
4444
import { ClientApi, ClientService, CustomerReceiptItem, ReceiptApi, ReceiptTypes, TaxationSystem } from 'cloudpayments';
45-
import { ComposePaymentPayload } from './types/composePaymentPayload';
4645

4746
const PENNY_MULTIPLIER = 100;
4847

49-
interface ComposePaymentRequest extends express.Request {
50-
query: ComposePaymentPayload & { [key: string]: any };
51-
context: import('../types/graphql').ResolverContextBase;
52-
};
53-
5448
/**
5549
* Class for describing the logic of payment routes
5650
*/
@@ -86,7 +80,6 @@ export default class CloudPaymentsWebhooks {
8680
public getRouter(): express.Router {
8781
const router = express.Router();
8882

89-
router.get('/compose-payment', this.composePayment.bind(this));
9083
router.all('/check', this.check.bind(this));
9184
router.all('/pay', this.pay.bind(this));
9285
router.all('/fail', this.fail.bind(this));
@@ -95,120 +88,6 @@ export default class CloudPaymentsWebhooks {
9588
return router;
9689
}
9790

98-
/**
99-
* Prepares payment data before charge
100-
*
101-
* @param req — Express request object
102-
* @param res - Express response object
103-
*/
104-
private async composePayment(req: ComposePaymentRequest, res: express.Response): Promise<void> {
105-
const { workspaceId, tariffPlanId, shouldSaveCard } = req.query;
106-
const userId = req.context.user.id;
107-
108-
if (!workspaceId || !tariffPlanId || !userId) {
109-
this.sendError(res, 1, `[Billing / Compose payment] No workspace, tariff plan or user id in request body
110-
Details:
111-
workspaceId: ${workspaceId}
112-
tariffPlanId: ${tariffPlanId}
113-
userId: ${userId}`
114-
, req.query);
115-
116-
return;
117-
}
118-
119-
let workspace;
120-
let tariffPlan;
121-
122-
try {
123-
workspace = await this.getWorkspace(req, workspaceId);
124-
tariffPlan = await this.getPlan(req, tariffPlanId);
125-
} catch (e) {
126-
const error = e as Error;
127-
128-
this.sendError(res, 1, `[Billing / Compose payment] Can't get data from Database ${error.toString()}`, req.query);
129-
130-
return;
131-
}
132-
133-
try {
134-
await this.getMember(userId, workspace);
135-
} catch (e) {
136-
const error = e as Error;
137-
138-
this.sendError(res, 1, `[Billing / Compose payment] Can't compose payment due to error: ${error.toString()}`, req.query);
139-
140-
return;
141-
}
142-
const invoiceId = this.generateInvoiceId(tariffPlan, workspace);
143-
144-
const isCardLinkOperation = workspace.tariffPlanId.toString() === tariffPlanId && !workspace.isTariffPlanExpired();
145-
146-
// Calculate next payment date
147-
const lastChargeDate = new Date(workspace.lastChargeDate);
148-
const now = new Date();
149-
let nextPaymentDate: Date;
150-
151-
if (isCardLinkOperation) {
152-
nextPaymentDate = new Date(lastChargeDate);
153-
} else {
154-
nextPaymentDate = new Date(now);
155-
}
156-
157-
if (workspace.isDebug) {
158-
nextPaymentDate.setDate(nextPaymentDate.getDate() + 1);
159-
} else {
160-
nextPaymentDate.setMonth(nextPaymentDate.getMonth() + 1);
161-
}
162-
163-
let checksum;
164-
165-
try {
166-
const checksumData = isCardLinkOperation ? {
167-
isCardLinkOperation: true,
168-
workspaceId: workspace._id.toString(),
169-
userId: userId,
170-
nextPaymentDate: nextPaymentDate.toISOString(),
171-
} : {
172-
workspaceId: workspace._id.toString(),
173-
userId: userId,
174-
tariffPlanId: tariffPlan._id.toString(),
175-
shouldSaveCard: shouldSaveCard === 'true',
176-
nextPaymentDate: nextPaymentDate.toISOString(),
177-
};
178-
179-
checksum = await checksumService.generateChecksum(checksumData);
180-
} catch (e) {
181-
const error = e as Error;
182-
183-
this.sendError(res, 1, `[Billing / Compose payment] Can't generate checksum: ${error.toString()}`, req.query);
184-
185-
return;
186-
}
187-
188-
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Compose payment]
189-
190-
card link operation: ${isCardLinkOperation}
191-
amount: ${+tariffPlan.monthlyCharge} RUB
192-
last charge date: ${workspace.lastChargeDate?.toISOString()}
193-
next payment date: ${nextPaymentDate.toISOString()}
194-
workspace id: ${workspace._id.toString()}
195-
debug: ${Boolean(workspace.isDebug)}`
196-
, TelegramBotURLs.Money));
197-
198-
res.send({
199-
invoiceId,
200-
plan: {
201-
id: tariffPlan._id.toString(),
202-
name: tariffPlan.name,
203-
monthlyCharge: tariffPlan.monthlyCharge,
204-
},
205-
isCardLinkOperation,
206-
currency: 'RUB',
207-
checksum,
208-
nextPaymentDate: nextPaymentDate.toISOString(),
209-
});
210-
}
211-
21291
/**
21392
* Generates invoice id for payment
21493
*
@@ -557,14 +436,26 @@ plan monthly charge: ${data.cloudPayments?.recurrent.amount} ${body.Currency}`
557436

558437
await this.sendReceipt(workspace, tariffPlan, userEmail);
559438

560-
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Pay] New payment
439+
let messageText = '';
440+
441+
if (data.cloudPayments?.recurrent.startDate) {
442+
messageText = `✅ [Billing / Pay] New payment
561443
562444
amount: ${+body.Amount} ${body.Currency}
563445
next payment date: ${data.cloudPayments?.recurrent.startDate}
564446
workspace id: ${workspace._id}
565447
date of operation: ${body.DateTime}
566-
subscription id: ${body.SubscriptionId}`
567-
, TelegramBotURLs.Money));
448+
subscription id: ${body.SubscriptionId}`;
449+
} else {
450+
messageText = `✅ [Billing / Pay] New Recurrent payment
451+
452+
amount: ${+body.Amount} ${body.Currency}
453+
workspace id: ${workspace._id}
454+
date of operation: ${body.DateTime}
455+
subscription id: ${body.SubscriptionId}`;
456+
}
457+
458+
this.handleSendingToTelegramError(telegram.sendMessage(messageText, TelegramBotURLs.Money));
568459
}
569460
} catch (e) {
570461
const error = e as Error;
@@ -676,14 +567,17 @@ subscription id: ${body.SubscriptionId}`
676567

677568
console.log('💎 CloudPayments /recurrent request', body);
678569

679-
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Recurrent] New recurrent transaction
570+
const emoji = [SubscriptionStatus.CANCELLED, SubscriptionStatus.REJECTED].includes(body.Status) ? '❌' : '✅';
571+
572+
this.handleSendingToTelegramError(telegram.sendMessage(`${emoji} [Billing / Recurrent] New recurrent event
680573
681574
amount: ${+body.Amount} ${body.Currency}
682575
next payment date: ${body.NextTransactionDate}
683576
workspace id: ${body.AccountId}
684577
subscription id: ${body.Id}
685578
status: ${body.Status}`
686579
, TelegramBotURLs.Money));
580+
687581
HawkCatcher.send(new Error(`[Billing / Recurrent] New recurrent event with ${body.Status} status`), req.body);
688582

689583
switch (body.Status) {

src/billing/types/composePaymentPayload.ts

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

src/models/event.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
/**
2525
* @typedef {Object} EventPayload
2626
* @property {string} title - event title
27-
* @property {DateTime} timestamp - event datetime
2827
* @property {Number} level - event severity level
2928
* @property {EventBacktraceFrame[]} [backtrace] - event stack array from the latest call to the earliest
3029
* @property {Object} [get] - GET params
@@ -39,11 +38,13 @@
3938
/**
4039
* @typedef {Object} EventSchema
4140
* @property {String} _id - event ID
42-
* @property {String} catcherType - type of an event
43-
* @property {Number} count - event repetitions count
4441
* @property {String} groupHash - event's hash (catcherType + title + salt)
45-
* @property {User[]} visitedBy - array of users who visited this event
42+
* @property {Number} totalCount - event repetitions count
43+
* @property {String} catcherType - type of an event
4644
* @property {EventPayload} payload - event's payload
45+
* @property {Number} timestamp - event's Unix timestamp
46+
* @property {Number} usersAffected - number of users that were affected by the event
47+
* @property {User[]} visitedBy - array of users who visited this event
4748
*/
4849

4950
/**

0 commit comments

Comments
 (0)