Skip to content

Commit 0a52335

Browse files
Merge pull request #485 from codex-team/fix/payments-logs
Fix/payments logs
2 parents 02c2717 + 43729f5 commit 0a52335

6 files changed

Lines changed: 81 additions & 11 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hawk.api",
3-
"version": "1.1.19",
3+
"version": "1.1.20",
44
"main": "index.ts",
55
"license": "UNLICENSED",
66
"scripts": {

src/billing/cloudpayments.ts

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
PlanDBScheme,
2626
PlanProlongationPayload
2727
} from '@hawk.so/types';
28-
import { PENNY_MULTIPLIER } from 'codex-accounting-sdk';
2928
import WorkspaceModel from '../models/workspace';
3029
import HawkCatcher from '@hawk.so/nodejs';
3130
import { publish } from '../rabbitmq';
@@ -45,6 +44,8 @@ import PlanModel from '../models/plan';
4544
import { ClientApi, ClientService, CustomerReceiptItem, ReceiptApi, ReceiptTypes, TaxationSystem } from 'cloudpayments';
4645
import { ComposePaymentPayload } from './types/composePaymentPayload';
4746

47+
const PENNY_MULTIPLIER = 100;
48+
4849
interface ComposePaymentRequest extends express.Request {
4950
query: ComposePaymentPayload & { [key: string]: any };
5051
context: import('../types/graphql').ResolverContextBase;
@@ -105,7 +106,12 @@ export default class CloudPaymentsWebhooks {
105106
const userId = req.context.user.id;
106107

107108
if (!workspaceId || !tariffPlanId || !userId) {
108-
this.sendError(res, 1, `[Billing / Compose payment] No workspace, tariff plan or user id in request body`, req.query);
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);
109115

110116
return;
111117
}
@@ -137,18 +143,37 @@ export default class CloudPaymentsWebhooks {
137143

138144
const isCardLinkOperation = workspace.tariffPlanId.toString() === tariffPlanId && !workspace.isTariffPlanExpired();
139145

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+
140163
let checksum;
141164

142165
try {
143166
const checksumData = isCardLinkOperation ? {
144167
isCardLinkOperation: true,
145168
workspaceId: workspace._id.toString(),
146169
userId: userId,
170+
nextPaymentDate: nextPaymentDate.toISOString(),
147171
} : {
148172
workspaceId: workspace._id.toString(),
149173
userId: userId,
150174
tariffPlanId: tariffPlan._id.toString(),
151175
shouldSaveCard: shouldSaveCard === 'true',
176+
nextPaymentDate: nextPaymentDate.toISOString(),
152177
};
153178

154179
checksum = await checksumService.generateChecksum(checksumData);
@@ -170,6 +195,7 @@ export default class CloudPaymentsWebhooks {
170195
isCardLinkOperation,
171196
currency: 'RUB',
172197
checksum,
198+
nextPaymentDate: nextPaymentDate.toISOString(),
173199
});
174200
}
175201

@@ -268,7 +294,7 @@ export default class CloudPaymentsWebhooks {
268294
status: BusinessOperationStatus.Pending,
269295
payload: {
270296
workspaceId: workspace._id,
271-
amount: +body.Amount * PENNY_MULTIPLIER,
297+
amount: +body.Amount,
272298
currency: body.Currency,
273299
userId: member._id,
274300
tariffPlanId: plan._id,
@@ -479,8 +505,6 @@ export default class CloudPaymentsWebhooks {
479505
* Refund the money that were charged to link a card
480506
*/
481507
if (data.isCardLinkOperation) {
482-
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Pay] Recurrent payments activated for «${workspace.name}». 1 RUB charged`, TelegramBotURLs.Money));
483-
484508
await cloudPaymentsApi.cancelPayment(body.TransactionId);
485509

486510
const member = await this.getMember(data.userId, workspace);
@@ -503,7 +527,13 @@ export default class CloudPaymentsWebhooks {
503527
dtCreated: new Date(),
504528
});
505529

506-
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Pay] Recurrent payments activated for «${workspace.name}». 1 RUB returned`, TelegramBotURLs.Money));
530+
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Pay] Card linked
531+
532+
workspace id: ${workspace._id}
533+
date of operation: ${body.DateTime}
534+
first payment date: ${data.cloudPayments?.recurrent.startDate}
535+
sum: ${data.cloudPayments?.recurrent.amount}${body.Currency}`
536+
, TelegramBotURLs.Money));
507537
} else {
508538
/**
509539
* Russia code from ISO 3166-1
@@ -517,7 +547,14 @@ export default class CloudPaymentsWebhooks {
517547

518548
await this.sendReceipt(workspace, tariffPlan, userEmail);
519549

520-
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Pay] Payment passed successfully for «${workspace.name}»`, TelegramBotURLs.Money));
550+
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Pay] New payment
551+
552+
amount: ${+body.Amount} ${body.Currency}
553+
next payment date: ${data.cloudPayments?.recurrent.startDate}
554+
workspace id: ${workspace._id}
555+
date of operation: ${body.DateTime}
556+
subscription id: ${body.SubscriptionId}`
557+
, TelegramBotURLs.Money));
521558
}
522559
} catch (e) {
523560
const error = e as Error;
@@ -607,7 +644,7 @@ export default class CloudPaymentsWebhooks {
607644
return;
608645
}
609646

610-
this.handleSendingToTelegramError(telegram.sendMessage(` [Billing / Fail] Transaction failed for «${workspace.name}»`, TelegramBotURLs.Money));
647+
this.handleSendingToTelegramError(telegram.sendMessage(` [Billing / Fail] Transaction failed for «${workspace.name}»`, TelegramBotURLs.Money));
611648

612649
HawkCatcher.send(new Error('[Billing / Fail] Transaction failed'), body as any);
613650

@@ -629,7 +666,13 @@ export default class CloudPaymentsWebhooks {
629666

630667
console.log('💎 CloudPayments /recurrent request', body);
631668

632-
this.handleSendingToTelegramError(telegram.sendMessage(`[Billing / Recurrent] New recurrent event with ${body.Status} status`, TelegramBotURLs.Money));
669+
this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Recurrent] New recurrent transaction
670+
671+
amount: ${+body.Amount} ${body.Currency}
672+
next payment date: ${body.NextTransactionDate}
673+
workspace id: ${body.AccountId}
674+
subscription id: ${body.Id}`
675+
, TelegramBotURLs.Money));
633676
HawkCatcher.send(new Error(`[Billing / Recurrent] New recurrent event with ${body.Status} status`), req.body);
634677

635678
switch (body.Status) {

src/utils/checksumService.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ interface PlanPurchaseChecksumData {
2020
* If true, we will save user card
2121
*/
2222
shouldSaveCard: boolean;
23+
/**
24+
* Next payment date
25+
*/
26+
nextPaymentDate: string;
2327
}
2428

2529
interface CardLinkChecksumData {
@@ -35,6 +39,10 @@ interface CardLinkChecksumData {
3539
* True if this is card linking operation – charging minimal amount of money to validate card info
3640
*/
3741
isCardLinkOperation: boolean;
42+
/**
43+
* Next payment date
44+
*/
45+
nextPaymentDate: string;
3846
}
3947

4048
/**
@@ -67,13 +75,15 @@ class ChecksumService {
6775
workspaceId: payload.workspaceId,
6876
userId: payload.userId,
6977
isCardLinkOperation: payload.isCardLinkOperation,
78+
nextPaymentDate: payload.nextPaymentDate,
7079
};
7180
} else {
7281
return {
7382
workspaceId: payload.workspaceId,
7483
userId: payload.userId,
7584
tariffPlanId: payload.tariffPlanId,
7685
shouldSaveCard: payload.shouldSaveCard,
86+
nextPaymentDate: payload.nextPaymentDate,
7787
};
7888
}
7989
}

test/integration/cases/billing/check.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ describe('Check webhook', () => {
151151
userId: admin._id.toString(),
152152
tariffPlanId: planToChange._id.toString(),
153153
shouldSaveCard: false,
154+
nextPaymentDate: new Date().toString(),
154155
}),
155156
}),
156157
};
@@ -172,6 +173,7 @@ describe('Check webhook', () => {
172173
userId: externalUser._id.toString(),
173174
tariffPlanId: planToChange._id.toString(),
174175
shouldSaveCard: false,
176+
nextPaymentDate: new Date().toString(),
175177
}),
176178
}),
177179
};
@@ -193,6 +195,7 @@ describe('Check webhook', () => {
193195
userId: member._id.toString(),
194196
tariffPlanId: planToChange._id.toString(),
195197
shouldSaveCard: false,
198+
nextPaymentDate: new Date().toString(),
196199
}),
197200
}),
198201
};
@@ -214,6 +217,7 @@ describe('Check webhook', () => {
214217
userId: admin._id.toString(),
215218
tariffPlanId: '5fe383b0126d28007780641b',
216219
shouldSaveCard: false,
220+
nextPaymentDate: new Date().toString(),
217221
}),
218222
}),
219223
};
@@ -236,6 +240,7 @@ describe('Check webhook', () => {
236240
userId: admin._id.toString(),
237241
tariffPlanId: planToChange._id.toString(),
238242
shouldSaveCard: false,
243+
nextPaymentDate: new Date().toString(),
239244
}),
240245
}),
241246
};
@@ -257,6 +262,7 @@ describe('Check webhook', () => {
257262
userId: admin._id.toString(),
258263
tariffPlanId: planToChange._id.toString(),
259264
shouldSaveCard: false,
265+
nextPaymentDate: new Date().toString(),
260266
}),
261267
}),
262268
};
@@ -283,6 +289,7 @@ describe('Check webhook', () => {
283289
userId: admin._id.toString(),
284290
tariffPlanId: planToChange._id.toString(),
285291
shouldSaveCard: false,
292+
nextPaymentDate: new Date().toString(),
286293
}),
287294
cloudPayments: {
288295
recurrent: {

test/integration/cases/billing/fail.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,12 @@ const tariffPlan: PlanDBScheme = {
5050
name: 'Test plan',
5151
};
5252

53-
const planProlongationPayload: PlanProlongationPayload = {
53+
const planProlongationPayload = {
5454
userId: user._id.toString(),
5555
workspaceId: workspace._id.toString(),
5656
tariffPlanId: tariffPlan._id.toString(),
5757
shouldSaveCard: false,
58+
nextPaymentDate: new Date().toString(),
5859
};
5960

6061
const validRequest: FailRequest = {
@@ -239,6 +240,7 @@ describe('Fail webhook', () => {
239240
workspaceId: workspace._id.toString(),
240241
tariffPlanId: tariffPlan._id.toString(),
241242
shouldSaveCard: false,
243+
nextPaymentDate: new Date().toString(),
242244
}),
243245
}),
244246
});

test/integration/cases/billing/pay.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ describe('Pay webhook', () => {
127127
checksum: await checksumService.generateChecksum({
128128
...paymentSuccessPayload,
129129
shouldSaveCard: false,
130+
nextPaymentDate: new Date().toString(),
130131
}),
131132
}),
132133
};
@@ -457,6 +458,7 @@ describe('Pay webhook', () => {
457458
checksum: await checksumService.generateChecksum({
458459
...paymentSuccessPayload,
459460
shouldSaveCard: true,
461+
nextPaymentDate: new Date().toString(),
460462
}),
461463
}),
462464
...cardDetails,
@@ -502,6 +504,7 @@ describe('Pay webhook', () => {
502504
workspaceId: '',
503505
tariffPlanId: planToChange._id.toString(),
504506
shouldSaveCard: false,
507+
nextPaymentDate: new Date().toString(),
505508
}),
506509
}),
507510
});
@@ -523,6 +526,7 @@ describe('Pay webhook', () => {
523526
workspaceId: workspace._id.toString(),
524527
tariffPlanId: planToChange._id.toString(),
525528
shouldSaveCard: false,
529+
nextPaymentDate: new Date().toString(),
526530
}),
527531
}),
528532
});
@@ -544,6 +548,7 @@ describe('Pay webhook', () => {
544548
workspaceId: workspace._id.toString(),
545549
tariffPlanId: '',
546550
shouldSaveCard: false,
551+
nextPaymentDate: new Date().toString(),
547552
}),
548553
}),
549554
});
@@ -565,6 +570,7 @@ describe('Pay webhook', () => {
565570
workspaceId: new ObjectId().toString(),
566571
tariffPlanId: planToChange._id.toString(),
567572
shouldSaveCard: false,
573+
nextPaymentDate: new Date().toString(),
568574
}),
569575
}),
570576
});
@@ -586,6 +592,7 @@ describe('Pay webhook', () => {
586592
workspaceId: workspace._id.toString(),
587593
tariffPlanId: new ObjectId().toString(),
588594
shouldSaveCard: false,
595+
nextPaymentDate: new Date().toString(),
589596
}),
590597
}),
591598
});
@@ -607,6 +614,7 @@ describe('Pay webhook', () => {
607614
workspaceId: workspace._id.toString(),
608615
tariffPlanId: planToChange._id.toString(),
609616
shouldSaveCard: false,
617+
nextPaymentDate: new Date().toString(),
610618
}),
611619
}),
612620
});

0 commit comments

Comments
 (0)