async billing - some additional consistency checks + logs
MODIFY
src/async-task/tasks/BillTransactionAsyncTask.ts
src/async-task/tasks/BillTransactionAsyncTask.ts
+import { BillingDataTransactionStop, BillingStatus } from '../../types/Billing';
+
import AbstractAsyncTask from '../AsyncTask';
-import { BillingDataTransactionStop } from '../../types/Billing';
import BillingFactory from '../../integration/billing/BillingFactory';
import LockingHelper from '../../locking/LockingHelper';
import LockingManager from '../../locking/LockingManager';
@@ -27,13 +28,19 @@ export default class BillTransactionAsyncTask extends AbstractAsyncTask {
if (!transaction) {
throw new Error(`Unknown Transaction ID '${this.asyncTask.parameters.transactionID}'`);
}
+ // Check consistency - async task should only bill transactions created while transaction billing was ON
+ if (!transaction.billingData?.withBillingActive) {
+ throw new Error(`Unexpected situation - billing should be active - transaction ID: '${this.asyncTask.parameters.transactionID}'`);
+ }
+ // Check status - async task should only bill transactions marked as PENDING
+ if (transaction.billingData?.stop?.status !== BillingStatus.PENDING) {
+ throw new Error(`Unexpected situation - billing status should be PENDING - transaction ID: '${this.asyncTask.parameters.transactionID}'`);
+ }
// Attempt to finalize and pay invoices
const billingDataStop: BillingDataTransactionStop = await billingImpl.billTransaction(transaction);
// Update
- if (transaction.billingData) {
transaction.billingData.stop = billingDataStop;
transaction.billingData.lastUpdate = new Date();
- }
// Save
await TransactionStorage.saveTransaction(tenant.id, transaction);
} finally {

MODIFY
src/integration/billing/stripe/StripeBillingIntegration.ts
src/integration/billing/stripe/StripeBillingIntegration.ts
@@ -533,6 +533,14 @@ export default class StripeBillingIntegration extends BillingIntegration {
// Check billing data consistency
const customerID = user?.billingData?.customerID;
const paymentMethods: BillingPaymentMethod[] = await this._getPaymentMethods(user, customerID);
+ await Logging.logInfo({
+ tenantID: this.tenant.id,
+ user,
+ source: Constants.CENTRAL_SERVER,
+ action: ServerAction.BILLING_PAYMENT_METHODS,
+ module: MODULE_NAME, method: 'getPaymentMethods',
+ message: `Number of payment methods: ${paymentMethods?.length}`
+ });
return paymentMethods;
}
@@ -943,6 +951,14 @@ export default class StripeBillingIntegration extends BillingIntegration {
const customerID: string = transaction.user?.billingData?.customerID;
const customer = await this.getStripeCustomer(customerID);
if (customer) {
+ await Logging.logInfo({
+ tenantID: this.tenant.id,
+ user: transaction.userID,
+ source: Constants.CENTRAL_SERVER,
+ action: ServerAction.BILLING_TRANSACTION,
+ module: MODULE_NAME, method: 'billTransaction',
+ message: `Billing process is about to start - transaction ID: ${transaction.id}`
+ });
const billingDataTransactionStop: BillingDataTransactionStop = await this._billTransaction(transaction);
return billingDataTransactionStop;
}
@@ -952,7 +968,7 @@ export default class StripeBillingIntegration extends BillingIntegration {
user: transaction.userID,
source: Constants.CENTRAL_SERVER,
action: ServerAction.BILLING_TRANSACTION,
- module: MODULE_NAME, method: 'stopTransaction',
+ module: MODULE_NAME, method: 'billTransaction',
message: `Failed to bill the transaction - Transaction ID '${transaction.id}'`,
detailedMessages: { error: error.message, stack: error.stack }
});

async billing - some additional consistency checks + logs