@stamhoofd/backend 2.39.1 → 2.40.1
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/eslint.config.mjs +5 -0
- package/index.ts +81 -74
- package/jest.config.cjs +10 -0
- package/migrations.ts +16 -14
- package/package.json +11 -11
- package/src/crons/clear-excel-cache.test.ts +48 -50
- package/src/crons/clear-excel-cache.ts +18 -18
- package/src/crons/setup-steps.ts +2 -2
- package/src/crons.ts +325 -306
- package/src/decoders/StringArrayDecoder.ts +7 -7
- package/src/decoders/StringNullableDecoder.ts +1 -2
- package/src/email-recipient-loaders/members.ts +22 -22
- package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
- package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
- package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
- package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
- package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
- package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
- package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
- package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
- package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
- package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
- package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
- package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
- package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
- package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
- package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
- package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
- package/src/endpoints/auth/SignupEndpoint.ts +37 -36
- package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
- package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
- package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
- package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
- package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
- package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
- package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
- package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
- package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
- package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
- package/src/endpoints/global/files/GetFileCache.ts +13 -13
- package/src/endpoints/global/files/UploadFile.ts +51 -54
- package/src/endpoints/global/files/UploadImage.ts +53 -53
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
- package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
- package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
- package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
- package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
- package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
- package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
- package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
- package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
- package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
- package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
- package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
- package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
- package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
- package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
- package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
- package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
- package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
- package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
- package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
- package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
- package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
- package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
- package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
- package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
- package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
- package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
- package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
- package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
- package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
- package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
- package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
- package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
- package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
- package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
- package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
- package/src/excel-loaders/members.ts +275 -273
- package/src/excel-loaders/payments.ts +155 -156
- package/src/helpers/AddressValidator.test.ts +32 -32
- package/src/helpers/AddressValidator.ts +128 -122
- package/src/helpers/AdminPermissionChecker.ts +339 -236
- package/src/helpers/AuthenticatedStructures.ts +233 -134
- package/src/helpers/BuckarooHelper.ts +134 -134
- package/src/helpers/CheckSettlements.ts +94 -88
- package/src/helpers/Context.ts +87 -86
- package/src/helpers/CookieHelper.ts +23 -22
- package/src/helpers/EmailResumer.ts +10 -10
- package/src/helpers/FileCache.ts +62 -62
- package/src/helpers/ForwardHandler.test.ts +122 -124
- package/src/helpers/ForwardHandler.ts +76 -70
- package/src/helpers/MemberUserSyncer.ts +101 -96
- package/src/helpers/MembershipCharger.ts +69 -69
- package/src/helpers/MembershipHelper.ts +11 -12
- package/src/helpers/OpenIDConnectHelper.ts +85 -82
- package/src/helpers/PeriodHelper.ts +65 -70
- package/src/helpers/StripeHelper.ts +146 -137
- package/src/helpers/StripePayoutChecker.ts +51 -52
- package/src/helpers/ViesHelper.ts +46 -44
- package/src/helpers/fetchToAsyncIterator.ts +14 -14
- package/src/helpers/xlsxAddressTransformerColumnFactory.ts +58 -60
- package/src/middleware/ContextMiddleware.ts +5 -5
- package/src/migrations/1646578856-validate-addresses.ts +6 -9
- package/src/seeds/0000000000-example.ts +3 -5
- package/src/seeds/1715028563-user-permissions.ts +16 -18
- package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
- package/src/seeds/1722344162-sync-member-users.ts +14 -15
- package/src/seeds/1722344162-update-membership.ts +6 -6
- package/src/seeds/1726055544-balance-item-paid.ts +4 -4
- package/src/seeds/1726055545-balance-item-pending.ts +4 -4
- package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
- package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
- package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
- package/src/seeds/1726847064-setup-steps.ts +16 -0
- package/src/sql-filters/balance-item-payments.ts +7 -7
- package/src/sql-filters/events.ts +14 -14
- package/src/sql-filters/members.ts +96 -96
- package/src/sql-filters/organizations.ts +139 -75
- package/src/sql-filters/payments.ts +28 -28
- package/src/sql-filters/registrations.ts +14 -14
- package/src/sql-sorters/events.ts +25 -25
- package/src/sql-sorters/members.ts +26 -26
- package/src/sql-sorters/organizations.ts +36 -36
- package/src/sql-sorters/payments.ts +26 -26
- package/tests/e2e/stock.test.ts +616 -621
- package/tests/e2e/tickets.test.ts +255 -260
- package/tests/helpers/StripeMocker.ts +177 -179
- package/tests/helpers/TestServer.ts +9 -9
- package/tests/jest.global.setup.ts +14 -13
- package/tests/jest.setup.ts +33 -32
- package/.eslintrc.js +0 -61
- package/jest.config.js +0 -11
- package/src/helpers/SetupStepsUpdater.ts +0 -359
- package/src/seeds/1724076679-setup-steps.ts +0 -16
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
import {Order, Payment, StripeCheckoutSession, StripePaymentIntent} from
|
|
2
|
-
import { Settlement } from
|
|
3
|
-
import Stripe from
|
|
1
|
+
import { Order, Payment, StripeCheckoutSession, StripePaymentIntent } from '@stamhoofd/models';
|
|
2
|
+
import { Settlement } from '@stamhoofd/structures';
|
|
3
|
+
import Stripe from 'stripe';
|
|
4
4
|
|
|
5
5
|
export class StripePayoutChecker {
|
|
6
6
|
private stripe: Stripe;
|
|
7
7
|
private stripePlatform: Stripe;
|
|
8
8
|
|
|
9
|
-
constructor({secretKey, stripeAccount}: { secretKey: string
|
|
9
|
+
constructor({ secretKey, stripeAccount }: { secretKey: string; stripeAccount?: string }) {
|
|
10
10
|
this.stripe = new Stripe(
|
|
11
11
|
secretKey, {
|
|
12
|
-
apiVersion: '2024-06-20',
|
|
13
|
-
typescript: true,
|
|
14
|
-
maxNetworkRetries: 1,
|
|
12
|
+
apiVersion: '2024-06-20',
|
|
13
|
+
typescript: true,
|
|
14
|
+
maxNetworkRetries: 1,
|
|
15
15
|
timeout: 10000,
|
|
16
|
-
stripeAccount
|
|
17
|
-
|
|
16
|
+
stripeAccount,
|
|
17
|
+
});
|
|
18
18
|
|
|
19
19
|
this.stripePlatform = new Stripe(
|
|
20
20
|
secretKey, {
|
|
21
|
-
apiVersion: '2024-06-20',
|
|
22
|
-
typescript: true,
|
|
23
|
-
maxNetworkRetries: 1,
|
|
24
|
-
timeout: 10000
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
apiVersion: '2024-06-20',
|
|
22
|
+
typescript: true,
|
|
23
|
+
maxNetworkRetries: 1,
|
|
24
|
+
timeout: 10000,
|
|
25
|
+
});
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
async checkSettlements(checkAll = false) {
|
|
30
|
-
|
|
31
|
-
const d = new Date()
|
|
32
|
-
d.setDate(d.getDate() - 17)
|
|
29
|
+
// Check last 2 weeks + 3 day margin, unless we check them all
|
|
30
|
+
const d = new Date();
|
|
31
|
+
d.setDate(d.getDate() - 17);
|
|
33
32
|
|
|
34
33
|
if (checkAll) {
|
|
35
|
-
d.setFullYear(2022, 11, 1)
|
|
34
|
+
d.setFullYear(2022, 11, 1);
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
// Loop all payouts
|
|
@@ -41,26 +40,26 @@ export class StripePayoutChecker {
|
|
|
41
40
|
for await (const payout of this.stripe.payouts.list({
|
|
42
41
|
status: 'paid',
|
|
43
42
|
arrival_date: {
|
|
44
|
-
gte: Math.floor(d.getTime() / 1000)
|
|
45
|
-
}
|
|
43
|
+
gte: Math.floor(d.getTime() / 1000),
|
|
44
|
+
},
|
|
46
45
|
})) {
|
|
47
46
|
// Get all payments for this payout
|
|
48
47
|
await this.fetchBalanceItems(payout);
|
|
49
48
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
console.error(e)
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
console.error(e);
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
|
|
56
55
|
private async fetchBalanceItems(payout: Stripe.Payout) {
|
|
57
56
|
// For the given payout, fetch all balance items
|
|
58
57
|
const params = {
|
|
59
|
-
payout: payout.id,
|
|
58
|
+
payout: payout.id,
|
|
60
59
|
// Via the Application Fee object, we can get the original payment metadata
|
|
61
60
|
expand: ['data.source', 'data.source.application_fee', 'data.source.application_fee.originating_transaction'],
|
|
62
61
|
// TODO: ALSO DO CARDS! (type: 'charge')
|
|
63
|
-
//type: 'payment'
|
|
62
|
+
// type: 'payment'
|
|
64
63
|
};
|
|
65
64
|
|
|
66
65
|
for await (const balanceItem of this.stripe.balanceTransactions.list(params)) {
|
|
@@ -79,7 +78,7 @@ export class StripePayoutChecker {
|
|
|
79
78
|
return;
|
|
80
79
|
}
|
|
81
80
|
if (balanceItem.source.object !== 'charge') {
|
|
82
|
-
console.log(
|
|
81
|
+
console.log('No payment id set for charge ' + balanceItem.source.id);
|
|
83
82
|
return;
|
|
84
83
|
}
|
|
85
84
|
|
|
@@ -99,67 +98,68 @@ export class StripePayoutChecker {
|
|
|
99
98
|
// Try to look it up by payment intent id
|
|
100
99
|
|
|
101
100
|
if (originatingTransaction.payment_intent) {
|
|
102
|
-
const paymentIntentId = typeof originatingTransaction.payment_intent === 'string' ? originatingTransaction.payment_intent : originatingTransaction.payment_intent.id
|
|
101
|
+
const paymentIntentId = typeof originatingTransaction.payment_intent === 'string' ? originatingTransaction.payment_intent : originatingTransaction.payment_intent.id;
|
|
103
102
|
const stripePayments = await StripePaymentIntent.where({
|
|
104
|
-
stripeIntentId: paymentIntentId
|
|
105
|
-
}, {limit: 1});
|
|
103
|
+
stripeIntentId: paymentIntentId,
|
|
104
|
+
}, { limit: 1 });
|
|
106
105
|
|
|
107
106
|
if (stripePayments.length === 1) {
|
|
108
107
|
paymentId = stripePayments[0].paymentId;
|
|
109
|
-
console.log(
|
|
110
|
-
}
|
|
108
|
+
console.log('Found missing payment metadata for payment intent ', originatingTransaction.payment_intent, paymentId);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
111
|
// Probably a card payment
|
|
112
112
|
// Search for the checkout session
|
|
113
113
|
const checkoutSession = await this.stripePlatform.checkout.sessions.list({
|
|
114
|
-
payment_intent: paymentIntentId
|
|
115
|
-
})
|
|
114
|
+
payment_intent: paymentIntentId,
|
|
115
|
+
});
|
|
116
116
|
if (checkoutSession.data.length === 1) {
|
|
117
117
|
const session = checkoutSession.data[0];
|
|
118
|
-
console.log(
|
|
118
|
+
console.log('Found checkout session for payment intent ', paymentIntentId, session);
|
|
119
119
|
|
|
120
120
|
// Search
|
|
121
121
|
const stripeCheckoutSessions = await StripeCheckoutSession.where({
|
|
122
|
-
stripeSessionId: session.id
|
|
123
|
-
}, {limit: 1});
|
|
122
|
+
stripeSessionId: session.id,
|
|
123
|
+
}, { limit: 1 });
|
|
124
124
|
|
|
125
125
|
if (stripeCheckoutSessions.length === 1) {
|
|
126
126
|
paymentId = stripeCheckoutSessions[0].paymentId;
|
|
127
|
-
console.log(
|
|
128
|
-
}
|
|
129
|
-
|
|
127
|
+
console.log('Found missing payment metadata for payment intent ', originatingTransaction.payment_intent, paymentId);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
console.log('No payment found for checkout session ' + session.id);
|
|
130
131
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.log('No Stripe Checkout Sessions found for payment intent ' + paymentIntentId);
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
138
|
}
|
|
137
139
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
if (!paymentId) {
|
|
144
|
-
console.log(balanceItem)
|
|
145
|
-
console.log(
|
|
144
|
+
console.log(balanceItem);
|
|
145
|
+
console.log('No payment id set for charge ' + balanceItem.source.id);
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
const applicationFee = balanceItem.source.application_fee_amount;
|
|
150
|
-
const otherFees = balanceItem.fee
|
|
150
|
+
const otherFees = balanceItem.fee;
|
|
151
151
|
const totalFees = otherFees + (applicationFee ?? 0);
|
|
152
152
|
|
|
153
153
|
// Cool, we can store this in the database now.
|
|
154
154
|
|
|
155
155
|
const payment = await Payment.getByID(paymentId);
|
|
156
156
|
if (!payment) {
|
|
157
|
-
console.log(
|
|
157
|
+
console.log('Invalid payment id set for charge ' + balanceItem.source.id + ': ' + paymentId);
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
if (payment.price !== balanceItem.amount) {
|
|
162
|
-
console.log(
|
|
162
|
+
console.log('Amount mismatch for payment ' + payment.id + ': ' + payment.price + ' !== ' + balanceItem.amount);
|
|
163
163
|
return;
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -169,7 +169,7 @@ export class StripePayoutChecker {
|
|
|
169
169
|
settledAt: new Date(payout.arrival_date * 1000),
|
|
170
170
|
amount: payout.amount,
|
|
171
171
|
// Set only if application fee is witheld
|
|
172
|
-
fee: totalFees
|
|
172
|
+
fee: totalFees,
|
|
173
173
|
});
|
|
174
174
|
|
|
175
175
|
payment.settlement = settlement;
|
|
@@ -177,7 +177,7 @@ export class StripePayoutChecker {
|
|
|
177
177
|
|
|
178
178
|
// Force an updatedAt timestamp of the related order
|
|
179
179
|
// Mark order as 'updated', or the frontend won't pull in the updates
|
|
180
|
-
const order = await Order.getForPayment(null, payment.id)
|
|
180
|
+
const order = await Order.getForPayment(null, payment.id);
|
|
181
181
|
if (order) {
|
|
182
182
|
order.updatedAt = new Date();
|
|
183
183
|
order.forceSaveProperty('updatedAt');
|
|
@@ -186,5 +186,4 @@ export class StripePayoutChecker {
|
|
|
186
186
|
|
|
187
187
|
await payment.save();
|
|
188
188
|
}
|
|
189
|
-
|
|
190
189
|
}
|
|
@@ -7,26 +7,25 @@ import * as jsvat from 'jsvat-next'; // has no default export, so we need the wi
|
|
|
7
7
|
export class ViesHelperStatic {
|
|
8
8
|
testMode = false;
|
|
9
9
|
|
|
10
|
-
async request(method:
|
|
10
|
+
async request(method: 'GET' | 'POST', url: string, content: any) {
|
|
11
|
+
const json = content ? JSON.stringify(content) : '';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
console.log("[VIES REQUEST]", method, url, content ? "\n [VIES REQUEST] " : undefined, json)
|
|
13
|
+
console.log('[VIES REQUEST]', method, url, content ? '\n [VIES REQUEST] ' : undefined, json);
|
|
15
14
|
|
|
16
15
|
const response = await axios.request({
|
|
17
16
|
method,
|
|
18
17
|
url,
|
|
19
18
|
headers: {
|
|
20
|
-
'Content-Type': json.length > 0 ? 'application/json' :
|
|
19
|
+
'Content-Type': json.length > 0 ? 'application/json' : 'text/plain',
|
|
21
20
|
},
|
|
22
|
-
data: json
|
|
23
|
-
|
|
24
|
-
})
|
|
25
|
-
console.log(
|
|
26
|
-
return response.data
|
|
21
|
+
data: json,
|
|
22
|
+
|
|
23
|
+
});
|
|
24
|
+
console.log('[VIES RESPONSE]', method, url, '\n[VIES RESPONSE]', JSON.stringify(response.data));
|
|
25
|
+
return response.data;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
async checkCompany(company: Company, patch: AutoEncoderPatchType<Company
|
|
28
|
+
async checkCompany(company: Company, patch: AutoEncoderPatchType<Company> | Company) {
|
|
30
29
|
if (!company.address) {
|
|
31
30
|
// Not allowed to set
|
|
32
31
|
patch.companyNumber = null;
|
|
@@ -36,32 +35,33 @@ export class ViesHelperStatic {
|
|
|
36
35
|
|
|
37
36
|
if (company.VATNumber !== null) {
|
|
38
37
|
// Changed VAT number
|
|
39
|
-
patch.VATNumber = await ViesHelper.checkVATNumber(company.address.country, company.VATNumber)
|
|
38
|
+
patch.VATNumber = await ViesHelper.checkVATNumber(company.address.country, company.VATNumber);
|
|
40
39
|
|
|
41
40
|
if (company.address.country === Country.Belgium) {
|
|
42
|
-
patch.companyNumber = company.VATNumber
|
|
41
|
+
patch.companyNumber = company.VATNumber;
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
if (company.companyNumber) {
|
|
47
46
|
if (company.VATNumber !== null && company.address.country === Country.Belgium) {
|
|
48
47
|
// Already validated
|
|
49
|
-
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
50
|
// Need to validate
|
|
51
|
-
const result = await ViesHelper.checkCompanyNumber(company.address.country, company.companyNumber)
|
|
52
|
-
patch.companyNumber = result.companyNumber
|
|
51
|
+
const result = await ViesHelper.checkCompanyNumber(company.address.country, company.companyNumber);
|
|
52
|
+
patch.companyNumber = result.companyNumber;
|
|
53
53
|
if (result.VATNumber !== undefined) {
|
|
54
|
-
patch.VATNumber = result.VATNumber
|
|
54
|
+
patch.VATNumber = result.VATNumber;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
async checkCompanyNumber(country: Country, companyNumber: string): Promise<{companyNumber: string|null
|
|
60
|
+
async checkCompanyNumber(country: Country, companyNumber: string): Promise<{ companyNumber: string | null; VATNumber?: string | null }> {
|
|
61
61
|
if (country !== Country.Belgium) {
|
|
62
62
|
// Not supported
|
|
63
63
|
return {
|
|
64
|
-
companyNumber
|
|
64
|
+
companyNumber,
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -71,10 +71,10 @@ export class ViesHelperStatic {
|
|
|
71
71
|
|
|
72
72
|
if (!result.isValid) {
|
|
73
73
|
throw new SimpleError({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
})
|
|
74
|
+
code: 'invalid_field',
|
|
75
|
+
message: 'Ongeldig ondernemingsnummer: ' + companyNumber,
|
|
76
|
+
field: 'companyNumber',
|
|
77
|
+
});
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// If this is a valid VAT number, we can assume it's a valid company number
|
|
@@ -84,12 +84,14 @@ export class ViesHelperStatic {
|
|
|
84
84
|
// this is a VAT number, not a company number
|
|
85
85
|
return {
|
|
86
86
|
companyNumber: corrected,
|
|
87
|
-
VATNumber: corrected
|
|
88
|
-
}
|
|
89
|
-
}
|
|
87
|
+
VATNumber: corrected,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
90
91
|
if (isSimpleError(e) || isSimpleErrors(e)) {
|
|
91
92
|
// Ignore: normal that it is not a valid VAT number
|
|
92
|
-
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
93
95
|
// Other errors should be thrown
|
|
94
96
|
throw e;
|
|
95
97
|
}
|
|
@@ -99,7 +101,7 @@ export class ViesHelperStatic {
|
|
|
99
101
|
companyNumber: result.value ?? companyNumber,
|
|
100
102
|
|
|
101
103
|
// VATNumber should always be set to null if it is not a valid VAT number
|
|
102
|
-
VATNumber: null
|
|
104
|
+
VATNumber: null,
|
|
103
105
|
};
|
|
104
106
|
}
|
|
105
107
|
|
|
@@ -108,34 +110,35 @@ export class ViesHelperStatic {
|
|
|
108
110
|
|
|
109
111
|
if (!result.isValid) {
|
|
110
112
|
throw new SimpleError({
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
})
|
|
115
|
-
}
|
|
113
|
+
code: 'invalid_field',
|
|
114
|
+
message: 'Ongeldig BTW-nummer: ' + vatNumber,
|
|
115
|
+
field: 'VATNumber',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
116
118
|
|
|
117
119
|
const formatted = result.value ?? vatNumber;
|
|
118
120
|
|
|
119
121
|
try {
|
|
120
|
-
const cleaned = formatted.substring(2).replace(/(
|
|
121
|
-
const response = await this.request(
|
|
122
|
+
const cleaned = formatted.substring(2).replace(/(\.-\s)+/g, '');
|
|
123
|
+
const response = await this.request('POST', 'https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number', {
|
|
122
124
|
countryCode: country,
|
|
123
|
-
vatNumber: cleaned
|
|
125
|
+
vatNumber: cleaned,
|
|
124
126
|
});
|
|
125
127
|
|
|
126
128
|
if (typeof response !== 'object' || response === null || typeof response.valid !== 'boolean') {
|
|
127
129
|
// APi error
|
|
128
|
-
throw new Error(
|
|
130
|
+
throw new Error('Invalid response from VIES');
|
|
129
131
|
}
|
|
130
|
-
|
|
132
|
+
|
|
131
133
|
if (!response.valid) {
|
|
132
134
|
throw new SimpleError({
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
})
|
|
135
|
+
code: 'invalid_field',
|
|
136
|
+
message: 'Het opgegeven BTW-nummer is ongeldig of niet BTW-plichtig: ' + formatted,
|
|
137
|
+
field: 'VATNumber',
|
|
138
|
+
});
|
|
137
139
|
}
|
|
138
|
-
}
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
139
142
|
if (isSimpleError(e) || isSimpleErrors(e)) {
|
|
140
143
|
throw e;
|
|
141
144
|
}
|
|
@@ -145,7 +148,6 @@ export class ViesHelperStatic {
|
|
|
145
148
|
|
|
146
149
|
return formatted;
|
|
147
150
|
}
|
|
148
|
-
|
|
149
151
|
}
|
|
150
152
|
|
|
151
153
|
export const ViesHelper = new ViesHelperStatic();
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { IPaginatedResponse, LimitedFilteredRequest } from
|
|
1
|
+
import { IPaginatedResponse, LimitedFilteredRequest } from '@stamhoofd/structures';
|
|
2
2
|
|
|
3
3
|
export function fetchToAsyncIterator<T>(
|
|
4
|
-
initialFilter: LimitedFilteredRequest,
|
|
4
|
+
initialFilter: LimitedFilteredRequest,
|
|
5
5
|
loader: {
|
|
6
|
-
fetch(request: LimitedFilteredRequest): Promise<IPaginatedResponse<T, LimitedFilteredRequest
|
|
7
|
-
}
|
|
6
|
+
fetch(request: LimitedFilteredRequest): Promise<IPaginatedResponse<T, LimitedFilteredRequest>>;
|
|
7
|
+
},
|
|
8
8
|
): AsyncIterable<T> {
|
|
9
9
|
return {
|
|
10
10
|
[Symbol.asyncIterator]: function () {
|
|
11
|
-
let request: LimitedFilteredRequest|null = initialFilter
|
|
11
|
+
let request: LimitedFilteredRequest | null = initialFilter;
|
|
12
12
|
|
|
13
13
|
return {
|
|
14
14
|
async next(): Promise<IteratorResult<T, undefined>> {
|
|
15
15
|
if (!request) {
|
|
16
16
|
return {
|
|
17
17
|
done: true,
|
|
18
|
-
value: undefined
|
|
19
|
-
}
|
|
18
|
+
value: undefined,
|
|
19
|
+
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const response = await loader.fetch(request);
|
|
23
23
|
request = response.next ?? null;
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
return {
|
|
26
26
|
done: false,
|
|
27
|
-
value: response.results
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
27
|
+
value: response.results,
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
33
|
}
|