@stamhoofd/backend 2.58.0 → 2.60.0
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/index.ts +10 -1
- package/package.json +12 -12
- package/src/audit-logs/DocumentTemplateLogger.ts +22 -0
- package/src/audit-logs/EventLogger.ts +30 -0
- package/src/audit-logs/GroupLogger.ts +95 -0
- package/src/audit-logs/MemberLogger.ts +24 -0
- package/src/audit-logs/MemberPlatformMembershipLogger.ts +60 -0
- package/src/audit-logs/MemberResponsibilityRecordLogger.ts +69 -0
- package/src/audit-logs/ModelLogger.ts +219 -0
- package/src/audit-logs/OrderLogger.ts +57 -0
- package/src/audit-logs/OrganizationLogger.ts +16 -0
- package/src/audit-logs/OrganizationRegistrationPeriodLogger.ts +77 -0
- package/src/audit-logs/PaymentLogger.ts +43 -0
- package/src/audit-logs/PlatformLogger.ts +13 -0
- package/src/audit-logs/RegistrationLogger.ts +53 -0
- package/src/audit-logs/RegistrationPeriodLogger.ts +21 -0
- package/src/audit-logs/StripeAccountLogger.ts +47 -0
- package/src/audit-logs/WebshopLogger.ts +35 -0
- package/src/crons/updateSetupSteps.ts +1 -1
- package/src/crons.ts +2 -1
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +12 -24
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +7 -21
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +5 -13
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +5 -12
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +0 -15
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +43 -27
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +0 -19
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +3 -13
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +20 -43
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +0 -6
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +0 -6
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +5 -14
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +7 -4
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +8 -2
- package/src/helpers/AuthenticatedStructures.ts +16 -1
- package/src/helpers/Context.ts +8 -2
- package/src/helpers/MemberUserSyncer.ts +45 -40
- package/src/helpers/PeriodHelper.ts +5 -5
- package/src/helpers/SetupStepUpdater.ts +503 -0
- package/src/helpers/TagHelper.ts +23 -20
- package/src/seeds/1722344162-update-membership.ts +2 -2
- package/src/seeds/1726572303-schedule-stock-updates.ts +2 -1
- package/src/seeds/1726847064-setup-steps.ts +1 -1
- package/src/seeds/1733319079-fill-paying-organization-ids.ts +68 -0
- package/src/services/AuditLogService.ts +81 -296
- package/src/services/BalanceItemPaymentService.ts +1 -1
- package/src/services/BalanceItemService.ts +14 -5
- package/src/services/DocumentService.ts +43 -0
- package/src/services/MemberNumberService.ts +120 -0
- package/src/services/PaymentService.ts +199 -193
- package/src/services/PlatformMembershipService.ts +284 -0
- package/src/services/RegistrationService.ts +78 -27
- package/src/services/diff.ts +512 -0
- package/src/sql-filters/events.ts +13 -1
- package/src/helpers/MembershipHelper.ts +0 -54
- package/src/services/explainPatch.ts +0 -782
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { isSimpleError, isSimpleErrors, SimpleError } from '@simonbackx/simple-errors';
|
|
2
|
+
import { Member, MemberPlatformMembership, Organization } from '@stamhoofd/models';
|
|
3
|
+
import { QueueHandler } from '@stamhoofd/queues';
|
|
4
|
+
import { SQL, SQLWhereLike, scalarToSQLExpression } from '@stamhoofd/sql';
|
|
5
|
+
|
|
6
|
+
export class MemberNumberService {
|
|
7
|
+
static async assignMemberNumber(member: Member, membership: MemberPlatformMembership) {
|
|
8
|
+
if (member.details?.memberNumber) {
|
|
9
|
+
console.log('Member already has member number, should not happen');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return await QueueHandler.schedule('assignMemberNumber', async function (this: undefined) {
|
|
14
|
+
try {
|
|
15
|
+
const memberNumber = await MemberNumberService.createMemberNumber(member, membership);
|
|
16
|
+
member.details.memberNumber = memberNumber;
|
|
17
|
+
await member.save();
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (isSimpleError(error) || isSimpleErrors(error)) {
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.error(error);
|
|
25
|
+
throw new SimpleError({
|
|
26
|
+
code: 'assign_member_number',
|
|
27
|
+
message: error.message,
|
|
28
|
+
human: 'Er is iets misgegaan bij het aanmaken van het lidnummer.',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static async createMemberNumber(member: Member, membership: MemberPlatformMembership): Promise<string> {
|
|
36
|
+
// example: 5301-101012-1
|
|
37
|
+
|
|
38
|
+
// #region get birth date part (ddmmjj)
|
|
39
|
+
const birthDay = member.details?.birthDay;
|
|
40
|
+
if (!birthDay) {
|
|
41
|
+
throw new SimpleError({
|
|
42
|
+
code: 'assign_member_number',
|
|
43
|
+
message: 'Missing birthDay',
|
|
44
|
+
human: 'Er kon geen lidnummer aangemaakt worden omdat er geen geboortedatum is ingesteld.',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const dayPart = birthDay.getDate().toString().padStart(2, '0');
|
|
49
|
+
const monthPart = (birthDay.getMonth() + 1).toString().padStart(2, '0');
|
|
50
|
+
const yearPart = birthDay.getFullYear().toString().slice(2, 4);
|
|
51
|
+
const birthDatePart = `${dayPart}${monthPart}${yearPart}`;
|
|
52
|
+
// #endregion
|
|
53
|
+
|
|
54
|
+
// #region get group number
|
|
55
|
+
const organizationId = membership.organizationId;
|
|
56
|
+
const organization = await Organization.getByID(organizationId);
|
|
57
|
+
if (!organization) {
|
|
58
|
+
throw new Error(`Organization with id ${organizationId} not found`);
|
|
59
|
+
}
|
|
60
|
+
const groupNumber = organization.uri;
|
|
61
|
+
// #endregion
|
|
62
|
+
|
|
63
|
+
// #region get follow up number
|
|
64
|
+
const firstPart = `${groupNumber}-${birthDatePart}-`;
|
|
65
|
+
|
|
66
|
+
const query = SQL.select()
|
|
67
|
+
.from(SQL.table('members'))
|
|
68
|
+
.where(
|
|
69
|
+
new SQLWhereLike(
|
|
70
|
+
SQL.column('members', 'memberNumber'),
|
|
71
|
+
scalarToSQLExpression(`${SQLWhereLike.escape(firstPart)}%`),
|
|
72
|
+
),
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const count = await query.count();
|
|
76
|
+
console.log(`Found ${count} members with a memberNumber starting with ${firstPart}`);
|
|
77
|
+
|
|
78
|
+
let followUpNumber = count;
|
|
79
|
+
// #endregion
|
|
80
|
+
|
|
81
|
+
// #region check if memberNumber is unique
|
|
82
|
+
let doesExist = true;
|
|
83
|
+
let memberNumber: string = '';
|
|
84
|
+
let tries = 0;
|
|
85
|
+
|
|
86
|
+
while (doesExist) {
|
|
87
|
+
followUpNumber++;
|
|
88
|
+
memberNumber = firstPart + followUpNumber;
|
|
89
|
+
|
|
90
|
+
const result = await SQL.select()
|
|
91
|
+
.from(SQL.table('members'))
|
|
92
|
+
.where(
|
|
93
|
+
SQL.column('members', 'memberNumber'),
|
|
94
|
+
scalarToSQLExpression(memberNumber),
|
|
95
|
+
)
|
|
96
|
+
.first(false);
|
|
97
|
+
|
|
98
|
+
console.log(`Is ${memberNumber} unique? ${result === null}`);
|
|
99
|
+
|
|
100
|
+
if (result !== null) {
|
|
101
|
+
tries++;
|
|
102
|
+
if (tries > 9) {
|
|
103
|
+
throw new SimpleError({
|
|
104
|
+
code: 'assign_member_number',
|
|
105
|
+
message: `Duplicate member numbers (last try: ${memberNumber}, tries: ${tries})`,
|
|
106
|
+
human: 'Er kon geen uniek lidnummer aangemaakt worden. Mogelijks zijn er teveel leden met dezelfde geboortedatum. Neem contact op met de vereniging.',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
doesExist = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// #endregion
|
|
115
|
+
|
|
116
|
+
console.log(`Created member number: ${memberNumber}`);
|
|
117
|
+
|
|
118
|
+
return memberNumber;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import createMollieClient, { PaymentStatus as MolliePaymentStatus } from '@mollie/api-client';
|
|
2
2
|
import { BalanceItem, BalanceItemPayment, MolliePayment, MollieToken, Organization, PayconiqPayment, Payment } from '@stamhoofd/models';
|
|
3
3
|
import { QueueHandler } from '@stamhoofd/queues';
|
|
4
|
-
import { PaymentMethod, PaymentProvider, PaymentStatus } from '@stamhoofd/structures';
|
|
4
|
+
import { AuditLogSource, PaymentMethod, PaymentProvider, PaymentStatus } from '@stamhoofd/structures';
|
|
5
5
|
import { BuckarooHelper } from '../helpers/BuckarooHelper';
|
|
6
6
|
import { StripeHelper } from '../helpers/StripeHelper';
|
|
7
7
|
import { BalanceItemPaymentService } from './BalanceItemPaymentService';
|
|
8
|
+
import { AuditLogService } from './AuditLogService';
|
|
8
9
|
|
|
9
10
|
export const PaymentService = {
|
|
10
11
|
async handlePaymentStatusUpdate(payment: Payment, organization: Organization, status: PaymentStatus) {
|
|
@@ -12,79 +13,81 @@ export const PaymentService = {
|
|
|
12
13
|
return;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
16
|
+
await AuditLogService.setContext({ fallbackUserId: payment.payingUserId, source: AuditLogSource.Payment, fallbackOrganizationId: payment.organizationId }, async () => {
|
|
17
|
+
if (status === PaymentStatus.Succeeded) {
|
|
18
|
+
payment.status = PaymentStatus.Succeeded;
|
|
19
|
+
payment.paidAt = new Date();
|
|
20
|
+
await payment.save();
|
|
21
|
+
|
|
22
|
+
// Prevent concurrency issues
|
|
23
|
+
await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
|
|
24
|
+
const unloaded = (await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment));
|
|
25
|
+
const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
|
|
26
|
+
unloaded,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
for (const balanceItemPayment of balanceItemPayments) {
|
|
30
|
+
await BalanceItemPaymentService.markPaid(balanceItemPayment, organization);
|
|
31
|
+
}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
|
|
34
|
+
});
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
const oldStatus = payment.status;
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// Save before updating balance items
|
|
41
|
+
payment.status = status;
|
|
42
|
+
payment.paidAt = null;
|
|
43
|
+
await payment.save();
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
// If OLD status was succeeded, we need to revert the actions
|
|
46
|
+
if (oldStatus === PaymentStatus.Succeeded) {
|
|
45
47
|
// No longer succeeded
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
|
|
49
|
+
const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
|
|
50
|
+
(await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment)),
|
|
51
|
+
);
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
for (const balanceItemPayment of balanceItemPayments) {
|
|
54
|
+
await BalanceItemPaymentService.undoPaid(balanceItemPayment, organization);
|
|
55
|
+
}
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
|
|
58
|
+
});
|
|
59
|
+
}
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
// Moved to failed
|
|
62
|
+
if (status == PaymentStatus.Failed) {
|
|
63
|
+
await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
|
|
64
|
+
const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
|
|
65
|
+
(await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment)),
|
|
66
|
+
);
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
for (const balanceItemPayment of balanceItemPayments) {
|
|
69
|
+
await BalanceItemPaymentService.markFailed(balanceItemPayment, organization);
|
|
70
|
+
}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
|
|
73
|
+
});
|
|
74
|
+
}
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
// If OLD status was FAILED, we need to revert the actions
|
|
77
|
+
if (oldStatus === PaymentStatus.Failed) { // OLD FAILED!! -> NOW PENDING
|
|
78
|
+
await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
|
|
79
|
+
const balanceItemPayments = await BalanceItemPayment.balanceItem.load(
|
|
80
|
+
(await BalanceItemPayment.where({ paymentId: payment.id })).map(r => r.setRelation(BalanceItemPayment.payment, payment)),
|
|
81
|
+
);
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
for (const balanceItemPayment of balanceItemPayments) {
|
|
84
|
+
await BalanceItemPaymentService.undoFailed(balanceItemPayment, organization);
|
|
85
|
+
}
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
await BalanceItem.updateOutstanding(balanceItemPayments.map(p => p.balanceItem));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
});
|
|
88
91
|
},
|
|
89
92
|
|
|
90
93
|
/**
|
|
@@ -99,181 +102,184 @@ export const PaymentService = {
|
|
|
99
102
|
return;
|
|
100
103
|
}
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
// Explicitly set userId to null, because all actions caused by a poll are not caused by the currently signed in user, but the paying user id
|
|
106
|
+
return await AuditLogService.setContext({ userId: payment.payingUserId ?? null, source: AuditLogSource.Payment }, async () => {
|
|
107
|
+
if (!payment.organizationId) {
|
|
108
|
+
console.error('Payment without organization not supported', payment.id);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
106
111
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
const organization = org ?? await Organization.getByID(payment.organizationId);
|
|
113
|
+
if (!organization) {
|
|
114
|
+
console.error('Organization not found for payment', payment.id);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
112
117
|
|
|
113
|
-
|
|
118
|
+
const testMode = organization.privateMeta.useTestPayments ?? STAMHOOFD.environment !== 'production';
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
if (payment.status === PaymentStatus.Pending || payment.status === PaymentStatus.Created || (payment.provider === PaymentProvider.Buckaroo && payment.status === PaymentStatus.Failed)) {
|
|
121
|
+
if (payment.provider === PaymentProvider.Stripe) {
|
|
122
|
+
try {
|
|
123
|
+
let status = await StripeHelper.getStatus(payment, cancel || this.shouldTryToCancel(payment.status, payment), testMode);
|
|
119
124
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
if (this.isManualExpired(status, payment)) {
|
|
126
|
+
console.error('Manually marking Stripe payment as expired', payment.id);
|
|
127
|
+
status = PaymentStatus.Failed;
|
|
128
|
+
}
|
|
124
129
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
await this.handlePaymentStatusUpdate(payment, organization, status);
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
console.error('Payment check failed Stripe', payment.id, e);
|
|
134
|
+
if (this.isManualExpired(payment.status, payment)) {
|
|
135
|
+
console.error('Manually marking Stripe payment as expired', payment.id);
|
|
136
|
+
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
137
|
+
}
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
140
|
+
else if (payment.provider === PaymentProvider.Mollie) {
|
|
141
|
+
// check status via mollie
|
|
142
|
+
const molliePayments = await MolliePayment.where({ paymentId: payment.id }, { limit: 1 });
|
|
143
|
+
if (molliePayments.length == 1) {
|
|
144
|
+
const molliePayment = molliePayments[0];
|
|
145
|
+
// check status
|
|
146
|
+
const token = await MollieToken.getTokenFor(organization.id);
|
|
147
|
+
|
|
148
|
+
if (token) {
|
|
149
|
+
try {
|
|
150
|
+
const mollieClient = createMollieClient({ accessToken: await token.getAccessToken() });
|
|
151
|
+
const mollieData = await mollieClient.payments.get(molliePayment.mollieId, {
|
|
152
|
+
testmode: organization.privateMeta.useTestPayments ?? STAMHOOFD.environment !== 'production',
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
console.log(mollieData); // log to log files to check issues
|
|
156
|
+
|
|
157
|
+
const details = mollieData.details as any;
|
|
158
|
+
if (details?.consumerName) {
|
|
159
|
+
payment.ibanName = details.consumerName;
|
|
160
|
+
}
|
|
161
|
+
if (details?.consumerAccount) {
|
|
162
|
+
payment.iban = details.consumerAccount;
|
|
163
|
+
}
|
|
164
|
+
if (details?.cardHolder) {
|
|
165
|
+
payment.ibanName = details.cardHolder;
|
|
166
|
+
}
|
|
167
|
+
if (details?.cardNumber) {
|
|
168
|
+
payment.iban = 'xxxx xxxx xxxx ' + details.cardNumber;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (mollieData.status === MolliePaymentStatus.paid) {
|
|
172
|
+
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Succeeded);
|
|
173
|
+
}
|
|
174
|
+
else if (mollieData.status === MolliePaymentStatus.failed || mollieData.status === MolliePaymentStatus.expired || mollieData.status === MolliePaymentStatus.canceled) {
|
|
175
|
+
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
176
|
+
}
|
|
177
|
+
else if (this.isManualExpired(payment.status, payment)) {
|
|
178
|
+
// Mollie still returning pending after 1 day: mark as failed
|
|
179
|
+
console.error('Manually marking Mollie payment as expired', payment.id);
|
|
180
|
+
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
181
|
+
}
|
|
158
182
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (mollieData.status === MolliePaymentStatus.paid) {
|
|
167
|
-
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Succeeded);
|
|
168
|
-
}
|
|
169
|
-
else if (mollieData.status === MolliePaymentStatus.failed || mollieData.status === MolliePaymentStatus.expired || mollieData.status === MolliePaymentStatus.canceled) {
|
|
170
|
-
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
171
|
-
}
|
|
172
|
-
else if (this.isManualExpired(payment.status, payment)) {
|
|
173
|
-
// Mollie still returning pending after 1 day: mark as failed
|
|
174
|
-
console.error('Manually marking Mollie payment as expired', payment.id);
|
|
175
|
-
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
183
|
+
catch (e) {
|
|
184
|
+
console.error('Payment check failed Mollie', payment.id, e);
|
|
185
|
+
if (this.isManualExpired(payment.status, payment)) {
|
|
186
|
+
console.error('Manually marking Mollie payment as expired', payment.id);
|
|
187
|
+
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
188
|
+
}
|
|
176
189
|
}
|
|
177
190
|
}
|
|
178
|
-
|
|
179
|
-
console.
|
|
191
|
+
else {
|
|
192
|
+
console.warn('Mollie payment is missing for organization ' + organization.id + ' while checking payment status...');
|
|
193
|
+
|
|
180
194
|
if (this.isManualExpired(payment.status, payment)) {
|
|
181
|
-
console.error('Manually marking
|
|
195
|
+
console.error('Manually marking payment without mollie token as expired', payment.id);
|
|
182
196
|
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
183
197
|
}
|
|
184
198
|
}
|
|
185
199
|
}
|
|
186
200
|
else {
|
|
187
|
-
console.warn('Mollie payment is missing for organization ' + organization.id + ' while checking payment status...');
|
|
188
|
-
|
|
189
201
|
if (this.isManualExpired(payment.status, payment)) {
|
|
190
|
-
console.error('Manually marking payment without mollie
|
|
202
|
+
console.error('Manually marking payment without mollie payments as expired', payment.id);
|
|
191
203
|
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
192
204
|
}
|
|
193
205
|
}
|
|
194
206
|
}
|
|
195
|
-
else {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
await
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
else if (payment.provider == PaymentProvider.Buckaroo) {
|
|
203
|
-
const helper = new BuckarooHelper(organization.privateMeta.buckarooSettings?.key ?? '', organization.privateMeta.buckarooSettings?.secret ?? '', organization.privateMeta.useTestPayments ?? STAMHOOFD.environment !== 'production');
|
|
204
|
-
try {
|
|
205
|
-
let status = await helper.getStatus(payment);
|
|
206
|
-
|
|
207
|
-
if (this.isManualExpired(status, payment)) {
|
|
208
|
-
console.error('Manually marking Buckaroo payment as expired', payment.id);
|
|
209
|
-
status = PaymentStatus.Failed;
|
|
210
|
-
}
|
|
207
|
+
else if (payment.provider == PaymentProvider.Buckaroo) {
|
|
208
|
+
const helper = new BuckarooHelper(organization.privateMeta.buckarooSettings?.key ?? '', organization.privateMeta.buckarooSettings?.secret ?? '', organization.privateMeta.useTestPayments ?? STAMHOOFD.environment !== 'production');
|
|
209
|
+
try {
|
|
210
|
+
let status = await helper.getStatus(payment);
|
|
211
211
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
212
|
+
if (this.isManualExpired(status, payment)) {
|
|
213
|
+
console.error('Manually marking Buckaroo payment as expired', payment.id);
|
|
214
|
+
status = PaymentStatus.Failed;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
await this.handlePaymentStatusUpdate(payment, organization, status);
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
console.error('Payment check failed Buckaroo', payment.id, e);
|
|
221
|
+
if (this.isManualExpired(payment.status, payment)) {
|
|
222
|
+
console.error('Manually marking Buckaroo payment as expired', payment.id);
|
|
223
|
+
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
224
|
+
}
|
|
219
225
|
}
|
|
220
226
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
// Check status
|
|
227
|
+
else if (payment.provider == PaymentProvider.Payconiq) {
|
|
228
|
+
// Check status
|
|
224
229
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
230
|
+
const payconiqPayments = await PayconiqPayment.where({ paymentId: payment.id }, { limit: 1 });
|
|
231
|
+
if (payconiqPayments.length == 1) {
|
|
232
|
+
const payconiqPayment = payconiqPayments[0];
|
|
228
233
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
if (cancel) {
|
|
235
|
+
console.error('Cancelling Payconiq payment on request', payment.id);
|
|
236
|
+
await payconiqPayment.cancel(organization);
|
|
237
|
+
}
|
|
233
238
|
|
|
234
|
-
|
|
239
|
+
let status = await payconiqPayment.getStatus(organization);
|
|
235
240
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
241
|
+
if (!cancel && this.shouldTryToCancel(status, payment)) {
|
|
242
|
+
console.error('Manually cancelling Payconiq payment', payment.id);
|
|
243
|
+
if (await payconiqPayment.cancel(organization)) {
|
|
244
|
+
status = PaymentStatus.Failed;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (this.isManualExpired(status, payment)) {
|
|
249
|
+
console.error('Manually marking Payconiq payment as expired', payment.id);
|
|
239
250
|
status = PaymentStatus.Failed;
|
|
240
251
|
}
|
|
241
|
-
}
|
|
242
252
|
|
|
243
|
-
|
|
244
|
-
console.error('Manually marking Payconiq payment as expired', payment.id);
|
|
245
|
-
status = PaymentStatus.Failed;
|
|
253
|
+
await this.handlePaymentStatusUpdate(payment, organization, status);
|
|
246
254
|
}
|
|
255
|
+
else {
|
|
256
|
+
console.warn('Payconiq payment is missing for organization ' + organization.id + ' while checking payment status...');
|
|
247
257
|
|
|
248
|
-
|
|
258
|
+
if (this.isManualExpired(payment.status, payment)) {
|
|
259
|
+
console.error('Manually marking Payconiq payment as expired because not found', payment.id);
|
|
260
|
+
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
249
263
|
}
|
|
250
264
|
else {
|
|
251
|
-
console.
|
|
252
|
-
|
|
265
|
+
console.error('Invalid payment provider', payment.provider, 'for payment', payment.id);
|
|
253
266
|
if (this.isManualExpired(payment.status, payment)) {
|
|
254
|
-
console.error('Manually marking
|
|
267
|
+
console.error('Manually marking unknown payment as expired', payment.id);
|
|
255
268
|
await this.handlePaymentStatusUpdate(payment, organization, PaymentStatus.Failed);
|
|
256
269
|
}
|
|
257
270
|
}
|
|
258
271
|
}
|
|
259
272
|
else {
|
|
260
|
-
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
// Do a manual update if needed
|
|
269
|
-
if (payment.status === PaymentStatus.Succeeded) {
|
|
270
|
-
if (payment.provider === PaymentProvider.Stripe) {
|
|
271
|
-
// Update the status
|
|
272
|
-
await StripeHelper.getStatus(payment, false, testMode);
|
|
273
|
+
// Do a manual update if needed
|
|
274
|
+
if (payment.status === PaymentStatus.Succeeded) {
|
|
275
|
+
if (payment.provider === PaymentProvider.Stripe) {
|
|
276
|
+
// Update the status
|
|
277
|
+
await StripeHelper.getStatus(payment, false, testMode);
|
|
278
|
+
}
|
|
273
279
|
}
|
|
274
280
|
}
|
|
275
|
-
|
|
276
|
-
|
|
281
|
+
return payment;
|
|
282
|
+
});
|
|
277
283
|
});
|
|
278
284
|
},
|
|
279
285
|
|