@fantastic.dev/better-stripe 0.15.0 → 0.16.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/CHANGELOG.md +6 -0
- package/MIGRATION.md +6 -0
- package/README.md +7 -1
- package/dist/client/connect/payoutSnapshot.d.ts +2 -0
- package/dist/client/connect/payoutSnapshot.d.ts.map +1 -1
- package/dist/client/connect/payoutSnapshot.js +2 -0
- package/dist/client/connect/payoutSnapshot.js.map +1 -1
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/readContracts.d.ts +50 -0
- package/dist/client/readContracts.d.ts.map +1 -0
- package/dist/client/readContracts.js +24 -0
- package/dist/client/readContracts.js.map +1 -0
- package/dist/client/types/documents.d.ts +2 -0
- package/dist/client/types/documents.d.ts.map +1 -1
- package/dist/client/webhooks/processors.js +2 -0
- package/dist/client/webhooks/processors.js.map +1 -1
- package/dist/component/_generated/component.d.ts +177 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/connect/mutations.d.ts +2 -0
- package/dist/component/connect/mutations.d.ts.map +1 -1
- package/dist/component/connect/mutations.js +8 -8
- package/dist/component/connect/mutations.js.map +1 -1
- package/dist/component/connect/queries.d.ts +102 -2
- package/dist/component/connect/queries.d.ts.map +1 -1
- package/dist/component/connect/queries.js +88 -45
- package/dist/component/connect/queries.js.map +1 -1
- package/dist/component/connect/schema.d.ts +12 -2
- package/dist/component/connect/schema.d.ts.map +1 -1
- package/dist/component/connect/schema.js +10 -1
- package/dist/component/connect/schema.js.map +1 -1
- package/dist/component/connect/validators.d.ts +13 -2
- package/dist/component/connect/validators.d.ts.map +1 -1
- package/dist/component/connect/validators.js +4 -0
- package/dist/component/connect/validators.js.map +1 -1
- package/dist/component/earnings/legacyReads.d.ts +51 -0
- package/dist/component/earnings/legacyReads.d.ts.map +1 -0
- package/dist/component/earnings/legacyReads.js +43 -0
- package/dist/component/earnings/legacyReads.js.map +1 -0
- package/dist/component/earnings/mutations.d.ts +9 -0
- package/dist/component/earnings/mutations.d.ts.map +1 -0
- package/dist/component/earnings/mutations.js +23 -0
- package/dist/component/earnings/mutations.js.map +1 -0
- package/dist/component/earnings/reads.d.ts +14 -0
- package/dist/component/earnings/reads.d.ts.map +1 -0
- package/dist/component/earnings/reads.js +28 -0
- package/dist/component/earnings/reads.js.map +1 -0
- package/dist/component/earnings/schema.d.ts +20 -0
- package/dist/component/earnings/schema.d.ts.map +1 -0
- package/dist/component/earnings/schema.js +12 -0
- package/dist/component/earnings/schema.js.map +1 -0
- package/dist/component/earnings/triggers.d.ts +1290 -0
- package/dist/component/earnings/triggers.d.ts.map +1 -0
- package/dist/component/earnings/triggers.js +68 -0
- package/dist/component/earnings/triggers.js.map +1 -0
- package/dist/component/products/queries.d.ts +47 -0
- package/dist/component/products/queries.d.ts.map +1 -1
- package/dist/component/products/queries.js +59 -0
- package/dist/component/products/queries.js.map +1 -1
- package/dist/component/schema.d.ts +31 -2
- package/dist/component/schema.js +2 -0
- package/dist/component/schema.js.map +1 -1
- package/dist/react/components/EarningsSummary.d.ts +3 -1
- package/dist/react/components/EarningsSummary.d.ts.map +1 -1
- package/dist/react/components/EarningsSummary.js +3 -3
- package/dist/react/components/EarningsSummary.js.map +1 -1
- package/dist/react/hooks/useCurrencyEarnings.d.ts +31 -0
- package/dist/react/hooks/useCurrencyEarnings.d.ts.map +1 -0
- package/dist/react/hooks/useCurrencyEarnings.js +30 -0
- package/dist/react/hooks/useCurrencyEarnings.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +3 -0
- package/dist/react/index.js.map +1 -1
- package/docs/react-workflows.md +6 -0
- package/docs/read-contracts.md +136 -0
- package/package.json +3 -2
- package/src/client/connect/payoutSnapshot.test.ts +27 -0
- package/src/client/connect/payoutSnapshot.ts +4 -0
- package/src/client/index.ts +4 -4
- package/src/client/readContracts.ts +90 -0
- package/src/client/readPagination.test.ts +62 -0
- package/src/client/types/documents.ts +2 -0
- package/src/client/webhooks/payout-canceled.integration.test.ts +25 -0
- package/src/client/webhooks/processors.ts +2 -0
- package/src/component/_generated/api.ts +8 -0
- package/src/component/_generated/component.ts +201 -0
- package/src/component/connect/mutations.ts +8 -8
- package/src/component/connect/queries.ts +110 -48
- package/src/component/connect/schema.ts +10 -1
- package/src/component/connect/validators.ts +4 -0
- package/src/component/currency-migration.test.ts +119 -0
- package/src/component/currency-totals.test.ts +95 -0
- package/src/component/earnings/legacyReads.ts +59 -0
- package/src/component/earnings/mutations.ts +21 -0
- package/src/component/earnings/reads.ts +41 -0
- package/src/component/earnings/schema.ts +11 -0
- package/src/component/earnings/triggers.ts +91 -0
- package/src/component/products/queries.ts +74 -0
- package/src/component/public.test.ts +1 -1
- package/src/component/read-pagination.test.ts +193 -0
- package/src/component/schema.ts +2 -0
- package/src/react/components/EarningsSummary.tsx +5 -2
- package/src/react/hooks/useCurrencyEarnings.test.ts +59 -0
- package/src/react/hooks/useCurrencyEarnings.ts +73 -0
- package/src/react/index.ts +12 -0
- package/src/react/read-contracts.render.test.tsx +20 -0
|
@@ -882,6 +882,8 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
882
882
|
amount: number;
|
|
883
883
|
arrivalDate?: string;
|
|
884
884
|
currency: string;
|
|
885
|
+
failureCode?: string;
|
|
886
|
+
failureMessage?: string;
|
|
885
887
|
metadata?: any;
|
|
886
888
|
method?: string;
|
|
887
889
|
status: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
@@ -965,6 +967,41 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
965
967
|
sourceInvoiceId?: string;
|
|
966
968
|
status: "pending" | "paid" | "failed" | "reversed";
|
|
967
969
|
stripeTransferId: string;
|
|
970
|
+
totalsRecorded?: true;
|
|
971
|
+
}>;
|
|
972
|
+
},
|
|
973
|
+
Name
|
|
974
|
+
>;
|
|
975
|
+
getAccountEarningsByCurrency: FunctionReference<
|
|
976
|
+
"query",
|
|
977
|
+
"internal",
|
|
978
|
+
{ destinationAccountId: string; previewLimit?: number },
|
|
979
|
+
{
|
|
980
|
+
totals: Array<{
|
|
981
|
+
currency: string;
|
|
982
|
+
gross: number;
|
|
983
|
+
net: number;
|
|
984
|
+
reversed: number;
|
|
985
|
+
transferCount: number;
|
|
986
|
+
}>;
|
|
987
|
+
transfers: Array<{
|
|
988
|
+
_creationTime: number;
|
|
989
|
+
_id: string;
|
|
990
|
+
amount: number;
|
|
991
|
+
currency: string;
|
|
992
|
+
destinationAccountId: string;
|
|
993
|
+
metadata?: any;
|
|
994
|
+
paymentId?: string;
|
|
995
|
+
reinstatement?: boolean;
|
|
996
|
+
reversalClaimedAmount?: number;
|
|
997
|
+
reversalStatus?: "partially_reversed" | "fully_reversed";
|
|
998
|
+
reversedAmount?: number;
|
|
999
|
+
role?: "store" | "affiliate" | "other";
|
|
1000
|
+
sourceChargeId?: string;
|
|
1001
|
+
sourceInvoiceId?: string;
|
|
1002
|
+
status: "pending" | "paid" | "failed" | "reversed";
|
|
1003
|
+
stripeTransferId: string;
|
|
1004
|
+
totalsRecorded?: true;
|
|
968
1005
|
}>;
|
|
969
1006
|
},
|
|
970
1007
|
Name
|
|
@@ -983,10 +1020,41 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
983
1020
|
amount: number;
|
|
984
1021
|
arrivalDate?: string;
|
|
985
1022
|
currency: string;
|
|
1023
|
+
failureCode?: string;
|
|
1024
|
+
failureMessage?: string;
|
|
986
1025
|
metadata?: any;
|
|
987
1026
|
method?: string;
|
|
988
1027
|
status: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
989
1028
|
stripePayoutId: string;
|
|
1029
|
+
totalsRecorded?: true;
|
|
1030
|
+
}>;
|
|
1031
|
+
},
|
|
1032
|
+
Name
|
|
1033
|
+
>;
|
|
1034
|
+
getAccountPayoutsByCurrency: FunctionReference<
|
|
1035
|
+
"query",
|
|
1036
|
+
"internal",
|
|
1037
|
+
{ accountId: string; previewLimit?: number },
|
|
1038
|
+
{
|
|
1039
|
+
payouts: Array<{
|
|
1040
|
+
_creationTime: number;
|
|
1041
|
+
_id: string;
|
|
1042
|
+
accountId: string;
|
|
1043
|
+
amount: number;
|
|
1044
|
+
arrivalDate?: string;
|
|
1045
|
+
currency: string;
|
|
1046
|
+
failureCode?: string;
|
|
1047
|
+
failureMessage?: string;
|
|
1048
|
+
metadata?: any;
|
|
1049
|
+
method?: string;
|
|
1050
|
+
status: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
1051
|
+
stripePayoutId: string;
|
|
1052
|
+
totalsRecorded?: true;
|
|
1053
|
+
}>;
|
|
1054
|
+
totals: Array<{
|
|
1055
|
+
currency: string;
|
|
1056
|
+
paidOut: number;
|
|
1057
|
+
payoutCount: number;
|
|
990
1058
|
}>;
|
|
991
1059
|
},
|
|
992
1060
|
Name
|
|
@@ -1072,10 +1140,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1072
1140
|
amount: number;
|
|
1073
1141
|
arrivalDate?: string;
|
|
1074
1142
|
currency: string;
|
|
1143
|
+
failureCode?: string;
|
|
1144
|
+
failureMessage?: string;
|
|
1075
1145
|
metadata?: any;
|
|
1076
1146
|
method?: string;
|
|
1077
1147
|
status: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
1078
1148
|
stripePayoutId: string;
|
|
1149
|
+
totalsRecorded?: true;
|
|
1079
1150
|
} | null,
|
|
1080
1151
|
Name
|
|
1081
1152
|
>;
|
|
@@ -1090,10 +1161,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1090
1161
|
amount: number;
|
|
1091
1162
|
arrivalDate?: string;
|
|
1092
1163
|
currency: string;
|
|
1164
|
+
failureCode?: string;
|
|
1165
|
+
failureMessage?: string;
|
|
1093
1166
|
metadata?: any;
|
|
1094
1167
|
method?: string;
|
|
1095
1168
|
status: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
1096
1169
|
stripePayoutId: string;
|
|
1170
|
+
totalsRecorded?: true;
|
|
1097
1171
|
} | null,
|
|
1098
1172
|
Name
|
|
1099
1173
|
>;
|
|
@@ -1164,6 +1238,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1164
1238
|
sourceInvoiceId?: string;
|
|
1165
1239
|
status: "pending" | "paid" | "failed" | "reversed";
|
|
1166
1240
|
stripeTransferId: string;
|
|
1241
|
+
totalsRecorded?: true;
|
|
1167
1242
|
} | null,
|
|
1168
1243
|
Name
|
|
1169
1244
|
>;
|
|
@@ -1228,10 +1303,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1228
1303
|
amount: number;
|
|
1229
1304
|
arrivalDate?: string;
|
|
1230
1305
|
currency: string;
|
|
1306
|
+
failureCode?: string;
|
|
1307
|
+
failureMessage?: string;
|
|
1231
1308
|
metadata?: any;
|
|
1232
1309
|
method?: string;
|
|
1233
1310
|
status: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
1234
1311
|
stripePayoutId: string;
|
|
1312
|
+
totalsRecorded?: true;
|
|
1235
1313
|
}>,
|
|
1236
1314
|
Name
|
|
1237
1315
|
>;
|
|
@@ -1295,6 +1373,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1295
1373
|
sourceInvoiceId?: string;
|
|
1296
1374
|
status: "pending" | "paid" | "failed" | "reversed";
|
|
1297
1375
|
stripeTransferId: string;
|
|
1376
|
+
totalsRecorded?: true;
|
|
1298
1377
|
}>,
|
|
1299
1378
|
Name
|
|
1300
1379
|
>;
|
|
@@ -1319,6 +1398,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1319
1398
|
sourceInvoiceId?: string;
|
|
1320
1399
|
status: "pending" | "paid" | "failed" | "reversed";
|
|
1321
1400
|
stripeTransferId: string;
|
|
1401
|
+
totalsRecorded?: true;
|
|
1322
1402
|
}>,
|
|
1323
1403
|
Name
|
|
1324
1404
|
>;
|
|
@@ -1340,6 +1420,44 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1340
1420
|
}>,
|
|
1341
1421
|
Name
|
|
1342
1422
|
>;
|
|
1423
|
+
paginatePayouts: FunctionReference<
|
|
1424
|
+
"query",
|
|
1425
|
+
"internal",
|
|
1426
|
+
{
|
|
1427
|
+
accountId: string;
|
|
1428
|
+
paginationOpts: {
|
|
1429
|
+
cursor: string | null;
|
|
1430
|
+
endCursor?: string | null;
|
|
1431
|
+
id?: number;
|
|
1432
|
+
maximumBytesRead?: number;
|
|
1433
|
+
maximumRowsRead?: number;
|
|
1434
|
+
numItems: number;
|
|
1435
|
+
};
|
|
1436
|
+
status?: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
continueCursor: string;
|
|
1440
|
+
isDone: boolean;
|
|
1441
|
+
page: Array<{
|
|
1442
|
+
_creationTime: number;
|
|
1443
|
+
_id: string;
|
|
1444
|
+
accountId: string;
|
|
1445
|
+
amount: number;
|
|
1446
|
+
arrivalDate?: string;
|
|
1447
|
+
currency: string;
|
|
1448
|
+
failureCode?: string;
|
|
1449
|
+
failureMessage?: string;
|
|
1450
|
+
metadata?: any;
|
|
1451
|
+
method?: string;
|
|
1452
|
+
status: "pending" | "paid" | "failed" | "canceled" | "in_transit";
|
|
1453
|
+
stripePayoutId: string;
|
|
1454
|
+
totalsRecorded?: true;
|
|
1455
|
+
}>;
|
|
1456
|
+
pageStatus?: "SplitRecommended" | "SplitRequired" | null;
|
|
1457
|
+
splitCursor?: string | null;
|
|
1458
|
+
},
|
|
1459
|
+
Name
|
|
1460
|
+
>;
|
|
1343
1461
|
paginateTransfersByAccount: FunctionReference<
|
|
1344
1462
|
"query",
|
|
1345
1463
|
"internal",
|
|
@@ -1374,6 +1492,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
1374
1492
|
sourceInvoiceId?: string;
|
|
1375
1493
|
status: "pending" | "paid" | "failed" | "reversed";
|
|
1376
1494
|
stripeTransferId: string;
|
|
1495
|
+
totalsRecorded?: true;
|
|
1377
1496
|
}>;
|
|
1378
1497
|
pageStatus?: "SplitRecommended" | "SplitRequired" | null;
|
|
1379
1498
|
splitCursor?: string | null;
|
|
@@ -2064,6 +2183,17 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2064
2183
|
>;
|
|
2065
2184
|
};
|
|
2066
2185
|
};
|
|
2186
|
+
earnings: {
|
|
2187
|
+
mutations: {
|
|
2188
|
+
backfillCurrencyTotals: FunctionReference<
|
|
2189
|
+
"mutation",
|
|
2190
|
+
"internal",
|
|
2191
|
+
{ cursor: string | null; kind: "earnings" | "payouts" },
|
|
2192
|
+
{ continueCursor: string; isDone: boolean },
|
|
2193
|
+
Name
|
|
2194
|
+
>;
|
|
2195
|
+
};
|
|
2196
|
+
};
|
|
2067
2197
|
products: {
|
|
2068
2198
|
mutations: {
|
|
2069
2199
|
upsertPrice: FunctionReference<
|
|
@@ -2233,6 +2363,77 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
|
2233
2363
|
}>,
|
|
2234
2364
|
Name
|
|
2235
2365
|
>;
|
|
2366
|
+
paginatePrices: FunctionReference<
|
|
2367
|
+
"query",
|
|
2368
|
+
"internal",
|
|
2369
|
+
{
|
|
2370
|
+
active?: boolean;
|
|
2371
|
+
paginationOpts: {
|
|
2372
|
+
cursor: string | null;
|
|
2373
|
+
endCursor?: string | null;
|
|
2374
|
+
id?: number;
|
|
2375
|
+
maximumBytesRead?: number;
|
|
2376
|
+
maximumRowsRead?: number;
|
|
2377
|
+
numItems: number;
|
|
2378
|
+
};
|
|
2379
|
+
productId?: string;
|
|
2380
|
+
},
|
|
2381
|
+
{
|
|
2382
|
+
continueCursor: string;
|
|
2383
|
+
isDone: boolean;
|
|
2384
|
+
page: Array<{
|
|
2385
|
+
_creationTime: number;
|
|
2386
|
+
_id: string;
|
|
2387
|
+
active: boolean;
|
|
2388
|
+
currency: string;
|
|
2389
|
+
interval?: "day" | "week" | "month" | "year";
|
|
2390
|
+
intervalCount?: number;
|
|
2391
|
+
metadata?: any;
|
|
2392
|
+
nickname?: string;
|
|
2393
|
+
productId: string;
|
|
2394
|
+
stripePriceId: string;
|
|
2395
|
+
stripeProductId: string;
|
|
2396
|
+
type: "one_time" | "recurring";
|
|
2397
|
+
unitAmount: number;
|
|
2398
|
+
}>;
|
|
2399
|
+
pageStatus?: "SplitRecommended" | "SplitRequired" | null;
|
|
2400
|
+
splitCursor?: string | null;
|
|
2401
|
+
},
|
|
2402
|
+
Name
|
|
2403
|
+
>;
|
|
2404
|
+
paginateProducts: FunctionReference<
|
|
2405
|
+
"query",
|
|
2406
|
+
"internal",
|
|
2407
|
+
{
|
|
2408
|
+
accountId?: string;
|
|
2409
|
+
active?: boolean;
|
|
2410
|
+
paginationOpts: {
|
|
2411
|
+
cursor: string | null;
|
|
2412
|
+
endCursor?: string | null;
|
|
2413
|
+
id?: number;
|
|
2414
|
+
maximumBytesRead?: number;
|
|
2415
|
+
maximumRowsRead?: number;
|
|
2416
|
+
numItems: number;
|
|
2417
|
+
};
|
|
2418
|
+
},
|
|
2419
|
+
{
|
|
2420
|
+
continueCursor: string;
|
|
2421
|
+
isDone: boolean;
|
|
2422
|
+
page: Array<{
|
|
2423
|
+
_creationTime: number;
|
|
2424
|
+
_id: string;
|
|
2425
|
+
accountId?: string;
|
|
2426
|
+
active: boolean;
|
|
2427
|
+
description?: string;
|
|
2428
|
+
metadata?: any;
|
|
2429
|
+
name: string;
|
|
2430
|
+
stripeProductId: string;
|
|
2431
|
+
}>;
|
|
2432
|
+
pageStatus?: "SplitRecommended" | "SplitRequired" | null;
|
|
2433
|
+
splitCursor?: string | null;
|
|
2434
|
+
},
|
|
2435
|
+
Name
|
|
2436
|
+
>;
|
|
2236
2437
|
};
|
|
2237
2438
|
};
|
|
2238
2439
|
settlement: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { v } from "convex/values";
|
|
2
2
|
|
|
3
3
|
import type { Doc, Id } from "../_generated/dataModel";
|
|
4
|
-
import { mutation } from "../
|
|
4
|
+
import { mutation } from "../earnings/triggers.js";
|
|
5
5
|
import { feeRoutingFields } from "../lib/fees";
|
|
6
6
|
import { computeReversalSlices, deriveReversalState } from "../lib/reversals";
|
|
7
7
|
import { paymentSeller } from "../lib/paymentSeller";
|
|
@@ -121,6 +121,8 @@ export const upsertPayout = mutation({
|
|
|
121
121
|
status: payoutStatusValidator,
|
|
122
122
|
arrivalDate: v.optional(v.string()),
|
|
123
123
|
method: v.optional(v.string()),
|
|
124
|
+
failureCode: v.optional(v.string()),
|
|
125
|
+
failureMessage: v.optional(v.string()),
|
|
124
126
|
metadata: v.optional(v.any()),
|
|
125
127
|
},
|
|
126
128
|
returns: v.null(),
|
|
@@ -133,7 +135,11 @@ export const upsertPayout = mutation({
|
|
|
133
135
|
.first();
|
|
134
136
|
|
|
135
137
|
if (existing) {
|
|
136
|
-
await ctx.db.patch("payouts", existing._id,
|
|
138
|
+
await ctx.db.patch("payouts", existing._id, {
|
|
139
|
+
...args,
|
|
140
|
+
failureCode: args.failureCode,
|
|
141
|
+
failureMessage: args.failureMessage,
|
|
142
|
+
});
|
|
137
143
|
} else {
|
|
138
144
|
await ctx.db.insert("payouts", args);
|
|
139
145
|
}
|
|
@@ -142,9 +148,7 @@ export const upsertPayout = mutation({
|
|
|
142
148
|
},
|
|
143
149
|
});
|
|
144
150
|
|
|
145
|
-
// =============================================================================
|
|
146
151
|
// REFUND MUTATIONS
|
|
147
|
-
// =============================================================================
|
|
148
152
|
|
|
149
153
|
export const upsertRefund = mutation({
|
|
150
154
|
args: refundFields,
|
|
@@ -283,9 +287,7 @@ export const recordPaymentFeeRefund = mutation({
|
|
|
283
287
|
},
|
|
284
288
|
});
|
|
285
289
|
|
|
286
|
-
// =============================================================================
|
|
287
290
|
// DISPUTE MUTATIONS
|
|
288
|
-
// =============================================================================
|
|
289
291
|
|
|
290
292
|
export const upsertDispute = mutation({
|
|
291
293
|
args: disputeFields,
|
|
@@ -311,9 +313,7 @@ export const upsertDispute = mutation({
|
|
|
311
313
|
},
|
|
312
314
|
});
|
|
313
315
|
|
|
314
|
-
// =============================================================================
|
|
315
316
|
// TRANSFER MUTATIONS (ledger — BTS-12)
|
|
316
|
-
// =============================================================================
|
|
317
317
|
|
|
318
318
|
export const upsertTransfer = mutation({
|
|
319
319
|
args: transferFields,
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAccountEarnings as getAccountEarningsLegacy,
|
|
3
|
+
getAccountPayouts as getAccountPayoutsLegacy,
|
|
4
|
+
} from "../earnings/legacyReads.js";
|
|
5
|
+
import { currencyTotals, previewSize } from "../earnings/reads.js";
|
|
1
6
|
import { v } from "convex/values";
|
|
2
7
|
import { paginator } from "convex-helpers/server/pagination";
|
|
3
8
|
import schema from "../schema.js";
|
|
@@ -21,9 +26,7 @@ import {
|
|
|
21
26
|
wedgedReversalClaimValidator,
|
|
22
27
|
} from "./validators";
|
|
23
28
|
|
|
24
|
-
// =============================================================================
|
|
25
29
|
// PAYMENT QUERIES
|
|
26
|
-
// =============================================================================
|
|
27
30
|
|
|
28
31
|
export const getPaymentByStripeId = query({
|
|
29
32
|
args: { stripePaymentIntentId: v.string() },
|
|
@@ -38,9 +41,7 @@ export const getPaymentByStripeId = query({
|
|
|
38
41
|
},
|
|
39
42
|
});
|
|
40
43
|
|
|
41
|
-
// =============================================================================
|
|
42
44
|
// PAYOUT QUERIES
|
|
43
|
-
// =============================================================================
|
|
44
45
|
|
|
45
46
|
export const getPayout = query({
|
|
46
47
|
args: { payoutId: v.id("payouts") },
|
|
@@ -111,9 +112,7 @@ export const listPayouts = query({
|
|
|
111
112
|
},
|
|
112
113
|
});
|
|
113
114
|
|
|
114
|
-
// =============================================================================
|
|
115
115
|
// REFUND QUERIES
|
|
116
|
-
// =============================================================================
|
|
117
116
|
|
|
118
117
|
export const getRefundByStripeId = query({
|
|
119
118
|
args: { stripeRefundId: v.string() },
|
|
@@ -196,9 +195,7 @@ export const listRefunds = query({
|
|
|
196
195
|
},
|
|
197
196
|
});
|
|
198
197
|
|
|
199
|
-
// =============================================================================
|
|
200
198
|
// DISPUTE QUERIES
|
|
201
|
-
// =============================================================================
|
|
202
199
|
|
|
203
200
|
export const getDisputeByStripeId = query({
|
|
204
201
|
args: { stripeDisputeId: v.string() },
|
|
@@ -279,9 +276,7 @@ export const listDisputes = query({
|
|
|
279
276
|
},
|
|
280
277
|
});
|
|
281
278
|
|
|
282
|
-
// =============================================================================
|
|
283
279
|
// TRANSFER QUERIES (ledger — BTS-12)
|
|
284
|
-
// =============================================================================
|
|
285
280
|
|
|
286
281
|
export const getTransferByStripeId = query({
|
|
287
282
|
args: { stripeTransferId: v.string() },
|
|
@@ -366,9 +361,7 @@ export const paginateTransfersByAccount = query({
|
|
|
366
361
|
.paginate(args.paginationOpts),
|
|
367
362
|
});
|
|
368
363
|
|
|
369
|
-
// =============================================================================
|
|
370
364
|
// REVERSAL-CLAIM RECLAIM (BTS-74) — ops diagnostics for wedged legs
|
|
371
|
-
// =============================================================================
|
|
372
365
|
|
|
373
366
|
/**
|
|
374
367
|
* Fetch one reversal operation's claim record (BTS-63/74) by its id, or null.
|
|
@@ -447,9 +440,7 @@ export const listWedgedReversalClaims = query({
|
|
|
447
440
|
},
|
|
448
441
|
});
|
|
449
442
|
|
|
450
|
-
// =============================================================================
|
|
451
443
|
// EARNINGS AGGREGATES (BTS-64)
|
|
452
|
-
// =============================================================================
|
|
453
444
|
//
|
|
454
445
|
// The row-list queries above `.take(50)`, so summing their rows client-side
|
|
455
446
|
// (as the earnings hooks did) silently understated totals for accounts with
|
|
@@ -479,27 +470,7 @@ export const getAccountEarnings = query({
|
|
|
479
470
|
transferCount: v.number(),
|
|
480
471
|
transfers: v.array(transferDocValidator),
|
|
481
472
|
}),
|
|
482
|
-
handler:
|
|
483
|
-
const previewLimit = args.previewLimit ?? 50;
|
|
484
|
-
let gross = 0;
|
|
485
|
-
let reversed = 0;
|
|
486
|
-
let transferCount = 0;
|
|
487
|
-
const transfers: Doc<"transfers">[] = [];
|
|
488
|
-
|
|
489
|
-
for await (const tr of ctx.db
|
|
490
|
-
.query("transfers")
|
|
491
|
-
.withIndex("by_destination_account_id", (q) =>
|
|
492
|
-
q.eq("destinationAccountId", args.destinationAccountId),
|
|
493
|
-
)
|
|
494
|
-
.order("desc")) {
|
|
495
|
-
gross += tr.amount;
|
|
496
|
-
reversed += tr.reversedAmount ?? 0;
|
|
497
|
-
transferCount += 1;
|
|
498
|
-
if (transfers.length < previewLimit) transfers.push(tr);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
return { gross, reversed, transferCount, transfers };
|
|
502
|
-
},
|
|
473
|
+
handler: getAccountEarningsLegacy,
|
|
503
474
|
});
|
|
504
475
|
|
|
505
476
|
/**
|
|
@@ -515,20 +486,111 @@ export const getAccountPayouts = query({
|
|
|
515
486
|
payoutCount: v.number(),
|
|
516
487
|
payouts: v.array(payoutDocValidator),
|
|
517
488
|
}),
|
|
518
|
-
handler:
|
|
519
|
-
|
|
520
|
-
let paidOut = 0;
|
|
521
|
-
let payoutCount = 0;
|
|
522
|
-
const payouts: Doc<"payouts">[] = [];
|
|
489
|
+
handler: getAccountPayoutsLegacy,
|
|
490
|
+
});
|
|
523
491
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
492
|
+
/** Reactive, account-scoped history. A page is never a financial total. */
|
|
493
|
+
export const paginatePayouts = query({
|
|
494
|
+
args: {
|
|
495
|
+
accountId: v.string(),
|
|
496
|
+
status: v.optional(payoutStatusValidator),
|
|
497
|
+
paginationOpts: paginationOptsValidator,
|
|
498
|
+
},
|
|
499
|
+
returns: paginationResultValidator(payoutDocValidator),
|
|
500
|
+
handler: (ctx, args) => {
|
|
501
|
+
if (
|
|
502
|
+
!Number.isInteger(args.paginationOpts.numItems) ||
|
|
503
|
+
args.paginationOpts.numItems < 1 ||
|
|
504
|
+
args.paginationOpts.numItems > 100
|
|
505
|
+
)
|
|
506
|
+
throw new Error("Page size must be an integer from 1 to 100");
|
|
507
|
+
const rows = paginator(ctx.db, schema).query("payouts");
|
|
508
|
+
const scoped =
|
|
509
|
+
args.status === undefined
|
|
510
|
+
? rows.withIndex("by_account_id", (q) =>
|
|
511
|
+
q.eq("accountId", args.accountId),
|
|
512
|
+
)
|
|
513
|
+
: rows.withIndex("by_account_status", (q) =>
|
|
514
|
+
q.eq("accountId", args.accountId).eq("status", args.status!),
|
|
515
|
+
);
|
|
516
|
+
return scoped.order("desc").paginate({
|
|
517
|
+
...args.paginationOpts,
|
|
518
|
+
maximumRowsRead: 200,
|
|
519
|
+
maximumBytesRead: 1_000_000,
|
|
520
|
+
});
|
|
521
|
+
},
|
|
522
|
+
});
|
|
531
523
|
|
|
532
|
-
|
|
524
|
+
export const getAccountEarningsByCurrency = query({
|
|
525
|
+
args: {
|
|
526
|
+
destinationAccountId: v.string(),
|
|
527
|
+
previewLimit: v.optional(v.number()),
|
|
528
|
+
},
|
|
529
|
+
returns: v.object({
|
|
530
|
+
totals: v.array(
|
|
531
|
+
v.object({
|
|
532
|
+
currency: v.string(),
|
|
533
|
+
gross: v.number(),
|
|
534
|
+
reversed: v.number(),
|
|
535
|
+
net: v.number(),
|
|
536
|
+
transferCount: v.number(),
|
|
537
|
+
}),
|
|
538
|
+
),
|
|
539
|
+
transfers: v.array(transferDocValidator),
|
|
540
|
+
}),
|
|
541
|
+
handler: async (ctx, args) => {
|
|
542
|
+
const limit = previewSize(args.previewLimit);
|
|
543
|
+
const rows = await currencyTotals(
|
|
544
|
+
ctx,
|
|
545
|
+
args.destinationAccountId,
|
|
546
|
+
"earnings",
|
|
547
|
+
);
|
|
548
|
+
const transfers = await ctx.db
|
|
549
|
+
.query("transfers")
|
|
550
|
+
.withIndex("by_destination_account_id", (q) =>
|
|
551
|
+
q.eq("destinationAccountId", args.destinationAccountId),
|
|
552
|
+
)
|
|
553
|
+
.order("desc")
|
|
554
|
+
.take(limit);
|
|
555
|
+
return {
|
|
556
|
+
totals: rows.map((r) => ({
|
|
557
|
+
currency: r.currency,
|
|
558
|
+
gross: r.gross,
|
|
559
|
+
reversed: r.reversed,
|
|
560
|
+
net: r.gross - r.reversed,
|
|
561
|
+
transferCount: r.count,
|
|
562
|
+
})),
|
|
563
|
+
transfers,
|
|
564
|
+
};
|
|
565
|
+
},
|
|
566
|
+
});
|
|
567
|
+
export const getAccountPayoutsByCurrency = query({
|
|
568
|
+
args: { accountId: v.string(), previewLimit: v.optional(v.number()) },
|
|
569
|
+
returns: v.object({
|
|
570
|
+
totals: v.array(
|
|
571
|
+
v.object({
|
|
572
|
+
currency: v.string(),
|
|
573
|
+
paidOut: v.number(),
|
|
574
|
+
payoutCount: v.number(),
|
|
575
|
+
}),
|
|
576
|
+
),
|
|
577
|
+
payouts: v.array(payoutDocValidator),
|
|
578
|
+
}),
|
|
579
|
+
handler: async (ctx, args) => {
|
|
580
|
+
const limit = previewSize(args.previewLimit);
|
|
581
|
+
const rows = await currencyTotals(ctx, args.accountId, "payouts");
|
|
582
|
+
const payouts = await ctx.db
|
|
583
|
+
.query("payouts")
|
|
584
|
+
.withIndex("by_account_id", (q) => q.eq("accountId", args.accountId))
|
|
585
|
+
.order("desc")
|
|
586
|
+
.take(limit);
|
|
587
|
+
return {
|
|
588
|
+
totals: rows.map((r) => ({
|
|
589
|
+
currency: r.currency,
|
|
590
|
+
paidOut: r.paidOut,
|
|
591
|
+
payoutCount: r.count,
|
|
592
|
+
})),
|
|
593
|
+
payouts,
|
|
594
|
+
};
|
|
533
595
|
},
|
|
534
596
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
1
2
|
import { defineTable } from "convex/server";
|
|
2
3
|
|
|
3
4
|
import {
|
|
@@ -22,10 +23,14 @@ export const paymentsTable = defineTable(paymentFields)
|
|
|
22
23
|
/**
|
|
23
24
|
* Payouts to V2 accounts (marketplace).
|
|
24
25
|
*/
|
|
25
|
-
export const payoutsTable = defineTable(
|
|
26
|
+
export const payoutsTable = defineTable({
|
|
27
|
+
...payoutFields,
|
|
28
|
+
totalsRecorded: v.optional(v.literal(true)),
|
|
29
|
+
})
|
|
26
30
|
.index("by_stripe_payout_id", ["stripePayoutId"])
|
|
27
31
|
.index("by_account_id", ["accountId"])
|
|
28
32
|
.index("by_status", ["status"])
|
|
33
|
+
.index("by_account_totals_recorded", ["accountId", "totalsRecorded"])
|
|
29
34
|
.index("by_account_status", ["accountId", "status"]);
|
|
30
35
|
|
|
31
36
|
/**
|
|
@@ -63,6 +68,10 @@ export const transfersTable = defineTable({
|
|
|
63
68
|
...transferPersistedFields,
|
|
64
69
|
})
|
|
65
70
|
.index("by_stripe_transfer_id", ["stripeTransferId"])
|
|
71
|
+
.index("by_account_totals_recorded", [
|
|
72
|
+
"destinationAccountId",
|
|
73
|
+
"totalsRecorded",
|
|
74
|
+
])
|
|
66
75
|
.index("by_destination_account_id", ["destinationAccountId"])
|
|
67
76
|
.index("by_source_charge_id", ["sourceChargeId"]);
|
|
68
77
|
|
|
@@ -72,6 +72,8 @@ export const payoutFields = {
|
|
|
72
72
|
status: payoutStatusValidator,
|
|
73
73
|
arrivalDate: v.optional(v.string()),
|
|
74
74
|
method: v.optional(v.string()),
|
|
75
|
+
failureCode: v.optional(v.string()),
|
|
76
|
+
failureMessage: v.optional(v.string()),
|
|
75
77
|
metadata: v.optional(v.any()),
|
|
76
78
|
};
|
|
77
79
|
|
|
@@ -80,6 +82,7 @@ export const payoutDocValidator = v.object({
|
|
|
80
82
|
_id: v.id("payouts"),
|
|
81
83
|
_creationTime: v.number(),
|
|
82
84
|
...payoutFields,
|
|
85
|
+
totalsRecorded: v.optional(v.literal(true)),
|
|
83
86
|
});
|
|
84
87
|
|
|
85
88
|
// =============================================================================
|
|
@@ -266,6 +269,7 @@ export const transferFields = {
|
|
|
266
269
|
* redelivered base payload must not clobber an in-flight reversal claim.
|
|
267
270
|
*/
|
|
268
271
|
export const transferPersistedFields = {
|
|
272
|
+
totalsRecorded: v.optional(v.literal(true)),
|
|
269
273
|
/**
|
|
270
274
|
* Reversal claim frontier (BTS-63): the highest cumulative reversal amount
|
|
271
275
|
* reserved by `claimReversalSlices` before money moves. Always ≥
|