@monok/server 1.5.1 → 1.5.3
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/AGENTS.md +52 -9
- package/LICENSE +21 -0
- package/README.md +40 -6
- package/dist/affiliate.d.ts +6 -1
- package/dist/affiliate.d.ts.map +1 -1
- package/dist/affiliate.js +107 -20
- package/dist/affiliate.js.map +1 -1
- package/dist/client.d.ts +8 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +67 -0
- package/dist/client.js.map +1 -1
- package/dist/types.d.ts +61 -1
- package/dist/types.d.ts.map +1 -1
- package/dist-cjs/affiliate.js +107 -20
- package/dist-cjs/affiliate.js.map +1 -1
- package/dist-cjs/client.js +67 -0
- package/dist-cjs/client.js.map +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -222,7 +222,7 @@ If `getSiteInfo` is omitted, `/info` returns this authenticated fallback:
|
|
|
222
222
|
```json
|
|
223
223
|
{
|
|
224
224
|
"js_scripts": "Disabled",
|
|
225
|
-
"version": "1.5.
|
|
225
|
+
"version": "1.5.3",
|
|
226
226
|
"name": "Custom CMS",
|
|
227
227
|
"logo": "",
|
|
228
228
|
"categories": [],
|
|
@@ -345,21 +345,36 @@ account-creation routes:
|
|
|
345
345
|
```ts
|
|
346
346
|
import express from "express";
|
|
347
347
|
import {
|
|
348
|
+
clearMonokAffiliateAttribution,
|
|
348
349
|
createMonokReferral,
|
|
349
350
|
monokAffiliateAttribution
|
|
350
351
|
} from "@monok/server";
|
|
351
352
|
|
|
352
353
|
const app = express();
|
|
353
354
|
|
|
354
|
-
|
|
355
|
+
// Configure this only for the host's actual reverse-proxy topology.
|
|
356
|
+
app.set("trust proxy", 1);
|
|
357
|
+
|
|
358
|
+
app.use(monokAffiliateAttribution({ apiKey: process.env.MONOK_API_KEY! }));
|
|
355
359
|
app.use(express.json());
|
|
356
360
|
```
|
|
357
361
|
|
|
358
|
-
The middleware
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
362
|
+
The middleware forwards the visitor IP resolved by Express, user agent,
|
|
363
|
+
referrer, preferred language, and cleaned landing URL to Monok for affiliate
|
|
364
|
+
click analytics. When the merchant runs behind a reverse proxy, configure
|
|
365
|
+
Express `trust proxy` for the exact trusted proxy topology so `req.ip` is the
|
|
366
|
+
visitor rather than the proxy. Never trust arbitrary forwarded headers.
|
|
367
|
+
|
|
368
|
+
The merchant-facing link is the active default offer's exact destination URL
|
|
369
|
+
with `monok_ref=<publisher workspace referral code>`. The middleware exchanges
|
|
370
|
+
that code through Monok using the workspace API key, stores the returned signed
|
|
371
|
+
`monok_attr` token in an HttpOnly, Secure, SameSite=Lax cookie, and redirects to
|
|
372
|
+
the same URL without `monok_ref`. It also accepts signed `monok_attr` handoffs
|
|
373
|
+
from Monok redirect links. `monok_ref` is public; `monok_attr` is internal and
|
|
374
|
+
must not be presented as the affiliate's share URL. The offer controls
|
|
375
|
+
attribution duration; cookie expiry comes from the token. Do not add a
|
|
376
|
+
merchant-configured attribution duration. Only set `secure: false` for local
|
|
377
|
+
HTTP development.
|
|
363
378
|
|
|
364
379
|
For an apex landing site and an account application on a subdomain, explicitly
|
|
365
380
|
share the cookie across the parent domain:
|
|
@@ -385,6 +400,7 @@ if (req.monokAttribution) {
|
|
|
385
400
|
},
|
|
386
401
|
{ apiKey: process.env.MONOK_API_KEY! }
|
|
387
402
|
);
|
|
403
|
+
clearMonokAffiliateAttribution(res);
|
|
388
404
|
}
|
|
389
405
|
```
|
|
390
406
|
|
|
@@ -395,13 +411,40 @@ Registration is idempotent for an offer/customer. A temporary Monok failure
|
|
|
395
411
|
must not roll back an already-created customer; retain the token and customer ID
|
|
396
412
|
in durable retry work. Keep `MONOK_API_KEY` server-side.
|
|
397
413
|
|
|
414
|
+
Call `clearMonokAffiliateAttribution` only after referral registration succeeds
|
|
415
|
+
with `created` or `existing`. Pass the same cookie name, domain, and secure
|
|
416
|
+
setting used for capture. Do not clear the cookie after a failed registration.
|
|
417
|
+
|
|
418
|
+
When the referred customer produces qualifying revenue, report it from the
|
|
419
|
+
merchant's durable payment or billing-completion path:
|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
await reportMonokAffiliateTransaction(
|
|
423
|
+
{
|
|
424
|
+
customerReference: customer.id,
|
|
425
|
+
transactionReference: invoice.id,
|
|
426
|
+
amountCents: 10_000
|
|
427
|
+
},
|
|
428
|
+
{ apiKey: process.env.MONOK_API_KEY! }
|
|
429
|
+
);
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
`amountCents` is the qualifying merchant revenue in integer EUR cents, not the
|
|
433
|
+
affiliate payout. Monok calculates and snapshots the commission from the
|
|
434
|
+
registered offer. `transactionReference` must be a durable, non-sensitive ID
|
|
435
|
+
that is unique within the merchant workspace; repeating it with the same values
|
|
436
|
+
is idempotent, while reusing it with different values is rejected.
|
|
437
|
+
|
|
398
438
|
Monok's own sites use this same public package and API flow. Do not replace it
|
|
399
439
|
with direct database writes, an internal-only attribution service, or
|
|
400
440
|
`referredWorkspaceId` handling.
|
|
401
441
|
|
|
402
442
|
`monokAffiliateAttribution` is Express middleware;
|
|
403
|
-
`createMonokReferral`
|
|
404
|
-
|
|
443
|
+
`createMonokReferral` and `reportMonokAffiliateTransaction` are framework-independent
|
|
444
|
+
server code. The cookie-clearing
|
|
445
|
+
helper accepts either an Express response or a cookie store with a compatible
|
|
446
|
+
`set` method. In another server
|
|
447
|
+
framework, reproduce the capture contract server-side: read `monok_attr`, derive
|
|
405
448
|
expiry from the token, set the secure HttpOnly cookie, and redirect to the clean
|
|
406
449
|
URL. Then read the cookie during customer creation and pass it to
|
|
407
450
|
`createMonokReferral`. A static frontend cannot create an HttpOnly cookie; it
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Monok
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -245,10 +245,13 @@ await sendMonokLinkback({
|
|
|
245
245
|
Follow this section for **affiliate only** or **content and affiliate** mode.
|
|
246
246
|
Content-only integrations can ignore it completely.
|
|
247
247
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
248
|
+
Affiliates can link directly to an active default offer's landing URL with the
|
|
249
|
+
publisher workspace referral code, for example
|
|
250
|
+
`https://example.com/pricing?monok_ref=ABC12345`. The middleware exchanges that
|
|
251
|
+
code with Monok using the merchant API key, preserves the returned signed
|
|
252
|
+
`monok_attr` token in an HttpOnly, SameSite=Lax cookie, and redirects to the same
|
|
253
|
+
URL without `monok_ref`. It also accepts signed `monok_attr` handoffs from Monok
|
|
254
|
+
redirect links. The offer controls the attribution window and cookie expiry.
|
|
252
255
|
Mount it before the merchant's landing and signup routes. After the customer has
|
|
253
256
|
been durably created, register the referral using the merchant's own stable
|
|
254
257
|
customer ID.
|
|
@@ -256,12 +259,17 @@ customer ID.
|
|
|
256
259
|
```ts
|
|
257
260
|
import express from "express";
|
|
258
261
|
import {
|
|
262
|
+
clearMonokAffiliateAttribution,
|
|
259
263
|
createMonokReferral,
|
|
260
|
-
monokAffiliateAttribution
|
|
264
|
+
monokAffiliateAttribution,
|
|
265
|
+
reportMonokAffiliateTransaction
|
|
261
266
|
} from "@monok/server";
|
|
262
267
|
|
|
263
268
|
const app = express();
|
|
264
|
-
|
|
269
|
+
// Configure this for the merchant's actual proxy topology. This example trusts
|
|
270
|
+
// exactly one reverse proxy so Express resolves req.ip to the visitor address.
|
|
271
|
+
app.set("trust proxy", 1);
|
|
272
|
+
app.use(monokAffiliateAttribution({ apiKey: process.env.MONOK_API_KEY! }));
|
|
265
273
|
app.use(express.json());
|
|
266
274
|
|
|
267
275
|
app.post("/signup", async (req, res) => {
|
|
@@ -275,16 +283,42 @@ app.post("/signup", async (req, res) => {
|
|
|
275
283
|
},
|
|
276
284
|
{ apiKey: process.env.MONOK_API_KEY! }
|
|
277
285
|
);
|
|
286
|
+
clearMonokAffiliateAttribution(res);
|
|
278
287
|
}
|
|
279
288
|
|
|
280
289
|
res.status(201).json({ id: customer.id });
|
|
281
290
|
});
|
|
291
|
+
|
|
292
|
+
async function recordCompletedBilling(transaction) {
|
|
293
|
+
await reportMonokAffiliateTransaction(
|
|
294
|
+
{
|
|
295
|
+
customerReference: transaction.customerId,
|
|
296
|
+
transactionReference: transaction.id,
|
|
297
|
+
amountCents: transaction.amountCents
|
|
298
|
+
},
|
|
299
|
+
{ apiKey: process.env.MONOK_API_KEY! }
|
|
300
|
+
);
|
|
301
|
+
}
|
|
282
302
|
```
|
|
283
303
|
|
|
284
304
|
The middleware defaults to secure cookies. For local HTTP development only, use
|
|
285
305
|
`monokAffiliateAttribution({ secure: false })`. `customerReference` should be a
|
|
286
306
|
durable internal ID, not an email address or other personal data. Repeating the
|
|
287
307
|
same offer/customer registration is idempotent and retains the first referral.
|
|
308
|
+
Clear the attribution cookie only after referral registration returns `created`
|
|
309
|
+
or `existing`. Pass the same `cookieDomain`, `cookieName`, and `secure` options
|
|
310
|
+
used during capture when they differ from the defaults.
|
|
311
|
+
|
|
312
|
+
The middleware forwards the visitor IP, user agent, referrer, preferred
|
|
313
|
+
language, and cleaned landing URL for affiliate click analytics. When Express
|
|
314
|
+
runs behind a reverse proxy, configure `trust proxy` for the exact trusted proxy
|
|
315
|
+
topology; do not blindly trust arbitrary forwarded headers.
|
|
316
|
+
|
|
317
|
+
Report only qualifying merchant revenue after the underlying payment or billing
|
|
318
|
+
event has completed. `amountCents` is integer EUR cents and is not the affiliate
|
|
319
|
+
payout; Monok calculates and snapshots the commission from the registered offer.
|
|
320
|
+
Use a durable, non-sensitive `transactionReference`. Repeating the same reference
|
|
321
|
+
with the same values is idempotent; reusing it with different values is rejected.
|
|
288
322
|
|
|
289
323
|
Affiliate-only merchants do **not** need to mount `createMonokRouter` or expose
|
|
290
324
|
`/push`, `/info`, or `/postfilter`.
|
package/dist/affiliate.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RequestHandler } from "express";
|
|
2
|
-
import type { MonokAffiliateAttributionOptions } from "./types.js";
|
|
2
|
+
import type { MonokAffiliateAttributionOptions, MonokAffiliateCookieTarget } from "./types.js";
|
|
3
3
|
declare global {
|
|
4
4
|
namespace Express {
|
|
5
5
|
interface Request {
|
|
@@ -12,4 +12,9 @@ declare global {
|
|
|
12
12
|
* `req.monokAttribution`. This does not expose any content-receiving endpoint.
|
|
13
13
|
*/
|
|
14
14
|
export declare function monokAffiliateAttribution(options?: MonokAffiliateAttributionOptions): RequestHandler;
|
|
15
|
+
/**
|
|
16
|
+
* Expire the attribution cookie after its token has been successfully consumed.
|
|
17
|
+
* Supports an Express response or a framework cookie store such as Next.js.
|
|
18
|
+
*/
|
|
19
|
+
export declare function clearMonokAffiliateAttribution(target: MonokAffiliateCookieTarget, options?: Pick<MonokAffiliateAttributionOptions, "cookieName" | "cookieDomain" | "secure">): void;
|
|
15
20
|
//# sourceMappingURL=affiliate.d.ts.map
|
package/dist/affiliate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affiliate.d.ts","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,cAAc,EAAY,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"affiliate.d.ts","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,cAAc,EAAY,MAAM,SAAS,CAAC;AAE/E,OAAO,KAAK,EACV,gCAAgC,EAChC,0BAA0B,EAE3B,MAAM,YAAY,CAAC;AAgBpB,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;SAC3B;KACF;CACF;AAqHD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gCAAqC,GAC7C,cAAc,CA+DhB;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,0BAA0B,EAClC,OAAO,GAAE,IAAI,CACX,gCAAgC,EAChC,YAAY,GAAG,cAAc,GAAG,QAAQ,CACpC,GACL,IAAI,CAkBN"}
|
package/dist/affiliate.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
import { createMonokAttribution } from "./client.js";
|
|
2
|
+
const DEFAULT_QUERY_PARAMETER = "monok_attr";
|
|
3
|
+
const DEFAULT_REFERRAL_QUERY_PARAMETER = "monok_ref";
|
|
4
|
+
const DEFAULT_COOKIE_NAME = "monok_attr";
|
|
3
5
|
const MAX_TOKEN_LENGTH = 4096;
|
|
4
6
|
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
5
7
|
const MAX_ATTRIBUTION_WINDOW_DAYS = 365;
|
|
6
8
|
const TOKEN_PATTERN = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
9
|
+
const REFERRAL_CODE_PATTERN = /^[A-Za-z0-9]{1,128}$/;
|
|
7
10
|
function validToken(value) {
|
|
8
11
|
return typeof value === "string" &&
|
|
9
12
|
value.length > 0 &&
|
|
@@ -54,43 +57,127 @@ function readCookie(req, cookieName) {
|
|
|
54
57
|
}
|
|
55
58
|
return undefined;
|
|
56
59
|
}
|
|
60
|
+
function queryString(value) {
|
|
61
|
+
return typeof value === "string" ? value : undefined;
|
|
62
|
+
}
|
|
63
|
+
function preferredLanguage(req) {
|
|
64
|
+
return req.get("accept-language")?.split(",")[0]?.split(";")[0]?.trim() || undefined;
|
|
65
|
+
}
|
|
66
|
+
function visitorIp(req) {
|
|
67
|
+
return req.ip ?? req.socket.remoteAddress ?? "";
|
|
68
|
+
}
|
|
69
|
+
function publicRequestUrl(req, referralQueryParameter, publicOrigin) {
|
|
70
|
+
const forwardedProtocol = queryString(req.headers["x-forwarded-proto"])?.split(",")[0]?.trim();
|
|
71
|
+
const forwardedHost = queryString(req.headers["x-forwarded-host"])?.split(",")[0]?.trim();
|
|
72
|
+
const host = forwardedHost ?? req.get("host");
|
|
73
|
+
const origin = publicOrigin
|
|
74
|
+
? new URL(publicOrigin).origin
|
|
75
|
+
: `${forwardedProtocol ?? req.protocol}://${host}`;
|
|
76
|
+
const url = new URL(req.originalUrl, origin);
|
|
77
|
+
url.searchParams.delete(referralQueryParameter);
|
|
78
|
+
url.hash = "";
|
|
79
|
+
return url.toString();
|
|
80
|
+
}
|
|
81
|
+
function cleanRequestUrl(req, ...queryParameters) {
|
|
82
|
+
const cleanUrl = new URL(req.originalUrl, "http://monok.local");
|
|
83
|
+
for (const queryParameter of queryParameters)
|
|
84
|
+
cleanUrl.searchParams.delete(queryParameter);
|
|
85
|
+
return cleanUrl.pathname + cleanUrl.search;
|
|
86
|
+
}
|
|
87
|
+
function storeAttribution(req, res, attribution, cookieName, options) {
|
|
88
|
+
req.monokAttribution = attribution.token;
|
|
89
|
+
res.cookie(cookieName, attribution.token, {
|
|
90
|
+
httpOnly: true,
|
|
91
|
+
secure: options.secure ?? true,
|
|
92
|
+
sameSite: "lax",
|
|
93
|
+
path: "/",
|
|
94
|
+
maxAge: attribution.maxAgeMs,
|
|
95
|
+
...(options.cookieDomain ? { domain: options.cookieDomain } : {})
|
|
96
|
+
});
|
|
97
|
+
}
|
|
57
98
|
/**
|
|
58
99
|
* Preserve Monok's signed redirect token in an HttpOnly cookie and expose it as
|
|
59
100
|
* `req.monokAttribution`. This does not expose any content-receiving endpoint.
|
|
60
101
|
*/
|
|
61
102
|
export function monokAffiliateAttribution(options = {}) {
|
|
62
103
|
const queryParameter = options.queryParameter ?? DEFAULT_QUERY_PARAMETER;
|
|
104
|
+
const referralQueryParameter = options.referralQueryParameter ?? DEFAULT_REFERRAL_QUERY_PARAMETER;
|
|
63
105
|
const cookieName = options.cookieName ?? DEFAULT_COOKIE_NAME;
|
|
64
|
-
if (!queryParameter || !cookieName) {
|
|
65
|
-
throw new Error("Affiliate query
|
|
106
|
+
if (!queryParameter || !referralQueryParameter || !cookieName) {
|
|
107
|
+
throw new Error("Affiliate query parameters and cookie name cannot be empty");
|
|
66
108
|
}
|
|
67
109
|
return (req, res, next) => {
|
|
68
110
|
const queryToken = req.query[queryParameter];
|
|
69
111
|
const queryAttribution = readAttribution(queryToken);
|
|
70
|
-
const
|
|
71
|
-
? queryAttribution
|
|
72
|
-
: readCookie(req, cookieName);
|
|
73
|
-
if (attribution)
|
|
74
|
-
req.monokAttribution = attribution.token;
|
|
112
|
+
const cookieAttribution = readCookie(req, cookieName);
|
|
75
113
|
if (queryAttribution) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
path: "/",
|
|
81
|
-
maxAge: queryAttribution.maxAgeMs,
|
|
82
|
-
...(options.cookieDomain ? { domain: options.cookieDomain } : {})
|
|
83
|
-
});
|
|
114
|
+
storeAttribution(req, res, queryAttribution, cookieName, options);
|
|
115
|
+
}
|
|
116
|
+
else if (cookieAttribution) {
|
|
117
|
+
req.monokAttribution = cookieAttribution.token;
|
|
84
118
|
}
|
|
85
119
|
if (validToken(queryToken)) {
|
|
86
120
|
if (options.cleanUrl ?? true) {
|
|
87
|
-
|
|
88
|
-
cleanUrl.searchParams.delete(queryParameter);
|
|
89
|
-
res.redirect(302, cleanUrl.pathname + cleanUrl.search);
|
|
121
|
+
res.redirect(302, cleanRequestUrl(req, queryParameter));
|
|
90
122
|
return;
|
|
91
123
|
}
|
|
92
124
|
}
|
|
125
|
+
const referralCode = queryString(req.query[referralQueryParameter])?.trim().toUpperCase();
|
|
126
|
+
if (referralCode && REFERRAL_CODE_PATTERN.test(referralCode)) {
|
|
127
|
+
void (async () => {
|
|
128
|
+
try {
|
|
129
|
+
if (!options.apiKey)
|
|
130
|
+
throw new Error("A Monok API key is required to capture monok_ref");
|
|
131
|
+
const referrer = req.get("referer");
|
|
132
|
+
const language = preferredLanguage(req);
|
|
133
|
+
const result = await createMonokAttribution({
|
|
134
|
+
referralCode,
|
|
135
|
+
landingUrl: publicRequestUrl(req, referralQueryParameter, options.publicOrigin),
|
|
136
|
+
userAgent: req.get("user-agent") ?? "",
|
|
137
|
+
ip: visitorIp(req),
|
|
138
|
+
...(referrer ? { referrer } : {}),
|
|
139
|
+
...(language ? { language } : {})
|
|
140
|
+
}, { apiKey: options.apiKey, ...(options.monokBaseUrl ? { monokBaseUrl: options.monokBaseUrl } : {}) });
|
|
141
|
+
const attribution = readAttribution(result.attributionToken);
|
|
142
|
+
if (!attribution)
|
|
143
|
+
throw new Error("Monok returned an invalid attribution token");
|
|
144
|
+
storeAttribution(req, res, attribution, cookieName, options);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
options.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
148
|
+
}
|
|
149
|
+
if (options.cleanUrl ?? true) {
|
|
150
|
+
res.redirect(302, cleanRequestUrl(req, referralQueryParameter));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
next();
|
|
154
|
+
})().catch(next);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
93
157
|
next();
|
|
94
158
|
};
|
|
95
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Expire the attribution cookie after its token has been successfully consumed.
|
|
162
|
+
* Supports an Express response or a framework cookie store such as Next.js.
|
|
163
|
+
*/
|
|
164
|
+
export function clearMonokAffiliateAttribution(target, options = {}) {
|
|
165
|
+
const cookieName = options.cookieName ?? DEFAULT_COOKIE_NAME;
|
|
166
|
+
if (!cookieName)
|
|
167
|
+
throw new Error("Affiliate cookie name cannot be empty");
|
|
168
|
+
const cookieOptions = {
|
|
169
|
+
httpOnly: true,
|
|
170
|
+
secure: options.secure ?? true,
|
|
171
|
+
sameSite: "lax",
|
|
172
|
+
path: "/",
|
|
173
|
+
maxAge: 0,
|
|
174
|
+
...(options.cookieDomain ? { domain: options.cookieDomain } : {}),
|
|
175
|
+
};
|
|
176
|
+
if ("cookie" in target) {
|
|
177
|
+
target.cookie(cookieName, "", cookieOptions);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
target.set(cookieName, "", cookieOptions);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
96
183
|
//# sourceMappingURL=affiliate.js.map
|
package/dist/affiliate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affiliate.js","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"affiliate.js","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import type { CreateMonokReferralPayload, LinkbackPayload, MonokAffiliateClientOptions, MonokReferralResult } from "./types.js";
|
|
1
|
+
import type { CreateMonokAttributionPayload, CreateMonokReferralPayload, LinkbackPayload, MonokAffiliateTransactionResult, MonokAffiliateClientOptions, MonokAttributionResult, MonokReferralResult, ReportMonokAffiliateTransactionPayload } from "./types.js";
|
|
2
2
|
export declare const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
|
|
3
|
+
/** Exchange a publisher referral code on an offer landing page for a signed attribution token. */
|
|
4
|
+
export declare function createMonokAttribution({ referralCode, landingUrl, userAgent, ip, referrer, language }: CreateMonokAttributionPayload, { apiKey, monokBaseUrl }: MonokAffiliateClientOptions): Promise<MonokAttributionResult>;
|
|
3
5
|
/**
|
|
4
6
|
* Send a linkback to Monok after you publish the article.
|
|
5
7
|
*/
|
|
@@ -12,4 +14,9 @@ export declare function sendMonokLinkback({ monokId, externalId, url, title, thu
|
|
|
12
14
|
* Repeating the same offer/customer pair is safe and returns the existing referral.
|
|
13
15
|
*/
|
|
14
16
|
export declare function createMonokReferral({ attributionToken, customerReference }: CreateMonokReferralPayload, { apiKey, monokBaseUrl }: MonokAffiliateClientOptions): Promise<MonokReferralResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Report qualifying merchant revenue for a previously registered affiliate customer.
|
|
19
|
+
* Repeating the same transaction reference is safe and returns the existing receipt.
|
|
20
|
+
*/
|
|
21
|
+
export declare function reportMonokAffiliateTransaction({ customerReference, transactionReference, amountCents }: ReportMonokAffiliateTransactionPayload, { apiKey, monokBaseUrl }: MonokAffiliateClientOptions): Promise<MonokAffiliateTransactionResult>;
|
|
15
22
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,eAAe,EACf,2BAA2B,EAC3B,mBAAmB,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,6BAA6B,EAC7B,0BAA0B,EAC1B,eAAe,EACf,+BAA+B,EAC/B,2BAA2B,EAC3B,sBAAsB,EACtB,mBAAmB,EACnB,sCAAsC,EACvC,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,sBAAsB,0BAA0B,CAAC;AAE9D,kGAAkG;AAClG,wBAAsB,sBAAsB,CAC1C,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,6BAA6B,EAC9F,EAAE,MAAM,EAAE,YAAqC,EAAE,EAAE,2BAA2B,GAC7E,OAAO,CAAC,sBAAsB,CAAC,CA8BjC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,eAAe,EAClE,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,EAAE,0BAA0B,EACnE,EAAE,MAAM,EAAE,YAAqC,EAAE,EAAE,2BAA2B,GAC7E,OAAO,CAAC,mBAAmB,CAAC,CAwB9B;AAED;;;GAGG;AACH,wBAAsB,+BAA+B,CACnD,EACE,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACZ,EAAE,sCAAsC,EACzC,EAAE,MAAM,EAAE,YAAqC,EAAE,EAAE,2BAA2B,GAC7E,OAAO,CAAC,+BAA+B,CAAC,CA4B1C"}
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
import fetch from "node-fetch";
|
|
2
2
|
export const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
|
|
3
|
+
/** Exchange a publisher referral code on an offer landing page for a signed attribution token. */
|
|
4
|
+
export async function createMonokAttribution({ referralCode, landingUrl, userAgent, ip, referrer, language }, { apiKey, monokBaseUrl = DEFAULT_MONOK_BASE_URL }) {
|
|
5
|
+
if (!apiKey.trim())
|
|
6
|
+
throw new Error("A Monok API key is required");
|
|
7
|
+
if (!referralCode.trim())
|
|
8
|
+
throw new Error("A publisher referral code is required");
|
|
9
|
+
if (!landingUrl.trim())
|
|
10
|
+
throw new Error("A merchant landing URL is required");
|
|
11
|
+
if (!userAgent.trim())
|
|
12
|
+
throw new Error("The visitor User-Agent is required");
|
|
13
|
+
if (!ip.trim())
|
|
14
|
+
throw new Error("The visitor IP address is required");
|
|
15
|
+
const endpoint = monokBaseUrl.replace(/\/$/, "") + "/api/v1/affiliate/attributions";
|
|
16
|
+
const resp = await fetch(endpoint, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
"X-API-Key": apiKey
|
|
21
|
+
},
|
|
22
|
+
body: JSON.stringify({
|
|
23
|
+
referralCode,
|
|
24
|
+
landingUrl,
|
|
25
|
+
userAgent,
|
|
26
|
+
ip,
|
|
27
|
+
...(referrer ? { referrer } : {}),
|
|
28
|
+
...(language ? { language } : {})
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
if (!resp.ok) {
|
|
32
|
+
const text = await resp.text().catch(() => "");
|
|
33
|
+
throw new Error(`Monok attribution exchange failed: ${resp.status} ${text}`);
|
|
34
|
+
}
|
|
35
|
+
return await resp.json();
|
|
36
|
+
}
|
|
3
37
|
/**
|
|
4
38
|
* Send a linkback to Monok after you publish the article.
|
|
5
39
|
*/
|
|
@@ -57,4 +91,37 @@ export async function createMonokReferral({ attributionToken, customerReference
|
|
|
57
91
|
}
|
|
58
92
|
return await resp.json();
|
|
59
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Report qualifying merchant revenue for a previously registered affiliate customer.
|
|
96
|
+
* Repeating the same transaction reference is safe and returns the existing receipt.
|
|
97
|
+
*/
|
|
98
|
+
export async function reportMonokAffiliateTransaction({ customerReference, transactionReference, amountCents }, { apiKey, monokBaseUrl = DEFAULT_MONOK_BASE_URL }) {
|
|
99
|
+
if (!apiKey.trim())
|
|
100
|
+
throw new Error("A Monok API key is required");
|
|
101
|
+
if (!customerReference.trim())
|
|
102
|
+
throw new Error("A customer reference is required");
|
|
103
|
+
if (!transactionReference.trim())
|
|
104
|
+
throw new Error("A transaction reference is required");
|
|
105
|
+
if (!Number.isSafeInteger(amountCents) || amountCents <= 0) {
|
|
106
|
+
throw new Error("amountCents must be a positive integer");
|
|
107
|
+
}
|
|
108
|
+
const endpoint = monokBaseUrl.replace(/\/$/, "") + "/api/v1/affiliate/transactions";
|
|
109
|
+
const resp = await fetch(endpoint, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
"X-API-Key": apiKey
|
|
114
|
+
},
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
customerReference,
|
|
117
|
+
transactionReference,
|
|
118
|
+
amountCents
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
if (!resp.ok) {
|
|
122
|
+
const text = await resp.text().catch(() => "");
|
|
123
|
+
throw new Error(`Monok affiliate transaction failed: ${resp.status} ${text}`);
|
|
124
|
+
}
|
|
125
|
+
return await resp.json();
|
|
126
|
+
}
|
|
60
127
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -92,6 +92,8 @@ export interface LinkbackPayload {
|
|
|
92
92
|
export interface MonokAffiliateAttributionOptions {
|
|
93
93
|
/** Query parameter carrying the signed Monok attribution token. */
|
|
94
94
|
queryParameter?: string;
|
|
95
|
+
/** Merchant-facing query parameter carrying a publisher referral code. Defaults to `monok_ref`. */
|
|
96
|
+
referralQueryParameter?: string;
|
|
95
97
|
/** HttpOnly cookie used to preserve attribution until signup. */
|
|
96
98
|
cookieName?: string;
|
|
97
99
|
/** Optional cookie domain, for example `.example.com`. */
|
|
@@ -100,12 +102,52 @@ export interface MonokAffiliateAttributionOptions {
|
|
|
100
102
|
secure?: boolean;
|
|
101
103
|
/** Remove the token from the address bar with a safe same-site redirect. Defaults to true. */
|
|
102
104
|
cleanUrl?: boolean;
|
|
103
|
-
|
|
105
|
+
/** Workspace API key. Required to exchange a merchant-facing referral code. */
|
|
106
|
+
apiKey?: string;
|
|
107
|
+
/** Override Monok's API origin. */
|
|
108
|
+
monokBaseUrl?: string;
|
|
109
|
+
/** Public merchant origin when proxy headers do not describe the external request correctly. */
|
|
110
|
+
publicOrigin?: string;
|
|
111
|
+
/** Optional non-blocking error observer for referral-code exchange failures. */
|
|
112
|
+
onError?: (error: Error) => void;
|
|
113
|
+
}
|
|
114
|
+
export interface MonokAffiliateCookieWriteOptions {
|
|
115
|
+
httpOnly: true;
|
|
116
|
+
secure: boolean;
|
|
117
|
+
sameSite: "lax";
|
|
118
|
+
path: "/";
|
|
119
|
+
maxAge: 0;
|
|
120
|
+
domain?: string;
|
|
121
|
+
}
|
|
122
|
+
export type MonokAffiliateCookieTarget = {
|
|
123
|
+
cookie: (name: string, value: string, options: MonokAffiliateCookieWriteOptions) => unknown;
|
|
124
|
+
} | {
|
|
125
|
+
set: (name: string, value: string, options: MonokAffiliateCookieWriteOptions) => unknown;
|
|
126
|
+
};
|
|
104
127
|
export interface CreateMonokReferralPayload {
|
|
105
128
|
attributionToken: string;
|
|
106
129
|
/** The merchant's durable, non-sensitive customer ID. */
|
|
107
130
|
customerReference: string;
|
|
108
131
|
}
|
|
132
|
+
export interface CreateMonokAttributionPayload {
|
|
133
|
+
/** Public publisher workspace referral code from the merchant URL. */
|
|
134
|
+
referralCode: string;
|
|
135
|
+
/** Current merchant landing URL after removing `monok_ref`. */
|
|
136
|
+
landingUrl: string;
|
|
137
|
+
/** User-Agent from the visitor's request, used for click analytics. */
|
|
138
|
+
userAgent: string;
|
|
139
|
+
/** IP address resolved by the merchant's trusted Express proxy configuration. */
|
|
140
|
+
ip: string;
|
|
141
|
+
/** Referrer from the visitor's request, when present. */
|
|
142
|
+
referrer?: string;
|
|
143
|
+
/** Preferred language from the visitor's Accept-Language header, when present. */
|
|
144
|
+
language?: string;
|
|
145
|
+
}
|
|
146
|
+
export interface MonokAttributionResult {
|
|
147
|
+
attributionToken: string;
|
|
148
|
+
offerId: string;
|
|
149
|
+
expiresAt: number;
|
|
150
|
+
}
|
|
109
151
|
export interface MonokAffiliateClientOptions {
|
|
110
152
|
apiKey: string;
|
|
111
153
|
monokBaseUrl?: string;
|
|
@@ -117,6 +159,24 @@ export interface MonokReferralResult {
|
|
|
117
159
|
publisherWorkspaceId: string;
|
|
118
160
|
customerReference: string;
|
|
119
161
|
}
|
|
162
|
+
export interface ReportMonokAffiliateTransactionPayload {
|
|
163
|
+
/** The same durable merchant customer ID used with `createMonokReferral`. */
|
|
164
|
+
customerReference: string;
|
|
165
|
+
/** A durable, non-sensitive merchant transaction ID used for idempotency. */
|
|
166
|
+
transactionReference: string;
|
|
167
|
+
/** Qualifying merchant revenue in integer EUR cents. */
|
|
168
|
+
amountCents: number;
|
|
169
|
+
}
|
|
170
|
+
export interface MonokAffiliateTransactionResult {
|
|
171
|
+
id: string;
|
|
172
|
+
status: "created" | "existing";
|
|
173
|
+
offerId: string;
|
|
174
|
+
publisherWorkspaceId: string;
|
|
175
|
+
customerReference: string;
|
|
176
|
+
transactionReference: string;
|
|
177
|
+
amountCents: number;
|
|
178
|
+
commissionAmountCents: number;
|
|
179
|
+
}
|
|
120
180
|
export interface CreateRouterOptions {
|
|
121
181
|
/**
|
|
122
182
|
* Token Monok will send in the `token` header.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist-cjs/affiliate.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
import { createMonokAttribution } from "./client.js";
|
|
2
|
+
const DEFAULT_QUERY_PARAMETER = "monok_attr";
|
|
3
|
+
const DEFAULT_REFERRAL_QUERY_PARAMETER = "monok_ref";
|
|
4
|
+
const DEFAULT_COOKIE_NAME = "monok_attr";
|
|
3
5
|
const MAX_TOKEN_LENGTH = 4096;
|
|
4
6
|
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
5
7
|
const MAX_ATTRIBUTION_WINDOW_DAYS = 365;
|
|
6
8
|
const TOKEN_PATTERN = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
9
|
+
const REFERRAL_CODE_PATTERN = /^[A-Za-z0-9]{1,128}$/;
|
|
7
10
|
function validToken(value) {
|
|
8
11
|
return typeof value === "string" &&
|
|
9
12
|
value.length > 0 &&
|
|
@@ -54,43 +57,127 @@ function readCookie(req, cookieName) {
|
|
|
54
57
|
}
|
|
55
58
|
return undefined;
|
|
56
59
|
}
|
|
60
|
+
function queryString(value) {
|
|
61
|
+
return typeof value === "string" ? value : undefined;
|
|
62
|
+
}
|
|
63
|
+
function preferredLanguage(req) {
|
|
64
|
+
return req.get("accept-language")?.split(",")[0]?.split(";")[0]?.trim() || undefined;
|
|
65
|
+
}
|
|
66
|
+
function visitorIp(req) {
|
|
67
|
+
return req.ip ?? req.socket.remoteAddress ?? "";
|
|
68
|
+
}
|
|
69
|
+
function publicRequestUrl(req, referralQueryParameter, publicOrigin) {
|
|
70
|
+
const forwardedProtocol = queryString(req.headers["x-forwarded-proto"])?.split(",")[0]?.trim();
|
|
71
|
+
const forwardedHost = queryString(req.headers["x-forwarded-host"])?.split(",")[0]?.trim();
|
|
72
|
+
const host = forwardedHost ?? req.get("host");
|
|
73
|
+
const origin = publicOrigin
|
|
74
|
+
? new URL(publicOrigin).origin
|
|
75
|
+
: `${forwardedProtocol ?? req.protocol}://${host}`;
|
|
76
|
+
const url = new URL(req.originalUrl, origin);
|
|
77
|
+
url.searchParams.delete(referralQueryParameter);
|
|
78
|
+
url.hash = "";
|
|
79
|
+
return url.toString();
|
|
80
|
+
}
|
|
81
|
+
function cleanRequestUrl(req, ...queryParameters) {
|
|
82
|
+
const cleanUrl = new URL(req.originalUrl, "http://monok.local");
|
|
83
|
+
for (const queryParameter of queryParameters)
|
|
84
|
+
cleanUrl.searchParams.delete(queryParameter);
|
|
85
|
+
return cleanUrl.pathname + cleanUrl.search;
|
|
86
|
+
}
|
|
87
|
+
function storeAttribution(req, res, attribution, cookieName, options) {
|
|
88
|
+
req.monokAttribution = attribution.token;
|
|
89
|
+
res.cookie(cookieName, attribution.token, {
|
|
90
|
+
httpOnly: true,
|
|
91
|
+
secure: options.secure ?? true,
|
|
92
|
+
sameSite: "lax",
|
|
93
|
+
path: "/",
|
|
94
|
+
maxAge: attribution.maxAgeMs,
|
|
95
|
+
...(options.cookieDomain ? { domain: options.cookieDomain } : {})
|
|
96
|
+
});
|
|
97
|
+
}
|
|
57
98
|
/**
|
|
58
99
|
* Preserve Monok's signed redirect token in an HttpOnly cookie and expose it as
|
|
59
100
|
* `req.monokAttribution`. This does not expose any content-receiving endpoint.
|
|
60
101
|
*/
|
|
61
102
|
export function monokAffiliateAttribution(options = {}) {
|
|
62
103
|
const queryParameter = options.queryParameter ?? DEFAULT_QUERY_PARAMETER;
|
|
104
|
+
const referralQueryParameter = options.referralQueryParameter ?? DEFAULT_REFERRAL_QUERY_PARAMETER;
|
|
63
105
|
const cookieName = options.cookieName ?? DEFAULT_COOKIE_NAME;
|
|
64
|
-
if (!queryParameter || !cookieName) {
|
|
65
|
-
throw new Error("Affiliate query
|
|
106
|
+
if (!queryParameter || !referralQueryParameter || !cookieName) {
|
|
107
|
+
throw new Error("Affiliate query parameters and cookie name cannot be empty");
|
|
66
108
|
}
|
|
67
109
|
return (req, res, next) => {
|
|
68
110
|
const queryToken = req.query[queryParameter];
|
|
69
111
|
const queryAttribution = readAttribution(queryToken);
|
|
70
|
-
const
|
|
71
|
-
? queryAttribution
|
|
72
|
-
: readCookie(req, cookieName);
|
|
73
|
-
if (attribution)
|
|
74
|
-
req.monokAttribution = attribution.token;
|
|
112
|
+
const cookieAttribution = readCookie(req, cookieName);
|
|
75
113
|
if (queryAttribution) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
path: "/",
|
|
81
|
-
maxAge: queryAttribution.maxAgeMs,
|
|
82
|
-
...(options.cookieDomain ? { domain: options.cookieDomain } : {})
|
|
83
|
-
});
|
|
114
|
+
storeAttribution(req, res, queryAttribution, cookieName, options);
|
|
115
|
+
}
|
|
116
|
+
else if (cookieAttribution) {
|
|
117
|
+
req.monokAttribution = cookieAttribution.token;
|
|
84
118
|
}
|
|
85
119
|
if (validToken(queryToken)) {
|
|
86
120
|
if (options.cleanUrl ?? true) {
|
|
87
|
-
|
|
88
|
-
cleanUrl.searchParams.delete(queryParameter);
|
|
89
|
-
res.redirect(302, cleanUrl.pathname + cleanUrl.search);
|
|
121
|
+
res.redirect(302, cleanRequestUrl(req, queryParameter));
|
|
90
122
|
return;
|
|
91
123
|
}
|
|
92
124
|
}
|
|
125
|
+
const referralCode = queryString(req.query[referralQueryParameter])?.trim().toUpperCase();
|
|
126
|
+
if (referralCode && REFERRAL_CODE_PATTERN.test(referralCode)) {
|
|
127
|
+
void (async () => {
|
|
128
|
+
try {
|
|
129
|
+
if (!options.apiKey)
|
|
130
|
+
throw new Error("A Monok API key is required to capture monok_ref");
|
|
131
|
+
const referrer = req.get("referer");
|
|
132
|
+
const language = preferredLanguage(req);
|
|
133
|
+
const result = await createMonokAttribution({
|
|
134
|
+
referralCode,
|
|
135
|
+
landingUrl: publicRequestUrl(req, referralQueryParameter, options.publicOrigin),
|
|
136
|
+
userAgent: req.get("user-agent") ?? "",
|
|
137
|
+
ip: visitorIp(req),
|
|
138
|
+
...(referrer ? { referrer } : {}),
|
|
139
|
+
...(language ? { language } : {})
|
|
140
|
+
}, { apiKey: options.apiKey, ...(options.monokBaseUrl ? { monokBaseUrl: options.monokBaseUrl } : {}) });
|
|
141
|
+
const attribution = readAttribution(result.attributionToken);
|
|
142
|
+
if (!attribution)
|
|
143
|
+
throw new Error("Monok returned an invalid attribution token");
|
|
144
|
+
storeAttribution(req, res, attribution, cookieName, options);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
options.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
148
|
+
}
|
|
149
|
+
if (options.cleanUrl ?? true) {
|
|
150
|
+
res.redirect(302, cleanRequestUrl(req, referralQueryParameter));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
next();
|
|
154
|
+
})().catch(next);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
93
157
|
next();
|
|
94
158
|
};
|
|
95
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Expire the attribution cookie after its token has been successfully consumed.
|
|
162
|
+
* Supports an Express response or a framework cookie store such as Next.js.
|
|
163
|
+
*/
|
|
164
|
+
export function clearMonokAffiliateAttribution(target, options = {}) {
|
|
165
|
+
const cookieName = options.cookieName ?? DEFAULT_COOKIE_NAME;
|
|
166
|
+
if (!cookieName)
|
|
167
|
+
throw new Error("Affiliate cookie name cannot be empty");
|
|
168
|
+
const cookieOptions = {
|
|
169
|
+
httpOnly: true,
|
|
170
|
+
secure: options.secure ?? true,
|
|
171
|
+
sameSite: "lax",
|
|
172
|
+
path: "/",
|
|
173
|
+
maxAge: 0,
|
|
174
|
+
...(options.cookieDomain ? { domain: options.cookieDomain } : {}),
|
|
175
|
+
};
|
|
176
|
+
if ("cookie" in target) {
|
|
177
|
+
target.cookie(cookieName, "", cookieOptions);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
target.set(cookieName, "", cookieOptions);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
96
183
|
//# sourceMappingURL=affiliate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affiliate.js","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"affiliate.js","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"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"}
|
package/dist-cjs/client.js
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
import fetch from "node-fetch";
|
|
2
2
|
export const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
|
|
3
|
+
/** Exchange a publisher referral code on an offer landing page for a signed attribution token. */
|
|
4
|
+
export async function createMonokAttribution({ referralCode, landingUrl, userAgent, ip, referrer, language }, { apiKey, monokBaseUrl = DEFAULT_MONOK_BASE_URL }) {
|
|
5
|
+
if (!apiKey.trim())
|
|
6
|
+
throw new Error("A Monok API key is required");
|
|
7
|
+
if (!referralCode.trim())
|
|
8
|
+
throw new Error("A publisher referral code is required");
|
|
9
|
+
if (!landingUrl.trim())
|
|
10
|
+
throw new Error("A merchant landing URL is required");
|
|
11
|
+
if (!userAgent.trim())
|
|
12
|
+
throw new Error("The visitor User-Agent is required");
|
|
13
|
+
if (!ip.trim())
|
|
14
|
+
throw new Error("The visitor IP address is required");
|
|
15
|
+
const endpoint = monokBaseUrl.replace(/\/$/, "") + "/api/v1/affiliate/attributions";
|
|
16
|
+
const resp = await fetch(endpoint, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
"X-API-Key": apiKey
|
|
21
|
+
},
|
|
22
|
+
body: JSON.stringify({
|
|
23
|
+
referralCode,
|
|
24
|
+
landingUrl,
|
|
25
|
+
userAgent,
|
|
26
|
+
ip,
|
|
27
|
+
...(referrer ? { referrer } : {}),
|
|
28
|
+
...(language ? { language } : {})
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
if (!resp.ok) {
|
|
32
|
+
const text = await resp.text().catch(() => "");
|
|
33
|
+
throw new Error(`Monok attribution exchange failed: ${resp.status} ${text}`);
|
|
34
|
+
}
|
|
35
|
+
return await resp.json();
|
|
36
|
+
}
|
|
3
37
|
/**
|
|
4
38
|
* Send a linkback to Monok after you publish the article.
|
|
5
39
|
*/
|
|
@@ -57,4 +91,37 @@ export async function createMonokReferral({ attributionToken, customerReference
|
|
|
57
91
|
}
|
|
58
92
|
return await resp.json();
|
|
59
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Report qualifying merchant revenue for a previously registered affiliate customer.
|
|
96
|
+
* Repeating the same transaction reference is safe and returns the existing receipt.
|
|
97
|
+
*/
|
|
98
|
+
export async function reportMonokAffiliateTransaction({ customerReference, transactionReference, amountCents }, { apiKey, monokBaseUrl = DEFAULT_MONOK_BASE_URL }) {
|
|
99
|
+
if (!apiKey.trim())
|
|
100
|
+
throw new Error("A Monok API key is required");
|
|
101
|
+
if (!customerReference.trim())
|
|
102
|
+
throw new Error("A customer reference is required");
|
|
103
|
+
if (!transactionReference.trim())
|
|
104
|
+
throw new Error("A transaction reference is required");
|
|
105
|
+
if (!Number.isSafeInteger(amountCents) || amountCents <= 0) {
|
|
106
|
+
throw new Error("amountCents must be a positive integer");
|
|
107
|
+
}
|
|
108
|
+
const endpoint = monokBaseUrl.replace(/\/$/, "") + "/api/v1/affiliate/transactions";
|
|
109
|
+
const resp = await fetch(endpoint, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
"X-API-Key": apiKey
|
|
114
|
+
},
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
customerReference,
|
|
117
|
+
transactionReference,
|
|
118
|
+
amountCents
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
if (!resp.ok) {
|
|
122
|
+
const text = await resp.text().catch(() => "");
|
|
123
|
+
throw new Error(`Monok affiliate transaction failed: ${resp.status} ${text}`);
|
|
124
|
+
}
|
|
125
|
+
return await resp.json();
|
|
126
|
+
}
|
|
60
127
|
//# sourceMappingURL=client.js.map
|
package/dist-cjs/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|