PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.0.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.0.0
2.0.0 1.11.2 1.11.1 1.11.0 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.6 1.9.5 trunk 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 All 61 releases
subscription / src / index.js

index.js in Subscriptions for WooCommerce with Stripe Recurring Payments 2.0.0, at src/index.js

194 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import {
2 ExperimentalOrderMeta,
3 registerCheckoutFilters,
4 TotalsItem,
5 TotalsWrapper,
6 } from "@woocommerce/blocks-checkout";
7 import { FormattedMonetaryAmount } from "@woocommerce/blocks-components";
8 import { __, sprintf } from "@wordpress/i18n";
9 import { registerPlugin } from "@wordpress/plugins";
10
11 import { formatPrice, getCurrencyFromPriceResponse } from "@woocommerce/price-format";
12 // import { useStoreCart } from "@woocommerce/base-context/hooks";
13
14 const modifyCartItemPrice = (defaultValue, extensions, args, validation) => {
15 const { cartItem } = args;
16 const { totals } = cartItem;
17
18 if (totals === undefined) {
19 return defaultValue;
20 }
21 if (totals.line_total === "0") {
22 return `<price/> ${__("Due Today", "subscription")}`;
23 }
24 // The per-unit price shows no cadence — the recurring cadence appears on the
25 // line total (subtotalPriceFormat) and the "Recurring totals" summary.
26 return defaultValue;
27 };
28
29 const modifySubtotalPriceFormat = (defaultValue, extensions, args, validation) => {
30 const { sdevs_subscription } = extensions;
31 const { sdevs_subscription: recurrings } = extensions;
32
33 if (sdevs_subscription && sdevs_subscription.type) {
34 // Capitalize the first letter to match product page display
35 const capitalizedType = sdevs_subscription.type.charAt(0).toUpperCase() + sdevs_subscription.type.slice(1);
36
37 // Check max_no_payment - handle string, number, null, undefined
38 const maxPayments = parseInt(sdevs_subscription.max_no_payment, 10);
39 const paymentInfo = !isNaN(maxPayments) && maxPayments > 0 ? ` x ${maxPayments}` : "";
40
41 const timePart = sdevs_subscription.time && sdevs_subscription.time > 1 ? sdevs_subscription.time + "-" : "";
42 const priceText = "<price/>\u00A0" + __("Every", "subscription") + " " + timePart + capitalizedType + paymentInfo;
43
44 return priceText;
45 }
46
47 return defaultValue;
48 };
49
50 registerCheckoutFilters("sdevs-subscription", {
51 cartItemPrice: modifyCartItemPrice,
52 subtotalPriceFormat: modifySubtotalPriceFormat,
53 });
54
55 const RecurringTotals = ({ cart, extensions }) => {
56 if (Object.keys(extensions).length === 0) {
57 return;
58 }
59 const { cartTotals } = cart;
60 const { sdevs_subscription: recurrings } = extensions;
61 if (recurrings.length === 0) {
62 return;
63 }
64
65 const currency = getCurrencyFromPriceResponse(cartTotals);
66 const multiplier = Math.pow(10, currency.minorUnit);
67
68 return (
69 <TotalsWrapper>
70 <TotalsItem
71 className="wc-block-components-totals-footer-item"
72 label={__("Recurring totals", "subscription")}
73 description={
74 <div style={{ display: "grid" }}>
75 {recurrings.map((recurring) => {
76 // Capitalize the first letter to match product page display
77 const capitalizedType = recurring.type.charAt(0).toUpperCase() + recurring.type.slice(1);
78
79 const priceFormatArgs = {
80 currency: currency.code,
81 currency_symbol: currency.symbol,
82 decimal_separator: currency.decimalSeparator,
83 thousand_separator: currency.thousandSeparator,
84 precision: currency.minorUnit,
85 price_format: currency.priceFormat,
86 };
87
88 /**
89 * Format an amount the same way the surrounding totals are formatted.
90 *
91 * @param {number} amount Amount in major units.
92 * @return {string} Formatted price.
93 */
94 const format = (amount) => formatPrice(Math.round(amount * multiplier), priceFormatArgs);
95
96 const recurringLimit = parseInt(recurring.recurring_limit, 10) || 0;
97
98 // Billing period as plain text, so notes can quote a price the same way the row does.
99 const periodLabel =
100 recurring.time && recurring.time > 1 ? `${recurring.time}-${capitalizedType}` : capitalizedType;
101
102 return (
103 <div style={{ margin: "8px 0px 0px", float: "right" }}>
104 <div style={{ fontSize: "18px" }}>
105 {recurring.has_recurring_discount && (
106 <del aria-hidden="true" style={{ marginRight: "6px", opacity: 0.6 }}>
107 {format(recurring.full_price)}
108 </del>
109 )}
110 <FormattedMonetaryAmount currency={currency} value={Math.round(recurring.price * multiplier)} />
111 <span class="wpsubs-subscription-timing">
112 &nbsp;/&nbsp;
113 {recurring.time && recurring.time > 1
114 ? `${recurring.time + "-" + capitalizedType} `
115 : capitalizedType}
116 </span>
117 </div>
118 <small>{recurring.description}</small>
119 {recurring.has_one_time_discount && (
120 <>
121 <br />
122 <small>
123 {sprintf(
124 // translators: 1: amount paid today, 2: amount charged on each renewal.
125 __("You pay %1$s today. %2$s will be charged from the next renewal.", "subscription"),
126 format(recurring.first_price),
127 format(recurring.price),
128 )}
129 </small>
130 </>
131 )}
132 {recurring.has_recurring_discount && recurringLimit > 1 && (
133 <>
134 <br />
135 <small>
136 {sprintf(
137 // translators: 1: number of discounted payments, 2: full price charged afterwards.
138 __("Discount applies to your first %1$s payments. After that, %2$s.", "subscription"),
139 recurringLimit,
140 `${format(recurring.full_price)} / ${periodLabel}`,
141 )}
142 </small>
143 </>
144 )}
145 {recurring.can_user_cancel === "yes" &&
146 (recurring.max_no_payment === "" || parseInt(recurring.max_no_payment) === 0) && (
147 <>
148 <br />
149 <small>{__("You can cancel subscription at any time!", "subscription")} </small>
150 </>
151 )}
152 {parseInt(recurring.max_no_payment) > 0 && (
153 <>
154 <br />
155 <small>
156 {sprintf(
157 // translators: 1: number of installments, 2: total amount.
158 __(
159 "This subscription will be billed in %1$s installments, for a total of %2$s.",
160 "subscription",
161 ),
162 recurring.max_no_payment,
163 format(
164 recurring.split_total != null
165 ? recurring.split_total
166 : recurring.price * parseInt(recurring.max_no_payment),
167 ),
168 )}
169 </small>
170 </>
171 )}
172 </div>
173 );
174 })}
175 </div>
176 }
177 ></TotalsItem>
178 </TotalsWrapper>
179 );
180 };
181
182 const render = () => {
183 return (
184 <ExperimentalOrderMeta>
185 <RecurringTotals />
186 </ExperimentalOrderMeta>
187 );
188 };
189
190 registerPlugin("sdevs-subscription", {
191 render,
192 scope: "woocommerce-checkout",
193 });
194