Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hawk.api",
"version": "1.5.9",
"version": "1.5.10",
"main": "index.ts",
"license": "BUSL-1.1",
"scripts": {
Expand Down
75 changes: 52 additions & 23 deletions src/billing/cloudpayments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
return router;
}

/**

Check warning on line 91 in src/billing/cloudpayments.ts

View workflow job for this annotation

GitHub Actions / ESlint

Missing JSDoc @returns for function
* Generates invoice id for payment
*
* @param tariffPlan - tariff plan to generate invoice id
Expand Down Expand Up @@ -202,10 +202,10 @@
return;
}

telegram.sendMessage(`🤗 [Billing / Check] All checks passed successfully «${workspace.name}»`, TelegramBotURLs.Money)
telegram.sendMessage(`🤗 [Billing / Check] All checks passed successfully ${this.formatWorkspaceForTelegram(workspace)}`, TelegramBotURLs.Money)
.catch(e => console.error('Error while sending message to Telegram: ' + e));

HawkCatcher.send(new Error('[Billing / Check] All checks passed successfully'), body as any);

Check warning on line 208 in src/billing/cloudpayments.ts

View workflow job for this annotation

GitHub Actions / ESlint

Unexpected any. Specify a different type

res.json({
code: CheckCodes.SUCCESS,
Expand Down Expand Up @@ -425,7 +425,7 @@

this.handleSendingToTelegramError(telegram.sendMessage(`✅ [Billing / Pay] Card linked

workspace id: ${workspace._id}
${this.formatWorkspaceForTelegram(workspace)}
date of operation: ${body.DateTime}
first payment date: ${data.cloudPayments?.recurrent.startDate}
card link charge: ${+body.Amount} ${body.Currency}
Expand All @@ -451,14 +451,14 @@

amount: ${+body.Amount} ${body.Currency}
next payment date: ${data.cloudPayments?.recurrent.startDate}
workspace id: ${workspace._id}
${this.formatWorkspaceForTelegram(workspace)}
date of operation: ${body.DateTime}
subscription id: ${body.SubscriptionId}`;
} else {
messageText = `✅ [Billing / Pay] New Recurrent payment

amount: ${+body.Amount} ${body.Currency}
workspace id: ${workspace._id}
${this.formatWorkspaceForTelegram(workspace)}
date of operation: ${body.DateTime}
subscription id: ${body.SubscriptionId}`;
}
Expand Down Expand Up @@ -491,10 +491,12 @@

console.log('💎 CloudPayments /fail request', body);

const failReasonLine = `reason: ${body.Reason} (${body.ReasonCode})`;

try {
data = await this.getDataFromRequest(req);
} catch (e) {
this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] Invalid request`, body);
this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] Invalid request\n${failReasonLine}`, body);

return;
}
Expand All @@ -508,7 +510,7 @@
*/

if (!data.workspaceId || !data.userId || !data.tariffPlanId) {
this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] No workspace or user id or plan id in request body`, body);
this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] No workspace or user id or plan id in request body\n${failReasonLine}`, body);

return;
}
Expand All @@ -520,7 +522,7 @@
} catch (e) {
const error = e as Error;

this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] ${error.toString()}`, body);
this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] ${error.toString()}\n${failReasonLine}`, body);

return;
}
Expand All @@ -530,7 +532,7 @@
} catch (e) {
const error = e as Error;

this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] Can't update business operation status ${error.toString()}`, body);
this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] Can't update business operation status ${error.toString()}\n${failReasonLine}`, body);

return;
}
Expand All @@ -548,14 +550,20 @@
} catch (e) {
const error = e as Error;

this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] Error while sending notification to the user ${error.toString()}`, body);
this.sendError(res, FailCodes.SUCCESS, `[Billing / Fail] Error while sending notification to the user ${error.toString()}\n${failReasonLine}`, body);

return;
}

this.handleSendingToTelegramError(telegram.sendMessage(`❌ [Billing / Fail] Transaction failed for «${workspace.name}»`, TelegramBotURLs.Money));
this.handleSendingToTelegramError(telegram.sendMessage(`❌ [Billing / Fail] Transaction failed for ${this.formatWorkspaceForTelegram(workspace)}

amount: ${+body.Amount} ${body.Currency}
${failReasonLine}
transaction id: ${body.TransactionId}
subscription id: ${body.SubscriptionId || 'none'}`
, TelegramBotURLs.Money));

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

Check warning on line 566 in src/billing/cloudpayments.ts

View workflow job for this annotation

GitHub Actions / ESlint

Unexpected any. Specify a different type

res.json({
code: FailCodes.SUCCESS,
Expand All @@ -577,11 +585,21 @@

const emoji = [SubscriptionStatus.CANCELLED, SubscriptionStatus.REJECTED].includes(body.Status) ? '❌' : '✅';

let workspace: WorkspaceModel | null = null;
let workspaceLookupError: Error | null = null;

try {
workspace = await context.factories.workspacesFactory.findBySubscriptionId(body.Id);
} catch (e) {
workspaceLookupError = e as Error;
}

this.handleSendingToTelegramError(telegram.sendMessage(`${emoji} [Billing / Recurrent] New recurrent event

amount: ${+body.Amount} ${body.Currency}
next payment date: ${body.NextTransactionDate}
workspace id: ${body.AccountId}
${this.formatWorkspaceForTelegram(workspace)}
user id: ${body.AccountId}
subscription id: ${body.Id}
status: ${body.Status}`
, TelegramBotURLs.Money));
Expand All @@ -591,18 +609,8 @@
switch (body.Status) {
case SubscriptionStatus.CANCELLED:
case SubscriptionStatus.REJECTED: {
let workspace;

try {
/**
* If there is a workspace with subscription id then subscription was cancelled via CloudPayments admin panel (or other no garage way)
* We need to remove subscription id from workspace
*/
workspace = await context.factories.workspacesFactory.findBySubscriptionId(body.Id);
} catch (e) {
const error = e as Error;

this.sendError(res, RecurrentCodes.SUCCESS, `[Billing / Recurrent] Can't get data from database: ${error.toString()}`, {
if (workspaceLookupError) {
this.sendError(res, RecurrentCodes.SUCCESS, `[Billing / Recurrent] Can't get data from database: ${workspaceLookupError.toString()}`, {
body,
workspace,
});
Expand All @@ -624,6 +632,10 @@
}

try {
/**
* Subscription was cancelled via CloudPayments admin panel (or other no-garage way).
* Remove subscription id from workspace.
*/
await workspace.setSubscriptionId(null);
} catch (e) {
const error = e as Error;
Expand All @@ -641,6 +653,23 @@
} as RecurrentResponse);
}

/**

Check warning on line 656 in src/billing/cloudpayments.ts

View workflow job for this annotation

GitHub Actions / ESlint

Missing JSDoc @returns for function
* Formats workspace identity for Telegram money notifications
*
* @param workspace - workspace model or null when it was not found
*/
private formatWorkspaceForTelegram(workspace: Pick<WorkspaceModel, '_id' | 'name'> | null): string {
if (!workspace) {
return 'workspace: unknown';
}

if (workspace.name) {
return `workspace: «${workspace.name}» (${workspace._id})`;
}

return `workspace id: ${workspace._id}`;
}

/**
* Get workspace by workspace id
*
Expand Down Expand Up @@ -737,7 +766,7 @@
* @param errorText - error description
* @param backtrace - request data and error data
*/
private sendError(res: express.Response, errorCode: CheckCodes | PayCodes | FailCodes | RecurrentCodes, errorText: string, backtrace: { [key: string]: any }): void {

Check warning on line 769 in src/billing/cloudpayments.ts

View workflow job for this annotation

GitHub Actions / ESlint

Unexpected any. Specify a different type
res.json({
code: errorCode,
});
Expand Down Expand Up @@ -802,7 +831,7 @@
promise.catch(e => console.error('Error while sending message to Telegram: ' + e));
}

/**

Check warning on line 834 in src/billing/cloudpayments.ts

View workflow job for this annotation

GitHub Actions / ESlint

Missing JSDoc @returns for function
* Parses body and returns card data
* @param request - request body to parse
*/
Expand Down
6 changes: 4 additions & 2 deletions src/resolvers/billingNew.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ export default {
isCardLinkOperation = true;
}

// Calculate next payment date
/**
* Calculate next payment date
*/
const lastChargeDate = workspace.lastChargeDate ? new Date(workspace.lastChargeDate) : now;
const nextPaymentDate = isCardLinkOperation ? new Date(lastChargeDate) : new Date(now);

Expand Down Expand Up @@ -163,7 +165,7 @@ card link operation: ${isCardLinkOperation}
amount: ${+plan.monthlyCharge} RUB
last charge date: ${workspace.lastChargeDate?.toISOString()}
next payment date: ${nextPaymentDate.toISOString()}
workspace id: ${workspace._id.toString()}
workspace: «${workspace.name}» (${workspace._id.toString()})
debug: ${Boolean(workspace.isDebug)}`
, TelegramBotURLs.Money)
.catch(e => console.error('Error while sending message to Telegram: ' + e));
Expand Down
Loading