hookwright 1.12.2 → 2.0.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/dist/cli.js +476 -27
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ var init_package = __esm({
|
|
|
24
24
|
"package.json"() {
|
|
25
25
|
package_default = {
|
|
26
26
|
name: "hookwright",
|
|
27
|
-
version: "
|
|
27
|
+
version: "2.0.0",
|
|
28
28
|
description: "Build real, signed e-commerce webhooks from a live Shopify catalogue \u2014 interactive terminal UI, no backend",
|
|
29
29
|
keywords: [
|
|
30
30
|
"webhook",
|
|
@@ -178,7 +178,9 @@ var DEFAULT_CONFIG = {
|
|
|
178
178
|
shopflo: { webhookUrl: "", webhookSecret: "" },
|
|
179
179
|
flexype: { webhookUrl: "", webhookSecret: "" },
|
|
180
180
|
"return-prime": { webhookUrl: "", webhookSecret: "" },
|
|
181
|
-
fastrr: { webhookUrl: "", webhookSecret: "" }
|
|
181
|
+
fastrr: { webhookUrl: "", webhookSecret: "" },
|
|
182
|
+
gokwik: { webhookUrl: "", webhookSecret: "" },
|
|
183
|
+
ecom360: { webhookUrl: "", webhookSecret: "" }
|
|
182
184
|
},
|
|
183
185
|
customer: {
|
|
184
186
|
firstName: "",
|
|
@@ -1805,26 +1807,40 @@ function selectionFor4(eventName) {
|
|
|
1805
1807
|
return eventDef3(eventName).selection;
|
|
1806
1808
|
}
|
|
1807
1809
|
var COMMON_FIELDS3 = [
|
|
1808
|
-
{ source: "request_type", target: "\xABgate\xBB + requestType", required: true, note: "return or exchange" },
|
|
1809
|
-
{ source: "status", target: "\xABgate\xBB + status", required: true, note: "requested, approved, received, inspected or rejected" },
|
|
1810
|
-
{ source: "customer.phone", target: "phone", required: true, note: "missing phone is rejected on every event" },
|
|
1811
|
-
{ source: "customer.address.country_code", target: "phone region" },
|
|
1812
|
-
{ source: "
|
|
1813
|
-
{ source: "
|
|
1814
|
-
{ source: "
|
|
1815
|
-
{ source: "
|
|
1816
|
-
{ source: "
|
|
1817
|
-
{ source: "
|
|
1818
|
-
{ source: "
|
|
1819
|
-
{ source: "
|
|
1820
|
-
{ source: "line_items[].
|
|
1821
|
-
{ source: "line_items[].
|
|
1822
|
-
{ source: "line_items[].
|
|
1823
|
-
{ source: "
|
|
1810
|
+
{ source: "request.request_type", target: "\xABgate\xBB + requestType", required: true, note: "return or exchange" },
|
|
1811
|
+
{ source: "request.status", target: "\xABgate\xBB + status", required: true, note: "requested, approved, received, inspected or rejected" },
|
|
1812
|
+
{ source: "request.customer.phone", target: "phone", required: true, note: "missing phone is rejected on every event" },
|
|
1813
|
+
{ source: "request.customer.address.country_code", target: "phone region" },
|
|
1814
|
+
{ source: "request.customer.name", target: "customer.name" },
|
|
1815
|
+
{ source: "request.customer.email", target: "customer.email", note: "null on some real requests" },
|
|
1816
|
+
{ source: "request.request_number", target: "requestNumber" },
|
|
1817
|
+
{ source: "request.id", target: "requestId" },
|
|
1818
|
+
{ source: "request.manual_request", target: "manualRequest" },
|
|
1819
|
+
{ source: "request.smart_exchange", target: "smartExchange" },
|
|
1820
|
+
{ source: "request.order.name", target: "order.name" },
|
|
1821
|
+
{ source: "request.order.id", target: "order.id" },
|
|
1822
|
+
{ source: "request.line_items[].original_product.title", target: "product.name + product.details", required: true, note: "the first PAID line wins; freebies rank last" },
|
|
1823
|
+
{ source: "request.line_items[].original_product.image.src", target: "product.image" },
|
|
1824
|
+
{ source: "request.line_items[].original_product.price", target: "product.price", note: "a zero price marks the line a freebie" },
|
|
1825
|
+
{ source: "request.line_items[].original_product.sku", target: "product.sku" },
|
|
1826
|
+
{ source: "request.line_items[].reason", target: "reason" },
|
|
1827
|
+
{ source: "request.line_items[].quantity", target: "product.quantity" },
|
|
1828
|
+
{ source: "request.line_items[].presentment_price.actual_amount", target: "pricing.totalPrice" },
|
|
1829
|
+
{ source: "request.line_items[].presentment_price.currency", target: "pricing.currency" },
|
|
1830
|
+
{ source: "request.line_items[].return_fee.price_set.presentment_money.amount", target: "pricing.returnFee" },
|
|
1831
|
+
{ source: "request.line_items[].refund.status", target: "refund.status" },
|
|
1832
|
+
{ source: "request.line_items[].refund.requested_mode", target: "refund.requestedMode" },
|
|
1833
|
+
{ source: "request.line_items[].refund.meta.discount_code", target: "refund.discountCode", note: "only present once store credit is issued" },
|
|
1834
|
+
{ source: "request.line_items[].shipping[0].awb", target: "shipping.awb", note: "absent until a label is raised" },
|
|
1835
|
+
{ source: "request.line_items[].shipping[0].tracking_available", target: "shipping.trackingAvailable" },
|
|
1836
|
+
{ source: "request.approved.created_at / request.received.created_at / request.inspected.created_at / request.rejected.created_at", target: "timeline.*", note: "whichever steps have happened" },
|
|
1837
|
+
{ source: "request.created_at", target: "createdAt" }
|
|
1824
1838
|
];
|
|
1825
1839
|
var EXCHANGE_FIELDS = [
|
|
1826
|
-
{ source: "line_items[].exchange_product.title", target: "exchangeProduct.name", note: "exchanges only \u2014 returns never carry it" },
|
|
1827
|
-
{ source: "line_items[].exchange_product.price", target: "exchangeProduct.price + pricing.priceDifference", note: "difference is signed: positive means the shopper owes more" }
|
|
1840
|
+
{ source: "request.line_items[].exchange_product.title", target: "exchangeProduct.name", note: "exchanges only \u2014 returns never carry it" },
|
|
1841
|
+
{ source: "request.line_items[].exchange_product.price", target: "exchangeProduct.price + pricing.priceDifference", note: "difference is signed: positive means the shopper owes more" },
|
|
1842
|
+
{ source: "request.line_items[].exchange_product.image.src", target: "exchangeProduct.image" },
|
|
1843
|
+
{ source: "request.line_items[].exchange_product.sku", target: "exchangeProduct.sku" }
|
|
1828
1844
|
];
|
|
1829
1845
|
var fieldMap6 = COMMON_FIELDS3;
|
|
1830
1846
|
function fieldMapFor2(eventName) {
|
|
@@ -1863,7 +1879,7 @@ function buildPayload6(ctx) {
|
|
|
1863
1879
|
const cust = config.customer;
|
|
1864
1880
|
const at = now.toISOString();
|
|
1865
1881
|
const first = items?.[0];
|
|
1866
|
-
const second = items?.[1] ?? first;
|
|
1882
|
+
const second = ctx.exchange ?? items?.[1] ?? first;
|
|
1867
1883
|
const originalPrice = money2(first?.variant?.price ?? 0);
|
|
1868
1884
|
const exchangePrice = money2(second?.variant?.price ?? 0);
|
|
1869
1885
|
const reachedIndex = STATUSES.indexOf(def.status);
|
|
@@ -2258,6 +2274,423 @@ var fastrr_default = {
|
|
|
2258
2274
|
summarize: summarize7
|
|
2259
2275
|
};
|
|
2260
2276
|
|
|
2277
|
+
// src/providers/gokwik.mjs
|
|
2278
|
+
var GATE_PATH5 = "abc_url";
|
|
2279
|
+
var GATE_VALUE4 = "";
|
|
2280
|
+
var fieldMap8 = [
|
|
2281
|
+
{ source: "abc_url", target: "\xABgate\xBB + checkout_link", required: true, note: "absent and the event is dropped; its origin builds every other link" },
|
|
2282
|
+
{ source: "customer.phone / address.phone", target: "customer.phone", required: true },
|
|
2283
|
+
{ source: "sa_localization", target: "phone region", required: true, note: 'address.country says "India", which the parser cannot use' },
|
|
2284
|
+
{ source: "customer.firstname", target: "customer.firstName" },
|
|
2285
|
+
{ source: "customer.lastname", target: "customer.lastName" },
|
|
2286
|
+
{ source: "customer.email / address.email", target: "customer.email" },
|
|
2287
|
+
{ source: "items[].title", target: "product_details", required: true, note: "the first PAID line wins; freebies rank last" },
|
|
2288
|
+
{ source: "items[].product_title", target: "product_name" },
|
|
2289
|
+
{ source: "items[].image", target: "product_image_url", note: "read off the featured line only" },
|
|
2290
|
+
{ source: "items[].url", target: "product_url", note: "relative \u2014 resolved against the abc_url origin" },
|
|
2291
|
+
{ source: "items[].final_price", target: "product_price", note: "PAISE \u2014 the consumer divides by 100" },
|
|
2292
|
+
{ source: "items[].sku", target: "product_sku" },
|
|
2293
|
+
{ source: "items[].product_type", target: "product_type" },
|
|
2294
|
+
{ source: "items[].variant_id", target: "cart_link", note: "joined as variant:quantity" },
|
|
2295
|
+
{ source: "items[].quantity", target: "total_quantity", note: "summed across the cart" },
|
|
2296
|
+
{ source: "item_count", target: "item_count", note: "gokwik's own count is kept over the line count" },
|
|
2297
|
+
{ source: "total_price", target: "total_price", note: "RUPEE string, unlike the line prices" },
|
|
2298
|
+
{ source: "original_total_price", target: "original_total_price" },
|
|
2299
|
+
{ source: "items_subtotal_price", target: "subtotal_price" },
|
|
2300
|
+
{ source: "total_discount", target: "total_discount" },
|
|
2301
|
+
{ source: "currency", target: "currency" },
|
|
2302
|
+
{ source: "request_id", target: "request_id" },
|
|
2303
|
+
{ source: "token", target: "token" },
|
|
2304
|
+
{ source: "drop_stage", target: "drop_stage" },
|
|
2305
|
+
{ source: "rto_risk_flag", target: "rto_risk_flag" },
|
|
2306
|
+
{ source: "brand_order_count", target: "brand_order_count" },
|
|
2307
|
+
{ source: "mkt_source", target: "mkt_source" },
|
|
2308
|
+
{ source: "mkt_medium", target: "mkt_medium" },
|
|
2309
|
+
{ source: "mkt_campaign", target: "mkt_campaign" },
|
|
2310
|
+
{ source: "mkt_content", target: "mkt_content" },
|
|
2311
|
+
{ source: "mkt_term", target: "mkt_term" },
|
|
2312
|
+
{ source: "mkt_fbclid", target: "mkt_fbclid" },
|
|
2313
|
+
{ source: "landing_page", target: "landing_page" },
|
|
2314
|
+
{ source: "orig_referrer", target: "orig_referrer" },
|
|
2315
|
+
{ source: "address.city", target: "address.city" },
|
|
2316
|
+
{ source: "address.state", target: "address.state" },
|
|
2317
|
+
{ source: "address.pincode", target: "address.pincode" },
|
|
2318
|
+
{ source: "address.country", target: "address.country" },
|
|
2319
|
+
{ source: "address.address", target: "address.address" },
|
|
2320
|
+
{ source: "shipping.price", target: "shipping.price" },
|
|
2321
|
+
{ source: "city", target: "city", note: "the ip city, not the delivery city" },
|
|
2322
|
+
{ source: "isp", target: "isp" },
|
|
2323
|
+
{ source: "user_agent", target: "user_agent" },
|
|
2324
|
+
{ source: "updated_at", target: "eventTime" }
|
|
2325
|
+
];
|
|
2326
|
+
var editableFields8 = [
|
|
2327
|
+
{ group: "Checkout", path: "request_id", label: "Request id" },
|
|
2328
|
+
{ group: "Checkout", path: "token", label: "Token" },
|
|
2329
|
+
{ group: "Checkout", path: "abc_url", label: "Recovery URL", hint: "gates the event; its origin builds the product and cart links" },
|
|
2330
|
+
{ group: "Checkout", path: "drop_stage", label: "Drop stage" },
|
|
2331
|
+
{ group: "Checkout", path: "rto_risk_flag", label: "RTO risk flag" },
|
|
2332
|
+
{ group: "Checkout", path: "gokwik_source_channel", label: "Source channel" },
|
|
2333
|
+
{ group: "Pricing", path: "total_price", label: "Total price", hint: "rupee string, unlike the line prices" },
|
|
2334
|
+
{ group: "Pricing", path: "total_discount", label: "Discount" },
|
|
2335
|
+
{ group: "Pricing", path: "currency", label: "Currency" },
|
|
2336
|
+
{ group: "Customer", path: "customer.firstname", label: "First name" },
|
|
2337
|
+
{ group: "Customer", path: "customer.lastname", label: "Last name" },
|
|
2338
|
+
{ group: "Customer", path: "customer.email", label: "Email" },
|
|
2339
|
+
{ group: "Customer", path: "customer.phone", label: "Phone" },
|
|
2340
|
+
{ group: "Customer", path: "brand_order_count", label: "Brand order count", type: "number" },
|
|
2341
|
+
{ group: "Customer", path: "sa_localization", label: "Localization", hint: "two letter region used to parse the phone" },
|
|
2342
|
+
{ group: "Shipping", path: "address.address", label: "Address line" },
|
|
2343
|
+
{ group: "Shipping", path: "address.city", label: "City" },
|
|
2344
|
+
{ group: "Shipping", path: "address.state", label: "State" },
|
|
2345
|
+
{ group: "Shipping", path: "address.pincode", label: "Pincode", type: "number" },
|
|
2346
|
+
{ group: "Attribution", path: "mkt_source", label: "UTM source" },
|
|
2347
|
+
{ group: "Attribution", path: "mkt_medium", label: "UTM medium" },
|
|
2348
|
+
{ group: "Attribution", path: "mkt_campaign", label: "UTM campaign" },
|
|
2349
|
+
{ group: "Attribution", path: "landing_page", label: "Landing page" },
|
|
2350
|
+
{ group: "Attribution", path: "orig_referrer", label: "Referrer" }
|
|
2351
|
+
];
|
|
2352
|
+
function paise(rupees) {
|
|
2353
|
+
return Math.round(money2(rupees) * 100);
|
|
2354
|
+
}
|
|
2355
|
+
function buildPayload8(ctx) {
|
|
2356
|
+
const { config, items, phone } = ctx;
|
|
2357
|
+
const now = ctx.now ?? /* @__PURE__ */ new Date();
|
|
2358
|
+
const currency = ctx.currency || config.defaults.currency;
|
|
2359
|
+
const domain = config.shopify.domain;
|
|
2360
|
+
const cust = config.customer;
|
|
2361
|
+
const utm = config.defaults.utm ?? {};
|
|
2362
|
+
const lineItems = (items ?? []).map(({ product, variant, quantity }) => {
|
|
2363
|
+
const unit = money2(variant?.price ?? 0);
|
|
2364
|
+
return {
|
|
2365
|
+
id: Number(variant?.id ?? 0),
|
|
2366
|
+
sku: variant?.sku || "",
|
|
2367
|
+
url: `/products/${product.handle}?variant=${variant?.id ?? ""}`,
|
|
2368
|
+
grams: 500,
|
|
2369
|
+
image: imageForVariant(product, variant),
|
|
2370
|
+
price: paise(unit),
|
|
2371
|
+
title: `${product.title}${variant?.title ? ` - ${variant.title}` : ""}`,
|
|
2372
|
+
vendor: product.vendor ?? "",
|
|
2373
|
+
taxable: true,
|
|
2374
|
+
quantity,
|
|
2375
|
+
gift_card: false,
|
|
2376
|
+
line_price: paise(unit * quantity),
|
|
2377
|
+
product_id: Number(product.id),
|
|
2378
|
+
variant_id: Number(variant?.id ?? 0),
|
|
2379
|
+
final_price: paise(unit),
|
|
2380
|
+
product_type: product.productType ?? "",
|
|
2381
|
+
product_title: product.title,
|
|
2382
|
+
original_price: paise(unit),
|
|
2383
|
+
total_discount: 0,
|
|
2384
|
+
final_line_price: paise(unit * quantity),
|
|
2385
|
+
requires_shipping: true
|
|
2386
|
+
};
|
|
2387
|
+
});
|
|
2388
|
+
const subtotal = money2(lineItems.reduce((sum, li) => sum + li.final_line_price / 100, 0));
|
|
2389
|
+
const discount = money2(Math.min(ctx.discount ?? 0, subtotal));
|
|
2390
|
+
const total = money2(subtotal - discount);
|
|
2391
|
+
const requestId = ctx.requestId ?? `gk-${now.getTime()}`;
|
|
2392
|
+
const abcUrl = `https://${domain}?mrid=${requestId}`;
|
|
2393
|
+
return {
|
|
2394
|
+
request_id: requestId,
|
|
2395
|
+
token: `${requestId}?key=${now.getTime().toString(36)}`,
|
|
2396
|
+
note: null,
|
|
2397
|
+
attributes: "{}",
|
|
2398
|
+
original_total_price: subtotal.toFixed(4),
|
|
2399
|
+
total_price: total.toFixed(4),
|
|
2400
|
+
total_discount: discount.toFixed(4),
|
|
2401
|
+
total_weight: "500.0000",
|
|
2402
|
+
is_abandoned: true,
|
|
2403
|
+
item_count: lineItems.length,
|
|
2404
|
+
items: lineItems,
|
|
2405
|
+
requires_shipping: true,
|
|
2406
|
+
currency,
|
|
2407
|
+
items_subtotal_price: String(subtotal),
|
|
2408
|
+
cart_level_discount_applications: [],
|
|
2409
|
+
discount: null,
|
|
2410
|
+
shipping: {
|
|
2411
|
+
id: 1,
|
|
2412
|
+
name: "Shipping",
|
|
2413
|
+
price: ctx.shippingPrice ?? 0,
|
|
2414
|
+
title: "Shipping",
|
|
2415
|
+
base_price: 0,
|
|
2416
|
+
cod_charges: 0,
|
|
2417
|
+
prepaid_price: 0,
|
|
2418
|
+
payment_options: "all",
|
|
2419
|
+
discounted_price: 0
|
|
2420
|
+
},
|
|
2421
|
+
abc_url: abcUrl,
|
|
2422
|
+
created_at: now.toISOString(),
|
|
2423
|
+
updated_at: now.toISOString(),
|
|
2424
|
+
city: cust.city,
|
|
2425
|
+
isp: "Test ISP",
|
|
2426
|
+
ip: "203.0.113.10",
|
|
2427
|
+
mkt_source: utm.utm_source ?? "direct",
|
|
2428
|
+
mkt_medium: utm.utm_medium ?? null,
|
|
2429
|
+
mkt_campaign: utm.utm_campaign ?? null,
|
|
2430
|
+
mkt_content: utm.utm_content ?? null,
|
|
2431
|
+
mkt_term: utm.utm_term ?? null,
|
|
2432
|
+
mkt_fbclid: utm.fbclid ?? null,
|
|
2433
|
+
gift_card_total: "0",
|
|
2434
|
+
payment_methods: ["upi", "cc", "dc", "netbanking"],
|
|
2435
|
+
drop_stage: "Payment Page",
|
|
2436
|
+
checkout_url: null,
|
|
2437
|
+
note_text: "",
|
|
2438
|
+
landing_page: "/",
|
|
2439
|
+
orig_referrer: `https://${domain}/`,
|
|
2440
|
+
gokwik_source_channel: "shopify_checkout",
|
|
2441
|
+
store_source: "web",
|
|
2442
|
+
store_platform: null,
|
|
2443
|
+
rto_risk_flag: "Control",
|
|
2444
|
+
sa_localization: cust.countryCode,
|
|
2445
|
+
shopifysessionid: `gk-session-${now.getTime()}`,
|
|
2446
|
+
user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/151.0.0.0 Safari/537.36",
|
|
2447
|
+
notify_customer: false,
|
|
2448
|
+
brand_order_count: 2,
|
|
2449
|
+
address: {
|
|
2450
|
+
firstname: cust.firstName,
|
|
2451
|
+
lastname: cust.lastName,
|
|
2452
|
+
city: cust.city,
|
|
2453
|
+
pincode: Number(cust.zip) || 0,
|
|
2454
|
+
state: cust.province,
|
|
2455
|
+
country: cust.country,
|
|
2456
|
+
email: cust.email,
|
|
2457
|
+
phone,
|
|
2458
|
+
default_address: 0,
|
|
2459
|
+
addresstype: "home",
|
|
2460
|
+
partial_address: false,
|
|
2461
|
+
total_order_count: 1,
|
|
2462
|
+
deliver_order_count: 0,
|
|
2463
|
+
address: cust.address1
|
|
2464
|
+
},
|
|
2465
|
+
customer: {
|
|
2466
|
+
firstname: cust.firstName,
|
|
2467
|
+
lastname: cust.lastName,
|
|
2468
|
+
email: cust.email,
|
|
2469
|
+
phone
|
|
2470
|
+
}
|
|
2471
|
+
};
|
|
2472
|
+
}
|
|
2473
|
+
function sign8() {
|
|
2474
|
+
return { signature: null, timestamp: null, headers: { "content-type": "application/json" } };
|
|
2475
|
+
}
|
|
2476
|
+
function webhookUrl8(config) {
|
|
2477
|
+
return String(targetFor(config, "gokwik").webhookUrl ?? "").trim();
|
|
2478
|
+
}
|
|
2479
|
+
function webhookSecret8(config) {
|
|
2480
|
+
return String(targetFor(config, "gokwik").webhookSecret ?? "");
|
|
2481
|
+
}
|
|
2482
|
+
function summarize8(payload) {
|
|
2483
|
+
const items = Array.isArray(payload?.items) ? payload.items : [];
|
|
2484
|
+
let store;
|
|
2485
|
+
try {
|
|
2486
|
+
store = payload?.abc_url ? new URL(payload.abc_url).host : void 0;
|
|
2487
|
+
} catch {
|
|
2488
|
+
store = payload?.abc_url;
|
|
2489
|
+
}
|
|
2490
|
+
return {
|
|
2491
|
+
event: "abandoned checkout",
|
|
2492
|
+
store,
|
|
2493
|
+
customer: `${payload?.customer?.firstname ?? ""} ${payload?.customer?.lastname ?? ""} \xB7 ${payload?.customer?.phone ?? ""}`.trim(),
|
|
2494
|
+
items: items.map((i) => `${i.title} x${i.quantity}`).join(", "),
|
|
2495
|
+
total: payload?.total_price,
|
|
2496
|
+
currency: payload?.currency,
|
|
2497
|
+
extra: `stage ${payload?.drop_stage}, rto ${payload?.rto_risk_flag}`,
|
|
2498
|
+
link: payload?.abc_url
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
var gokwik_default = {
|
|
2502
|
+
id: "gokwik",
|
|
2503
|
+
urlKey: "gokwik",
|
|
2504
|
+
label: "GoKwik",
|
|
2505
|
+
eventType: "gokwik_abandoned_checkout",
|
|
2506
|
+
gate: { path: GATE_PATH5, value: GATE_VALUE4 },
|
|
2507
|
+
signatureScheme: "none documented \u2014 every request is accepted",
|
|
2508
|
+
signatureHeader: null,
|
|
2509
|
+
fieldMap: fieldMap8,
|
|
2510
|
+
editableFields: editableFields8,
|
|
2511
|
+
buildPayload: buildPayload8,
|
|
2512
|
+
sign: sign8,
|
|
2513
|
+
webhookUrl: webhookUrl8,
|
|
2514
|
+
webhookSecret: webhookSecret8,
|
|
2515
|
+
summarize: summarize8
|
|
2516
|
+
};
|
|
2517
|
+
|
|
2518
|
+
// src/providers/ecom360.mjs
|
|
2519
|
+
import crypto4 from "crypto";
|
|
2520
|
+
var GATE_PATH6 = "event";
|
|
2521
|
+
var GATE_VALUE5 = "ABANDONED_CHECKOUT";
|
|
2522
|
+
var fieldMap9 = [
|
|
2523
|
+
{ source: "event", target: "\xABgate\xBB", required: true, note: "must be ABANDONED_CHECKOUT or the event is dropped" },
|
|
2524
|
+
{ source: "data.phone / data.customer.shipping_address.phone", target: "customer.phone", required: true },
|
|
2525
|
+
{ source: "data.customer.shipping_address.country_code", target: "phone region" },
|
|
2526
|
+
{ source: "data.customer.first_name", target: "customer.firstName" },
|
|
2527
|
+
{ source: "data.customer.last_name", target: "customer.lastName" },
|
|
2528
|
+
{ source: "data.email / data.customer.email", target: "customer.email" },
|
|
2529
|
+
{ source: "data.abandoned_checkout_url", target: "checkout_link", required: true },
|
|
2530
|
+
{ source: "data.store_url", target: "store_url + cart_link", required: true, note: "the cart link is built from it; no lookup needed" },
|
|
2531
|
+
{ source: "data.line_items[].title", target: "product_details", required: true, note: "the first PAID line wins; freebies rank last" },
|
|
2532
|
+
{ source: "data.line_items[].sku", target: "product_sku" },
|
|
2533
|
+
{ source: "data.line_items[].price", target: "product_price", note: "also ranks the lines; a zero marks a freebie" },
|
|
2534
|
+
{ source: "data.line_items[].variant_id", target: "cart_link", note: "joined as variant:quantity" },
|
|
2535
|
+
{ source: "data.line_items[].quantity", target: "total_quantity", note: "summed across the cart" },
|
|
2536
|
+
{ source: "data.line_items[]", target: "item_count", note: "the line count" },
|
|
2537
|
+
{ source: "\u2014 (no handle is sent)", target: "product_url", note: "the consumer builds none, by design" },
|
|
2538
|
+
{ source: "data.total_price", target: "total_price" },
|
|
2539
|
+
{ source: "data.original_total_price", target: "original_total_price" },
|
|
2540
|
+
{ source: "data.total_discount", target: "total_discount" },
|
|
2541
|
+
{ source: "data.promotions[0].code", target: "coupon_code" },
|
|
2542
|
+
{ source: "data.promotions[0].value", target: "coupon_value" },
|
|
2543
|
+
{ source: "data.cart_id", target: "cart_id" },
|
|
2544
|
+
{ source: "data.cart_token", target: "cart_token" },
|
|
2545
|
+
{ source: "data.platform", target: "platform" },
|
|
2546
|
+
{ source: "data.utm_parameters.utm_source", target: "utm_parameters.utm_source" },
|
|
2547
|
+
{ source: "data.utm_parameters.utm_medium", target: "utm_parameters.utm_medium" },
|
|
2548
|
+
{ source: "data.utm_parameters.utm_campaign", target: "utm_parameters.utm_campaign" },
|
|
2549
|
+
{ source: "data.utm_parameters.fbclid", target: "utm_parameters.fbclid" },
|
|
2550
|
+
{ source: "data.customer.shipping_address.city", target: "shipping_address.city" },
|
|
2551
|
+
{ source: "data.customer.shipping_address.province", target: "shipping_address.province" },
|
|
2552
|
+
{ source: "data.customer.shipping_address.zip", target: "shipping_address.zip" },
|
|
2553
|
+
{ source: "data.customer.shipping_address.country", target: "shipping_address.country" }
|
|
2554
|
+
];
|
|
2555
|
+
var editableFields9 = [
|
|
2556
|
+
{ group: "Checkout", path: "data.cart_id", label: "Cart id" },
|
|
2557
|
+
{ group: "Checkout", path: "data.cart_token", label: "Cart token" },
|
|
2558
|
+
{ group: "Checkout", path: "data.abandoned_checkout_url", label: "Checkout URL", hint: "the link the shopper is sent back to" },
|
|
2559
|
+
{ group: "Checkout", path: "data.store_url", label: "Store domain", hint: "the cart link is built from this" },
|
|
2560
|
+
{ group: "Checkout", path: "data.platform", label: "Platform" },
|
|
2561
|
+
{ group: "Pricing", path: "data.total_price", label: "Total price", type: "number" },
|
|
2562
|
+
{ group: "Pricing", path: "data.original_total_price", label: "Original total", type: "number" },
|
|
2563
|
+
{ group: "Pricing", path: "data.total_discount", label: "Discount", type: "number" },
|
|
2564
|
+
{ group: "Customer", path: "data.customer.first_name", label: "First name" },
|
|
2565
|
+
{ group: "Customer", path: "data.customer.last_name", label: "Last name" },
|
|
2566
|
+
{ group: "Customer", path: "data.email", label: "Email" },
|
|
2567
|
+
{ group: "Customer", path: "data.phone", label: "Phone" },
|
|
2568
|
+
{ group: "Shipping", path: "data.customer.shipping_address.address1", label: "Address line 1" },
|
|
2569
|
+
{ group: "Shipping", path: "data.customer.shipping_address.city", label: "City" },
|
|
2570
|
+
{ group: "Shipping", path: "data.customer.shipping_address.province", label: "State" },
|
|
2571
|
+
{ group: "Shipping", path: "data.customer.shipping_address.zip", label: "Zip / postcode" },
|
|
2572
|
+
{ group: "Shipping", path: "data.customer.shipping_address.country_code", label: "Country code", hint: "region used to parse the phone" },
|
|
2573
|
+
{ group: "Attribution", path: "data.utm_parameters.utm_source", label: "UTM source" },
|
|
2574
|
+
{ group: "Attribution", path: "data.utm_parameters.utm_campaign", label: "UTM campaign" },
|
|
2575
|
+
{ group: "Attribution", path: "data.utm_parameters.fbclid", label: "FBCLID" }
|
|
2576
|
+
];
|
|
2577
|
+
function buildPayload9(ctx) {
|
|
2578
|
+
const { config, items, phone } = ctx;
|
|
2579
|
+
const now = ctx.now ?? /* @__PURE__ */ new Date();
|
|
2580
|
+
const domain = config.shopify.domain;
|
|
2581
|
+
const cust = config.customer;
|
|
2582
|
+
const utm = config.defaults.utm ?? {};
|
|
2583
|
+
const lineItems = (items ?? []).map(({ product, variant, quantity }) => ({
|
|
2584
|
+
product_id: String(product.id),
|
|
2585
|
+
variant_id: String(variant?.id ?? ""),
|
|
2586
|
+
sku: variant?.sku || "",
|
|
2587
|
+
price: money2(variant?.price ?? 0),
|
|
2588
|
+
quantity,
|
|
2589
|
+
gram: 200,
|
|
2590
|
+
title: `${product.title}${variant?.title ? ` - ${variant.title}` : ""}`
|
|
2591
|
+
}));
|
|
2592
|
+
const subtotal = money2(lineItems.reduce((sum, li) => sum + li.price * li.quantity, 0));
|
|
2593
|
+
const discount = money2(Math.min(ctx.discount ?? 0, subtotal));
|
|
2594
|
+
const total = money2(subtotal - discount);
|
|
2595
|
+
const cartToken = ctx.cartToken ?? `ec-${now.getTime()}`;
|
|
2596
|
+
const shippingAddress = {
|
|
2597
|
+
first_name: cust.firstName,
|
|
2598
|
+
last_name: cust.lastName,
|
|
2599
|
+
address1: cust.address1,
|
|
2600
|
+
address2: "",
|
|
2601
|
+
city: cust.city,
|
|
2602
|
+
province: cust.province,
|
|
2603
|
+
country: cust.country,
|
|
2604
|
+
zip: cust.zip,
|
|
2605
|
+
phone,
|
|
2606
|
+
name: `${cust.firstName} ${cust.lastName}`.trim(),
|
|
2607
|
+
province_code: cust.provinceCode ?? "",
|
|
2608
|
+
country_code: cust.countryCode
|
|
2609
|
+
};
|
|
2610
|
+
return {
|
|
2611
|
+
event: GATE_VALUE5,
|
|
2612
|
+
data: {
|
|
2613
|
+
cart_id: `cart_${now.getTime()}`,
|
|
2614
|
+
store_url: domain,
|
|
2615
|
+
platform: "SHOPIFY",
|
|
2616
|
+
cart_token: cartToken,
|
|
2617
|
+
email: cust.email,
|
|
2618
|
+
phone,
|
|
2619
|
+
abandoned_checkout_url: `https://${domain}/checkouts/${cartToken}`,
|
|
2620
|
+
original_total_price: subtotal,
|
|
2621
|
+
total_price: total,
|
|
2622
|
+
total_discount: discount,
|
|
2623
|
+
utm_parameters: {
|
|
2624
|
+
fbclid: utm.fbclid ?? void 0,
|
|
2625
|
+
utm_source: utm.utm_source ?? void 0,
|
|
2626
|
+
utm_medium: utm.utm_medium ?? void 0,
|
|
2627
|
+
utm_campaign: utm.utm_campaign ?? void 0,
|
|
2628
|
+
utm_content: utm.utm_content ?? void 0,
|
|
2629
|
+
utm_term: utm.utm_term ?? void 0
|
|
2630
|
+
},
|
|
2631
|
+
line_items: lineItems,
|
|
2632
|
+
promotions: ctx.couponCode ? [{ code: ctx.couponCode, value: discount }] : [],
|
|
2633
|
+
customer: {
|
|
2634
|
+
email: cust.email,
|
|
2635
|
+
first_name: cust.firstName,
|
|
2636
|
+
last_name: cust.lastName,
|
|
2637
|
+
shipping_address: shippingAddress
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
};
|
|
2641
|
+
}
|
|
2642
|
+
function sign9({ body, secret }) {
|
|
2643
|
+
const signature = crypto4.createHmac("sha256", String(secret)).update(body).digest("base64");
|
|
2644
|
+
return {
|
|
2645
|
+
timestamp: null,
|
|
2646
|
+
signature,
|
|
2647
|
+
headers: {
|
|
2648
|
+
"content-type": "application/json",
|
|
2649
|
+
"x-webhook-signature": signature,
|
|
2650
|
+
"x-webhook-topic": "abandonedCheckout",
|
|
2651
|
+
"x-webhook-version": "v1",
|
|
2652
|
+
"user-agent": "Ecom360-v1"
|
|
2653
|
+
}
|
|
2654
|
+
};
|
|
2655
|
+
}
|
|
2656
|
+
function webhookUrl9(config) {
|
|
2657
|
+
return String(targetFor(config, "ecom360").webhookUrl ?? "").trim();
|
|
2658
|
+
}
|
|
2659
|
+
function webhookSecret9(config) {
|
|
2660
|
+
return String(targetFor(config, "ecom360").webhookSecret ?? "");
|
|
2661
|
+
}
|
|
2662
|
+
function summarize9(payload) {
|
|
2663
|
+
const d = payload?.data ?? {};
|
|
2664
|
+
const items = Array.isArray(d.line_items) ? d.line_items : [];
|
|
2665
|
+
const c2 = d.customer ?? {};
|
|
2666
|
+
return {
|
|
2667
|
+
event: "abandoned checkout",
|
|
2668
|
+
store: d.store_url,
|
|
2669
|
+
customer: `${c2.first_name ?? ""} ${c2.last_name ?? ""} \xB7 ${d.phone ?? ""}`.trim(),
|
|
2670
|
+
items: items.map((i) => `${i.title} x${i.quantity}`).join(", "),
|
|
2671
|
+
total: d.total_price,
|
|
2672
|
+
currency: void 0,
|
|
2673
|
+
extra: `platform ${d.platform}`,
|
|
2674
|
+
link: d.abandoned_checkout_url
|
|
2675
|
+
};
|
|
2676
|
+
}
|
|
2677
|
+
var ecom360_default = {
|
|
2678
|
+
id: "ecom360",
|
|
2679
|
+
urlKey: "ecom360",
|
|
2680
|
+
label: "Ecom 360",
|
|
2681
|
+
eventType: "ecom360_abandoned_checkout",
|
|
2682
|
+
gate: { path: GATE_PATH6, value: GATE_VALUE5 },
|
|
2683
|
+
signatureScheme: "base64 HMAC-SHA256 over the body",
|
|
2684
|
+
signatureHeader: "x-webhook-signature",
|
|
2685
|
+
fieldMap: fieldMap9,
|
|
2686
|
+
editableFields: editableFields9,
|
|
2687
|
+
buildPayload: buildPayload9,
|
|
2688
|
+
sign: sign9,
|
|
2689
|
+
webhookUrl: webhookUrl9,
|
|
2690
|
+
webhookSecret: webhookSecret9,
|
|
2691
|
+
summarize: summarize9
|
|
2692
|
+
};
|
|
2693
|
+
|
|
2261
2694
|
// src/providers/index.mjs
|
|
2262
2695
|
var PROVIDER_META = [
|
|
2263
2696
|
{
|
|
@@ -2311,6 +2744,20 @@ var PROVIDER_META = [
|
|
|
2311
2744
|
signature: "none documented \u2014 every request is accepted",
|
|
2312
2745
|
header: null,
|
|
2313
2746
|
available: true
|
|
2747
|
+
},
|
|
2748
|
+
{
|
|
2749
|
+
id: "gokwik",
|
|
2750
|
+
label: "GoKwik",
|
|
2751
|
+
signature: "none documented \u2014 every request is accepted",
|
|
2752
|
+
header: null,
|
|
2753
|
+
available: true
|
|
2754
|
+
},
|
|
2755
|
+
{
|
|
2756
|
+
id: "ecom360",
|
|
2757
|
+
label: "Ecom 360",
|
|
2758
|
+
signature: "base64 HMAC-SHA256 over the body",
|
|
2759
|
+
header: "x-webhook-signature",
|
|
2760
|
+
available: true
|
|
2314
2761
|
}
|
|
2315
2762
|
];
|
|
2316
2763
|
var providers = {
|
|
@@ -2320,7 +2767,9 @@ var providers = {
|
|
|
2320
2767
|
[shopflo_default.id]: shopflo_default,
|
|
2321
2768
|
[flexype_default.id]: flexype_default,
|
|
2322
2769
|
[return_prime_default.id]: return_prime_default,
|
|
2323
|
-
[fastrr_default.id]: fastrr_default
|
|
2770
|
+
[fastrr_default.id]: fastrr_default,
|
|
2771
|
+
[gokwik_default.id]: gokwik_default,
|
|
2772
|
+
[ecom360_default.id]: ecom360_default
|
|
2324
2773
|
};
|
|
2325
2774
|
function getProvider(id) {
|
|
2326
2775
|
const provider = providers[id];
|
|
@@ -2980,8 +3429,8 @@ function resolveSource(payload, source) {
|
|
|
2980
3429
|
}
|
|
2981
3430
|
return void 0;
|
|
2982
3431
|
}
|
|
2983
|
-
function coverage(payload,
|
|
2984
|
-
return
|
|
3432
|
+
function coverage(payload, fieldMap10) {
|
|
3433
|
+
return fieldMap10.map((f) => {
|
|
2985
3434
|
const value = resolveSource(payload, f.source);
|
|
2986
3435
|
const present = value !== void 0 && value !== null && value !== "";
|
|
2987
3436
|
return {
|
|
@@ -3146,7 +3595,7 @@ function applyEdits(payload, fields, edits) {
|
|
|
3146
3595
|
}
|
|
3147
3596
|
return payload;
|
|
3148
3597
|
}
|
|
3149
|
-
async function
|
|
3598
|
+
async function buildPayload10({ cfg, providerId = "cashfree-occ", items = [], discount = 0, phone, checkImageUrls = true, payload: prebuilt, eventName, collection, envelope, live, delta }) {
|
|
3150
3599
|
const provider0 = getProvider(providerId);
|
|
3151
3600
|
const needsItems = !provider0.selectionFor || ["cart", "product"].includes(provider0.selectionFor(eventName ?? provider0.defaultEvent));
|
|
3152
3601
|
if (needsItems && !items.length) throw new ConfigError("no products selected");
|
|
@@ -3693,7 +4142,7 @@ function Build({ config, providerId = "cashfree-occ", onDone }) {
|
|
|
3693
4142
|
const onDiscount = (raw) => startReview(Math.max(0, Number.parseFloat(raw) || 0));
|
|
3694
4143
|
const finalise = (payload) => {
|
|
3695
4144
|
setStep(STEP.BUILDING);
|
|
3696
|
-
|
|
4145
|
+
buildPayload10({ cfg: config, providerId, items, discount: draft.discount, payload, eventName, collection, live: draft.live, delta: draft.delta }).then(async (result) => {
|
|
3697
4146
|
setBuilt(result);
|
|
3698
4147
|
let req = null;
|
|
3699
4148
|
let command = "";
|
|
@@ -4964,7 +5413,7 @@ async function cmdBuild(args, config) {
|
|
|
4964
5413
|
else if (live?.kind === "order") log.ok(`order ${live.name} (${live.id})`);
|
|
4965
5414
|
else log.warn("no live record available \u2014 falling back to a generated one");
|
|
4966
5415
|
}
|
|
4967
|
-
const built = await
|
|
5416
|
+
const built = await buildPayload10({
|
|
4968
5417
|
cfg: config,
|
|
4969
5418
|
providerId,
|
|
4970
5419
|
eventName,
|