@aglyn/plugins-commerce 1.0.0-beta.220 → 1.0.0-beta.221
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/package.json +13 -13
- package/src/lib/server/billing-webhook.js +73 -43
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/pos-order.js +17 -9
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/testing/stand-in-record-system.d.ts +11 -2
- package/src/lib/testing/stand-in-record-system.js +5 -3
- package/src/lib/testing/stand-in-record-system.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aglyn/plugins-commerce",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.221",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://aglyn.com",
|
|
6
6
|
"repository": {
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aglyn/aglyn": "1.0.0-beta.
|
|
29
|
-
"@aglyn/shared-data-mdi": "1.0.0-beta.
|
|
30
|
-
"@aglyn/shared-ui-jsx": "1.0.0-beta.
|
|
31
|
-
"@aglyn/shared-ui-next": "1.0.0-beta.
|
|
32
|
-
"@aglyn/shared-ui-snackstack": "1.0.0-beta.
|
|
33
|
-
"@aglyn/shared-util-email": "1.0.0-beta.
|
|
34
|
-
"@aglyn/shared-util-http": "1.0.0-beta.
|
|
35
|
-
"@aglyn/shared-util-timestamp": "1.0.0-beta.
|
|
36
|
-
"@aglyn/shared-util-tools": "1.0.0-beta.
|
|
37
|
-
"@aglyn/tenant-data-admin": "1.0.0-beta.
|
|
38
|
-
"@aglyn/tenant-feature-instance": "1.0.0-beta.
|
|
39
|
-
"@aglyn/tenant-runtime": "1.0.0-beta.
|
|
28
|
+
"@aglyn/aglyn": "1.0.0-beta.221",
|
|
29
|
+
"@aglyn/shared-data-mdi": "1.0.0-beta.221",
|
|
30
|
+
"@aglyn/shared-ui-jsx": "1.0.0-beta.221",
|
|
31
|
+
"@aglyn/shared-ui-next": "1.0.0-beta.221",
|
|
32
|
+
"@aglyn/shared-ui-snackstack": "1.0.0-beta.221",
|
|
33
|
+
"@aglyn/shared-util-email": "1.0.0-beta.221",
|
|
34
|
+
"@aglyn/shared-util-http": "1.0.0-beta.221",
|
|
35
|
+
"@aglyn/shared-util-timestamp": "1.0.0-beta.221",
|
|
36
|
+
"@aglyn/shared-util-tools": "1.0.0-beta.221",
|
|
37
|
+
"@aglyn/tenant-data-admin": "1.0.0-beta.221",
|
|
38
|
+
"@aglyn/tenant-feature-instance": "1.0.0-beta.221",
|
|
39
|
+
"@aglyn/tenant-runtime": "1.0.0-beta.221",
|
|
40
40
|
"@stripe/react-stripe-js": "^6.12.0",
|
|
41
41
|
"@stripe/stripe-js": "^9.17.0",
|
|
42
42
|
"@swc/helpers": "0.5.23",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import * as Aglyn from "@aglyn/aglyn/server";
|
|
18
18
|
import { findUserByUidAcrossPools, firebaseAdmin, getOrgForHost, meterHostEmail, notifyHostManagers, notifyRiskEvent, raiseOperatorAlert, renderHostEmailWithTokens, updateExisting, hostSendingIdentity } from "@aglyn/tenant-data-admin";
|
|
19
19
|
import { paymentProvider } from "@aglyn/tenant-data-admin/server/payment-provider";
|
|
20
|
-
import
|
|
20
|
+
import recordCapturedContact from "@aglyn/aglyn/plugin-manager/record-captured-contact";
|
|
21
21
|
import { formatOperatorAlertAmount } from "@aglyn/aglyn/app-utils/operator-alerts";
|
|
22
22
|
import { resolveSiteTimeZone } from "@aglyn/aglyn/app-utils/collection-entry-date";
|
|
23
23
|
import { resolveHostToken } from "@aglyn/aglyn/app-utils/host-tokens";
|
|
@@ -1870,9 +1870,9 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
1870
1870
|
const subscriptionRef = hostRef.collection('subscriptions').doc(String(object.subscription));
|
|
1871
1871
|
// Redelivery guard (AGL-1732, the AGL-498 shape). Stripe delivers at
|
|
1872
1872
|
// least once, and the effects below this write are NOT idempotent —
|
|
1873
|
-
//
|
|
1874
|
-
// a replay would inflate the subscriber's lifetime value and
|
|
1875
|
-
// order count on every retry.
|
|
1873
|
+
// the capture's `purchaseCents` is added to the person's lifetime
|
|
1874
|
+
// value, so a replay would inflate the subscriber's lifetime value and
|
|
1875
|
+
// their order count on every retry.
|
|
1876
1876
|
//
|
|
1877
1877
|
// Keyed on `checkoutSessionId` rather than on the document existing:
|
|
1878
1878
|
// `customer.subscription.created` writes the SAME doc path (status and
|
|
@@ -1955,24 +1955,35 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
1955
1955
|
link: `/${hostId}/products`
|
|
1956
1956
|
});
|
|
1957
1957
|
// AWAITED SINCE AGL-2473, here and at the five sibling call sites in
|
|
1958
|
-
// this file.
|
|
1959
|
-
//
|
|
1960
|
-
// customer quietly missing from the
|
|
1961
|
-
// touches only our own Firestore,
|
|
1962
|
-
// drew: Aglyn's own storage is
|
|
1963
|
-
// `refund.ts` already awaited
|
|
1964
|
-
|
|
1958
|
+
// this file. The capture carries `purchaseCents`, which is what the
|
|
1959
|
+
// record system adds to a person's lifetime value and the RFM ranking
|
|
1960
|
+
// — a `void`ed one is a paying customer quietly missing from the
|
|
1961
|
+
// segment the merchant emails. It touches only our own Firestore,
|
|
1962
|
+
// which is the whole line AGL-2473 drew: Aglyn's own storage is
|
|
1963
|
+
// awaited, a stranger's server is queued. `refund.ts` already awaited
|
|
1964
|
+
// its sibling for exactly this reason.
|
|
1965
|
+
//
|
|
1966
|
+
// Through the contact-capture contract (AGL-3080), like every other
|
|
1967
|
+
// door commerce owns: the plugin that keeps people decides what a
|
|
1968
|
+
// purchase makes of them, and commerce imports none of it.
|
|
1969
|
+
await recordCapturedContact(_extends({
|
|
1970
|
+
orgId: '',
|
|
1965
1971
|
hostId: String(hostId),
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1972
|
+
identity: {
|
|
1973
|
+
email: object == null ? void 0 : (_object_customer_details1 = object.customer_details) == null ? void 0 : _object_customer_details1.email,
|
|
1974
|
+
name: (_ref10 = object == null ? void 0 : (_object_customer_details2 = object.customer_details) == null ? void 0 : _object_customer_details2.name) != null ? _ref10 : null
|
|
1975
|
+
},
|
|
1976
|
+
// A purchase makes the person a relationship (AGL-3232): a contact,
|
|
1977
|
+
// with an open lead for the address closed onto it.
|
|
1978
|
+
surface: 'relationship',
|
|
1969
1979
|
// Every order door names `customer` (AGL-2612): a floor, so the
|
|
1970
1980
|
// stage fills or advances and never moves anybody back.
|
|
1971
|
-
|
|
1981
|
+
lifecycleFloor: 'customer'
|
|
1972
1982
|
}, subscriptionCents > 0 ? {
|
|
1973
1983
|
purchaseCents: subscriptionCents
|
|
1974
1984
|
} : {}, {
|
|
1975
1985
|
interaction: {
|
|
1986
|
+
source: 'order',
|
|
1976
1987
|
refId: String(object.subscription),
|
|
1977
1988
|
summary: `Started a subscription ($${(subscriptionCents / 100).toFixed(2)})`
|
|
1978
1989
|
}
|
|
@@ -2513,20 +2524,23 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2513
2524
|
// counting only the first charge ranks them as a one-purchase
|
|
2514
2525
|
// customer forever. Keyed to the invoice so the guard above is what
|
|
2515
2526
|
// stops a redelivery inflating it.
|
|
2516
|
-
await
|
|
2527
|
+
await recordCapturedContact({
|
|
2528
|
+
orgId: '',
|
|
2517
2529
|
hostId: invoiceHostId,
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2530
|
+
identity: _extends({
|
|
2531
|
+
email: renewalEmail
|
|
2532
|
+
}, soldSnapshot.get('customerName') ? {
|
|
2533
|
+
name: String(soldSnapshot.get('customerName'))
|
|
2534
|
+
} : {}),
|
|
2535
|
+
surface: 'relationship',
|
|
2536
|
+
lifecycleFloor: 'customer',
|
|
2524
2537
|
purchaseCents: paidCents,
|
|
2525
2538
|
interaction: {
|
|
2539
|
+
source: 'order',
|
|
2526
2540
|
refId: invoiceId,
|
|
2527
2541
|
summary: `Subscription renewed ($${(paidCents / 100).toFixed(2)})`
|
|
2528
2542
|
}
|
|
2529
|
-
})
|
|
2543
|
+
});
|
|
2530
2544
|
}
|
|
2531
2545
|
}
|
|
2532
2546
|
}
|
|
@@ -2704,18 +2718,22 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
2704
2718
|
if (guestContactEmail) {
|
|
2705
2719
|
var _ref37, _ref38;
|
|
2706
2720
|
var _object_customer_details6;
|
|
2707
|
-
await
|
|
2721
|
+
await recordCapturedContact(_extends({
|
|
2722
|
+
orgId: '',
|
|
2708
2723
|
hostId: String(hostId),
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2724
|
+
identity: {
|
|
2725
|
+
email: guestContactEmail,
|
|
2726
|
+
name: (_ref37 = (_ref38 = object == null ? void 0 : (_object_customer_details6 = object.customer_details) == null ? void 0 : _object_customer_details6.name) != null ? _ref38 : reservation['guestName']) != null ? _ref37 : null
|
|
2727
|
+
},
|
|
2728
|
+
surface: 'relationship',
|
|
2712
2729
|
// A paid stay is a sale (AGL-2612), whatever the source says
|
|
2713
2730
|
// about the kind of thing that was bought.
|
|
2714
|
-
|
|
2731
|
+
lifecycleFloor: 'customer'
|
|
2715
2732
|
}, paidCents > 0 ? {
|
|
2716
2733
|
purchaseCents: paidCents
|
|
2717
2734
|
} : {}, {
|
|
2718
2735
|
interaction: {
|
|
2736
|
+
source: 'booking',
|
|
2719
2737
|
refId: String(reservationId),
|
|
2720
2738
|
summary: `Reserved a stay ($${(paidCents / 100).toFixed(2)})`
|
|
2721
2739
|
}
|
|
@@ -3117,17 +3135,21 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3117
3135
|
body: `Order ${cartOrderLabel} came in on {site}: ${cartUnits} ` + `item${cartUnits === 1 ? '' : 's'}, ${cartOrderTotal}` + ((object == null ? void 0 : (_object_customer_details8 = object.customer_details) == null ? void 0 : _object_customer_details8.email) ? `, from ${object.customer_details.email}.` : '.'),
|
|
3118
3136
|
link: `/${hostId}/products`
|
|
3119
3137
|
});
|
|
3120
|
-
await
|
|
3138
|
+
await recordCapturedContact(_extends({
|
|
3139
|
+
orgId: '',
|
|
3121
3140
|
hostId: String(hostId),
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3141
|
+
identity: {
|
|
3142
|
+
email: object == null ? void 0 : (_object_customer_details9 = object.customer_details) == null ? void 0 : _object_customer_details9.email,
|
|
3143
|
+
name: (_ref43 = object == null ? void 0 : (_object_customer_details10 = object.customer_details) == null ? void 0 : _object_customer_details10.name) != null ? _ref43 : null
|
|
3144
|
+
},
|
|
3145
|
+
surface: 'relationship',
|
|
3146
|
+
lifecycleFloor: 'customer'
|
|
3126
3147
|
}, marketingOptIn ? {
|
|
3127
3148
|
marketingConsent: true
|
|
3128
3149
|
} : {}, {
|
|
3129
3150
|
purchaseCents: Number((_ref44 = object == null ? void 0 : object.amount_total) != null ? _ref44 : 0),
|
|
3130
3151
|
interaction: {
|
|
3152
|
+
source: 'order',
|
|
3131
3153
|
refId: String(object.id),
|
|
3132
3154
|
summary: `Placed an order ($${(Number((_ref45 = object == null ? void 0 : object.amount_total) != null ? _ref45 : 0) / 100).toFixed(2)})`
|
|
3133
3155
|
}
|
|
@@ -3559,16 +3581,20 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3559
3581
|
var _ref68, _ref69, _ref70;
|
|
3560
3582
|
var _order_totals1, _object_customer_details17;
|
|
3561
3583
|
const chargedCents = Number((_ref68 = object == null ? void 0 : object.amount_total) != null ? _ref68 : 0) || Number((_ref69 = (_order_totals1 = order.totals) == null ? void 0 : _order_totals1.totalCents) != null ? _ref69 : 0);
|
|
3562
|
-
await
|
|
3584
|
+
await recordCapturedContact(_extends({
|
|
3585
|
+
orgId: '',
|
|
3563
3586
|
hostId: String(hostId),
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3587
|
+
identity: {
|
|
3588
|
+
email: draftEmail,
|
|
3589
|
+
name: (_ref70 = object == null ? void 0 : (_object_customer_details17 = object.customer_details) == null ? void 0 : _object_customer_details17.name) != null ? _ref70 : null
|
|
3590
|
+
},
|
|
3591
|
+
surface: 'relationship',
|
|
3592
|
+
lifecycleFloor: 'customer'
|
|
3568
3593
|
}, chargedCents > 0 ? {
|
|
3569
3594
|
purchaseCents: chargedCents
|
|
3570
3595
|
} : {}, {
|
|
3571
3596
|
interaction: {
|
|
3597
|
+
source: 'order',
|
|
3572
3598
|
refId: String(orderId),
|
|
3573
3599
|
summary: `Paid ${CommerceModel.formatOrderNumber(order, String(orderId))} ($${(chargedCents / 100).toFixed(2)})`
|
|
3574
3600
|
}
|
|
@@ -3943,14 +3969,18 @@ async function findOrderForDispute(paymentIntentId) {
|
|
|
3943
3969
|
}
|
|
3944
3970
|
})();
|
|
3945
3971
|
// Contacts ingestion (AGL-197): buyers become contacts.
|
|
3946
|
-
await
|
|
3972
|
+
await recordCapturedContact({
|
|
3973
|
+
orgId: '',
|
|
3947
3974
|
hostId: String(hostId),
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3975
|
+
identity: {
|
|
3976
|
+
email: object == null ? void 0 : (_object_customer_details19 = object.customer_details) == null ? void 0 : _object_customer_details19.email,
|
|
3977
|
+
name: (_ref79 = object == null ? void 0 : (_object_customer_details20 = object.customer_details) == null ? void 0 : _object_customer_details20.name) != null ? _ref79 : null
|
|
3978
|
+
},
|
|
3979
|
+
surface: 'relationship',
|
|
3980
|
+
lifecycleFloor: 'customer',
|
|
3952
3981
|
purchaseCents: Number((_ref80 = object == null ? void 0 : object.amount_total) != null ? _ref80 : 0),
|
|
3953
3982
|
interaction: {
|
|
3983
|
+
source: 'order',
|
|
3954
3984
|
refId: String(object.id),
|
|
3955
3985
|
summary: `Placed an order ($${(Number((_ref81 = object == null ? void 0 : object.amount_total) != null ? _ref81 : 0) / 100).toFixed(2)})`
|
|
3956
3986
|
}
|