recur-tw 0.9.10 → 0.9.12
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/index.cjs +61 -77
- package/dist/index.js +61 -77
- package/dist/recur.umd.js +144 -118
- package/dist/server.cjs +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -657,11 +657,11 @@ var init_payment_form_skeleton2 = __esm({
|
|
|
657
657
|
<h3 class="section-title">訂單摘要</h3>
|
|
658
658
|
<div class="order-summary">
|
|
659
659
|
<div class="order-row">
|
|
660
|
-
<span class="order-label"
|
|
661
|
-
<div class="skeleton skeleton-order-value"></div>
|
|
660
|
+
<span class="order-label">方案</span>
|
|
661
|
+
<div class="skeleton skeleton-order-value" style="width: 120px;"></div>
|
|
662
662
|
</div>
|
|
663
663
|
<div class="order-row">
|
|
664
|
-
<span class="order-label"
|
|
664
|
+
<span class="order-label">小計</span>
|
|
665
665
|
<div class="skeleton skeleton-order-value"></div>
|
|
666
666
|
</div>
|
|
667
667
|
<div class="coupon-section">
|
|
@@ -1035,7 +1035,7 @@ var init_payment_form_shadow = __esm({
|
|
|
1035
1035
|
var payment_form_light_default;
|
|
1036
1036
|
var init_payment_form_light = __esm({
|
|
1037
1037
|
"src/components/styles/payment-form-light.css"() {
|
|
1038
|
-
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input {\n flex: 1;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:focus {\n border-color: #
|
|
1038
|
+
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input {\n flex: 1;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n background-color: #ffffff;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n.recur-coupon__input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-coupon__btn {\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s, opacity 0.2s;\n white-space: nowrap;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.recur-coupon__btn--apply {\n background: #18181b;\n color: white;\n border: none;\n min-width: 52px;\n}\n\n.recur-coupon__btn--apply .recur-coupon__spinner {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__btn--apply:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-coupon__btn--apply:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.recur-coupon__btn--cancel {\n background: transparent;\n color: #718096;\n border: 1px solid #d1d5db;\n}\n\n.recur-coupon__btn--cancel:hover {\n background: #f7fafc;\n}\n\n.recur-coupon__error {\n width: 100%;\n margin-top: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.recur-coupon__applied {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__applied-info {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n flex: 1;\n}\n\n.recur-coupon__applied-icon {\n width: 16px;\n height: 16px;\n color: #dc2626;\n flex-shrink: 0;\n}\n\n.recur-coupon__applied-name {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n}\n\n.recur-coupon__applied-code {\n font-size: 14px;\n color: #9ca3af;\n white-space: nowrap;\n margin-right: 2px;\n}\n\n.recur-coupon__applied-amount {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n margin-left: auto;\n}\n\n.recur-coupon__remove {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #9ca3af;\n border-radius: 4px;\n transition: color 0.2s, background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.recur-coupon__remove:hover {\n color: #6b7280;\n background: rgba(0, 0, 0, 0.05);\n}\n\n.recur-coupon__remove-icon {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__spinner {\n width: 14px;\n height: 14px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n/* Discount Row */\n.recur-order-summary__row--discount {\n color: #16a34a;\n}\n\n.recur-order-summary__row--discount .recur-order-summary__value {\n color: #16a34a;\n font-weight: 500;\n}\n\n/* ============================================\n * Customer Info Styles\n * ============================================ */\n.recur-info-display {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n padding: 12px;\n margin-bottom: 8px;\n}\n\n.recur-info-row {\n margin-bottom: 12px;\n}\n\n.recur-info-row:last-child {\n margin-bottom: 0;\n}\n\n.recur-info-label {\n display: block;\n font-size: 12px;\n line-height: 16px;\n color: #718096;\n margin-bottom: 2px;\n}\n\n.recur-info-value {\n display: block;\n font-size: 14px;\n line-height: 20px;\n min-height: 20px;\n color: #2d3748;\n font-weight: 500;\n word-break: break-all;\n}\n\n.recur-form-group {\n margin-bottom: 16px;\n}\n\n.recur-form-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-form-input {\n width: 100%;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n transition: border-color 0.2s;\n box-sizing: border-box;\n}\n\n.recur-form-input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-form-input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n/* ============================================\n * Card Fields Styles\n * ============================================ */\n.recur-card-field {\n margin-bottom: 16px;\n}\n\n.recur-card-field-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-payuni-iframe {\n height: 36px;\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n touch-action: manipulation;\n}\n\n.recur-card-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n column-gap: 16px;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.recur-card-field-container {\n position: relative;\n touch-action: manipulation;\n}\n\n.recur-card-skeleton {\n position: absolute;\n top: 0;\n left: 0;\n height: 36px;\n width: 100%;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n z-index: 1;\n pointer-events: none;\n}\n\n.recur-card-skeleton.hidden {\n display: none;\n}\n\n@keyframes recur-skeleton-loading {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* ============================================\n * Submit Button Styles\n * ============================================ */\n.recur-submit-button {\n width: 100%;\n padding: 14px 20px;\n font-size: 16px;\n font-weight: 500;\n color: #ffffff;\n background: #18181b;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n box-sizing: border-box;\n}\n\n.recur-submit-button:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-submit-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.recur-submit-button.loading {\n cursor: wait;\n}\n\n.recur-loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n@keyframes recur-spin {\n to { transform: rotate(360deg); }\n}\n\n/* ============================================\n * Skeleton Loading Styles\n * ============================================ */\n.recur-skeleton {\n display: inline-block;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n}\n";
|
|
1039
1039
|
}
|
|
1040
1040
|
});
|
|
1041
1041
|
|
|
@@ -1224,7 +1224,25 @@ var init_payment_form = __esm({
|
|
|
1224
1224
|
const amount = this.getAttribute("amount");
|
|
1225
1225
|
const interval = this.getAttribute("interval");
|
|
1226
1226
|
if (!productName || !amount) {
|
|
1227
|
-
return litHtml.html
|
|
1227
|
+
return litHtml.html`
|
|
1228
|
+
<div class="recur-order-summary" id="${this.containerId}-order-summary">
|
|
1229
|
+
<div class="recur-order-summary__row">
|
|
1230
|
+
<span class="recur-order-summary__label">方案</span>
|
|
1231
|
+
<span class="recur-order-summary__value recur-skeleton" style="width: 120px; height: 20px;"></span>
|
|
1232
|
+
</div>
|
|
1233
|
+
<div class="recur-order-summary__row">
|
|
1234
|
+
<span class="recur-order-summary__label">小計</span>
|
|
1235
|
+
<span class="recur-order-summary__value recur-skeleton" style="width: 80px; height: 20px;"></span>
|
|
1236
|
+
</div>
|
|
1237
|
+
<div class="recur-coupon">
|
|
1238
|
+
<span class="recur-skeleton" style="width: 80px; height: 20px;"></span>
|
|
1239
|
+
</div>
|
|
1240
|
+
<div class="recur-order-summary__row recur-order-summary__row--total">
|
|
1241
|
+
<span class="recur-order-summary__label">總計</span>
|
|
1242
|
+
<span class="recur-order-summary__total recur-skeleton" style="width: 100px; height: 26px;"></span>
|
|
1243
|
+
</div>
|
|
1244
|
+
</div>
|
|
1245
|
+
`;
|
|
1228
1246
|
}
|
|
1229
1247
|
const intervalMap = {
|
|
1230
1248
|
"day": "\u65E5",
|
|
@@ -1236,35 +1254,26 @@ var init_payment_form = __esm({
|
|
|
1236
1254
|
const originalAmount = Number(amount);
|
|
1237
1255
|
const discountAmount = this._appliedCoupon?.discountAmount || 0;
|
|
1238
1256
|
const finalAmount = originalAmount - discountAmount;
|
|
1257
|
+
const productDisplay = periodText ? `${productName} / \u6BCF${periodText}` : productName;
|
|
1239
1258
|
return litHtml.html`
|
|
1240
1259
|
<div class="recur-order-summary" id="${this.containerId}-order-summary">
|
|
1241
1260
|
<div class="recur-order-summary__row">
|
|
1242
|
-
<span class="recur-order-summary__label"
|
|
1243
|
-
<span class="recur-order-summary__value">${
|
|
1261
|
+
<span class="recur-order-summary__label">方案</span>
|
|
1262
|
+
<span class="recur-order-summary__value">${productDisplay}</span>
|
|
1244
1263
|
</div>
|
|
1245
1264
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
` : litHtml.nothing}
|
|
1265
|
+
<!-- 小計 (Subtotal) - always show -->
|
|
1266
|
+
<div class="recur-order-summary__row">
|
|
1267
|
+
<span class="recur-order-summary__label">小計</span>
|
|
1268
|
+
<span class="recur-order-summary__value">NT$ ${originalAmount.toLocaleString()}</span>
|
|
1269
|
+
</div>
|
|
1252
1270
|
|
|
1271
|
+
<!-- 優惠碼區塊 (Coupon section with discount amount) -->
|
|
1253
1272
|
<div class="recur-coupon" id="${this.containerId}-coupon">
|
|
1254
1273
|
${this.renderCoupon()}
|
|
1255
1274
|
</div>
|
|
1256
1275
|
|
|
1257
|
-
|
|
1258
|
-
<div class="recur-order-summary__row">
|
|
1259
|
-
<span class="recur-order-summary__label">小計</span>
|
|
1260
|
-
<span class="recur-order-summary__value">NT$ ${originalAmount.toLocaleString()}</span>
|
|
1261
|
-
</div>
|
|
1262
|
-
<div class="recur-order-summary__row recur-order-summary__row--discount">
|
|
1263
|
-
<span class="recur-order-summary__label">折扣</span>
|
|
1264
|
-
<span class="recur-order-summary__value">-NT$ ${discountAmount.toLocaleString()}</span>
|
|
1265
|
-
</div>
|
|
1266
|
-
` : litHtml.nothing}
|
|
1267
|
-
|
|
1276
|
+
<!-- 總計 (Total) -->
|
|
1268
1277
|
<div class="recur-order-summary__row recur-order-summary__row--total">
|
|
1269
1278
|
<span class="recur-order-summary__label">總計</span>
|
|
1270
1279
|
<span class="recur-order-summary__total">NT$ ${finalAmount.toLocaleString()}</span>
|
|
@@ -1278,26 +1287,24 @@ var init_payment_form = __esm({
|
|
|
1278
1287
|
<div class="recur-coupon__applied">
|
|
1279
1288
|
<div class="recur-coupon__applied-info">
|
|
1280
1289
|
${icons.tagApplied}
|
|
1281
|
-
|
|
1282
|
-
<
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1290
|
+
${this._appliedCoupon.couponName ? litHtml.html`
|
|
1291
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.couponName}</span>
|
|
1292
|
+
<span class="recur-coupon__applied-code">(${this._appliedCoupon.code})</span>
|
|
1293
|
+
` : litHtml.html`
|
|
1294
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.code}</span>
|
|
1295
|
+
`}
|
|
1296
|
+
<button
|
|
1297
|
+
type="button"
|
|
1298
|
+
class="recur-coupon__remove"
|
|
1299
|
+
?disabled=${this._couponLoading}
|
|
1300
|
+
@click=${() => this.removeCoupon()}
|
|
1301
|
+
>
|
|
1302
|
+
${this._couponLoading ? icons.spinner : icons.close}
|
|
1303
|
+
</button>
|
|
1289
1304
|
</div>
|
|
1290
1305
|
<span class="recur-coupon__applied-amount">
|
|
1291
1306
|
-NT$ ${this._appliedCoupon.discountAmount.toLocaleString()}
|
|
1292
1307
|
</span>
|
|
1293
|
-
<button
|
|
1294
|
-
type="button"
|
|
1295
|
-
class="recur-coupon__remove"
|
|
1296
|
-
?disabled=${this._couponLoading}
|
|
1297
|
-
@click=${() => this.removeCoupon()}
|
|
1298
|
-
>
|
|
1299
|
-
${this._couponLoading ? icons.spinner : icons.close}
|
|
1300
|
-
</button>
|
|
1301
1308
|
</div>
|
|
1302
1309
|
`;
|
|
1303
1310
|
}
|
|
@@ -1386,7 +1393,8 @@ var init_payment_form = __esm({
|
|
|
1386
1393
|
}
|
|
1387
1394
|
// Direct DOM manipulation for coupon section updates (avoids lit-html tracking issues)
|
|
1388
1395
|
updateCouponSectionDOM() {
|
|
1389
|
-
const
|
|
1396
|
+
const containerId = `${this.containerId}-coupon`;
|
|
1397
|
+
const container = document.getElementById(containerId);
|
|
1390
1398
|
if (!container) return;
|
|
1391
1399
|
if (this._appliedCoupon) {
|
|
1392
1400
|
container.innerHTML = this.getCouponAppliedHTML();
|
|
@@ -1443,22 +1451,19 @@ var init_payment_form = __esm({
|
|
|
1443
1451
|
}
|
|
1444
1452
|
getCouponAppliedHTML() {
|
|
1445
1453
|
const coupon = this._appliedCoupon;
|
|
1446
|
-
const
|
|
1454
|
+
const nameHTML = coupon.couponName ? `<span class="recur-coupon__applied-name">${coupon.couponName}</span><span class="recur-coupon__applied-code">(${coupon.code})</span>` : `<span class="recur-coupon__applied-name">${coupon.code}</span>`;
|
|
1447
1455
|
return `
|
|
1448
1456
|
<div class="recur-coupon__applied">
|
|
1449
1457
|
<div class="recur-coupon__applied-info">
|
|
1450
1458
|
<svg class="recur-coupon__applied-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1451
1459
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
|
|
1452
1460
|
</svg>
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
${
|
|
1456
|
-
</
|
|
1461
|
+
${nameHTML}
|
|
1462
|
+
<button type="button" class="recur-coupon__remove" ${this._couponLoading ? "disabled" : ""}>
|
|
1463
|
+
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : '<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>'}
|
|
1464
|
+
</button>
|
|
1457
1465
|
</div>
|
|
1458
1466
|
<span class="recur-coupon__applied-amount">-NT$ ${coupon.discountAmount.toLocaleString()}</span>
|
|
1459
|
-
<button type="button" class="recur-coupon__remove" ${this._couponLoading ? "disabled" : ""}>
|
|
1460
|
-
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : '<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>'}
|
|
1461
|
-
</button>
|
|
1462
1467
|
</div>
|
|
1463
1468
|
`;
|
|
1464
1469
|
}
|
|
@@ -1485,31 +1490,7 @@ var init_payment_form = __esm({
|
|
|
1485
1490
|
const amount = Number(this.getAttribute("amount") || 0);
|
|
1486
1491
|
const discountAmount = this._appliedCoupon?.discountAmount || 0;
|
|
1487
1492
|
const finalAmount = amount - discountAmount;
|
|
1488
|
-
let discountRow = summaryContainer.querySelector(".recur-order-summary__row--discount");
|
|
1489
1493
|
const totalRow = summaryContainer.querySelector(".recur-order-summary__row--total");
|
|
1490
|
-
if (discountAmount > 0) {
|
|
1491
|
-
if (!discountRow && totalRow) {
|
|
1492
|
-
const subtotalHTML = `
|
|
1493
|
-
<div class="recur-order-summary__row">
|
|
1494
|
-
<span class="recur-order-summary__label">\u5C0F\u8A08</span>
|
|
1495
|
-
<span class="recur-order-summary__value">NT$ ${amount.toLocaleString()}</span>
|
|
1496
|
-
</div>
|
|
1497
|
-
`;
|
|
1498
|
-
const discountHTML = `
|
|
1499
|
-
<div class="recur-order-summary__row recur-order-summary__row--discount">
|
|
1500
|
-
<span class="recur-order-summary__label">\u6298\u6263</span>
|
|
1501
|
-
<span class="recur-order-summary__value">-NT$ ${discountAmount.toLocaleString()}</span>
|
|
1502
|
-
</div>
|
|
1503
|
-
`;
|
|
1504
|
-
totalRow.insertAdjacentHTML("beforebegin", subtotalHTML + discountHTML);
|
|
1505
|
-
}
|
|
1506
|
-
} else {
|
|
1507
|
-
const subtotalRow = summaryContainer.querySelector(".recur-order-summary__row:not(.recur-order-summary__row--total):last-of-type");
|
|
1508
|
-
discountRow?.remove();
|
|
1509
|
-
if (subtotalRow?.querySelector(".recur-order-summary__label")?.textContent === "\u5C0F\u8A08") {
|
|
1510
|
-
subtotalRow.remove();
|
|
1511
|
-
}
|
|
1512
|
-
}
|
|
1513
1494
|
const totalValue = totalRow?.querySelector(".recur-order-summary__total");
|
|
1514
1495
|
if (totalValue) {
|
|
1515
1496
|
totalValue.textContent = `NT$ ${finalAmount.toLocaleString()}`;
|
|
@@ -1537,7 +1518,7 @@ var init_payment_form = __esm({
|
|
|
1537
1518
|
this._couponError = null;
|
|
1538
1519
|
this.updateCouponSectionDOM();
|
|
1539
1520
|
try {
|
|
1540
|
-
const response = await fetch(`${apiBaseUrl}/
|
|
1521
|
+
const response = await fetch(`${apiBaseUrl}/v1/checkouts/${checkoutId}/coupon`, {
|
|
1541
1522
|
method: "POST",
|
|
1542
1523
|
headers: { "Content-Type": "application/json" },
|
|
1543
1524
|
body: JSON.stringify({ code })
|
|
@@ -1583,7 +1564,7 @@ var init_payment_form = __esm({
|
|
|
1583
1564
|
this._couponLoading = true;
|
|
1584
1565
|
this.updateCouponSectionDOM();
|
|
1585
1566
|
try {
|
|
1586
|
-
const response = await fetch(`${apiBaseUrl}/
|
|
1567
|
+
const response = await fetch(`${apiBaseUrl}/v1/checkouts/${checkoutId}/coupon`, {
|
|
1587
1568
|
method: "DELETE"
|
|
1588
1569
|
});
|
|
1589
1570
|
if (!response.ok) {
|
|
@@ -2565,7 +2546,7 @@ function toCamelCase(obj) {
|
|
|
2565
2546
|
|
|
2566
2547
|
// package.json
|
|
2567
2548
|
var package_default = {
|
|
2568
|
-
version: "0.9.
|
|
2549
|
+
version: "0.9.12"};
|
|
2569
2550
|
var SDK_VERSION = package_default.version;
|
|
2570
2551
|
var SDK_TYPE = "react";
|
|
2571
2552
|
var RecurContext = React.createContext(null);
|
|
@@ -2881,6 +2862,10 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2881
2862
|
container.innerHTML = "";
|
|
2882
2863
|
const paymentForm = document.createElement("recur-payment-form");
|
|
2883
2864
|
paymentForm.setAttribute("container-id", containerElementId);
|
|
2865
|
+
if (checkoutResult.checkout?.id) {
|
|
2866
|
+
paymentForm.setAttribute("checkout-id", checkoutResult.checkout.id);
|
|
2867
|
+
}
|
|
2868
|
+
paymentForm.setAttribute("api-base-url", baseUrl);
|
|
2884
2869
|
if (options.customerName) {
|
|
2885
2870
|
paymentForm.setAttribute("customer-name", options.customerName);
|
|
2886
2871
|
}
|
|
@@ -2897,7 +2882,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2897
2882
|
paymentForm.setAttribute("interval", checkoutResult.product.interval);
|
|
2898
2883
|
}
|
|
2899
2884
|
const customStyles = `
|
|
2900
|
-
/* PAYUNi SDK focus \u6A23\u5F0F - shadcn \u98A8\u683C */
|
|
2901
2885
|
.form-input-focus {
|
|
2902
2886
|
border-color: var(--ring, hsl(215 16% 47%)) !important;
|
|
2903
2887
|
outline: 0 !important;
|
package/dist/index.js
CHANGED
|
@@ -651,11 +651,11 @@ var init_payment_form_skeleton2 = __esm({
|
|
|
651
651
|
<h3 class="section-title">訂單摘要</h3>
|
|
652
652
|
<div class="order-summary">
|
|
653
653
|
<div class="order-row">
|
|
654
|
-
<span class="order-label"
|
|
655
|
-
<div class="skeleton skeleton-order-value"></div>
|
|
654
|
+
<span class="order-label">方案</span>
|
|
655
|
+
<div class="skeleton skeleton-order-value" style="width: 120px;"></div>
|
|
656
656
|
</div>
|
|
657
657
|
<div class="order-row">
|
|
658
|
-
<span class="order-label"
|
|
658
|
+
<span class="order-label">小計</span>
|
|
659
659
|
<div class="skeleton skeleton-order-value"></div>
|
|
660
660
|
</div>
|
|
661
661
|
<div class="coupon-section">
|
|
@@ -1029,7 +1029,7 @@ var init_payment_form_shadow = __esm({
|
|
|
1029
1029
|
var payment_form_light_default;
|
|
1030
1030
|
var init_payment_form_light = __esm({
|
|
1031
1031
|
"src/components/styles/payment-form-light.css"() {
|
|
1032
|
-
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input {\n flex: 1;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:focus {\n border-color: #
|
|
1032
|
+
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input {\n flex: 1;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n background-color: #ffffff;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n.recur-coupon__input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-coupon__btn {\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s, opacity 0.2s;\n white-space: nowrap;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.recur-coupon__btn--apply {\n background: #18181b;\n color: white;\n border: none;\n min-width: 52px;\n}\n\n.recur-coupon__btn--apply .recur-coupon__spinner {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__btn--apply:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-coupon__btn--apply:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.recur-coupon__btn--cancel {\n background: transparent;\n color: #718096;\n border: 1px solid #d1d5db;\n}\n\n.recur-coupon__btn--cancel:hover {\n background: #f7fafc;\n}\n\n.recur-coupon__error {\n width: 100%;\n margin-top: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.recur-coupon__applied {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__applied-info {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n flex: 1;\n}\n\n.recur-coupon__applied-icon {\n width: 16px;\n height: 16px;\n color: #dc2626;\n flex-shrink: 0;\n}\n\n.recur-coupon__applied-name {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n}\n\n.recur-coupon__applied-code {\n font-size: 14px;\n color: #9ca3af;\n white-space: nowrap;\n margin-right: 2px;\n}\n\n.recur-coupon__applied-amount {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n margin-left: auto;\n}\n\n.recur-coupon__remove {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #9ca3af;\n border-radius: 4px;\n transition: color 0.2s, background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.recur-coupon__remove:hover {\n color: #6b7280;\n background: rgba(0, 0, 0, 0.05);\n}\n\n.recur-coupon__remove-icon {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__spinner {\n width: 14px;\n height: 14px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n/* Discount Row */\n.recur-order-summary__row--discount {\n color: #16a34a;\n}\n\n.recur-order-summary__row--discount .recur-order-summary__value {\n color: #16a34a;\n font-weight: 500;\n}\n\n/* ============================================\n * Customer Info Styles\n * ============================================ */\n.recur-info-display {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n padding: 12px;\n margin-bottom: 8px;\n}\n\n.recur-info-row {\n margin-bottom: 12px;\n}\n\n.recur-info-row:last-child {\n margin-bottom: 0;\n}\n\n.recur-info-label {\n display: block;\n font-size: 12px;\n line-height: 16px;\n color: #718096;\n margin-bottom: 2px;\n}\n\n.recur-info-value {\n display: block;\n font-size: 14px;\n line-height: 20px;\n min-height: 20px;\n color: #2d3748;\n font-weight: 500;\n word-break: break-all;\n}\n\n.recur-form-group {\n margin-bottom: 16px;\n}\n\n.recur-form-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-form-input {\n width: 100%;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n transition: border-color 0.2s;\n box-sizing: border-box;\n}\n\n.recur-form-input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-form-input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n/* ============================================\n * Card Fields Styles\n * ============================================ */\n.recur-card-field {\n margin-bottom: 16px;\n}\n\n.recur-card-field-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-payuni-iframe {\n height: 36px;\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n touch-action: manipulation;\n}\n\n.recur-card-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n column-gap: 16px;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.recur-card-field-container {\n position: relative;\n touch-action: manipulation;\n}\n\n.recur-card-skeleton {\n position: absolute;\n top: 0;\n left: 0;\n height: 36px;\n width: 100%;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n z-index: 1;\n pointer-events: none;\n}\n\n.recur-card-skeleton.hidden {\n display: none;\n}\n\n@keyframes recur-skeleton-loading {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* ============================================\n * Submit Button Styles\n * ============================================ */\n.recur-submit-button {\n width: 100%;\n padding: 14px 20px;\n font-size: 16px;\n font-weight: 500;\n color: #ffffff;\n background: #18181b;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n box-sizing: border-box;\n}\n\n.recur-submit-button:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-submit-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.recur-submit-button.loading {\n cursor: wait;\n}\n\n.recur-loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n@keyframes recur-spin {\n to { transform: rotate(360deg); }\n}\n\n/* ============================================\n * Skeleton Loading Styles\n * ============================================ */\n.recur-skeleton {\n display: inline-block;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n}\n";
|
|
1033
1033
|
}
|
|
1034
1034
|
});
|
|
1035
1035
|
|
|
@@ -1218,7 +1218,25 @@ var init_payment_form = __esm({
|
|
|
1218
1218
|
const amount = this.getAttribute("amount");
|
|
1219
1219
|
const interval = this.getAttribute("interval");
|
|
1220
1220
|
if (!productName || !amount) {
|
|
1221
|
-
return html
|
|
1221
|
+
return html`
|
|
1222
|
+
<div class="recur-order-summary" id="${this.containerId}-order-summary">
|
|
1223
|
+
<div class="recur-order-summary__row">
|
|
1224
|
+
<span class="recur-order-summary__label">方案</span>
|
|
1225
|
+
<span class="recur-order-summary__value recur-skeleton" style="width: 120px; height: 20px;"></span>
|
|
1226
|
+
</div>
|
|
1227
|
+
<div class="recur-order-summary__row">
|
|
1228
|
+
<span class="recur-order-summary__label">小計</span>
|
|
1229
|
+
<span class="recur-order-summary__value recur-skeleton" style="width: 80px; height: 20px;"></span>
|
|
1230
|
+
</div>
|
|
1231
|
+
<div class="recur-coupon">
|
|
1232
|
+
<span class="recur-skeleton" style="width: 80px; height: 20px;"></span>
|
|
1233
|
+
</div>
|
|
1234
|
+
<div class="recur-order-summary__row recur-order-summary__row--total">
|
|
1235
|
+
<span class="recur-order-summary__label">總計</span>
|
|
1236
|
+
<span class="recur-order-summary__total recur-skeleton" style="width: 100px; height: 26px;"></span>
|
|
1237
|
+
</div>
|
|
1238
|
+
</div>
|
|
1239
|
+
`;
|
|
1222
1240
|
}
|
|
1223
1241
|
const intervalMap = {
|
|
1224
1242
|
"day": "\u65E5",
|
|
@@ -1230,35 +1248,26 @@ var init_payment_form = __esm({
|
|
|
1230
1248
|
const originalAmount = Number(amount);
|
|
1231
1249
|
const discountAmount = this._appliedCoupon?.discountAmount || 0;
|
|
1232
1250
|
const finalAmount = originalAmount - discountAmount;
|
|
1251
|
+
const productDisplay = periodText ? `${productName} / \u6BCF${periodText}` : productName;
|
|
1233
1252
|
return html`
|
|
1234
1253
|
<div class="recur-order-summary" id="${this.containerId}-order-summary">
|
|
1235
1254
|
<div class="recur-order-summary__row">
|
|
1236
|
-
<span class="recur-order-summary__label"
|
|
1237
|
-
<span class="recur-order-summary__value">${
|
|
1255
|
+
<span class="recur-order-summary__label">方案</span>
|
|
1256
|
+
<span class="recur-order-summary__value">${productDisplay}</span>
|
|
1238
1257
|
</div>
|
|
1239
1258
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
` : nothing}
|
|
1259
|
+
<!-- 小計 (Subtotal) - always show -->
|
|
1260
|
+
<div class="recur-order-summary__row">
|
|
1261
|
+
<span class="recur-order-summary__label">小計</span>
|
|
1262
|
+
<span class="recur-order-summary__value">NT$ ${originalAmount.toLocaleString()}</span>
|
|
1263
|
+
</div>
|
|
1246
1264
|
|
|
1265
|
+
<!-- 優惠碼區塊 (Coupon section with discount amount) -->
|
|
1247
1266
|
<div class="recur-coupon" id="${this.containerId}-coupon">
|
|
1248
1267
|
${this.renderCoupon()}
|
|
1249
1268
|
</div>
|
|
1250
1269
|
|
|
1251
|
-
|
|
1252
|
-
<div class="recur-order-summary__row">
|
|
1253
|
-
<span class="recur-order-summary__label">小計</span>
|
|
1254
|
-
<span class="recur-order-summary__value">NT$ ${originalAmount.toLocaleString()}</span>
|
|
1255
|
-
</div>
|
|
1256
|
-
<div class="recur-order-summary__row recur-order-summary__row--discount">
|
|
1257
|
-
<span class="recur-order-summary__label">折扣</span>
|
|
1258
|
-
<span class="recur-order-summary__value">-NT$ ${discountAmount.toLocaleString()}</span>
|
|
1259
|
-
</div>
|
|
1260
|
-
` : nothing}
|
|
1261
|
-
|
|
1270
|
+
<!-- 總計 (Total) -->
|
|
1262
1271
|
<div class="recur-order-summary__row recur-order-summary__row--total">
|
|
1263
1272
|
<span class="recur-order-summary__label">總計</span>
|
|
1264
1273
|
<span class="recur-order-summary__total">NT$ ${finalAmount.toLocaleString()}</span>
|
|
@@ -1272,26 +1281,24 @@ var init_payment_form = __esm({
|
|
|
1272
1281
|
<div class="recur-coupon__applied">
|
|
1273
1282
|
<div class="recur-coupon__applied-info">
|
|
1274
1283
|
${icons.tagApplied}
|
|
1275
|
-
|
|
1276
|
-
<
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1284
|
+
${this._appliedCoupon.couponName ? html`
|
|
1285
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.couponName}</span>
|
|
1286
|
+
<span class="recur-coupon__applied-code">(${this._appliedCoupon.code})</span>
|
|
1287
|
+
` : html`
|
|
1288
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.code}</span>
|
|
1289
|
+
`}
|
|
1290
|
+
<button
|
|
1291
|
+
type="button"
|
|
1292
|
+
class="recur-coupon__remove"
|
|
1293
|
+
?disabled=${this._couponLoading}
|
|
1294
|
+
@click=${() => this.removeCoupon()}
|
|
1295
|
+
>
|
|
1296
|
+
${this._couponLoading ? icons.spinner : icons.close}
|
|
1297
|
+
</button>
|
|
1283
1298
|
</div>
|
|
1284
1299
|
<span class="recur-coupon__applied-amount">
|
|
1285
1300
|
-NT$ ${this._appliedCoupon.discountAmount.toLocaleString()}
|
|
1286
1301
|
</span>
|
|
1287
|
-
<button
|
|
1288
|
-
type="button"
|
|
1289
|
-
class="recur-coupon__remove"
|
|
1290
|
-
?disabled=${this._couponLoading}
|
|
1291
|
-
@click=${() => this.removeCoupon()}
|
|
1292
|
-
>
|
|
1293
|
-
${this._couponLoading ? icons.spinner : icons.close}
|
|
1294
|
-
</button>
|
|
1295
1302
|
</div>
|
|
1296
1303
|
`;
|
|
1297
1304
|
}
|
|
@@ -1380,7 +1387,8 @@ var init_payment_form = __esm({
|
|
|
1380
1387
|
}
|
|
1381
1388
|
// Direct DOM manipulation for coupon section updates (avoids lit-html tracking issues)
|
|
1382
1389
|
updateCouponSectionDOM() {
|
|
1383
|
-
const
|
|
1390
|
+
const containerId = `${this.containerId}-coupon`;
|
|
1391
|
+
const container = document.getElementById(containerId);
|
|
1384
1392
|
if (!container) return;
|
|
1385
1393
|
if (this._appliedCoupon) {
|
|
1386
1394
|
container.innerHTML = this.getCouponAppliedHTML();
|
|
@@ -1437,22 +1445,19 @@ var init_payment_form = __esm({
|
|
|
1437
1445
|
}
|
|
1438
1446
|
getCouponAppliedHTML() {
|
|
1439
1447
|
const coupon = this._appliedCoupon;
|
|
1440
|
-
const
|
|
1448
|
+
const nameHTML = coupon.couponName ? `<span class="recur-coupon__applied-name">${coupon.couponName}</span><span class="recur-coupon__applied-code">(${coupon.code})</span>` : `<span class="recur-coupon__applied-name">${coupon.code}</span>`;
|
|
1441
1449
|
return `
|
|
1442
1450
|
<div class="recur-coupon__applied">
|
|
1443
1451
|
<div class="recur-coupon__applied-info">
|
|
1444
1452
|
<svg class="recur-coupon__applied-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1445
1453
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
|
|
1446
1454
|
</svg>
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
${
|
|
1450
|
-
</
|
|
1455
|
+
${nameHTML}
|
|
1456
|
+
<button type="button" class="recur-coupon__remove" ${this._couponLoading ? "disabled" : ""}>
|
|
1457
|
+
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : '<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>'}
|
|
1458
|
+
</button>
|
|
1451
1459
|
</div>
|
|
1452
1460
|
<span class="recur-coupon__applied-amount">-NT$ ${coupon.discountAmount.toLocaleString()}</span>
|
|
1453
|
-
<button type="button" class="recur-coupon__remove" ${this._couponLoading ? "disabled" : ""}>
|
|
1454
|
-
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : '<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>'}
|
|
1455
|
-
</button>
|
|
1456
1461
|
</div>
|
|
1457
1462
|
`;
|
|
1458
1463
|
}
|
|
@@ -1479,31 +1484,7 @@ var init_payment_form = __esm({
|
|
|
1479
1484
|
const amount = Number(this.getAttribute("amount") || 0);
|
|
1480
1485
|
const discountAmount = this._appliedCoupon?.discountAmount || 0;
|
|
1481
1486
|
const finalAmount = amount - discountAmount;
|
|
1482
|
-
let discountRow = summaryContainer.querySelector(".recur-order-summary__row--discount");
|
|
1483
1487
|
const totalRow = summaryContainer.querySelector(".recur-order-summary__row--total");
|
|
1484
|
-
if (discountAmount > 0) {
|
|
1485
|
-
if (!discountRow && totalRow) {
|
|
1486
|
-
const subtotalHTML = `
|
|
1487
|
-
<div class="recur-order-summary__row">
|
|
1488
|
-
<span class="recur-order-summary__label">\u5C0F\u8A08</span>
|
|
1489
|
-
<span class="recur-order-summary__value">NT$ ${amount.toLocaleString()}</span>
|
|
1490
|
-
</div>
|
|
1491
|
-
`;
|
|
1492
|
-
const discountHTML = `
|
|
1493
|
-
<div class="recur-order-summary__row recur-order-summary__row--discount">
|
|
1494
|
-
<span class="recur-order-summary__label">\u6298\u6263</span>
|
|
1495
|
-
<span class="recur-order-summary__value">-NT$ ${discountAmount.toLocaleString()}</span>
|
|
1496
|
-
</div>
|
|
1497
|
-
`;
|
|
1498
|
-
totalRow.insertAdjacentHTML("beforebegin", subtotalHTML + discountHTML);
|
|
1499
|
-
}
|
|
1500
|
-
} else {
|
|
1501
|
-
const subtotalRow = summaryContainer.querySelector(".recur-order-summary__row:not(.recur-order-summary__row--total):last-of-type");
|
|
1502
|
-
discountRow?.remove();
|
|
1503
|
-
if (subtotalRow?.querySelector(".recur-order-summary__label")?.textContent === "\u5C0F\u8A08") {
|
|
1504
|
-
subtotalRow.remove();
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
1488
|
const totalValue = totalRow?.querySelector(".recur-order-summary__total");
|
|
1508
1489
|
if (totalValue) {
|
|
1509
1490
|
totalValue.textContent = `NT$ ${finalAmount.toLocaleString()}`;
|
|
@@ -1531,7 +1512,7 @@ var init_payment_form = __esm({
|
|
|
1531
1512
|
this._couponError = null;
|
|
1532
1513
|
this.updateCouponSectionDOM();
|
|
1533
1514
|
try {
|
|
1534
|
-
const response = await fetch(`${apiBaseUrl}/
|
|
1515
|
+
const response = await fetch(`${apiBaseUrl}/v1/checkouts/${checkoutId}/coupon`, {
|
|
1535
1516
|
method: "POST",
|
|
1536
1517
|
headers: { "Content-Type": "application/json" },
|
|
1537
1518
|
body: JSON.stringify({ code })
|
|
@@ -1577,7 +1558,7 @@ var init_payment_form = __esm({
|
|
|
1577
1558
|
this._couponLoading = true;
|
|
1578
1559
|
this.updateCouponSectionDOM();
|
|
1579
1560
|
try {
|
|
1580
|
-
const response = await fetch(`${apiBaseUrl}/
|
|
1561
|
+
const response = await fetch(`${apiBaseUrl}/v1/checkouts/${checkoutId}/coupon`, {
|
|
1581
1562
|
method: "DELETE"
|
|
1582
1563
|
});
|
|
1583
1564
|
if (!response.ok) {
|
|
@@ -2559,7 +2540,7 @@ function toCamelCase(obj) {
|
|
|
2559
2540
|
|
|
2560
2541
|
// package.json
|
|
2561
2542
|
var package_default = {
|
|
2562
|
-
version: "0.9.
|
|
2543
|
+
version: "0.9.12"};
|
|
2563
2544
|
var SDK_VERSION = package_default.version;
|
|
2564
2545
|
var SDK_TYPE = "react";
|
|
2565
2546
|
var RecurContext = createContext(null);
|
|
@@ -2875,6 +2856,10 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2875
2856
|
container.innerHTML = "";
|
|
2876
2857
|
const paymentForm = document.createElement("recur-payment-form");
|
|
2877
2858
|
paymentForm.setAttribute("container-id", containerElementId);
|
|
2859
|
+
if (checkoutResult.checkout?.id) {
|
|
2860
|
+
paymentForm.setAttribute("checkout-id", checkoutResult.checkout.id);
|
|
2861
|
+
}
|
|
2862
|
+
paymentForm.setAttribute("api-base-url", baseUrl);
|
|
2878
2863
|
if (options.customerName) {
|
|
2879
2864
|
paymentForm.setAttribute("customer-name", options.customerName);
|
|
2880
2865
|
}
|
|
@@ -2891,7 +2876,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2891
2876
|
paymentForm.setAttribute("interval", checkoutResult.product.interval);
|
|
2892
2877
|
}
|
|
2893
2878
|
const customStyles = `
|
|
2894
|
-
/* PAYUNi SDK focus \u6A23\u5F0F - shadcn \u98A8\u683C */
|
|
2895
2879
|
.form-input-focus {
|
|
2896
2880
|
border-color: var(--ring, hsl(215 16% 47%)) !important;
|
|
2897
2881
|
outline: 0 !important;
|