@aglyn/plugins-commerce 1.0.0-beta.287 → 1.0.0-beta.289
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/README.md +2 -2
- package/package.json +13 -13
- package/src/lib/components/commerce-console-page.js +29 -2
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/console/commerce-analytics-card.component.js +4 -2
- package/src/lib/components/console/commerce-analytics-card.component.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.js +5 -1
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/host-quotes-card.component.d.ts +34 -0
- package/src/lib/components/console/host-quotes-card.component.js +247 -0
- package/src/lib/components/console/host-quotes-card.component.js.map +1 -0
- package/src/lib/components/console/order-webhooks-card.component.js +1 -1
- package/src/lib/components/console/order-webhooks-card.component.js.map +1 -1
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +33 -28
- package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
- package/src/lib/components/console/quote-editor-dialog.component.d.ts +45 -0
- package/src/lib/components/console/quote-editor-dialog.component.js +1266 -0
- package/src/lib/components/console/quote-editor-dialog.component.js.map +1 -0
- package/src/lib/components/console/quote-pay-link.component.d.ts +38 -0
- package/src/lib/components/console/quote-pay-link.component.js +213 -0
- package/src/lib/components/console/quote-pay-link.component.js.map +1 -0
- package/src/lib/components/console/quote-settings-card.component.d.ts +29 -0
- package/src/lib/components/console/quote-settings-card.component.js +121 -0
- package/src/lib/components/console/quote-settings-card.component.js.map +1 -0
- package/src/lib/components/console/tax-settings-card.component.js +4 -1
- package/src/lib/components/console/tax-settings-card.component.js.map +1 -1
- package/src/lib/components/quote-page-body.d.ts +33 -0
- package/src/lib/components/quote-page-body.js +696 -0
- package/src/lib/components/quote-page-body.js.map +1 -0
- package/src/lib/components/quote-page.d.ts +29 -0
- package/src/lib/components/quote-page.js +96 -0
- package/src/lib/components/quote-page.js.map +1 -0
- package/src/lib/components/storefront-payment-element.d.ts +7 -1
- package/src/lib/components/storefront-payment-element.js +8 -3
- package/src/lib/components/storefront-payment-element.js.map +1 -1
- package/src/lib/constants/orders-list-query.js +6 -1
- package/src/lib/constants/orders-list-query.js.map +1 -1
- package/src/lib/constants/quote-page.d.ts +30 -0
- package/src/lib/constants/quote-page.js +35 -0
- package/src/lib/constants/quote-page.js.map +1 -0
- package/src/lib/declarations.js +5 -1
- package/src/lib/declarations.js.map +1 -1
- package/src/lib/model/commerce-orders.d.ts +25 -2
- package/src/lib/model/commerce-orders.js +10 -1
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-quote-pay.d.ts +229 -0
- package/src/lib/model/commerce-quote-pay.js +393 -0
- package/src/lib/model/commerce-quote-pay.js.map +1 -0
- package/src/lib/model/commerce-quotes.d.ts +279 -0
- package/src/lib/model/commerce-quotes.js +522 -0
- package/src/lib/model/commerce-quotes.js.map +1 -0
- package/src/lib/model/index.d.ts +2 -0
- package/src/lib/model/index.js +2 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/plugin-permissions.d.ts +8 -1
- package/src/lib/model/plugin-permissions.js +21 -1
- package/src/lib/model/plugin-permissions.js.map +1 -1
- package/src/lib/model/workspace-site-permissions.d.ts +26 -0
- package/src/lib/model/workspace-site-permissions.js +81 -0
- package/src/lib/model/workspace-site-permissions.js.map +1 -0
- package/src/lib/server/api-v1/orders-and-products.js +6 -2
- package/src/lib/server/api-v1/orders-and-products.js.map +1 -1
- package/src/lib/server/billing-webhook.js +127 -52
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/checkout-session-expiry.d.ts +36 -0
- package/src/lib/server/checkout-session-expiry.js +63 -0
- package/src/lib/server/checkout-session-expiry.js.map +1 -0
- package/src/lib/server/commerce-site-keys.d.ts +19 -0
- package/src/lib/server/commerce-site-keys.js +23 -2
- package/src/lib/server/commerce-site-keys.js.map +1 -1
- package/src/lib/server/draft-order.js +16 -8
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/order-webhooks.js +8 -8
- package/src/lib/server/order-webhooks.js.map +1 -1
- package/src/lib/server/person-eraser.d.ts +7 -0
- package/src/lib/server/person-eraser.js +24 -2
- package/src/lib/server/person-eraser.js.map +1 -1
- package/src/lib/server/pos-ops-gate.d.ts +13 -5
- package/src/lib/server/pos-ops-gate.js +12 -14
- package/src/lib/server/pos-ops-gate.js.map +1 -1
- package/src/lib/server/pos-refund-authority.d.ts +3 -1
- package/src/lib/server/pos-refund-authority.js +3 -2
- package/src/lib/server/pos-refund-authority.js.map +1 -1
- package/src/lib/server/pos-return.js +6 -7
- package/src/lib/server/pos-return.js.map +1 -1
- package/src/lib/server/pos-staff-pin.js +7 -7
- package/src/lib/server/pos-staff-pin.js.map +1 -1
- package/src/lib/server/quote-link-token.d.ts +39 -0
- package/src/lib/server/quote-link-token.js +97 -0
- package/src/lib/server/quote-link-token.js.map +1 -0
- package/src/lib/server/quote-pay.d.ts +83 -0
- package/src/lib/server/quote-pay.js +606 -0
- package/src/lib/server/quote-pay.js.map +1 -0
- package/src/lib/server/quote.d.ts +49 -0
- package/src/lib/server/quote.js +513 -0
- package/src/lib/server/quote.js.map +1 -0
- package/src/lib/server/refund.js +26 -36
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/related.js +2 -0
- package/src/lib/server/related.js.map +1 -1
- package/src/lib/server/site-page-resolver.d.ts +2 -0
- package/src/lib/server/site-page-resolver.js +75 -0
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server.js +14 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/site.js +6 -0
- package/src/lib/site.js.map +1 -1
- package/src/lib/transfer/tracking.server.js +6 -0
- package/src/lib/transfer/tracking.server.js.map +1 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { ProductType } from './commerce';
|
|
18
|
+
import { type HostOrder, type OrderAddress } from './commerce-orders';
|
|
19
|
+
import { type OrderQuote, type QuoteUnmatchedPayment } from './commerce-quotes';
|
|
20
|
+
import type { StorefrontTaxMode } from './commerce-tax-decision';
|
|
21
|
+
import { type OrderListFields } from './order-list-fields';
|
|
22
|
+
/** Stripe's smallest card charge; a quote that totals less cannot be paid by card. */
|
|
23
|
+
export declare const QUOTE_MIN_CHARGE_CENTS = 50;
|
|
24
|
+
/** The pay link version a quote is on; absent reads as the first. */
|
|
25
|
+
export declare function quoteLinkVersion(quote: Pick<OrderQuote, 'linkVersion'> | null | undefined): number;
|
|
26
|
+
/** An address as the quote page prints it: no phone. */
|
|
27
|
+
export interface QuotePageAddress {
|
|
28
|
+
name: string | null;
|
|
29
|
+
line1: string | null;
|
|
30
|
+
line2: string | null;
|
|
31
|
+
city: string | null;
|
|
32
|
+
state: string | null;
|
|
33
|
+
postalCode: string | null;
|
|
34
|
+
country: string | null;
|
|
35
|
+
}
|
|
36
|
+
export interface QuotePageLine {
|
|
37
|
+
name: string;
|
|
38
|
+
/** The option and add-ons chosen, as order lines print them. */
|
|
39
|
+
variantLabel: string | null;
|
|
40
|
+
description: string | null;
|
|
41
|
+
sku: string | null;
|
|
42
|
+
quantity: number;
|
|
43
|
+
unitAmountCents: number;
|
|
44
|
+
/** What the line charges: 0 for an included line. */
|
|
45
|
+
amountCents: number;
|
|
46
|
+
/** Included at no charge. */
|
|
47
|
+
included: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** Where the quote stands, as its customer sees it. */
|
|
50
|
+
export type QuotePageStatus = 'unpaid' | 'paid' | 'canceled' | 'refunded';
|
|
51
|
+
/**
|
|
52
|
+
* What the quote page shows. Allow-listed, never spread: the order document
|
|
53
|
+
* carries the customer's email and phone, Stripe ids, the business's own
|
|
54
|
+
* timeline and who wrote the quote, none of which a forwarded link may show.
|
|
55
|
+
* New fields are added here deliberately, or not at all.
|
|
56
|
+
*/
|
|
57
|
+
export interface QuotePageView {
|
|
58
|
+
state: 'quote';
|
|
59
|
+
storeName: string;
|
|
60
|
+
/** `Quote #1042`. */
|
|
61
|
+
number: string;
|
|
62
|
+
/** When the quote was last written, which is the date it carries. */
|
|
63
|
+
dateMs: number | null;
|
|
64
|
+
/**
|
|
65
|
+
* The edit of the quote this view shows. Pay sends it back, and a quote
|
|
66
|
+
* changed since is refused, so nobody pays for a version they have not seen.
|
|
67
|
+
*/
|
|
68
|
+
version: number;
|
|
69
|
+
currency: string;
|
|
70
|
+
customerName: string | null;
|
|
71
|
+
company: string | null;
|
|
72
|
+
billTo: QuotePageAddress | null;
|
|
73
|
+
shipTo: QuotePageAddress | null;
|
|
74
|
+
lines: QuotePageLine[];
|
|
75
|
+
totals: {
|
|
76
|
+
itemsCents: number;
|
|
77
|
+
discountCents: number;
|
|
78
|
+
shippingCents: number;
|
|
79
|
+
taxCents: number;
|
|
80
|
+
totalCents: number;
|
|
81
|
+
};
|
|
82
|
+
/** `10% off`, or null for an amount or no discount. */
|
|
83
|
+
discountLabel: string | null;
|
|
84
|
+
/** The tax line's label, or `Tax is added at payment`. */
|
|
85
|
+
taxLabel: string;
|
|
86
|
+
/** Stripe Tax works the tax out when the customer pays; `taxCents` is 0 until then. */
|
|
87
|
+
taxAtPayment: boolean;
|
|
88
|
+
notes: string | null;
|
|
89
|
+
terms: string | null;
|
|
90
|
+
status: QuotePageStatus;
|
|
91
|
+
statusLabel: string;
|
|
92
|
+
paidAtMs: number | null;
|
|
93
|
+
/** The order's status page, once paid. */
|
|
94
|
+
receiptUrl: string | null;
|
|
95
|
+
/** The business asks the customer to approve the proof before paying. */
|
|
96
|
+
approvalRequired: boolean;
|
|
97
|
+
/** A Pay button belongs on the page. */
|
|
98
|
+
payable: boolean;
|
|
99
|
+
}
|
|
100
|
+
/** What a signed link for an older version of the quote opens: nothing of the quote. */
|
|
101
|
+
export interface QuotePageReplacedView {
|
|
102
|
+
state: 'replaced';
|
|
103
|
+
storeName: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The quote page's view of an order document on the `quote` channel. Totals
|
|
107
|
+
* are the stored lines' through {@link computeQuoteTotals} until the quote is
|
|
108
|
+
* paid, and the paid order's own totals (what Stripe charged) after.
|
|
109
|
+
*/
|
|
110
|
+
export declare function buildQuotePageView(input: {
|
|
111
|
+
order: Pick<HostOrder, 'number' | 'status' | 'lineItems' | 'totals' | 'quote' | 'timeline'>;
|
|
112
|
+
orderId: string;
|
|
113
|
+
storeName: string;
|
|
114
|
+
currency: string;
|
|
115
|
+
/** The order's status page, for a paid quote. */
|
|
116
|
+
receiptUrl?: string | null;
|
|
117
|
+
}): QuotePageView;
|
|
118
|
+
/** One line of a quote's Checkout Session. */
|
|
119
|
+
export interface QuoteCheckoutLine {
|
|
120
|
+
name: string;
|
|
121
|
+
/** The quote's lines this one charges for, as the hosted page lists them. */
|
|
122
|
+
description: string;
|
|
123
|
+
amountCents: number;
|
|
124
|
+
/** False for tax-exempt products: no rate is applied and Stripe Tax is told it is nontaxable. */
|
|
125
|
+
taxable: boolean;
|
|
126
|
+
}
|
|
127
|
+
/** What a quote's Checkout Session charges, priced from the stored quote alone. */
|
|
128
|
+
export interface QuoteCheckoutCharge {
|
|
129
|
+
/** The goods grouped by whether they are taxed, so one rate taxes exactly the quote's taxable amount. */
|
|
130
|
+
lines: QuoteCheckoutLine[];
|
|
131
|
+
itemsCents: number;
|
|
132
|
+
discountCents: number;
|
|
133
|
+
/** The goods after the discount: what the business is paid for them. */
|
|
134
|
+
goodsCents: number;
|
|
135
|
+
taxableCents: number;
|
|
136
|
+
shippingCents: number;
|
|
137
|
+
/** The quote's tax; 0 when Stripe Tax works it out at payment. */
|
|
138
|
+
taxCents: number;
|
|
139
|
+
/**
|
|
140
|
+
* The percentage applied to the taxed line as a Stripe tax rate, or null
|
|
141
|
+
* when no rate is applied (no tax, Stripe Tax, or tax charged as its own line).
|
|
142
|
+
*/
|
|
143
|
+
taxPct: number | null;
|
|
144
|
+
taxAtPayment: boolean;
|
|
145
|
+
/** Goods, shipping and the quote's tax. Stripe Tax adds to it at payment. */
|
|
146
|
+
totalCents: number;
|
|
147
|
+
/** What the platform fee prices the goods as. */
|
|
148
|
+
feeProductType: ProductType;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The charge for a quote, from its stored lines, discount, shipping and tax
|
|
152
|
+
* basis through {@link computeQuoteTotals} — the same function that priced it
|
|
153
|
+
* when it was saved, so the page, the session and the stored quote agree.
|
|
154
|
+
*
|
|
155
|
+
* The goods are charged as at most two lines, the taxed and the tax-exempt,
|
|
156
|
+
* each after its share of the discount. A store rate is applied to the taxed
|
|
157
|
+
* line as one Stripe tax rate, so Stripe's tax is the rate on exactly the
|
|
158
|
+
* amount the quote taxed, and the quote's figure is what is collected. A tax
|
|
159
|
+
* service's figure is carried the same way, as the percentage of the taxed
|
|
160
|
+
* line it amounts to. Included lines charge nothing and are not sent.
|
|
161
|
+
*/
|
|
162
|
+
export declare function quoteCheckoutCharge(order: Pick<HostOrder, 'number' | 'lineItems' | 'quote'>, orderId: string): QuoteCheckoutCharge;
|
|
163
|
+
export type QuotePayRefusal = 'paid' | 'closed' | 'approval-required' | 'tax-undecided' | 'nothing-to-pay';
|
|
164
|
+
/** Why a quote cannot be paid now, or null when it can. */
|
|
165
|
+
export declare function quotePayRefusal(order: Pick<HostOrder, 'number' | 'status' | 'lineItems' | 'quote'>, orderId: string): QuotePayRefusal | null;
|
|
166
|
+
/** What the customer is told for a {@link QuotePayRefusal}, naming the business. */
|
|
167
|
+
export declare function quotePayRefusalMessage(reason: QuotePayRefusal, storeName: string): string;
|
|
168
|
+
/** What a completed Checkout Session says about the quote it paid. */
|
|
169
|
+
export interface QuotePaymentFacts {
|
|
170
|
+
sessionId: string;
|
|
171
|
+
paymentIntentId: string | null;
|
|
172
|
+
/** The link version and quote edit the session was minted for, from its metadata. */
|
|
173
|
+
linkVersion?: string | number | null;
|
|
174
|
+
quoteUpdatedAtMs?: string | number | null;
|
|
175
|
+
paidAtMs: number;
|
|
176
|
+
/** The payer, as Stripe collected them. */
|
|
177
|
+
email: string | null;
|
|
178
|
+
name: string | null;
|
|
179
|
+
/** What Stripe charged in all, and its shipping and tax parts. */
|
|
180
|
+
amountTotalCents: number | null;
|
|
181
|
+
shippingCents: number;
|
|
182
|
+
taxCents: number;
|
|
183
|
+
/** The platform fee the session was minted with. */
|
|
184
|
+
feeCents: number;
|
|
185
|
+
taxMode: StorefrontTaxMode;
|
|
186
|
+
/** The address Stripe collected, when the session asked for one. */
|
|
187
|
+
shippingAddress: OrderAddress | null;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* What a completed payment does to a quote:
|
|
191
|
+
*
|
|
192
|
+
* - `pay`: the quote is unpaid and the payment is for it as it stands, so it
|
|
193
|
+
* becomes the order.
|
|
194
|
+
* - `superseded`: the quote is unpaid, but the payment was made through a pay
|
|
195
|
+
* link the business replaced, or for a version of the quote it has since
|
|
196
|
+
* changed. Taking it would record a sale at a price or for a link the
|
|
197
|
+
* business withdrew.
|
|
198
|
+
* - `already-paid`: another payment paid the quote first.
|
|
199
|
+
* - `redelivery`: Stripe sending this same payment again; nothing to do.
|
|
200
|
+
*
|
|
201
|
+
* The two refusals keep the money visible: they are recorded on the quote and
|
|
202
|
+
* the business is told, so a payment is never fulfilled twice and never lost.
|
|
203
|
+
*/
|
|
204
|
+
export type QuotePaymentDisposition = 'pay' | 'superseded' | 'already-paid' | 'redelivery';
|
|
205
|
+
export declare function quotePaymentDisposition(order: Pick<HostOrder, 'status' | 'quote' | 'checkoutSessionId' | 'paymentIntentId'>, payment: Pick<QuotePaymentFacts, 'sessionId' | 'paymentIntentId' | 'linkVersion' | 'quoteUpdatedAtMs'>): QuotePaymentDisposition;
|
|
206
|
+
/** A payment the quote could not take, as {@link QuoteUnmatchedPayment} records it. */
|
|
207
|
+
export declare function quoteUnmatchedPayment(facts: Pick<QuotePaymentFacts, 'sessionId' | 'paymentIntentId' | 'amountTotalCents' | 'paidAtMs'>, reason: QuoteUnmatchedPayment['reason']): QuoteUnmatchedPayment;
|
|
208
|
+
/** The timeline line for a payment the quote could not take. */
|
|
209
|
+
export declare function quoteUnmatchedPaymentDetail(entry: QuoteUnmatchedPayment): string;
|
|
210
|
+
/**
|
|
211
|
+
* The order a paid quote becomes, the whole document as it will stand. A
|
|
212
|
+
* quote carries none of the fields order lists read (`commerce-quotes.ts`);
|
|
213
|
+
* paying it writes them:
|
|
214
|
+
*
|
|
215
|
+
* - `createdAtMs` is the time it was paid, the moment it became an order, so
|
|
216
|
+
* it lists and counts on the day the money came in.
|
|
217
|
+
* - The customer moves to the top-level fields every order reader asks
|
|
218
|
+
* (`customerEmail`, `customerName`, `customerPhone`, `customerRecord`), the
|
|
219
|
+
* payer's own email first, as a paid draft takes it.
|
|
220
|
+
* - The address Stripe collected ships it, else the quote's ship-to; the
|
|
221
|
+
* quote's bill-to bills it.
|
|
222
|
+
* - The totals are what Stripe charged: its shipping and tax where it charged
|
|
223
|
+
* any, the platform fee the session was minted with, and its total.
|
|
224
|
+
* - The list fields (`withOrderListFields`) are stamped from all of that.
|
|
225
|
+
*/
|
|
226
|
+
export declare function paidQuoteOrder(order: HostOrder, orderId: string, facts: QuotePaymentFacts): HostOrder & OrderListFields & {
|
|
227
|
+
updatedAtMs: number;
|
|
228
|
+
requiresShipping: boolean;
|
|
229
|
+
};
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
17
|
+
import { appendOrderEvent, formatOrderNumber } from "./commerce-orders.js";
|
|
18
|
+
import { computeQuoteTotals, describeQuoteTax, formatQuoteNumber, quoteLineAmounts, quotePaymentBlockedByApproval } from "./commerce-quotes.js";
|
|
19
|
+
import { engineLineTaxPercentages } from "./commerce-tax-engine.js";
|
|
20
|
+
import { withOrderListFields } from "./order-list-fields.js";
|
|
21
|
+
/*==========================================
|
|
22
|
+
* PAYING A QUOTE (AGL-4094).
|
|
23
|
+
*
|
|
24
|
+
* The customer opens the quote on the business's own site from a signed pay
|
|
25
|
+
* link, sees it, and pays it. Everything here is pure, so the page's view,
|
|
26
|
+
* the pay route's charge and the webhook's paid order all come from one
|
|
27
|
+
* reading of the stored quote, and none of them from anything the browser
|
|
28
|
+
* sends:
|
|
29
|
+
*
|
|
30
|
+
* - {@link buildQuotePageView}: the ONE projection of a quote that leaves the
|
|
31
|
+
* server for a visitor holding the link, allow-listed field by field.
|
|
32
|
+
* - {@link quoteCheckoutCharge}: what a Checkout Session charges, priced from
|
|
33
|
+
* the stored lines, discount, shipping and tax basis.
|
|
34
|
+
* - {@link quotePayRefusal}: why a quote cannot be paid now, if it cannot.
|
|
35
|
+
* - {@link quotePaymentDisposition} and {@link paidQuoteOrder}: what a
|
|
36
|
+
* completed payment does to the quote, and the order it becomes.
|
|
37
|
+
*
|
|
38
|
+
* The customer side has no expiry and no open or closed states: a quote and
|
|
39
|
+
* its link stay until the quote is paid or the business replaces the link.
|
|
40
|
+
*=========================================*/ /** Stripe's smallest card charge; a quote that totals less cannot be paid by card. */ export const QUOTE_MIN_CHARGE_CENTS = 50;
|
|
41
|
+
/** The pay link version a quote is on; absent reads as the first. */ export function quoteLinkVersion(quote) {
|
|
42
|
+
const version = Math.floor(Number(quote == null ? void 0 : quote.linkVersion));
|
|
43
|
+
return Number.isFinite(version) && version >= 1 ? version : 1;
|
|
44
|
+
}
|
|
45
|
+
const text = (value)=>{
|
|
46
|
+
const trimmed = typeof value === 'string' ? value.trim() : '';
|
|
47
|
+
return trimmed ? trimmed : null;
|
|
48
|
+
};
|
|
49
|
+
const cents = (value)=>{
|
|
50
|
+
const number = Math.round(Number(value));
|
|
51
|
+
return Number.isFinite(number) ? number : 0;
|
|
52
|
+
};
|
|
53
|
+
function pageAddress(address) {
|
|
54
|
+
if (!address) return null;
|
|
55
|
+
const view = {
|
|
56
|
+
name: text(address.name),
|
|
57
|
+
line1: text(address.line1),
|
|
58
|
+
line2: text(address.line2),
|
|
59
|
+
city: text(address.city),
|
|
60
|
+
state: text(address.state),
|
|
61
|
+
postalCode: text(address.postalCode),
|
|
62
|
+
country: text(address.country)
|
|
63
|
+
};
|
|
64
|
+
return Object.values(view).some(Boolean) ? view : null;
|
|
65
|
+
}
|
|
66
|
+
function pageStatus(status) {
|
|
67
|
+
if (status === 'pending') return {
|
|
68
|
+
status: 'unpaid',
|
|
69
|
+
label: 'Unpaid'
|
|
70
|
+
};
|
|
71
|
+
if (status === 'cancelled') return {
|
|
72
|
+
status: 'canceled',
|
|
73
|
+
label: 'Canceled'
|
|
74
|
+
};
|
|
75
|
+
if (status === 'refunded') return {
|
|
76
|
+
status: 'refunded',
|
|
77
|
+
label: 'Refunded'
|
|
78
|
+
};
|
|
79
|
+
return {
|
|
80
|
+
status: 'paid',
|
|
81
|
+
label: 'Paid'
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function discountLabel(discount) {
|
|
85
|
+
if ((discount == null ? void 0 : discount.kind) !== 'percent' || !(Number(discount.pct) > 0)) return null;
|
|
86
|
+
return `${Number(discount.pct)}% off`;
|
|
87
|
+
}
|
|
88
|
+
/** When the quote was paid: its stamp, else the timeline's `paid` event. */ function paidAt(order) {
|
|
89
|
+
var _order_timeline;
|
|
90
|
+
var _order_quote;
|
|
91
|
+
if (order.status === 'pending') return null;
|
|
92
|
+
const stamped = Number((_order_quote = order.quote) == null ? void 0 : _order_quote.paidAtMs);
|
|
93
|
+
if (Number.isFinite(stamped) && stamped > 0) return stamped;
|
|
94
|
+
const event = ((_order_timeline = order.timeline) != null ? _order_timeline : []).find((entry)=>(entry == null ? void 0 : entry.event) === 'paid');
|
|
95
|
+
return event ? Number(event.atMs) || null : null;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The quote page's view of an order document on the `quote` channel. Totals
|
|
99
|
+
* are the stored lines' through {@link computeQuoteTotals} until the quote is
|
|
100
|
+
* paid, and the paid order's own totals (what Stripe charged) after.
|
|
101
|
+
*/ export function buildQuotePageView(input) {
|
|
102
|
+
var _order_lineItems, _ref, _text, _input_receiptUrl;
|
|
103
|
+
var _quote_tax, _quote_customer, _quote_customer1, _quote_customer2, _quote_customer3, _quote_tax1;
|
|
104
|
+
const { order } = input;
|
|
105
|
+
const quote = order.quote;
|
|
106
|
+
const lines = (_order_lineItems = order.lineItems) != null ? _order_lineItems : [];
|
|
107
|
+
const status = pageStatus(order.status);
|
|
108
|
+
const unpaid = status.status === 'unpaid';
|
|
109
|
+
const charge = quoteCheckoutCharge(order, input.orderId);
|
|
110
|
+
const stored = order.totals;
|
|
111
|
+
const totals = unpaid || !stored ? {
|
|
112
|
+
itemsCents: charge.itemsCents,
|
|
113
|
+
discountCents: charge.discountCents,
|
|
114
|
+
shippingCents: charge.shippingCents,
|
|
115
|
+
taxCents: charge.taxCents,
|
|
116
|
+
totalCents: charge.totalCents
|
|
117
|
+
} : {
|
|
118
|
+
itemsCents: cents(stored.itemsCents),
|
|
119
|
+
discountCents: cents(stored.discountCents),
|
|
120
|
+
shippingCents: cents(stored.shippingCents),
|
|
121
|
+
taxCents: cents(stored.taxCents),
|
|
122
|
+
totalCents: cents(stored.totalCents)
|
|
123
|
+
};
|
|
124
|
+
const approvalRequired = unpaid && quotePaymentBlockedByApproval(quote);
|
|
125
|
+
const taxAtPayment = unpaid && (quote == null ? void 0 : (_quote_tax = quote.tax) == null ? void 0 : _quote_tax.kind) === 'at-payment';
|
|
126
|
+
return {
|
|
127
|
+
state: 'quote',
|
|
128
|
+
storeName: input.storeName,
|
|
129
|
+
number: formatQuoteNumber(order, input.orderId),
|
|
130
|
+
dateMs: Number((_ref = quote == null ? void 0 : quote.updatedAtMs) != null ? _ref : quote == null ? void 0 : quote.createdAtMs) || null,
|
|
131
|
+
version: Number(quote == null ? void 0 : quote.updatedAtMs) || 0,
|
|
132
|
+
currency: input.currency || 'USD',
|
|
133
|
+
customerName: (_text = text(quote == null ? void 0 : (_quote_customer = quote.customer) == null ? void 0 : _quote_customer.name)) != null ? _text : text(quote == null ? void 0 : (_quote_customer1 = quote.customer) == null ? void 0 : _quote_customer1.company),
|
|
134
|
+
company: text(quote == null ? void 0 : (_quote_customer2 = quote.customer) == null ? void 0 : _quote_customer2.name) ? text(quote == null ? void 0 : (_quote_customer3 = quote.customer) == null ? void 0 : _quote_customer3.company) : null,
|
|
135
|
+
billTo: pageAddress(quote == null ? void 0 : quote.billTo),
|
|
136
|
+
shipTo: pageAddress(quote == null ? void 0 : quote.shipTo),
|
|
137
|
+
lines: lines.map((line)=>{
|
|
138
|
+
var _line_name;
|
|
139
|
+
const included = line.included === true;
|
|
140
|
+
const quantity = Math.max(0, cents(line.quantity));
|
|
141
|
+
const unitAmountCents = included ? 0 : Math.max(0, cents(line.unitAmountCents));
|
|
142
|
+
return {
|
|
143
|
+
name: String((_line_name = line.name) != null ? _line_name : ''),
|
|
144
|
+
variantLabel: text(line.variantLabel),
|
|
145
|
+
description: text(line.description),
|
|
146
|
+
sku: text(line.sku),
|
|
147
|
+
quantity,
|
|
148
|
+
unitAmountCents,
|
|
149
|
+
amountCents: unitAmountCents * quantity,
|
|
150
|
+
included
|
|
151
|
+
};
|
|
152
|
+
}),
|
|
153
|
+
totals,
|
|
154
|
+
discountLabel: discountLabel(quote == null ? void 0 : quote.discount),
|
|
155
|
+
// Once paid, the tax is what was charged: Stripe's figure under Stripe Tax.
|
|
156
|
+
taxLabel: unpaid || (quote == null ? void 0 : (_quote_tax1 = quote.tax) == null ? void 0 : _quote_tax1.kind) !== 'at-payment' ? describeQuoteTax(quote == null ? void 0 : quote.tax) : 'Tax',
|
|
157
|
+
taxAtPayment,
|
|
158
|
+
notes: text(quote == null ? void 0 : quote.notes),
|
|
159
|
+
terms: text(quote == null ? void 0 : quote.terms),
|
|
160
|
+
status: status.status,
|
|
161
|
+
statusLabel: status.label,
|
|
162
|
+
paidAtMs: paidAt(order),
|
|
163
|
+
receiptUrl: unpaid ? null : (_input_receiptUrl = input.receiptUrl) != null ? _input_receiptUrl : null,
|
|
164
|
+
approvalRequired,
|
|
165
|
+
payable: unpaid && !approvalRequired && quotePayRefusal(order, input.orderId) === null
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const LINE_DESCRIPTION_MAX = 500;
|
|
169
|
+
function lineSummary(lines) {
|
|
170
|
+
const parts = lines.map((line)=>{
|
|
171
|
+
const label = line.variantLabel ? `${line.name} (${line.variantLabel})` : line.name;
|
|
172
|
+
return `${Math.max(1, cents(line.quantity))} × ${label}`;
|
|
173
|
+
});
|
|
174
|
+
const summary = parts.join(', ');
|
|
175
|
+
return summary.length > LINE_DESCRIPTION_MAX ? `${summary.slice(0, LINE_DESCRIPTION_MAX - 1)}…` : summary;
|
|
176
|
+
}
|
|
177
|
+
/** What the fee ladder prices the quote's charged goods as: physical when any line ships. */ function feeProductTypeOf(lines) {
|
|
178
|
+
const charged = lines.filter((line)=>!line.included);
|
|
179
|
+
const types = new Set(charged.map((line)=>{
|
|
180
|
+
var _line_productType;
|
|
181
|
+
return (_line_productType = line.productType) != null ? _line_productType : 'physical';
|
|
182
|
+
}));
|
|
183
|
+
if (types.has('physical') || types.size === 0) return 'physical';
|
|
184
|
+
return types.has('service') ? 'service' : 'digital';
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* The charge for a quote, from its stored lines, discount, shipping and tax
|
|
188
|
+
* basis through {@link computeQuoteTotals} — the same function that priced it
|
|
189
|
+
* when it was saved, so the page, the session and the stored quote agree.
|
|
190
|
+
*
|
|
191
|
+
* The goods are charged as at most two lines, the taxed and the tax-exempt,
|
|
192
|
+
* each after its share of the discount. A store rate is applied to the taxed
|
|
193
|
+
* line as one Stripe tax rate, so Stripe's tax is the rate on exactly the
|
|
194
|
+
* amount the quote taxed, and the quote's figure is what is collected. A tax
|
|
195
|
+
* service's figure is carried the same way, as the percentage of the taxed
|
|
196
|
+
* line it amounts to. Included lines charge nothing and are not sent.
|
|
197
|
+
*/ export function quoteCheckoutCharge(order, orderId) {
|
|
198
|
+
var _order_lineItems, _ref, _ref1;
|
|
199
|
+
var _order_quote, _order_quote1, _order_quote_shipping, _order_quote2;
|
|
200
|
+
const lineItems = (_order_lineItems = order.lineItems) != null ? _order_lineItems : [];
|
|
201
|
+
const tax = (_ref = (_order_quote = order.quote) == null ? void 0 : _order_quote.tax) != null ? _ref : {
|
|
202
|
+
kind: 'none',
|
|
203
|
+
reason: 'not-collected'
|
|
204
|
+
};
|
|
205
|
+
const discount = (_ref1 = (_order_quote1 = order.quote) == null ? void 0 : _order_quote1.discount) != null ? _ref1 : null;
|
|
206
|
+
const shippingCents = Math.max(0, cents((_order_quote2 = order.quote) == null ? void 0 : (_order_quote_shipping = _order_quote2.shipping) == null ? void 0 : _order_quote_shipping.amountCents));
|
|
207
|
+
const totals = computeQuoteTotals({
|
|
208
|
+
lines: lineItems,
|
|
209
|
+
discount,
|
|
210
|
+
shippingCents,
|
|
211
|
+
tax
|
|
212
|
+
});
|
|
213
|
+
const amounts = quoteLineAmounts(lineItems, discount);
|
|
214
|
+
const label = formatQuoteNumber(order, orderId);
|
|
215
|
+
const groups = [
|
|
216
|
+
true,
|
|
217
|
+
false
|
|
218
|
+
].map((taxable)=>{
|
|
219
|
+
const members = lineItems.map((line, index)=>({
|
|
220
|
+
line,
|
|
221
|
+
net: amounts.netCents[index]
|
|
222
|
+
})).filter(({ line, net })=>net > 0 && line.taxExempt !== true === taxable);
|
|
223
|
+
return {
|
|
224
|
+
taxable,
|
|
225
|
+
amountCents: members.reduce((sum, { net })=>sum + net, 0),
|
|
226
|
+
description: lineSummary(members.map(({ line })=>line))
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
const charged = groups.filter((group)=>group.amountCents > 0);
|
|
230
|
+
const lines = charged.map((group)=>({
|
|
231
|
+
name: charged.length > 1 && !group.taxable ? `${label} (tax-exempt items)` : label,
|
|
232
|
+
description: group.description,
|
|
233
|
+
amountCents: group.amountCents,
|
|
234
|
+
taxable: group.taxable
|
|
235
|
+
}));
|
|
236
|
+
const taxableCents = groups[0].amountCents;
|
|
237
|
+
const taxPct = totals.taxCents > 0 && taxableCents > 0 ? tax.kind === 'rate' ? Number(tax.pct) : engineLineTaxPercentages([
|
|
238
|
+
{
|
|
239
|
+
amountCents: taxableCents,
|
|
240
|
+
taxCents: totals.taxCents
|
|
241
|
+
}
|
|
242
|
+
], 0)[0] : null;
|
|
243
|
+
// A tax service can tax a quote whose goods are all exempt (on its
|
|
244
|
+
// shipping, say): with no taxed line to carry a rate, its figure is
|
|
245
|
+
// charged as a line of its own, so the customer still pays what the quote says.
|
|
246
|
+
if (totals.taxCents > 0 && taxPct === null) {
|
|
247
|
+
lines.push({
|
|
248
|
+
name: tax.providerLabel ? `Sales tax (${tax.providerLabel})` : 'Sales tax',
|
|
249
|
+
description: label,
|
|
250
|
+
amountCents: totals.taxCents,
|
|
251
|
+
taxable: false
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
lines,
|
|
256
|
+
itemsCents: totals.itemsCents,
|
|
257
|
+
discountCents: totals.discountCents,
|
|
258
|
+
goodsCents: totals.itemsCents - totals.discountCents,
|
|
259
|
+
taxableCents,
|
|
260
|
+
shippingCents,
|
|
261
|
+
taxCents: totals.taxCents,
|
|
262
|
+
taxPct,
|
|
263
|
+
taxAtPayment: totals.taxAtPayment,
|
|
264
|
+
totalCents: totals.totalCents,
|
|
265
|
+
feeProductType: feeProductTypeOf(lineItems)
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/** Why a quote cannot be paid now, or null when it can. */ export function quotePayRefusal(order, orderId) {
|
|
269
|
+
var _order_quote_tax, _order_quote;
|
|
270
|
+
if (order.status === 'cancelled' || order.status === 'refunded') return 'closed';
|
|
271
|
+
if (order.status !== 'pending') return 'paid';
|
|
272
|
+
if (quotePaymentBlockedByApproval(order.quote)) return 'approval-required';
|
|
273
|
+
if (((_order_quote = order.quote) == null ? void 0 : (_order_quote_tax = _order_quote.tax) == null ? void 0 : _order_quote_tax.kind) === 'none' && order.quote.tax.reason === 'undecided') return 'tax-undecided';
|
|
274
|
+
if (quoteCheckoutCharge(order, orderId).totalCents < QUOTE_MIN_CHARGE_CENTS) return 'nothing-to-pay';
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
/** What the customer is told for a {@link QuotePayRefusal}, naming the business. */ export function quotePayRefusalMessage(reason, storeName) {
|
|
278
|
+
const business = storeName.trim() || 'the business';
|
|
279
|
+
switch(reason){
|
|
280
|
+
case 'paid':
|
|
281
|
+
return 'This quote has been paid.';
|
|
282
|
+
case 'closed':
|
|
283
|
+
return `This quote is closed. Contact ${business} with any questions.`;
|
|
284
|
+
case 'approval-required':
|
|
285
|
+
return `${business} asks you to approve the proof before you pay.`;
|
|
286
|
+
case 'tax-undecided':
|
|
287
|
+
return `${business} has not finished setting up payments. Contact them to pay this quote.`;
|
|
288
|
+
case 'nothing-to-pay':
|
|
289
|
+
return `This quote has nothing to pay by card. Contact ${business} with any questions.`;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
export function quotePaymentDisposition(order, payment) {
|
|
293
|
+
var _ref;
|
|
294
|
+
var _order_quote, _order_quote1;
|
|
295
|
+
const recorded = ((_ref = (_order_quote = order.quote) == null ? void 0 : _order_quote.unmatchedPayments) != null ? _ref : []).some((entry)=>(entry == null ? void 0 : entry.sessionId) === payment.sessionId);
|
|
296
|
+
if (recorded) return 'redelivery';
|
|
297
|
+
if (order.status !== 'pending') {
|
|
298
|
+
const same = order.checkoutSessionId && order.checkoutSessionId === payment.sessionId || payment.paymentIntentId && order.paymentIntentId === payment.paymentIntentId;
|
|
299
|
+
return same ? 'redelivery' : 'already-paid';
|
|
300
|
+
}
|
|
301
|
+
const sentVersion = payment.linkVersion;
|
|
302
|
+
if (sentVersion != null && sentVersion !== '' && Number(sentVersion) !== quoteLinkVersion(order.quote)) {
|
|
303
|
+
return 'superseded';
|
|
304
|
+
}
|
|
305
|
+
const sentEdit = payment.quoteUpdatedAtMs;
|
|
306
|
+
if (sentEdit != null && sentEdit !== '' && Number(sentEdit) !== Number((_order_quote1 = order.quote) == null ? void 0 : _order_quote1.updatedAtMs)) {
|
|
307
|
+
return 'superseded';
|
|
308
|
+
}
|
|
309
|
+
return 'pay';
|
|
310
|
+
}
|
|
311
|
+
/** A payment the quote could not take, as {@link QuoteUnmatchedPayment} records it. */ export function quoteUnmatchedPayment(facts, reason) {
|
|
312
|
+
return {
|
|
313
|
+
sessionId: facts.sessionId,
|
|
314
|
+
paymentIntentId: facts.paymentIntentId,
|
|
315
|
+
amountCents: Math.max(0, cents(facts.amountTotalCents)),
|
|
316
|
+
atMs: facts.paidAtMs,
|
|
317
|
+
reason
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/** The timeline line for a payment the quote could not take. */ export function quoteUnmatchedPaymentDetail(entry) {
|
|
321
|
+
const amount = `$${(entry.amountCents / 100).toFixed(2)}`;
|
|
322
|
+
return entry.reason === 'superseded' ? `A payment of ${amount} came through a pay link that was replaced, or for an earlier ` + 'version of this quote. The money is in Stripe and this quote records no sale for it; ' + 'refund it in Stripe, or reconcile it by hand.' : `A second payment of ${amount} came in after this quote was paid. The money is in Stripe ` + 'and no second sale was recorded; refund it in Stripe, or reconcile it by hand.';
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* The order a paid quote becomes, the whole document as it will stand. A
|
|
326
|
+
* quote carries none of the fields order lists read (`commerce-quotes.ts`);
|
|
327
|
+
* paying it writes them:
|
|
328
|
+
*
|
|
329
|
+
* - `createdAtMs` is the time it was paid, the moment it became an order, so
|
|
330
|
+
* it lists and counts on the day the money came in.
|
|
331
|
+
* - The customer moves to the top-level fields every order reader asks
|
|
332
|
+
* (`customerEmail`, `customerName`, `customerPhone`, `customerRecord`), the
|
|
333
|
+
* payer's own email first, as a paid draft takes it.
|
|
334
|
+
* - The address Stripe collected ships it, else the quote's ship-to; the
|
|
335
|
+
* quote's bill-to bills it.
|
|
336
|
+
* - The totals are what Stripe charged: its shipping and tax where it charged
|
|
337
|
+
* any, the platform fee the session was minted with, and its total.
|
|
338
|
+
* - The list fields (`withOrderListFields`) are stamped from all of that.
|
|
339
|
+
*/ export function paidQuoteOrder(order, orderId, facts) {
|
|
340
|
+
var _ref, _order_totals, _ref1, _facts_shippingAddress, _text, _ref2, _text1, _facts_paymentIntentId;
|
|
341
|
+
var _customer_record, _customer_record1;
|
|
342
|
+
const quote = order.quote;
|
|
343
|
+
const customer = (_ref = quote == null ? void 0 : quote.customer) != null ? _ref : {};
|
|
344
|
+
const stored = (_order_totals = order.totals) != null ? _order_totals : {
|
|
345
|
+
itemsCents: 0,
|
|
346
|
+
discountCents: 0,
|
|
347
|
+
shippingCents: 0,
|
|
348
|
+
taxCents: 0,
|
|
349
|
+
feeCents: 0,
|
|
350
|
+
totalCents: 0
|
|
351
|
+
};
|
|
352
|
+
const shippingCents = facts.shippingCents > 0 ? facts.shippingCents : cents(stored.shippingCents);
|
|
353
|
+
const taxCents = facts.taxCents > 0 ? facts.taxCents : cents(stored.taxCents);
|
|
354
|
+
const totalCents = facts.amountTotalCents != null && Number.isFinite(facts.amountTotalCents) ? facts.amountTotalCents : cents(stored.itemsCents) - cents(stored.discountCents) + shippingCents + taxCents;
|
|
355
|
+
const shippingAddress = (_ref1 = (_facts_shippingAddress = facts.shippingAddress) != null ? _facts_shippingAddress : quote == null ? void 0 : quote.shipTo) != null ? _ref1 : null;
|
|
356
|
+
const label = formatOrderNumber(order, orderId);
|
|
357
|
+
const paid = _extends({}, order, {
|
|
358
|
+
status: 'paid',
|
|
359
|
+
createdAtMs: facts.paidAtMs,
|
|
360
|
+
customerEmail: (_text = text(facts.email)) != null ? _text : text(customer.email),
|
|
361
|
+
customerName: (_ref2 = (_text1 = text(customer.name)) != null ? _text1 : text(facts.name)) != null ? _ref2 : text(customer.company)
|
|
362
|
+
}, text(customer.phone) ? {
|
|
363
|
+
customerPhone: text(customer.phone)
|
|
364
|
+
} : {}, ((_customer_record = customer.record) == null ? void 0 : _customer_record.kind) && ((_customer_record1 = customer.record) == null ? void 0 : _customer_record1.id) ? {
|
|
365
|
+
customerRecord: _extends({}, customer.record)
|
|
366
|
+
} : {}, shippingAddress ? {
|
|
367
|
+
shippingAddress: _extends({}, shippingAddress)
|
|
368
|
+
} : {}, (quote == null ? void 0 : quote.billTo) ? {
|
|
369
|
+
billingAddress: _extends({}, quote.billTo)
|
|
370
|
+
} : {}, {
|
|
371
|
+
totals: {
|
|
372
|
+
itemsCents: cents(stored.itemsCents),
|
|
373
|
+
discountCents: cents(stored.discountCents),
|
|
374
|
+
shippingCents,
|
|
375
|
+
taxCents,
|
|
376
|
+
feeCents: Math.max(0, cents(facts.feeCents)),
|
|
377
|
+
totalCents
|
|
378
|
+
},
|
|
379
|
+
taxMode: facts.taxMode,
|
|
380
|
+
paymentIntentId: (_facts_paymentIntentId = facts.paymentIntentId) != null ? _facts_paymentIntentId : undefined,
|
|
381
|
+
checkoutSessionId: facts.sessionId,
|
|
382
|
+
timeline: appendOrderEvent(order, 'paid', `${label} paid through its pay link`, facts.paidAtMs),
|
|
383
|
+
quote: _extends({}, quote, {
|
|
384
|
+
paidAtMs: facts.paidAtMs
|
|
385
|
+
}),
|
|
386
|
+
// New to a shipping tool's feed from the moment it is paid.
|
|
387
|
+
updatedAtMs: facts.paidAtMs
|
|
388
|
+
});
|
|
389
|
+
if (!paid.paymentIntentId) delete paid.paymentIntentId;
|
|
390
|
+
return withOrderListFields(orderId, paid);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
//# sourceMappingURL=commerce-quote-pay.js.map
|