Changeset 3310934
- Timestamp:
- 06/13/2025 09:18:26 AM (10 months ago)
- Location:
- digicommerce/trunk
- Files:
-
- 10 edited
-
assets/css/front.css (modified) (1 diff)
-
assets/js/front/checkout.js (modified) (1 diff)
-
assets/js/front/delete-button.js (modified) (1 diff)
-
digicommerce.php (modified) (1 diff)
-
includes/class-digicommerce-checkout.php (modified) (6 diffs)
-
includes/gateways/class-digicommerce-paypal.php (modified) (9 diffs)
-
includes/gateways/class-digicommerce-stripe.php (modified) (16 diffs)
-
readme.txt (modified) (1 diff)
-
resources/js/front/checkout.js (modified) (2 diffs)
-
resources/js/front/delete-button.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
digicommerce/trunk/assets/css/front.css
r3308154 r3310934 1 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.visible{visibility:visible}.collapse{visibility:collapse}.\!static{position:static!important}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.top-8{top:2rem}.z-50{z-index:50}.col-span-6{grid-column:span 6/span 6}.m-0{margin:0}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-4{margin-top:1rem;margin-bottom:1rem}.mb-0{margin-bottom:0}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.m t-0{margin-top:0}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-16{margin-top:4rem}.mt-2{margin-top:.5rem}.mt-20{margin-top:5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-auto{height:auto}.h-full{height:100%}.max-h-20{max-height:5rem}.max-h-\[70vh\]{max-height:70vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-\[375px\]{width:375px}.w-auto{width:auto}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-40{max-width:10rem}.max-w-64{max-width:16rem}.max-w-7xl{max-width:80rem}.max-w-\[90\%\]{max-width:90%}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.border-collapse{border-collapse:collapse}.translate-y-\[-20px\]{--tw-translate-y:-20px}.transform,.translate-y-\[-20px\]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.list-none{list-style-type:none}.columns-2{-moz-columns:2;column-count:2}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-12{gap:3rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-\[\.1rem\]{gap:.1rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.border{border-width:1px}.border-0{border-width:0}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-0{border-left-width:0}.border-l-2{border-left-width:2px}.border-r-0{border-right-width:0}.border-t{border-top-width:1px}.border-t-0{border-top-width:0}.border-solid{border-style:solid}.border-\[\#ddd\]{--tw-border-opacity:1;border-color:rgb(221 221 221/var(--tw-border-opacity,1))}.border-border{border-color:var(--dc-border)}.border-dark-blue{border-color:var(--dc-dark-blue)}.border-dark-blue-20{border-color:var(--dc-dark-blue-20)}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.bg-\[\#FFA500\]{--tw-bg-opacity:1;background-color:rgb(255 165 0/var(--tw-bg-opacity,1))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.bg-dark-blue{background-color:var(--dc-dark-blue)}.bg-dark-blue-10{background-color:var(--dc-dark-blue-10)}.bg-gold{background-color:var(--dc-gold)}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity,1))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity,1))}.bg-green-600{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity,1))}.bg-light-blue{background-color:var(--dc-light-blue)}.bg-light-blue-bg{background-color:var(--dc-light-blue-bg)}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.bg-red-600{background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-red-600,.bg-white{--tw-bg-opacity:1}.bg-white{background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow{background-color:var(--dc-yellow)}.bg-opacity-75{--tw-bg-opacity:0.75}.bg-opacity-90{--tw-bg-opacity:0.9}.fill-dark-blue{fill:var(--dc-dark-blue)}.object-cover{-o-object-fit:cover;object-fit:cover}.object-center{-o-object-position:center;object-position:center}.p-0{padding:0}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pl-4{padding-left:1rem}.pt-0{padding-top:0}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-center{text-align:center}.text-2xl{font-size:1.5rem}.text-3xl{font-size:1.8rem}.text-4xl{font-size:2.4rem}.text-\[\.64rem\]{font-size:.64rem}.text-\[\.68rem\]{font-size:.68rem}.text-\[\.6rem\]{font-size:.6rem}.text-\[1\.2rem\]{font-size:1.2rem}.text-\[1\.625rem\]{font-size:1.625rem}.text-\[2rem\]{font-size:2rem}.text-base{font-size:1.1rem}.text-medium{font-size:1rem}.text-sm{font-size:.8rem}.text-xl{font-size:1.4rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.italic{font-style:italic}.leading-6{line-height:1.5rem}.leading-none{line-height:1}.leading-normal{line-height:1.5}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.text-\[\#8d752d\]{--tw-text-opacity:1;color:rgb(141 117 45/var(--tw-text-opacity,1))}.text-dark-blue{color:var(--dc-dark-blue)}.text-dark-blue-20{color:var(--dc-dark-blue-20)}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-hover-blue{color:var(--dc-hover-blue)}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-none{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-sm,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.blur{--tw-blur:blur(8px)}.blur,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.choices{position:relative;overflow:hidden;margin-bottom:24px;font-size:16px}.choices:focus{outline:0}.choices:last-child{margin-bottom:0}.choices.is-open{overflow:visible}.choices.is-disabled .choices__inner,.choices.is-disabled .choices__input{background-color:#eaeaea;cursor:not-allowed;-webkit-user-select:none;-moz-user-select:none;user-select:none}.choices.is-disabled .choices__item{cursor:not-allowed}.choices [hidden]{display:none!important}.choices[data-type*=select-one]{cursor:pointer}.choices[data-type*=select-one] .choices__inner{padding-bottom:7.5px}.choices[data-type*=select-one] .choices__input{display:block;width:100%;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;margin:0}.choices[data-type*=select-one] .choices__button{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMSIgaGVpZ2h0PSIyMSI+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJtMi41OTIuMDQ0IDE4LjM2NCAxOC4zNjQtMi41NDggMi41NDhMLjA0NCAyLjU5MnoiLz48cGF0aCBkPSJNMCAxOC4zNjQgMTguMzY0IDBsMi41NDggMi41NDhMMi41NDggMjAuOTEyeiIvPjwvZz48L3N2Zz4=);padding:0;background-size:8px;position:absolute;top:50%;right:0;margin-top:-10px;margin-right:25px;height:20px;width:20px;border-radius:10em;opacity:.25}.choices[data-type*=select-one] .choices__button:focus,.choices[data-type*=select-one] .choices__button:hover{opacity:1}.choices[data-type*=select-one] .choices__button:focus{box-shadow:0 0 0 2px #005f75}.choices[data-type*=select-one] .choices__item[data-placeholder] .choices__button{display:none}.choices[data-type*=select-one]:after{content:"";height:0;width:0;border:5px solid transparent;border-top-color:#333;position:absolute;right:11.5px;top:50%;margin-top:-2.5px;pointer-events:none}.choices[data-type*=select-one].is-open:after{border-color:transparent transparent #333;margin-top:-7.5px}.choices[data-type*=select-one][dir=rtl]:after{left:11.5px;right:auto}.choices[data-type*=select-one][dir=rtl] .choices__button{right:auto;left:0;margin-left:25px;margin-right:0}.choices[data-type*=select-multiple] .choices__inner,.choices[data-type*=text] .choices__inner{cursor:text}.choices[data-type*=select-multiple] .choices__button,.choices[data-type*=text] .choices__button{position:relative;display:inline-block;margin:0-4px 0 8px;padding-left:16px;border-left:1px solid #003642;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMSIgaGVpZ2h0PSIyMSI+PGcgZmlsbD0iI0ZGRiIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJtMi41OTIuMDQ0IDE4LjM2NCAxOC4zNjQtMi41NDggMi41NDhMLjA0NCAyLjU5MnoiLz48cGF0aCBkPSJNMCAxOC4zNjQgMTguMzY0IDBsMi41NDggMi41NDhMMi41NDggMjAuOTEyeiIvPjwvZz48L3N2Zz4=);background-size:8px;width:8px;line-height:1;opacity:.75;border-radius:0}.choices[data-type*=select-multiple] .choices__button:focus,.choices[data-type*=select-multiple] .choices__button:hover,.choices[data-type*=text] .choices__button:focus,.choices[data-type*=text] .choices__button:hover{opacity:1}.choices__inner{display:inline-block;vertical-align:top;width:100%;background-color:#f9f9f9;padding:7.5px 7.5px 3.75px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;min-height:44px;overflow:hidden}.is-focused .choices__inner,.is-open .choices__inner{border-color:#b7b7b7}.is-open .choices__inner{border-radius:2.5px 2.5px 0 0}.is-flipped.is-open .choices__inner{border-radius:0 0 2.5px 2.5px}.choices__list{margin:0;padding-left:0;list-style:none}.choices__list--single{display:inline-block;padding:4px 16px 4px 4px;width:100%}[dir=rtl] .choices__list--single{padding-right:4px;padding-left:16px}.choices__list--single .choices__item{width:100%}.choices__list--multiple{display:inline}.choices__list--multiple .choices__item{display:inline-block;vertical-align:middle;border-radius:20px;padding:4px 10px;font-size:12px;font-weight:500;margin-right:3.75px;margin-bottom:3.75px;background-color:#005f75;border:1px solid #004a5c;color:#fff;word-break:break-all;box-sizing:border-box}.choices__list--multiple .choices__item[data-deletable]{padding-right:5px}[dir=rtl] .choices__list--multiple .choices__item{margin-right:0;margin-left:3.75px}.choices__list--multiple .choices__item.is-highlighted{background-color:#004a5c;border:1px solid #003642}.is-disabled .choices__list--multiple .choices__item{background-color:#aaa;border:1px solid #919191}.choices__list--dropdown,.choices__list[aria-expanded]{display:none;z-index:1;position:absolute;width:100%;background-color:#fff;border:1px solid #ddd;top:100%;margin-top:-1px;border-bottom-left-radius:2.5px;border-bottom-right-radius:2.5px;overflow:hidden;word-break:break-all}.is-active.choices__list--dropdown,.is-active.choices__list[aria-expanded]{display:block}.is-open .choices__list--dropdown,.is-open .choices__list[aria-expanded]{border-color:#b7b7b7}.is-flipped .choices__list--dropdown,.is-flipped .choices__list[aria-expanded]{top:auto;bottom:100%;margin-top:0;margin-bottom:-1px;border-radius:.25rem .25rem 0 0}.choices__list--dropdown .choices__list,.choices__list[aria-expanded] .choices__list{position:relative;max-height:300px;overflow:auto;-webkit-overflow-scrolling:touch;will-change:scroll-position}.choices__list--dropdown .choices__item,.choices__list[aria-expanded] .choices__item{position:relative;padding:10px;font-size:14px}[dir=rtl] .choices__list--dropdown .choices__item,[dir=rtl] .choices__list[aria-expanded] .choices__item{text-align:right}@media (min-width:640px){.choices__list--dropdown .choices__item--selectable[data-select-text],.choices__list[aria-expanded] .choices__item--selectable[data-select-text]{padding-right:100px}.choices__list--dropdown .choices__item--selectable[data-select-text]:after,.choices__list[aria-expanded] .choices__item--selectable[data-select-text]:after{content:attr(data-select-text);font-size:12px;opacity:0;position:absolute;right:10px;top:50%;transform:translateY(-50%)}[dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text],[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text]{text-align:right;padding-left:100px;padding-right:10px}[dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text]:after,[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text]:after{right:auto;left:10px}}.choices__list--dropdown .choices__item--selectable.is-highlighted,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted{background-color:#f2f2f2}.choices__list--dropdown .choices__item--selectable.is-highlighted:after,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted:after{opacity:.5}.choices__item{cursor:default}.choices__item--selectable{cursor:pointer}.choices__item--disabled{cursor:not-allowed;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.5}.choices__heading{font-weight:600;font-size:12px;padding:10px;border-bottom:1px solid #f7f7f7;color:gray}.choices__button{text-indent:-9999px;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;background-color:transparent;background-repeat:no-repeat;background-position:50%;cursor:pointer}.choices__button:focus,.choices__input:focus{outline:0}.choices__input{display:inline-block;vertical-align:baseline;background-color:#f9f9f9;font-size:14px;margin-bottom:5px;border:0;border-radius:0;max-width:100%;padding:4px 0 4px 2px}.choices__input::-webkit-search-cancel-button,.choices__input::-webkit-search-decoration,.choices__input::-webkit-search-results-button,.choices__input::-webkit-search-results-decoration{display:none}.choices__input::-ms-clear,.choices__input::-ms-reveal{display:none;width:0;height:0}[dir=rtl] .choices__input{padding-right:2px;padding-left:0}.choices__placeholder{opacity:.5}.digi__form .digi__login a,.digi__form .digi__register a{color:var(--dc-dark-blue);text-decoration-line:underline}.digi__form .digi__login a:hover,.digi__form .digi__register a:hover{color:var(--dc-gold);text-decoration-line:none}.digi__form .field input,.digi__form .field textarea{min-height:64px;width:100%;border-radius:.375rem;border-width:1px;border-style:solid;border-color:var(--dc-border);padding-left:1rem;padding-right:1rem;padding-top:.75rem;padding-bottom:.75rem;font-size:1.1rem;color:var(--dc-dark-blue)}.digi__form .field input:focus,.digi__form .field textarea:focus{border-color:var(--dc-gold)}.digi__form .field input,.digi__form .field textarea{box-shadow:none;outline:none}.digi__form .field input.focused,.digi__form .field input:focus,.digi__form .field textarea.focused,.digi__form .field textarea:focus{padding-left:1.25rem;padding-right:1.25rem;padding-bottom:.75rem;padding-top:1.3rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:cubic-bezier(.64,.09,.08,1)}.digi__form .field input.focused+label,.digi__form .field input:focus+label,.digi__form .field textarea.focused+label,.digi__form .field textarea:focus+label{top:1rem;font-size:.7rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:cubic-bezier(.64,.09,.08,1)}.digi__form .field label{pointer-events:none;position:absolute;left:1rem;top:50%;margin:0;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));font-size:1rem;font-weight:700;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:cubic-bezier(.64,.09,.08,1)}.digi__form .field textarea+label{top:1.5rem;margin:0}.digi__form button.digi__button{min-height:62px;width:100%;cursor:pointer;justify-content:center;gap:.5rem;font-size:1rem;font-weight:700}.digi__form button.pass__icon{position:absolute;right:0;top:50%;display:flex;width:3rem;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));align-items:center;justify-content:center;color:rgba(0,0,0,.5)}.digi__form button.pass__icon:hover{color:var(--dc-dark-blue)}.digi__form button.pass__icon:focus{outline:2px solid transparent;outline-offset:2px}.digi__form button.pass__icon,.digi__form button.pass__icon:focus{box-shadow:none;outline:none}.digi__form .return__link svg{fill:var(--dc-dark-blue)}.digi__form .return__link:hover svg{fill:var(--dc-gold)}.digi__form .message{margin-bottom:1rem;border-radius:.75rem;padding:1rem;text-align:center;font-size:.875rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.digi__form .message.success{--tw-bg-opacity:1;background-color:rgb(70 180 80/var(--tw-bg-opacity,1))}.digi__form .message.error{--tw-bg-opacity:1;background-color:rgb(254 82 82/var(--tw-bg-opacity,1))}.digicommerce input[type=checkbox]{position:relative;top:0;margin:0;height:1.5rem;width:1.5rem;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.125rem;border-width:1px;border-style:solid;border-color:var(--dc-border);--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;box-shadow:none}.digicommerce input[type=checkbox]:focus{box-shadow:none;outline:none}.digicommerce input[type=checkbox]:focus-visible{outline:none}.digicommerce input[type=checkbox]:checked,.digicommerce input[type=checkbox]:checked:focus,.digicommerce input[type=checkbox]:checked:hover{border-color:var(--dc-gold);background-color:var(--dc-gold)}.digicommerce input[type=checkbox]:checked{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="white"><path d="M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z"/></svg>')}.digicommerce input[type=radio]{margin:0;display:none;height:1.5rem;width:1.5rem;border-width:1px;border-style:solid;border-color:var(--dc-border);--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.digicommerce input[type=radio]:checked{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="white"><circle cx="8" cy="8" r="3" /></svg>');border-color:var(--dc-dark-blue);background-color:var(--dc-dark-blue)}.digicommerce input[type=radio]:before{display:none}.digicommerce input[type=radio]:focus{box-shadow:none}.digicommerce select{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="20" height="20" fill="currentColor"><path d="M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z" /></svg>');background-size:1rem 1rem;min-width:10rem;cursor:pointer;background-position:right .7rem top 50%;background-repeat:no-repeat;padding-left:.5rem;padding-right:2rem;-webkit-appearance:none}.custom-login.reset-pass .field input{padding-right:3rem}.custom-login.reset-pass .hide__btn{position:absolute;right:0;top:0;display:flex;width:3rem;align-items:center}.password-strength{margin:1rem 0 1.25rem}.password-strength.weak .password-strength-meter-bar{width:20%;--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.password-strength.weak .password-strength-text{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.password-strength.medium .password-strength-meter-bar{width:50%;--tw-bg-opacity:1;background-color:rgb(245 158 11/var(--tw-bg-opacity,1))}.password-strength.medium .password-strength-text{--tw-text-opacity:1;color:rgb(245 158 11/var(--tw-text-opacity,1))}.password-strength.strong .password-strength-meter-bar{width:100%;--tw-bg-opacity:1;background-color:rgb(16 185 129/var(--tw-bg-opacity,1))}.password-strength.strong .password-strength-text{--tw-text-opacity:1;color:rgb(16 185 129/var(--tw-text-opacity,1))}.password-strength-text{font-size:.8rem}.password-strength-meter{position:relative;margin-bottom:.5rem;height:.25rem;width:100%;border-radius:.125rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.password-strength-meter-bar{height:100%;width:0;border-radius:.125rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:ease}#digicommerce-login-checkout.digi__form .field input{min-height:50px;padding-top:.25rem;padding-bottom:.25rem;font-size:.8rem}#digicommerce-login-checkout.digi__form .field input.focused,#digicommerce-login-checkout.digi__form .field input:focus{padding-bottom:.25rem;padding-top:1.2rem}#digicommerce-login-checkout.digi__form .field input.focused+label,#digicommerce-login-checkout.digi__form .field input:focus+label{font-size:.7rem}#digicommerce-login-checkout.digi__form .field label{font-size:.8rem}#digicommerce-login-checkout.digi__form button.digi__button{min-height:50px;width:auto;padding-left:1rem;padding-right:1rem;padding-top:0;padding-bottom:0;font-size:.8rem}#digicommerce-login-checkout.digi__form .message{margin-bottom:0;margin-top:1rem;border-radius:.125rem;padding:.25rem}.choices{margin:0}.choices__inner{min-height:0;width:100%;border-radius:.375rem;border-color:var(--dc-border);--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding-left:.75rem;padding-right:.75rem;padding-top:.25rem;padding-bottom:.25rem;color:var(--dc-dark-blue);--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);outline:2px solid transparent;outline-offset:2px}.choices__inner:focus,.choices__inner:hover{border-color:var(--dc-gold)}.choices__inner{transition:all .3s ease-in-out}.choices__inner::-moz-placeholder{color:var(--dc-dark-blue)}.choices__inner::placeholder{color:var(--dc-dark-blue)}.choices__inner:focus{box-shadow:none}.choices__placeholder{margin:0;font-size:1rem;font-weight:700;opacity:1}.choices__item--selectable{font-size:1rem}.choices.is-open .choices__inner{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.choices[data-type*=select-one] .choices__inner{padding-bottom:.25rem}.choices[data-type*=select-one]:after{right:7px;margin:0;height:.7rem;width:.7rem;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-width:0;background-size:contain;background-position:50%;background-repeat:no-repeat;--tw-content:"";content:var(--tw-content);background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 429.3l22.6-22.6 192-192L493.3 192 448 146.7l-22.6 22.6L256 338.7 86.6 169.4 64 146.7 18.7 192l22.6 22.6 192 192L256 429.3z"/></svg>')}.choices[data-type*=select-one] .choices__input{min-height:3rem;border-radius:0;border-left-width:0;border-right-width:0;border-top-width:0;--tw-border-opacity:1;padding-left:.75rem;padding-right:.75rem;padding-top:.25rem;padding-bottom:.25rem;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);outline:none}.choices[data-type*=select-one] .choices__input,.choices[data-type*=select-one] .choices__input:focus{border-color:rgb(221 221 221/var(--tw-border-opacity,1))}.choices[data-type*=select-one] .choices__input:focus{--tw-border-opacity:1;padding-left:.75rem;padding-right:.75rem;padding-top:.25rem;padding-bottom:.25rem;box-shadow:none;outline:none}.choices[data-type*=select-one].is-open:after{margin-top:0}.choices__list--single{padding-left:0;padding-right:0;padding-top:.8125rem;padding-bottom:.8125rem}.button-disabled{pointer-events:none;cursor:not-allowed;opacity:.5}.digicommerce-single-product .product-summary input[type=radio]{position:absolute;margin:-1px;height:1px;width:1px;overflow:hidden;white-space:nowrap;border-width:0;padding:0;clip:rect(0,0,0,0)}.digicommerce-single-product .product-summary input[type=radio]+label{margin:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;border-radius:.25rem;background-color:var(--dc-light-blue-bg);padding:1rem;text-align:center;font-size:.85rem;font-weight:400;color:var(--dc-dark-blue)}.digicommerce-single-product .product-summary input[type=radio]+label:hover{background-color:var(--dc-dark-blue);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.digicommerce-single-product .product-summary input[type=radio]+label{transition:all .3s ease-in-out}.digicommerce-single-product .product-summary input[type=radio]+label:after,.digicommerce-single-product .product-summary input[type=radio]+label:before{display:none}.digicommerce-single-product .product-summary input[type=radio]+label .variation-regular-price{color:rgba(0,0,0,.5);transition:all .3s ease-in-out}.digicommerce-single-product .product-summary input[type=radio]:checked+label,.digicommerce-single-product .product-summary input[type=radio]:hover+label{background-color:var(--dc-dark-blue);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.digicommerce-single-product .product-summary input[type=radio]:checked+label .variation-regular-price,.digicommerce-single-product .product-summary input[type=radio]:hover+label .variation-regular-price{color:hsla(0,0%,100%,.5)}.digicommerce-radio input[type=radio]+.payment_method_name .radio-icon{position:relative}.digicommerce-radio input[type=radio]+.payment_method_name .radio-icon:before{position:absolute;left:50%;top:50%;height:.75rem;width:.75rem;--tw-translate-x:-50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:100%;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:ease-in-out;--tw-content:"";content:var(--tw-content)}.digicommerce-radio input[type=radio]:checked+.payment_method_name .radio-icon{border-color:var(--dc-gold)}.digicommerce-radio input[type=radio]:checked+.payment_method_name .radio-icon:before{background-color:var(--dc-gold)}@media (max-width:600px){.digicommerce-radio .payment_method_name svg{height:3rem;width:3rem}}@media (max-width:480px){.digicommerce-radio .payment_method_name svg{display:none}}body.rtl .choices[data-type*=select-one]:after{left:7px;right:auto}body.rtl .digi__form .field label{left:auto;right:1rem}body.rtl .digi__form button.pass__icon{left:0;right:auto}body.rtl .digicommerce select{background-position:left .7rem top 50%;padding-left:2rem;padding-right:.5rem}.digicommerce-table{margin:0;width:100%;border-collapse:collapse;border-width:0;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.digicommerce-table .end{text-align:right}.digicommerce-table td,.digicommerce-table th{border-width:0;padding:1rem;text-align:left;line-height:1.5}.digicommerce-table th{font-weight:700;color:var(--dc-dark-blue)}.digicommerce-table thead th{border-bottom-width:1px;border-style:solid;--tw-border-opacity:1;border-bottom-color:rgb(225 225 225/var(--tw-border-opacity,1))}.digicommerce-table tbody{font-size:.8rem}.digicommerce-table tbody tr:nth-child(odd){--tw-bg-opacity:1;background-color:rgb(247 247 249/var(--tw-bg-opacity,1))}.digicommerce-table tfoot{font-size:.8rem}.digicommerce-table tfoot th{color:var(--dc-dark-blue)}.digicommerce-table tfoot td,.digicommerce-table tfoot th{border-top-width:1px;border-style:solid;--tw-border-opacity:1;border-top-color:rgb(225 225 225/var(--tw-border-opacity,1))}.digicommerce-table tfoot .order-total{font-size:1rem}.digicommerce-table .amount{font-size:1.1rem;font-weight:700;--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}@media only screen and (max-width:768px){.digicommerce-table tbody,.digicommerce-table td,.digicommerce-table tr{display:block;width:100%}.digicommerce-table th,.digicommerce-table thead{display:none}.digicommerce-table td{position:relative;display:flex;justify-content:space-between;text-align:right}.digicommerce-table td:before{float:left;font-size:1rem;font-weight:600;color:var(--dc-dark-blue);--tw-content:attr(data-label);content:var(--tw-content)}.digicommerce-table td[rowspan]{display:none}}.digicommerce-table tr.order-total{--tw-bg-opacity:1;background-color:rgb(247 247 249/var(--tw-bg-opacity,1))}.digicommerce-table tr.order-total td,.digicommerce-table tr.order-total th{font-weight:700}body.rtl .digicommerce-table .end{text-align:left}body.rtl .digicommerce-table td,body.rtl .digicommerce-table th{text-align:right}@media only screen and (max-width:768px){body.rtl .digicommerce-table td{text-align:left}}:root{--dc-gold:#ccb161;--dc-yellow:#ffe599;--dc-border:#caced9;--dc-light-blue:#e1e4ed;--dc-light-blue-bg:#f6f7f9;--dc-dark-blue:#09053a;--dc-dark-blue-10:#e6e5eb;--dc-dark-blue-20:#bab8c8;--dc-hover-blue:#362f85;--dc-grey:#646071;--dc-dark-grey:#5b5766}.digicommerce{font-size:1rem}.digicommerce button{cursor:pointer;transition:all .3s ease-in-out}.digicommerce a{text-decoration:none!important;transition:all .3s ease-in-out}body .no-margin{margin:0}.no-background{padding:0;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.no-background,.no-background:focus,.no-background:hover{background-color:transparent}.default-transition{transition:all .3s ease-in-out}.price-wrapper{display:flex;align-items:flex-start;line-height:1}.price-wrapper .price-symbol{font-size:.75em}.price-wrapper.single-price{white-space:nowrap;font-weight:700;--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.end .price-wrapper{justify-content:flex-end}.product-share a:hover svg{fill:#fff}.cart-item .cart-item-name{flex-direction:column;align-items:flex-start}@media (min-width:768px){.cart-item .cart-item-name{flex-direction:row;align-items:center}}.cart-item .cart-item-info,.cart-item .cart-item-name.has-variation-name{align-items:flex-start}@media (min-width:768px){.cart-item .cart-item-info{align-items:flex-end}}input[type=radio]:checked+.payment_method_name{background-color:var(--dc-light-blue-bg)}.digi-captcha .grecaptcha-badge{display:none}.first\:pt-0:first-child{padding-top:0}.last\:pb-0:last-child{padding-bottom:0}.hover\:border-dark-blue:hover{border-color:var(--dc-dark-blue)}.hover\:bg-dark-blue:hover{background-color:var(--dc-dark-blue)}.hover\:bg-gold:hover{background-color:var(--dc-gold)}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:bg-hover-blue:hover{background-color:var(--dc-hover-blue)}.hover\:bg-light-blue-bg:hover{background-color:var(--dc-light-blue-bg)}.hover\:bg-red-400:hover{--tw-bg-opacity:1;background-color:rgb(248 113 113/var(--tw-bg-opacity,1))}.hover\:bg-red-50:hover{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.hover\:text-blue-600:hover{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.hover\:text-dark-blue:hover{color:var(--dc-dark-blue)}.hover\:text-gold:hover{color:var(--dc-gold)}.hover\:text-gray-500:hover{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.hover\:text-hover-blue:hover{color:var(--dc-hover-blue)}.hover\:text-red-400:hover{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.hover\:text-red-600:hover{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:border-dark-blue:focus{border-color:var(--dc-dark-blue)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\:ring-dark-blue:focus{--tw-ring-color:var(--dc-dark-blue)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}.group:hover .group-hover\:scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-gold{color:var(--dc-gold)}@media (min-width:380px){.esm\:flex-row{flex-direction:row}}@media (min-width:640px){.sm\:mt-16{margin-top:4rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:rounded-lg{border-radius:.5rem}.sm\:p-6{padding:1.5rem}.sm\:px-0{padding-left:0;padding-right:0}.sm\:px-2{padding-left:.5rem;padding-right:.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-4xl{font-size:2.4rem}.sm\:text-sm{font-size:.8rem}}@media (min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-end{align-items:flex-end}}@media (min-width:980px){.mdl\:flex-row{flex-direction:row}.mdl\:items-center{align-items:center}.mdl\:py-28{padding-top:7rem;padding-bottom:7rem}}@media (min-width:1024px){.lg\:col-span-1{grid-column:span 1/span 1}.lg\:col-span-2{grid-column:span 2/span 2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-7{grid-column:span 7/span 7}.lg\:col-span-9{grid-column:span 9/span 9}.lg\:mt-0{margin-top:0}.lg\:grid{display:grid}.lg\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:items-start{align-items:flex-start}.lg\:gap-x-12{-moz-column-gap:3rem;column-gap:3rem}.lg\:gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.lg\:gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.lg\:px-0{padding-left:0;padding-right:0}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:py-0{padding-bottom:0}.lg\:pt-0,.lg\:py-0{padding-top:0}}.ltr\:ml-3:where([dir=ltr],[dir=ltr] *){margin-left:.75rem}.ltr\:text-left:where([dir=ltr],[dir=ltr] *){text-align:left}.ltr\:text-right:where([dir=ltr],[dir=ltr] *){text-align:right}.rtl\:mr-3:where([dir=rtl],[dir=rtl] *){margin-right:.75rem}.rtl\:text-left:where([dir=rtl],[dir=rtl] *){text-align:left}.rtl\:text-right:where([dir=rtl],[dir=rtl] *){text-align:right}1 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.visible{visibility:visible}.collapse{visibility:collapse}.\!static{position:static!important}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.top-8{top:2rem}.z-50{z-index:50}.col-span-6{grid-column:span 6/span 6}.m-0{margin:0}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-4{margin-top:1rem;margin-bottom:1rem}.mb-0{margin-bottom:0}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-0{margin-left:0}.mt-0{margin-top:0}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-16{margin-top:4rem}.mt-2{margin-top:.5rem}.mt-20{margin-top:5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-auto{margin-top:auto}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-auto{height:auto}.h-full{height:100%}.max-h-20{max-height:5rem}.max-h-\[70vh\]{max-height:70vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-\[375px\]{width:375px}.w-auto{width:auto}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-40{max-width:10rem}.max-w-64{max-width:16rem}.max-w-7xl{max-width:80rem}.max-w-\[90\%\]{max-width:90%}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.border-collapse{border-collapse:collapse}.translate-y-\[-20px\]{--tw-translate-y:-20px}.transform,.translate-y-\[-20px\]{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.list-none{list-style-type:none}.columns-2{-moz-columns:2;column-count:2}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-12{gap:3rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-\[\.1rem\]{gap:.1rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity,1))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.border{border-width:1px}.border-0{border-width:0}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-0{border-left-width:0}.border-l-2{border-left-width:2px}.border-r-0{border-right-width:0}.border-t{border-top-width:1px}.border-t-0{border-top-width:0}.border-solid{border-style:solid}.border-\[\#ddd\]{--tw-border-opacity:1;border-color:rgb(221 221 221/var(--tw-border-opacity,1))}.border-border{border-color:var(--dc-border)}.border-dark-blue{border-color:var(--dc-dark-blue)}.border-dark-blue-20{border-color:var(--dc-dark-blue-20)}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.bg-\[\#FFA500\]{--tw-bg-opacity:1;background-color:rgb(255 165 0/var(--tw-bg-opacity,1))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.bg-dark-blue{background-color:var(--dc-dark-blue)}.bg-dark-blue-10{background-color:var(--dc-dark-blue-10)}.bg-gold{background-color:var(--dc-gold)}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity,1))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity,1))}.bg-green-600{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity,1))}.bg-light-blue{background-color:var(--dc-light-blue)}.bg-light-blue-bg{background-color:var(--dc-light-blue-bg)}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.bg-red-600{background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-red-600,.bg-white{--tw-bg-opacity:1}.bg-white{background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow{background-color:var(--dc-yellow)}.bg-opacity-75{--tw-bg-opacity:0.75}.bg-opacity-90{--tw-bg-opacity:0.9}.fill-dark-blue{fill:var(--dc-dark-blue)}.object-cover{-o-object-fit:cover;object-fit:cover}.object-center{-o-object-position:center;object-position:center}.p-0{padding:0}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pl-0{padding-left:0}.pl-4{padding-left:1rem}.pt-0{padding-top:0}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-center{text-align:center}.text-2xl{font-size:1.5rem}.text-3xl{font-size:1.8rem}.text-4xl{font-size:2.4rem}.text-\[\.64rem\]{font-size:.64rem}.text-\[\.68rem\]{font-size:.68rem}.text-\[\.6rem\]{font-size:.6rem}.text-\[1\.2rem\]{font-size:1.2rem}.text-\[1\.625rem\]{font-size:1.625rem}.text-\[2rem\]{font-size:2rem}.text-base{font-size:1.1rem}.text-medium{font-size:1rem}.text-sm{font-size:.8rem}.text-xl{font-size:1.4rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.italic{font-style:italic}.leading-6{line-height:1.5rem}.leading-none{line-height:1}.leading-normal{line-height:1.5}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.text-\[\#8d752d\]{--tw-text-opacity:1;color:rgb(141 117 45/var(--tw-text-opacity,1))}.text-dark-blue{color:var(--dc-dark-blue)}.text-dark-blue-20{color:var(--dc-dark-blue-20)}.text-gold{color:var(--dc-gold)}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-green-500{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-hover-blue{color:var(--dc-hover-blue)}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-none{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-sm,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.blur{--tw-blur:blur(8px)}.blur,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.choices{position:relative;overflow:hidden;margin-bottom:24px;font-size:16px}.choices:focus{outline:0}.choices:last-child{margin-bottom:0}.choices.is-open{overflow:visible}.choices.is-disabled .choices__inner,.choices.is-disabled .choices__input{background-color:#eaeaea;cursor:not-allowed;-webkit-user-select:none;-moz-user-select:none;user-select:none}.choices.is-disabled .choices__item{cursor:not-allowed}.choices [hidden]{display:none!important}.choices[data-type*=select-one]{cursor:pointer}.choices[data-type*=select-one] .choices__inner{padding-bottom:7.5px}.choices[data-type*=select-one] .choices__input{display:block;width:100%;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;margin:0}.choices[data-type*=select-one] .choices__button{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMSIgaGVpZ2h0PSIyMSI+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJtMi41OTIuMDQ0IDE4LjM2NCAxOC4zNjQtMi41NDggMi41NDhMLjA0NCAyLjU5MnoiLz48cGF0aCBkPSJNMCAxOC4zNjQgMTguMzY0IDBsMi41NDggMi41NDhMMi41NDggMjAuOTEyeiIvPjwvZz48L3N2Zz4=);padding:0;background-size:8px;position:absolute;top:50%;right:0;margin-top:-10px;margin-right:25px;height:20px;width:20px;border-radius:10em;opacity:.25}.choices[data-type*=select-one] .choices__button:focus,.choices[data-type*=select-one] .choices__button:hover{opacity:1}.choices[data-type*=select-one] .choices__button:focus{box-shadow:0 0 0 2px #005f75}.choices[data-type*=select-one] .choices__item[data-placeholder] .choices__button{display:none}.choices[data-type*=select-one]:after{content:"";height:0;width:0;border:5px solid transparent;border-top-color:#333;position:absolute;right:11.5px;top:50%;margin-top:-2.5px;pointer-events:none}.choices[data-type*=select-one].is-open:after{border-color:transparent transparent #333;margin-top:-7.5px}.choices[data-type*=select-one][dir=rtl]:after{left:11.5px;right:auto}.choices[data-type*=select-one][dir=rtl] .choices__button{right:auto;left:0;margin-left:25px;margin-right:0}.choices[data-type*=select-multiple] .choices__inner,.choices[data-type*=text] .choices__inner{cursor:text}.choices[data-type*=select-multiple] .choices__button,.choices[data-type*=text] .choices__button{position:relative;display:inline-block;margin:0-4px 0 8px;padding-left:16px;border-left:1px solid #003642;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMSIgaGVpZ2h0PSIyMSI+PGcgZmlsbD0iI0ZGRiIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJtMi41OTIuMDQ0IDE4LjM2NCAxOC4zNjQtMi41NDggMi41NDhMLjA0NCAyLjU5MnoiLz48cGF0aCBkPSJNMCAxOC4zNjQgMTguMzY0IDBsMi41NDggMi41NDhMMi41NDggMjAuOTEyeiIvPjwvZz48L3N2Zz4=);background-size:8px;width:8px;line-height:1;opacity:.75;border-radius:0}.choices[data-type*=select-multiple] .choices__button:focus,.choices[data-type*=select-multiple] .choices__button:hover,.choices[data-type*=text] .choices__button:focus,.choices[data-type*=text] .choices__button:hover{opacity:1}.choices__inner{display:inline-block;vertical-align:top;width:100%;background-color:#f9f9f9;padding:7.5px 7.5px 3.75px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;min-height:44px;overflow:hidden}.is-focused .choices__inner,.is-open .choices__inner{border-color:#b7b7b7}.is-open .choices__inner{border-radius:2.5px 2.5px 0 0}.is-flipped.is-open .choices__inner{border-radius:0 0 2.5px 2.5px}.choices__list{margin:0;padding-left:0;list-style:none}.choices__list--single{display:inline-block;padding:4px 16px 4px 4px;width:100%}[dir=rtl] .choices__list--single{padding-right:4px;padding-left:16px}.choices__list--single .choices__item{width:100%}.choices__list--multiple{display:inline}.choices__list--multiple .choices__item{display:inline-block;vertical-align:middle;border-radius:20px;padding:4px 10px;font-size:12px;font-weight:500;margin-right:3.75px;margin-bottom:3.75px;background-color:#005f75;border:1px solid #004a5c;color:#fff;word-break:break-all;box-sizing:border-box}.choices__list--multiple .choices__item[data-deletable]{padding-right:5px}[dir=rtl] .choices__list--multiple .choices__item{margin-right:0;margin-left:3.75px}.choices__list--multiple .choices__item.is-highlighted{background-color:#004a5c;border:1px solid #003642}.is-disabled .choices__list--multiple .choices__item{background-color:#aaa;border:1px solid #919191}.choices__list--dropdown,.choices__list[aria-expanded]{display:none;z-index:1;position:absolute;width:100%;background-color:#fff;border:1px solid #ddd;top:100%;margin-top:-1px;border-bottom-left-radius:2.5px;border-bottom-right-radius:2.5px;overflow:hidden;word-break:break-all}.is-active.choices__list--dropdown,.is-active.choices__list[aria-expanded]{display:block}.is-open .choices__list--dropdown,.is-open .choices__list[aria-expanded]{border-color:#b7b7b7}.is-flipped .choices__list--dropdown,.is-flipped .choices__list[aria-expanded]{top:auto;bottom:100%;margin-top:0;margin-bottom:-1px;border-radius:.25rem .25rem 0 0}.choices__list--dropdown .choices__list,.choices__list[aria-expanded] .choices__list{position:relative;max-height:300px;overflow:auto;-webkit-overflow-scrolling:touch;will-change:scroll-position}.choices__list--dropdown .choices__item,.choices__list[aria-expanded] .choices__item{position:relative;padding:10px;font-size:14px}[dir=rtl] .choices__list--dropdown .choices__item,[dir=rtl] .choices__list[aria-expanded] .choices__item{text-align:right}@media (min-width:640px){.choices__list--dropdown .choices__item--selectable[data-select-text],.choices__list[aria-expanded] .choices__item--selectable[data-select-text]{padding-right:100px}.choices__list--dropdown .choices__item--selectable[data-select-text]:after,.choices__list[aria-expanded] .choices__item--selectable[data-select-text]:after{content:attr(data-select-text);font-size:12px;opacity:0;position:absolute;right:10px;top:50%;transform:translateY(-50%)}[dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text],[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text]{text-align:right;padding-left:100px;padding-right:10px}[dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text]:after,[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text]:after{right:auto;left:10px}}.choices__list--dropdown .choices__item--selectable.is-highlighted,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted{background-color:#f2f2f2}.choices__list--dropdown .choices__item--selectable.is-highlighted:after,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted:after{opacity:.5}.choices__item{cursor:default}.choices__item--selectable{cursor:pointer}.choices__item--disabled{cursor:not-allowed;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.5}.choices__heading{font-weight:600;font-size:12px;padding:10px;border-bottom:1px solid #f7f7f7;color:gray}.choices__button{text-indent:-9999px;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;background-color:transparent;background-repeat:no-repeat;background-position:50%;cursor:pointer}.choices__button:focus,.choices__input:focus{outline:0}.choices__input{display:inline-block;vertical-align:baseline;background-color:#f9f9f9;font-size:14px;margin-bottom:5px;border:0;border-radius:0;max-width:100%;padding:4px 0 4px 2px}.choices__input::-webkit-search-cancel-button,.choices__input::-webkit-search-decoration,.choices__input::-webkit-search-results-button,.choices__input::-webkit-search-results-decoration{display:none}.choices__input::-ms-clear,.choices__input::-ms-reveal{display:none;width:0;height:0}[dir=rtl] .choices__input{padding-right:2px;padding-left:0}.choices__placeholder{opacity:.5}.digi__form .digi__login a,.digi__form .digi__register a{color:var(--dc-dark-blue);text-decoration-line:underline}.digi__form .digi__login a:hover,.digi__form .digi__register a:hover{color:var(--dc-gold);text-decoration-line:none}.digi__form .field input,.digi__form .field textarea{min-height:64px;width:100%;border-radius:.375rem;border-width:1px;border-style:solid;border-color:var(--dc-border);padding-left:1rem;padding-right:1rem;padding-top:.75rem;padding-bottom:.75rem;font-size:1.1rem;color:var(--dc-dark-blue)}.digi__form .field input:focus,.digi__form .field textarea:focus{border-color:var(--dc-gold)}.digi__form .field input,.digi__form .field textarea{box-shadow:none;outline:none}.digi__form .field input.focused,.digi__form .field input:focus,.digi__form .field textarea.focused,.digi__form .field textarea:focus{padding-left:1.25rem;padding-right:1.25rem;padding-bottom:.75rem;padding-top:1.3rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:cubic-bezier(.64,.09,.08,1)}.digi__form .field input.focused+label,.digi__form .field input:focus+label,.digi__form .field textarea.focused+label,.digi__form .field textarea:focus+label{top:1rem;font-size:.7rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:cubic-bezier(.64,.09,.08,1)}.digi__form .field label{pointer-events:none;position:absolute;left:1rem;top:50%;margin:0;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));font-size:1rem;font-weight:700;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:cubic-bezier(.64,.09,.08,1)}.digi__form .field textarea+label{top:1.5rem;margin:0}.digi__form button.digi__button{min-height:62px;width:100%;cursor:pointer;justify-content:center;gap:.5rem;font-size:1rem;font-weight:700}.digi__form button.pass__icon{position:absolute;right:0;top:50%;display:flex;width:3rem;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));align-items:center;justify-content:center;color:rgba(0,0,0,.5)}.digi__form button.pass__icon:hover{color:var(--dc-dark-blue)}.digi__form button.pass__icon:focus{outline:2px solid transparent;outline-offset:2px}.digi__form button.pass__icon,.digi__form button.pass__icon:focus{box-shadow:none;outline:none}.digi__form .return__link svg{fill:var(--dc-dark-blue)}.digi__form .return__link:hover svg{fill:var(--dc-gold)}.digi__form .message{margin-bottom:1rem;border-radius:.75rem;padding:1rem;text-align:center;font-size:.875rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.digi__form .message.success{--tw-bg-opacity:1;background-color:rgb(70 180 80/var(--tw-bg-opacity,1))}.digi__form .message.error{--tw-bg-opacity:1;background-color:rgb(254 82 82/var(--tw-bg-opacity,1))}.digicommerce input[type=checkbox]{position:relative;top:0;margin:0;height:1.5rem;width:1.5rem;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.125rem;border-width:1px;border-style:solid;border-color:var(--dc-border);--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;box-shadow:none}.digicommerce input[type=checkbox]:focus{box-shadow:none;outline:none}.digicommerce input[type=checkbox]:focus-visible{outline:none}.digicommerce input[type=checkbox]:checked,.digicommerce input[type=checkbox]:checked:focus,.digicommerce input[type=checkbox]:checked:hover{border-color:var(--dc-gold);background-color:var(--dc-gold)}.digicommerce input[type=checkbox]:checked{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="white"><path d="M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z"/></svg>')}.digicommerce input[type=radio]{margin:0;display:none;height:1.5rem;width:1.5rem;border-width:1px;border-style:solid;border-color:var(--dc-border);--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.digicommerce input[type=radio]:checked{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="white"><circle cx="8" cy="8" r="3" /></svg>');border-color:var(--dc-dark-blue);background-color:var(--dc-dark-blue)}.digicommerce input[type=radio]:before{display:none}.digicommerce input[type=radio]:focus{box-shadow:none}.digicommerce select{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="20" height="20" fill="currentColor"><path d="M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z" /></svg>');background-size:1rem 1rem;min-width:10rem;cursor:pointer;background-position:right .7rem top 50%;background-repeat:no-repeat;padding-left:.5rem;padding-right:2rem;-webkit-appearance:none}.custom-login.reset-pass .field input{padding-right:3rem}.custom-login.reset-pass .hide__btn{position:absolute;right:0;top:0;display:flex;width:3rem;align-items:center}.password-strength{margin:1rem 0 1.25rem}.password-strength.weak .password-strength-meter-bar{width:20%;--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.password-strength.weak .password-strength-text{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.password-strength.medium .password-strength-meter-bar{width:50%;--tw-bg-opacity:1;background-color:rgb(245 158 11/var(--tw-bg-opacity,1))}.password-strength.medium .password-strength-text{--tw-text-opacity:1;color:rgb(245 158 11/var(--tw-text-opacity,1))}.password-strength.strong .password-strength-meter-bar{width:100%;--tw-bg-opacity:1;background-color:rgb(16 185 129/var(--tw-bg-opacity,1))}.password-strength.strong .password-strength-text{--tw-text-opacity:1;color:rgb(16 185 129/var(--tw-text-opacity,1))}.password-strength-text{font-size:.8rem}.password-strength-meter{position:relative;margin-bottom:.5rem;height:.25rem;width:100%;border-radius:.125rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.password-strength-meter-bar{height:100%;width:0;border-radius:.125rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:ease}#digicommerce-login-checkout.digi__form .field input{min-height:50px;padding-top:.25rem;padding-bottom:.25rem;font-size:.8rem}#digicommerce-login-checkout.digi__form .field input.focused,#digicommerce-login-checkout.digi__form .field input:focus{padding-bottom:.25rem;padding-top:1.2rem}#digicommerce-login-checkout.digi__form .field input.focused+label,#digicommerce-login-checkout.digi__form .field input:focus+label{font-size:.7rem}#digicommerce-login-checkout.digi__form .field label{font-size:.8rem}#digicommerce-login-checkout.digi__form button.digi__button{min-height:50px;width:auto;padding-left:1rem;padding-right:1rem;padding-top:0;padding-bottom:0;font-size:.8rem}#digicommerce-login-checkout.digi__form .message{margin-bottom:0;margin-top:1rem;border-radius:.125rem;padding:.25rem}.choices{margin:0}.choices__inner{min-height:0;width:100%;border-radius:.375rem;border-color:var(--dc-border);--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding-left:.75rem;padding-right:.75rem;padding-top:.25rem;padding-bottom:.25rem;color:var(--dc-dark-blue);--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);outline:2px solid transparent;outline-offset:2px}.choices__inner:focus,.choices__inner:hover{border-color:var(--dc-gold)}.choices__inner{transition:all .3s ease-in-out}.choices__inner::-moz-placeholder{color:var(--dc-dark-blue)}.choices__inner::placeholder{color:var(--dc-dark-blue)}.choices__inner:focus{box-shadow:none}.choices__placeholder{margin:0;font-size:1rem;font-weight:700;opacity:1}.choices__item--selectable{font-size:1rem}.choices.is-open .choices__inner{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.choices[data-type*=select-one] .choices__inner{padding-bottom:.25rem}.choices[data-type*=select-one]:after{right:7px;margin:0;height:.7rem;width:.7rem;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-width:0;background-size:contain;background-position:50%;background-repeat:no-repeat;--tw-content:"";content:var(--tw-content);background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 429.3l22.6-22.6 192-192L493.3 192 448 146.7l-22.6 22.6L256 338.7 86.6 169.4 64 146.7 18.7 192l22.6 22.6 192 192L256 429.3z"/></svg>')}.choices[data-type*=select-one] .choices__input{min-height:3rem;border-radius:0;border-left-width:0;border-right-width:0;border-top-width:0;--tw-border-opacity:1;padding-left:.75rem;padding-right:.75rem;padding-top:.25rem;padding-bottom:.25rem;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);outline:none}.choices[data-type*=select-one] .choices__input,.choices[data-type*=select-one] .choices__input:focus{border-color:rgb(221 221 221/var(--tw-border-opacity,1))}.choices[data-type*=select-one] .choices__input:focus{--tw-border-opacity:1;padding-left:.75rem;padding-right:.75rem;padding-top:.25rem;padding-bottom:.25rem;box-shadow:none;outline:none}.choices[data-type*=select-one].is-open:after{margin-top:0}.choices__list--single{padding-left:0;padding-right:0;padding-top:.8125rem;padding-bottom:.8125rem}.button-disabled{pointer-events:none;cursor:not-allowed;opacity:.5}.digicommerce-single-product .product-summary input[type=radio]{position:absolute;margin:-1px;height:1px;width:1px;overflow:hidden;white-space:nowrap;border-width:0;padding:0;clip:rect(0,0,0,0)}.digicommerce-single-product .product-summary input[type=radio]+label{margin:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;border-radius:.25rem;background-color:var(--dc-light-blue-bg);padding:1rem;text-align:center;font-size:.85rem;font-weight:400;color:var(--dc-dark-blue)}.digicommerce-single-product .product-summary input[type=radio]+label:hover{background-color:var(--dc-dark-blue);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.digicommerce-single-product .product-summary input[type=radio]+label{transition:all .3s ease-in-out}.digicommerce-single-product .product-summary input[type=radio]+label:after,.digicommerce-single-product .product-summary input[type=radio]+label:before{display:none}.digicommerce-single-product .product-summary input[type=radio]+label .variation-regular-price{color:rgba(0,0,0,.5);transition:all .3s ease-in-out}.digicommerce-single-product .product-summary input[type=radio]:checked+label,.digicommerce-single-product .product-summary input[type=radio]:hover+label{background-color:var(--dc-dark-blue);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.digicommerce-single-product .product-summary input[type=radio]:checked+label .variation-regular-price,.digicommerce-single-product .product-summary input[type=radio]:hover+label .variation-regular-price{color:hsla(0,0%,100%,.5)}.digicommerce-radio input[type=radio]+.payment_method_name .radio-icon{position:relative}.digicommerce-radio input[type=radio]+.payment_method_name .radio-icon:before{position:absolute;left:50%;top:50%;height:.75rem;width:.75rem;--tw-translate-x:-50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));border-radius:100%;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-duration:.3s;transition-timing-function:ease-in-out;--tw-content:"";content:var(--tw-content)}.digicommerce-radio input[type=radio]:checked+.payment_method_name .radio-icon{border-color:var(--dc-gold)}.digicommerce-radio input[type=radio]:checked+.payment_method_name .radio-icon:before{background-color:var(--dc-gold)}@media (max-width:600px){.digicommerce-radio .payment_method_name svg{height:3rem;width:3rem}}@media (max-width:480px){.digicommerce-radio .payment_method_name svg{display:none}}body.rtl .choices[data-type*=select-one]:after{left:7px;right:auto}body.rtl .digi__form .field label{left:auto;right:1rem}body.rtl .digi__form button.pass__icon{left:0;right:auto}body.rtl .digicommerce select{background-position:left .7rem top 50%;padding-left:2rem;padding-right:.5rem}.digicommerce-table{margin:0;width:100%;border-collapse:collapse;border-width:0;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.digicommerce-table .end{text-align:right}.digicommerce-table td,.digicommerce-table th{border-width:0;padding:1rem;text-align:left;line-height:1.5}.digicommerce-table th{font-weight:700;color:var(--dc-dark-blue)}.digicommerce-table thead th{border-bottom-width:1px;border-style:solid;--tw-border-opacity:1;border-bottom-color:rgb(225 225 225/var(--tw-border-opacity,1))}.digicommerce-table tbody{font-size:.8rem}.digicommerce-table tbody tr:nth-child(odd){--tw-bg-opacity:1;background-color:rgb(247 247 249/var(--tw-bg-opacity,1))}.digicommerce-table tfoot{font-size:.8rem}.digicommerce-table tfoot th{color:var(--dc-dark-blue)}.digicommerce-table tfoot td,.digicommerce-table tfoot th{border-top-width:1px;border-style:solid;--tw-border-opacity:1;border-top-color:rgb(225 225 225/var(--tw-border-opacity,1))}.digicommerce-table tfoot .order-total{font-size:1rem}.digicommerce-table .amount{font-size:1.1rem;font-weight:700;--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}@media only screen and (max-width:768px){.digicommerce-table tbody,.digicommerce-table td,.digicommerce-table tr{display:block;width:100%}.digicommerce-table th,.digicommerce-table thead{display:none}.digicommerce-table td{position:relative;display:flex;justify-content:space-between;text-align:right}.digicommerce-table td:before{float:left;font-size:1rem;font-weight:600;color:var(--dc-dark-blue);--tw-content:attr(data-label);content:var(--tw-content)}.digicommerce-table td[rowspan]{display:none}}.digicommerce-table tr.order-total{--tw-bg-opacity:1;background-color:rgb(247 247 249/var(--tw-bg-opacity,1))}.digicommerce-table tr.order-total td,.digicommerce-table tr.order-total th{font-weight:700}body.rtl .digicommerce-table .end{text-align:left}body.rtl .digicommerce-table td,body.rtl .digicommerce-table th{text-align:right}@media only screen and (max-width:768px){body.rtl .digicommerce-table td{text-align:left}}:root{--dc-gold:#ccb161;--dc-yellow:#ffe599;--dc-border:#caced9;--dc-light-blue:#e1e4ed;--dc-light-blue-bg:#f6f7f9;--dc-dark-blue:#09053a;--dc-dark-blue-10:#e6e5eb;--dc-dark-blue-20:#bab8c8;--dc-hover-blue:#362f85;--dc-grey:#646071;--dc-dark-grey:#5b5766}.digicommerce{font-size:1rem}.digicommerce button{cursor:pointer;transition:all .3s ease-in-out}.digicommerce a{text-decoration:none!important;transition:all .3s ease-in-out}body .no-margin{margin:0}.no-background{padding:0;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.no-background,.no-background:focus,.no-background:hover{background-color:transparent}.default-transition{transition:all .3s ease-in-out}.price-wrapper{display:flex;align-items:flex-start;line-height:1}.price-wrapper .price-symbol{font-size:.75em}.price-wrapper.single-price{white-space:nowrap;font-weight:700;--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.end .price-wrapper{justify-content:flex-end}.product-share a:hover svg{fill:#fff}.cart-item .cart-item-name{flex-direction:column;align-items:flex-start}@media (min-width:768px){.cart-item .cart-item-name{flex-direction:row;align-items:center}}.cart-item .cart-item-info,.cart-item .cart-item-name.has-variation-name{align-items:flex-start}@media (min-width:768px){.cart-item .cart-item-info{align-items:flex-end}}input[type=radio]:checked+.payment_method_name{background-color:var(--dc-light-blue-bg)}.digi-captcha .grecaptcha-badge{display:none}.first\:pt-0:first-child{padding-top:0}.last\:pb-0:last-child{padding-bottom:0}.hover\:border-dark-blue:hover{border-color:var(--dc-dark-blue)}.hover\:bg-dark-blue:hover{background-color:var(--dc-dark-blue)}.hover\:bg-gold:hover{background-color:var(--dc-gold)}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:bg-hover-blue:hover{background-color:var(--dc-hover-blue)}.hover\:bg-light-blue-bg:hover{background-color:var(--dc-light-blue-bg)}.hover\:bg-red-400:hover{--tw-bg-opacity:1;background-color:rgb(248 113 113/var(--tw-bg-opacity,1))}.hover\:bg-red-50:hover{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.hover\:text-blue-600:hover{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.hover\:text-dark-blue:hover{color:var(--dc-dark-blue)}.hover\:text-gold:hover{color:var(--dc-gold)}.hover\:text-gray-500:hover{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.hover\:text-hover-blue:hover{color:var(--dc-hover-blue)}.hover\:text-red-400:hover{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.hover\:text-red-600:hover{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:border-dark-blue:focus{border-color:var(--dc-dark-blue)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\:ring-dark-blue:focus{--tw-ring-color:var(--dc-dark-blue)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}.group:hover .group-hover\:scale-105{--tw-scale-x:1.05;--tw-scale-y:1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-gold{color:var(--dc-gold)}@media (min-width:380px){.esm\:flex-row{flex-direction:row}}@media (min-width:640px){.sm\:mt-16{margin-top:4rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:rounded-lg{border-radius:.5rem}.sm\:p-6{padding:1.5rem}.sm\:px-0{padding-left:0;padding-right:0}.sm\:px-2{padding-left:.5rem;padding-right:.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-4xl{font-size:2.4rem}.sm\:text-sm{font-size:.8rem}}@media (min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-end{align-items:flex-end}}@media (min-width:980px){.mdl\:flex-row{flex-direction:row}.mdl\:items-center{align-items:center}.mdl\:py-28{padding-top:7rem;padding-bottom:7rem}}@media (min-width:1024px){.lg\:col-span-1{grid-column:span 1/span 1}.lg\:col-span-2{grid-column:span 2/span 2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-7{grid-column:span 7/span 7}.lg\:col-span-9{grid-column:span 9/span 9}.lg\:mt-0{margin-top:0}.lg\:grid{display:grid}.lg\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:items-start{align-items:flex-start}.lg\:gap-x-12{-moz-column-gap:3rem;column-gap:3rem}.lg\:gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.lg\:gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.lg\:px-0{padding-left:0;padding-right:0}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:py-0{padding-bottom:0}.lg\:pt-0,.lg\:py-0{padding-top:0}}.ltr\:ml-3:where([dir=ltr],[dir=ltr] *){margin-left:.75rem}.ltr\:text-left:where([dir=ltr],[dir=ltr] *){text-align:left}.ltr\:text-right:where([dir=ltr],[dir=ltr] *){text-align:right}.rtl\:mr-3:where([dir=rtl],[dir=rtl] *){margin-right:.75rem}.rtl\:text-left:where([dir=rtl],[dir=rtl] *){text-align:left}.rtl\:text-right:where([dir=rtl],[dir=rtl] *){text-align:right} -
digicommerce/trunk/assets/js/front/checkout.js
r3309447 r3310934 1 (()=>{var c={showMessage:(e,a,d=!0)=>{e.textContent=a,e.classList.remove("hidden","bg-green-500","bg-red-500"),e.classList.add(d?"bg-red-500":"bg-green-500","text-white");let g=e.getBoundingClientRect().top+window.pageYOffset-100;window.scrollTo({top:g,behavior:"smooth"})},hideMessage:(e,a=5e3)=>{setTimeout(()=>{e.classList.add("hidden")},a)},toggleLoading:(e,a)=>{a?(e.classList.remove("hidden"),e.classList.add("flex")):(e.classList.add("hidden"),e.classList.remove("flex"))},resetButton:(e,a)=>{e.disabled=!1,e.textContent=a},handleValidationFailure:(e,a,d,_,g)=>{c.showMessage(e,g),c.toggleLoading(a,!1),c.resetButton(d,_)}},q={async handlePayment(e,a,d){try{let g=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({action:"digicommerce_process_stripe_payment",nonce:e.get("checkout_nonce"),...this.getFormFields(e)})})).json();if(!g.success)throw new Error(g.data?.message||"Payment setup failed");let S={payment_method:{card:a,billing_details:this.getBillingDetails(e)}},y={customer_id:g.data.customerId},h=g.data.setupIntent!==void 0;if(g.data.setupIntent){let{setupIntent:u,error:r}=await d.confirmCardSetup(g.data.setupIntent.client_secret,S);if(r)throw new Error(r.message);y.payment_method=u.payment_method,y.setup_intent_id=u.id}if(g.data.paymentIntent){let{paymentIntent:u,error:r}=await d.confirmCardPayment(g.data.paymentIntent.client_secret,y.payment_method?{payment_method:y.payment_method}:S);if(r)throw new Error(r.message);if(y.payment_intent_id=u.id,u.status!=="succeeded")throw new Error("Payment verification failed. Please try again.")}if(y.payment_method&&h&&y.setup_intent_id){let r=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({action:"digicommerce_process_stripe_payment",nonce:e.get("checkout_nonce"),stripe_payment_data:JSON.stringify(y),...this.getFormFields(e)})})).json();if(!r.success)throw new Error(r.data?.message||"Failed to create subscription");if(r.data.requiresAction&&r.data.clientSecret){let{paymentIntent:E,error:I}=await d.confirmCardPayment(r.data.clientSecret);if(I)throw new Error(I.message);y.payment_intent_id=E.id}r.data.subscriptionId&&(y.subscription_id=r.data.subscriptionId)}return await this.processCheckout(new URLSearchParams({action:"digicommerce_process_checkout",checkout_nonce:e.get("checkout_nonce"),payment_method:"stripe",stripe_payment_data:JSON.stringify(y),...this.getFormFields(e)}))}catch(_){throw console.error("Payment error:",_),_}},processCheckout(e){return fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e}).then(a=>a.json()).then(a=>{if(!a.success)throw new Error(a.data?.message||"Checkout processing failed");return a})},getBillingDetails(e){return{name:`${e.get("billing_first_name")} ${e.get("billing_last_name")}`,email:e.get("billing_email"),phone:e.get("billing_phone"),address:{line1:e.get("billing_address"),city:e.get("billing_city"),postal_code:e.get("billing_postcode"),state:e.get("billing_state"),country:e.get("billing_country")}}},getFormFields(e){let a={first_name:e.get("billing_first_name"),last_name:e.get("billing_last_name"),email:e.get("billing_email"),phone:e.get("billing_phone"),company:e.get("billing_company")||"",address:e.get("billing_address"),city:e.get("billing_city"),postcode:e.get("billing_postcode"),state:e.get("billing_state"),country:e.get("billing_country"),vat_number:e.get("billing_vat_number")||""},d=document.getElementById("subscribe_mailing_list");d&&(a.subscribe_mailing_list=d.checked?"1":"0");let _=new URLSearchParams(window.location.search);return _.get("from_abandoned")==="1"&&(a.from_abandoned="1",_.get("coupon")&&(a.recovery_coupon=_.get("coupon"))),a}},P,x;document.addEventListener("DOMContentLoaded",function(){let e=document.getElementById("digicommerce-checkout-form"),a=new URLSearchParams(window.location.search);if(e&&(digicommerceVars.stripeEnabled&&(P=Stripe(digicommerceVars.publishableKey),x=P.elements().create("card",{hidePostalCode:!0,style:{base:{fontSize:"16px",color:"#32325d",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',"::placeholder":{color:"#aab7c4"}},invalid:{color:"#fa755a",iconColor:"#fa755a"}}}),x.mount("#card-element"),x.addEventListener("change",function(t){let o=document.getElementById("card-errors");t.error?(o.textContent=t.error.message,o.classList.remove("hidden"),o.classList.add("flex")):(o.textContent="",o.classList.remove("flex"),o.classList.add("hidden"))})),digicommerceVars.paypalEnabled)){let i=JSON.parse(digicommerceVars.cartItems||"[]"),t=i.some(l=>l.subscription_enabled),o=t?i.find(l=>l.subscription_enabled):null,p={fundingSource:paypal.FUNDING.PAYPAL,style:{layout:"vertical",shape:"rect",label:t?"subscribe":"pay"}};t?p.createSubscription=async(l,w)=>{try{if(!e)throw new Error("Checkout form not found");let n=new FormData(e);c.toggleLoading(document.getElementById("loading-overlay"),!0);let m=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({action:"digicommerce_create_paypal_plan",nonce:n.get("checkout_nonce"),first_name:n.get("billing_first_name"),last_name:n.get("billing_last_name"),email:n.get("billing_email"),country:n.get("billing_country"),vat_number:n.get("billing_vat_number")})})).json();if(!m.success||!m.data.plan_id)throw new Error(m.data?.message||"Failed to create PayPal plan");let f={plan_id:m.data.plan_id,application_context:{shipping_preference:"NO_SHIPPING"},subscriber:{name:{given_name:n.get("billing_first_name"),surname:n.get("billing_last_name")},email_address:n.get("billing_email")}};return c.toggleLoading(document.getElementById("loading-overlay"),!1),await w.subscription.create(f)}catch(n){throw console.error("Subscription creation error:",n),c.showMessage(document.getElementById("checkout-message"),n.message),n}}:p.createOrder=async(l,w)=>{try{if(!e)throw new Error("Checkout form not found");let n=new FormData(e),s=i.reduce((v,R)=>v+parseFloat(R.price),0),m=0;if(digicommerceVars.cartDiscount){let v=JSON.parse(digicommerceVars.cartDiscount);v.type==="percentage"?m=s*v.amount/100:m=Math.min(v.amount,s)}let f=s-m,L=n.get("billing_country"),V=digicommerceVars.businessCountry,b=n.get("billing_vat_number"),k=0,F=digicommerceVars.countries||{};digicommerceVars.removeTaxes||(L===V?k=F[V]?.tax_rate||0:F[L]?.eu&&F[V]?.eu&&(!b||!window.vatCalculator?.validateVATNumber(b,L))&&(k=F[L]?.tax_rate||0));let B=f*k,T=f+B;return w.order.create({purchase_units:[{amount:{currency_code:digicommerceVars.currency,value:T.toFixed(2),breakdown:{item_total:{currency_code:digicommerceVars.currency,value:s.toFixed(2)},tax_total:B>0?{currency_code:digicommerceVars.currency,value:B.toFixed(2)}:void 0,discount:m>0?{currency_code:digicommerceVars.currency,value:m.toFixed(2)}:void 0}},items:i.map(v=>({name:v.name,unit_amount:{currency_code:digicommerceVars.currency,value:v.price.toFixed(2)},quantity:1}))}]})}catch(n){throw console.error("Order creation error:",n),c.showMessage(document.getElementById("checkout-message"),n.message),n}},p.onApprove=async(l,w)=>{try{let n;l.orderID&&!l.subscriptionID&&(n=await w.order.capture());let s=new FormData(e),m=document.getElementById("checkout-message");c.toggleLoading(document.getElementById("loading-overlay"),!0);let f=new URLSearchParams({action:"digicommerce_process_checkout",checkout_nonce:s.get("checkout_nonce"),payment_method:"paypal",paypal_order_id:l.orderID,paypal_subscription_id:l.subscriptionID,email:s.get("billing_email"),first_name:s.get("billing_first_name"),last_name:s.get("billing_last_name"),company:s.get("billing_company"),country:s.get("billing_country"),address:s.get("billing_address"),city:s.get("billing_city"),postcode:s.get("billing_postcode"),state:s.get("billing_state"),phone:s.get("billing_phone"),vat_number:s.get("billing_vat_number")}),L=document.getElementById("subscribe_mailing_list");L&&f.append("subscribe_mailing_list",L.checked?"1":"0"),a.get("from_abandoned")==="1"&&(f.append("from_abandoned","1"),a.get("coupon")&&f.append("recovery_coupon",a.get("coupon")));let b=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:f})).json();if(b.success&&b.data.redirect)c.showMessage(m,digicommerceVars.i18n.success,!1),b.data.order_id&&localStorage.setItem("last_order_id",b.data.order_id),setTimeout(()=>{window.location.href=b.data.redirect},1500);else throw new Error(b.data?.message||"Payment processing failed")}catch(n){console.error("PayPal payment processing error:",n),c.showMessage(document.getElementById("checkout-message"),n.message),c.toggleLoading(document.getElementById("loading-overlay"),!1)}},p.onError=l=>{console.error("PayPal error:",l),c.showMessage(document.getElementById("checkout-message"),"PayPal payment failed"),c.toggleLoading(document.getElementById("loading-overlay"),!1)},p.onCancel=()=>{c.showMessage(document.getElementById("checkout-message"),"Payment cancelled"),c.toggleLoading(document.getElementById("loading-overlay"),!1)},paypal.Buttons(p).render("#paypal-button-container")}let d=document.getElementById("country");if(d){let i=new Choices(d,{searchEnabled:!0,searchPlaceholderValue:d.dataset.placeholder,searchResultLimit:-1}),t=a.get("country");t&&d.querySelector(`option[value="${t}"]`)&&(i.setChoiceByValue(t),d.value=t,setTimeout(()=>{window.vatCalculator&&window.vatCalculator.updateFromSubtotal()},0))}let _=document.querySelectorAll(".digi__form .field input");_&&_.forEach(i=>{let t=()=>{i.value!==""?i.classList.add("focused"):i.classList.remove("focused")};t(),i.addEventListener("blur",t),i.addEventListener("input",t)});let g={validateCountry:(i,t)=>i.value?!0:(t.onFailure(digicommerceVars.i18n.select_country),!1),validateRequiredFields:(i,t)=>{let o=i.querySelectorAll("input[required]"),p=!0;return o.forEach(l=>{l.value.trim()||(p=!1)}),p?!0:(t.onFailure(digicommerceVars.i18n.required_fields),!1)},validateVATNumber:(i,t,o)=>{if(!window.vatCalculator)return!0;let p=t.value,l=document.getElementById("vat_number"),w=document.getElementById("vat_number_field");if(!l||w.style.display==="none")return!0;if(window.vatCalculator.isEUCountry(p)){let n=l.value.trim();if(n&&!window.vatCalculator.validateVATNumber(n,p))return o.onFailure(digicommerceVars.i18n.vat_invalid||"Invalid VAT number format"),l.classList.add("border-red-500"),!1}return!0},validateForm:(i,t,o)=>g.validateCountry(t,o)&&g.validateVATNumber(i,t,o)&&g.validateRequiredFields(i,o)},S=document.getElementById("payment_method_stripe"),y=document.getElementById("payment_method_paypal"),h=document.querySelector(".digicommerce-stripe"),u=document.querySelector(".digicommerce-paypal"),r=document.querySelector(".digicommerce-checkout-button"),E=document.getElementById("paypal-button-container");if(S&&y&&h&&u){let i=function(t){t?(u.style.opacity="0",setTimeout(()=>{u.style.display="none",h.style.display="flex",r.style.display="flex",E.style.display="none",h.offsetWidth,h.style.opacity="1",r.style.opacity="1"},300)):(h.style.opacity="0",r.style.opacity="0",setTimeout(()=>{h.style.display="none",u.style.display="flex",r.style.display="none",E.style.display="flex",u.offsetWidth,u.style.opacity="1"},300))};var N=i;u.style.opacity="0",u.style.display="none",E.style.display="none",S.addEventListener("change",function(){this.checked&&i(!0)}),y.addEventListener("change",function(){this.checked&&i(!1)}),S.checked?(h.style.display="flex",h.style.opacity="1",r.style.display="flex",r.style.opacity="1",E.style.display="none"):y.checked&&(u.style.display="flex",u.style.opacity="1",r.style.display="none",E.style.display="flex"),h.style.transition="opacity 300ms ease-in-out",u.style.transition="opacity 300ms ease-in-out",r.style.transition="all 300ms ease-in-out"}let I=document.getElementById("loading-overlay"),C=document.getElementById("checkout-message");if(e&&d&&(digicommerceVars.stripeEnabled||digicommerceVars.paypalEnabled)){d.removeAttribute("required"),e.setAttribute("novalidate","");let i=document.getElementById("vat_number");i&&i.addEventListener("input",()=>{i.classList.remove("border-red-500"),C.classList.add("hidden")}),e.addEventListener("submit",async function(t){t.preventDefault();let o=e.querySelector("button.digicommerce-checkout-button .text"),p=o.textContent;c.toggleLoading(I,!0),o.disabled=!0,o.textContent=digicommerceVars.i18n.processing_payment;let l={onFailure:s=>{c.handleValidationFailure(C,I,o,p,s)}};if(!g.validateForm(e,d,l))return;let n=e.querySelector('input[name="billing_email"]')?.value.trim();if(!n||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n)){c.handleValidationFailure(C,I,o,p,digicommerceVars.i18n.invalid_email);return}C.classList.add("hidden");try{if(P&&x){let s=new FormData(e),m=await q.handlePayment(s,x,P);if(m.success)c.showMessage(C,digicommerceVars.i18n.success,!1),m.data.order_id&&localStorage.setItem("last_order_id",m.data.order_id),setTimeout(()=>{m.data.redirect?window.location.href=m.data.redirect:digicommerceVars.payment_success_page&&(window.location.href=digicommerceVars.payment_success_page)},1500);else throw new Error(m.data?.message||digicommerceVars.i18n.payment_error)}}catch(s){console.error("Checkout Error:",s),c.showMessage(C,s.message),c.resetButton(o,p)}finally{c.toggleLoading(I,!1)}}),e.querySelectorAll("input[required]").forEach(t=>{t.addEventListener("invalid",function(o){o.preventDefault(),t.classList.add("invalid")}),t.addEventListener("input",function(){t.classList.remove("invalid")})})}});})();1 (()=>{var s={showMessage:(e,i,l=!0)=>{e.textContent=i,e.classList.remove("hidden","bg-green-500","bg-red-500"),e.classList.add(l?"bg-red-500":"bg-green-500","text-white");let u=e.getBoundingClientRect().top+window.pageYOffset-100;window.scrollTo({top:u,behavior:"smooth"})},hideMessage:(e,i=5e3)=>{setTimeout(()=>{e.classList.add("hidden")},i)},toggleLoading:(e,i)=>{i?(e.classList.remove("hidden"),e.classList.add("flex")):(e.classList.add("hidden"),e.classList.remove("flex"))},resetButton:(e,i)=>{e.disabled=!1,e.textContent=i},handleValidationFailure:(e,i,l,p,u)=>{s.showMessage(e,u),s.toggleLoading(i,!1),s.resetButton(l,p)}},j={async handlePayment(e,i,l){try{let u=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({action:"digicommerce_process_stripe_payment",nonce:e.get("checkout_nonce"),...this.getFormFields(e)})})).json();if(!u.success)throw new Error(u.data?.message||"Payment setup failed");let B={payment_method:{card:i,billing_details:this.getBillingDetails(e)}},g={customer_id:u.data.customerId},_=u.data.setupIntent!==void 0;if(u.data.setupIntent){let{setupIntent:d,error:r}=await l.confirmCardSetup(u.data.setupIntent.client_secret,B);if(r)throw new Error(r.message);g.payment_method=d.payment_method,g.setup_intent_id=d.id}if(u.data.paymentIntent){let{paymentIntent:d,error:r}=await l.confirmCardPayment(u.data.paymentIntent.client_secret,g.payment_method?{payment_method:g.payment_method}:B);if(r)throw new Error(r.message);if(g.payment_intent_id=d.id,d.status!=="succeeded")throw new Error("Payment verification failed. Please try again.")}if(g.payment_method&&_&&g.setup_intent_id){let r=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({action:"digicommerce_process_stripe_payment",nonce:e.get("checkout_nonce"),stripe_payment_data:JSON.stringify(g),...this.getFormFields(e)})})).json();if(!r.success)throw new Error(r.data?.message||"Failed to create subscription");if(r.data.requiresAction&&r.data.clientSecret){let{paymentIntent:C,error:k}=await l.confirmCardPayment(r.data.clientSecret);if(k)throw new Error(k.message);g.payment_intent_id=C.id}r.data.subscriptionId&&(g.subscription_id=r.data.subscriptionId)}return await this.processCheckout(new URLSearchParams({action:"digicommerce_process_checkout",checkout_nonce:e.get("checkout_nonce"),payment_method:"stripe",stripe_payment_data:JSON.stringify(g),...this.getFormFields(e)}))}catch(p){throw console.error("Payment error:",p),p}},processCheckout(e){return fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:e}).then(i=>i.json()).then(i=>{if(!i.success)throw new Error(i.data?.message||"Checkout processing failed");return i})},getBillingDetails(e){return{name:`${e.get("billing_first_name")} ${e.get("billing_last_name")}`,email:e.get("billing_email"),phone:e.get("billing_phone"),address:{line1:e.get("billing_address"),city:e.get("billing_city"),postal_code:e.get("billing_postcode"),state:e.get("billing_state"),country:e.get("billing_country")}}},getFormFields(e){let i={first_name:e.get("billing_first_name"),last_name:e.get("billing_last_name"),email:e.get("billing_email"),phone:e.get("billing_phone"),company:e.get("billing_company")||"",address:e.get("billing_address"),city:e.get("billing_city"),postcode:e.get("billing_postcode"),state:e.get("billing_state"),country:e.get("billing_country"),vat_number:e.get("billing_vat_number")||""},l=document.getElementById("subscribe_mailing_list");l&&(i.subscribe_mailing_list=l.checked?"1":"0");let p=new URLSearchParams(window.location.search);return p.get("from_abandoned")==="1"&&(i.from_abandoned="1",p.get("coupon")&&(i.recovery_coupon=p.get("coupon"))),i}},O,T;document.addEventListener("DOMContentLoaded",function(){let e=document.getElementById("digicommerce-checkout-form"),i=new URLSearchParams(window.location.search);if(e&&(digicommerceVars.stripeEnabled&&(O=Stripe(digicommerceVars.publishableKey),T=O.elements().create("card",{hidePostalCode:!0,style:{base:{fontSize:"16px",color:"#32325d",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',"::placeholder":{color:"#aab7c4"}},invalid:{color:"#fa755a",iconColor:"#fa755a"}}}),T.mount("#card-element"),T.addEventListener("change",function(t){let a=document.getElementById("card-errors");t.error?(a.textContent=t.error.message,a.classList.remove("hidden"),a.classList.add("flex")):(a.textContent="",a.classList.remove("flex"),a.classList.add("hidden"))})),digicommerceVars.paypalEnabled)){let n=JSON.parse(digicommerceVars.cartItems||"[]"),t=n.some(m=>m.subscription_enabled),a=n.filter(m=>m.subscription_enabled),h=n.filter(m=>!m.subscription_enabled),f=t?a.length===1&&h.length===0:!0,w={fundingSource:paypal.FUNDING.PAYPAL,style:{layout:"vertical",shape:"rect",label:t?"subscribe":"pay"}};t&&f?w.createSubscription=async(m,I)=>{try{if(!e)throw new Error(digicommerceVars.i18n.checkout_form_not_found);let o=new FormData(e);s.toggleLoading(document.getElementById("loading-overlay"),!0);let y=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({action:"digicommerce_create_paypal_plan",nonce:o.get("checkout_nonce"),first_name:o.get("billing_first_name"),last_name:o.get("billing_last_name"),email:o.get("billing_email"),country:o.get("billing_country"),vat_number:o.get("billing_vat_number")})})).json();if(!y.success){let V=y.data?.message||digicommerceVars.i18n.paypal_plan_creation_failed;throw new Error(V)}if(!y.data.plan_id)throw new Error(digicommerceVars.i18n.paypal_plan_creation_failed);let L={plan_id:y.data.plan_id,application_context:{shipping_preference:"NO_SHIPPING"},subscriber:{name:{given_name:o.get("billing_first_name"),surname:o.get("billing_last_name")},email_address:o.get("billing_email")}};return s.toggleLoading(document.getElementById("loading-overlay"),!1),await I.subscription.create(L)}catch(o){throw console.error("Subscription creation error:",o),s.toggleLoading(document.getElementById("loading-overlay"),!1),s.showMessage(document.getElementById("checkout-message"),o.message),o}}:w.createOrder=x;async function x(m,I){try{if(!e)throw new Error(digicommerceVars.i18n.checkout_form_not_found);let o=new FormData(e),c=n.reduce((b,U)=>b+parseFloat(U.price),0),y=0;if(digicommerceVars.cartDiscount){let b=JSON.parse(digicommerceVars.cartDiscount);b.type==="percentage"?y=c*b.amount/100:y=Math.min(b.amount,c)}let L=c-y,V=o.get("billing_country"),R=digicommerceVars.businessCountry,S=o.get("billing_vat_number"),P=0,M=digicommerceVars.countries||{};digicommerceVars.removeTaxes||(V===R?P=M[R]?.tax_rate||0:M[V]?.eu&&M[R]?.eu&&(!S||!window.vatCalculator?.validateVATNumber(S,V))&&(P=M[V]?.tax_rate||0));let q=L*P,N=L+q;if(N<=0)throw new Error(digicommerceVars.i18n.invalid_order_total);let A={purchase_units:[{amount:{currency_code:digicommerceVars.currency,value:N.toFixed(2),breakdown:{item_total:{currency_code:digicommerceVars.currency,value:c.toFixed(2)}}},items:n.map(b=>({name:b.name+(b.variation_name?` (${b.variation_name})`:""),unit_amount:{currency_code:digicommerceVars.currency,value:parseFloat(b.price).toFixed(2)},quantity:1,category:"DIGITAL_GOODS"}))}]};return q>0&&(A.purchase_units[0].amount.breakdown.tax_total={currency_code:digicommerceVars.currency,value:q.toFixed(2)}),y>0&&(A.purchase_units[0].amount.breakdown.discount={currency_code:digicommerceVars.currency,value:y.toFixed(2)}),I.order.create(A)}catch(o){throw console.error("Order creation error:",o),s.showMessage(document.getElementById("checkout-message"),o.message),o}}w.onApprove=async(m,I)=>{try{let o;m.orderID&&!m.subscriptionID&&(o=await I.order.capture());let c=new FormData(e),y=document.getElementById("checkout-message");s.toggleLoading(document.getElementById("loading-overlay"),!0);let L=new URLSearchParams({action:"digicommerce_process_checkout",checkout_nonce:c.get("checkout_nonce"),payment_method:"paypal",paypal_order_id:m.orderID,paypal_subscription_id:m.subscriptionID,email:c.get("billing_email"),first_name:c.get("billing_first_name"),last_name:c.get("billing_last_name"),company:c.get("billing_company"),country:c.get("billing_country"),address:c.get("billing_address"),city:c.get("billing_city"),postcode:c.get("billing_postcode"),state:c.get("billing_state"),phone:c.get("billing_phone"),vat_number:c.get("billing_vat_number")}),V=document.getElementById("subscribe_mailing_list");V&&L.append("subscribe_mailing_list",V.checked?"1":"0"),i.get("from_abandoned")==="1"&&(L.append("from_abandoned","1"),i.get("coupon")&&L.append("recovery_coupon",i.get("coupon")));let S=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:L})).json();if(S.success&&S.data.redirect)s.showMessage(y,digicommerceVars.i18n.success,!1),S.data.order_id&&localStorage.setItem("last_order_id",S.data.order_id),setTimeout(()=>{window.location.href=S.data.redirect},1500);else{let P=S.data?.message||digicommerceVars.i18n.paypal_processing_failed;throw new Error(P)}}catch(o){console.error("PayPal payment processing error:",o);let c=o.message||digicommerceVars.i18n.paypal_processing_failed;s.showMessage(document.getElementById("checkout-message"),c),s.toggleLoading(document.getElementById("loading-overlay"),!1)}},w.onError=m=>{console.error("PayPal error:",m);let I=m?.message||digicommerceVars.i18n.paypal_failed;s.showMessage(document.getElementById("checkout-message"),I),s.toggleLoading(document.getElementById("loading-overlay"),!1)},w.onCancel=()=>{s.showMessage(document.getElementById("checkout-message"),digicommerceVars.i18n.paypal_cancelled),s.toggleLoading(document.getElementById("loading-overlay"),!1)},paypal.Buttons(w).render("#paypal-button-container");let v=document.getElementById("payment_method_paypal");v&&v.addEventListener("change",function(){if(this.checked&&!f){let m=document.getElementById("checkout-message"),I=a.length>1?digicommerceVars.i18n.multiple_subscriptions_error:digicommerceVars.i18n.mixed_cart_error;s.showMessage(m,I)}});let E=document.getElementById("payment_method_stripe");E&&E.addEventListener("change",function(){this.checked&&document.getElementById("checkout-message").classList.add("hidden")})}let l=document.getElementById("country");if(l){let n=new Choices(l,{searchEnabled:!0,searchPlaceholderValue:l.dataset.placeholder,searchResultLimit:-1}),t=i.get("country");t&&l.querySelector(`option[value="${t}"]`)&&(n.setChoiceByValue(t),l.value=t,setTimeout(()=>{window.vatCalculator&&window.vatCalculator.updateFromSubtotal()},0))}let p=document.querySelectorAll(".digi__form .field input");p&&p.forEach(n=>{let t=()=>{n.value!==""?n.classList.add("focused"):n.classList.remove("focused")};t(),n.addEventListener("blur",t),n.addEventListener("input",t)});let u={validateCountry:(n,t)=>n.value?!0:(t.onFailure(digicommerceVars.i18n.select_country),!1),validateRequiredFields:(n,t)=>{let a=n.querySelectorAll("input[required]"),h=!0;return a.forEach(f=>{f.value.trim()||(h=!1)}),h?!0:(t.onFailure(digicommerceVars.i18n.required_fields),!1)},validateVATNumber:(n,t,a)=>{if(!window.vatCalculator)return!0;let h=t.value,f=document.getElementById("vat_number"),w=document.getElementById("vat_number_field");if(!f||w.style.display==="none")return!0;if(window.vatCalculator.isEUCountry(h)){let x=f.value.trim();if(x&&!window.vatCalculator.validateVATNumber(x,h))return a.onFailure(digicommerceVars.i18n.vat_invalid||"Invalid VAT number format"),f.classList.add("border-red-500"),!1}return!0},validateForm:(n,t,a)=>u.validateCountry(t,a)&&u.validateVATNumber(n,t,a)&&u.validateRequiredFields(n,a)},B=document.getElementById("payment_method_stripe"),g=document.getElementById("payment_method_paypal"),_=document.querySelector(".digicommerce-stripe"),d=document.querySelector(".digicommerce-paypal"),r=document.querySelector(".digicommerce-checkout-button"),C=document.getElementById("paypal-button-container");if(B&&g&&_&&d){let n=function(t){t?(d.style.opacity="0",setTimeout(()=>{d.style.display="none",_.style.display="flex",r.style.display="flex",C.style.display="none",_.offsetWidth,_.style.opacity="1",r.style.opacity="1"},300)):(_.style.opacity="0",r.style.opacity="0",setTimeout(()=>{_.style.display="none",d.style.display="flex",r.style.display="none",C.style.display="flex",d.offsetWidth,d.style.opacity="1"},300))};var $=n;d.style.opacity="0",d.style.display="none",C.style.display="none",B.addEventListener("change",function(){this.checked&&n(!0)}),g.addEventListener("change",function(){this.checked&&n(!1)}),B.checked?(_.style.display="flex",_.style.opacity="1",r.style.display="flex",r.style.opacity="1",C.style.display="none"):g.checked&&(d.style.display="flex",d.style.opacity="1",r.style.display="none",C.style.display="flex"),_.style.transition="opacity 300ms ease-in-out",d.style.transition="opacity 300ms ease-in-out",r.style.transition="all 300ms ease-in-out"}let k=document.getElementById("loading-overlay"),F=document.getElementById("checkout-message");if(e&&l&&(digicommerceVars.stripeEnabled||digicommerceVars.paypalEnabled)){l.removeAttribute("required"),e.setAttribute("novalidate","");let n=document.getElementById("vat_number");n&&n.addEventListener("input",()=>{n.classList.remove("border-red-500"),F.classList.add("hidden")}),e.addEventListener("submit",async function(t){t.preventDefault();let a=e.querySelector("button.digicommerce-checkout-button .text"),h=a.textContent;s.toggleLoading(k,!0),a.disabled=!0,a.textContent=digicommerceVars.i18n.processing_payment;let f={onFailure:v=>{s.handleValidationFailure(F,k,a,h,v)}};if(!u.validateForm(e,l,f))return;let x=e.querySelector('input[name="billing_email"]')?.value.trim();if(!x||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(x)){s.handleValidationFailure(F,k,a,h,digicommerceVars.i18n.invalid_email);return}F.classList.add("hidden");try{if(O&&T){let v=new FormData(e),E=await j.handlePayment(v,T,O);if(E.success)s.showMessage(F,digicommerceVars.i18n.success,!1),E.data.order_id&&localStorage.setItem("last_order_id",E.data.order_id),setTimeout(()=>{E.data.redirect?window.location.href=E.data.redirect:digicommerceVars.payment_success_page&&(window.location.href=digicommerceVars.payment_success_page)},1500);else throw new Error(E.data?.message||digicommerceVars.i18n.payment_error)}}catch(v){console.error("Checkout Error:",v),s.showMessage(F,v.message),s.resetButton(a,h)}finally{s.toggleLoading(k,!1)}}),e.querySelectorAll("input[required]").forEach(t=>{t.addEventListener("invalid",function(a){a.preventDefault(),t.classList.add("invalid")}),t.addEventListener("input",function(){t.classList.remove("invalid")})})}});})(); -
digicommerce/trunk/assets/js/front/delete-button.js
r3308154 r3310934 1 (()=>{document.addEventListener("DOMContentLoaded",function(){document.addEventListener("digicommerce_cart_updated",function( o){o.detail&&o.detail.source!=="checkout_page"&&setTimeout(()=>{window.location.reload()},200)});let r=document.querySelectorAll(".remove-item-btn");r&&r.forEach(o=>{o.addEventListener("click",async function(n){n.preventDefault();let a=this.dataset.index;try{let t=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",body:new URLSearchParams({action:"digicommerce_remove_cart_item",index:a,nonce:digicommerceVars.order_nonce}),headers:{"Content-Type":"application/x-www-form-urlencoded"}})).json();if(t.success&&t.data){if(this.closest(".cart-item").remove(),document.querySelectorAll(".remove-item-btn").forEach((e,m)=>{e.dataset.index=m}),document.querySelectorAll(".cart-item").length){let e=document.getElementById("cart-subtotal");e&&(e.innerHTML=t.data.formatted_prices.subtotal),window.vatCalculator&&window.vatCalculator.updateFromSubtotal()}else{let e=document.querySelector(".digicommerce-checkout");e&&digicommerceVars.empty_cart_template&&(e.innerHTML=digicommerceVars.empty_cart_template)}let i=new CustomEvent("digicommerce_cart_updated",{detail:{source:"checkout_page",action:"remove",itemIndex:a,data:t.data}});document.dispatchEvent(i);let d=new CustomEvent("digicommerce_removed_from_cart",{detail:{source:"checkout_page",itemIndex:a,data:t.data}});if(document.dispatchEvent(d),digicommerceVars.proVersion&&digicommerceVars.enableSideCart){let e=new CustomEvent("digicommerce_cart_updated");document.dispatchEvent(e)}}else console.error("Remove cart item failed:",t),alert(t.data?.message||"Failed to remove item.")}catch(c){console.error("Cart removal error:",c),alert("An error occurred. Please try again.")}})})});})();1 (()=>{document.addEventListener("DOMContentLoaded",function(){document.addEventListener("digicommerce_cart_updated",function(t){t.detail&&t.detail.source!=="checkout_page"&&setTimeout(()=>{window.location.reload()},200)});function r(){let t=document.getElementById("payment_method_paypal");return t&&t.checked}let c=document.querySelectorAll(".remove-item-btn");c&&c.forEach(t=>{t.addEventListener("click",async function(i){i.preventDefault();let a=this.dataset.index;try{let o=await(await fetch(digicommerceVars.ajaxurl,{method:"POST",body:new URLSearchParams({action:"digicommerce_remove_cart_item",index:a,nonce:digicommerceVars.order_nonce}),headers:{"Content-Type":"application/x-www-form-urlencoded"}})).json();if(o.success&&o.data){if(r()){window.location.href=window.location.pathname;return}if(this.closest(".cart-item").remove(),document.querySelectorAll(".remove-item-btn").forEach((e,s)=>{e.dataset.index=s}),document.querySelectorAll(".cart-item").length){let e=document.getElementById("cart-subtotal");e&&(e.innerHTML=o.data.formatted_prices.subtotal),window.vatCalculator&&window.vatCalculator.updateFromSubtotal()}else{let e=document.querySelector(".digicommerce-checkout");e&&digicommerceVars.empty_cart_template&&(e.innerHTML=digicommerceVars.empty_cart_template)}let d=new CustomEvent("digicommerce_cart_updated",{detail:{source:"checkout_page",action:"remove",itemIndex:a,data:o.data}});document.dispatchEvent(d);let m=new CustomEvent("digicommerce_removed_from_cart",{detail:{source:"checkout_page",itemIndex:a,data:o.data}});if(document.dispatchEvent(m),digicommerceVars.proVersion&&digicommerceVars.enableSideCart){let e=new CustomEvent("digicommerce_cart_updated");document.dispatchEvent(e)}}else console.error("Remove cart item failed:",o),alert(o.data?.message||"Failed to remove item.")}catch(n){console.error("Cart removal error:",n),alert("An error occurred. Please try again.")}})})});})(); -
digicommerce/trunk/digicommerce.php
r3309447 r3310934 879 879 'select_option' => esc_html__( 'Select an option', 'digicommerce' ), 880 880 'purchase_for' => esc_html__( 'Purchase for', 'digicommerce' ), 881 882 // PayPal specific messages 883 'paypal_failed' => esc_html__( 'PayPal payment failed', 'digicommerce' ), 884 'paypal_cancelled' => esc_html__( 'Payment cancelled', 'digicommerce' ), 885 'paypal_processing_failed' => esc_html__( 'Payment processing failed', 'digicommerce' ), 886 'paypal_subscription_creation_failed' => esc_html__( 'Failed to create subscription', 'digicommerce' ), 887 'paypal_plan_creation_failed' => esc_html__( 'Failed to create PayPal plan', 'digicommerce' ), 888 'paypal_order_creation_failed' => esc_html__( 'Failed to create PayPal order', 'digicommerce' ), 889 'checkout_form_not_found' => esc_html__( 'Checkout form not found', 'digicommerce' ), 890 'invalid_order_total' => esc_html__( 'Invalid order total', 'digicommerce' ), 891 'multiple_subscriptions_error' => esc_html__( 'PayPal does not support multiple subscription products in one transaction.', 'digicommerce' ), 892 'mixed_cart_error' => esc_html__( 'PayPal subscriptions cannot be combined with one-time products. Please checkout subscription and one-time products separately.', 'digicommerce' ), 893 881 894 ); 882 895 } -
digicommerce/trunk/includes/class-digicommerce-checkout.php
r3309447 r3310934 1020 1020 } 1021 1021 1022 // Get product ID, variation index, and coupon code from the URL parameters. 1023 $product_id = isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0; 1024 $variation_index = isset( $_GET['variation'] ) ? ( intval( $_GET['variation'] ) - 1 ) : -1; 1025 1026 if ( ! $product_id ) { 1027 return; // Exit if no product ID is provided. 1028 } 1029 1022 // Parse multiple products from URL parameters 1023 $products_to_add = $this->parse_multiple_products_from_url(); 1024 1025 if ( empty( $products_to_add ) ) { 1026 return; // No products to add 1027 } 1028 1029 // Get current session and cart data 1030 $session_key = $this->get_current_session_key(); 1031 $session_data = $this->get_session( $session_key ); 1032 1033 if ( ! $session_data ) { 1034 $session_data = array( 'cart' => array() ); 1035 } 1036 1037 $cart_items = array(); 1038 $products_added = array(); 1039 1040 // Keep existing cart items (except those being replaced) 1041 foreach ( $session_data['cart'] as $cart_item ) { 1042 $should_keep = true; 1043 1044 foreach ( $products_to_add as $new_product ) { 1045 // Remove existing product if it's the same product 1046 // For variations, this will replace the variation 1047 if ( $cart_item['product_id'] === $new_product['product_id'] ) { 1048 if ( $new_product['has_variations'] ) { 1049 // Skip this product entirely - we'll add the new variation 1050 $should_keep = false; 1051 break; 1052 } else { 1053 // For non-variation products, check if it already exists 1054 $should_keep = false; 1055 break; 1056 } 1057 } 1058 } 1059 1060 if ( $should_keep ) { 1061 $cart_items[] = $cart_item; 1062 } 1063 } 1064 1065 // Add new products to cart 1066 foreach ( $products_to_add as $product_data ) { 1067 $product = get_post( $product_data['product_id'] ); 1068 1069 if ( ! $product || 'digi_product' !== $product->post_type ) { 1070 continue; // Skip invalid products 1071 } 1072 1073 // Create cart item 1074 $cart_item = array( 1075 'product_id' => $product_data['product_id'], 1076 'name' => $product->post_title, 1077 'price' => $product_data['price'], 1078 'variation_name' => $product_data['variation_name'], 1079 ); 1080 1081 // Add subscription data if subscription is enabled 1082 if ( ! empty( $product_data['subscription_data']['subscription_enabled'] ) ) { 1083 $cart_item['subscription_enabled'] = $product_data['subscription_data']['subscription_enabled']; 1084 $cart_item['subscription_period'] = $product_data['subscription_data']['subscription_period']; 1085 $cart_item['subscription_free_trial'] = $product_data['subscription_data']['subscription_free_trial']; 1086 $cart_item['subscription_signup_fee'] = $product_data['subscription_data']['subscription_signup_fee']; 1087 1088 // Add PayPal plan flag if needed 1089 if ( DigiCommerce()->is_paypal_enabled() ) { 1090 $cart_item['needs_paypal_plan'] = true; 1091 } 1092 } 1093 1094 $cart_items[] = $cart_item; 1095 $products_added[] = $product->post_title; 1096 } 1097 1098 // Update session data 1099 $session_data['cart'] = $cart_items; 1100 1101 // Save updated session data 1102 $this->save_session( $session_key, $session_data ); 1103 $this->cart_items = $cart_items; 1104 } 1105 1106 /** 1107 * Parse multiple products from URL parameters 1108 * Handles URLs like: ?id=123&id=456&variation=1&id=789&variation=2 1109 * 1110 * @return array Array of product data to add to cart 1111 */ 1112 private function parse_multiple_products_from_url() { 1113 // Get the raw query string to preserve parameter order 1114 $query_string = $_SERVER['QUERY_STRING'] ?? ''; 1115 1116 if ( empty( $query_string ) ) { 1117 return array(); 1118 } 1119 1120 // Parse the query string manually to preserve order and handle duplicate keys 1121 $params = array(); 1122 $pairs = explode( '&', $query_string ); 1123 1124 foreach ( $pairs as $pair ) { 1125 if ( strpos( $pair, '=' ) !== false ) { 1126 list( $key, $value ) = explode( '=', $pair, 2 ); 1127 $key = urldecode( $key ); 1128 $value = urldecode( $value ); 1129 1130 // Only capture 'id' and 'variation' parameters 1131 if ( in_array( $key, array( 'id', 'variation' ), true ) ) { 1132 $params[] = array( 1133 'key' => $key, 1134 'value' => $value, 1135 ); 1136 } 1137 } 1138 } 1139 1140 if ( empty( $params ) ) { 1141 return array(); 1142 } 1143 1144 // Group parameters into products 1145 $products = array(); 1146 $current_product = null; 1147 1148 foreach ( $params as $param ) { 1149 if ( 'id' === $param['key'] ) { 1150 // Save previous product if exists 1151 if ( $current_product !== null ) { 1152 $product_data = $this->process_single_product( $current_product['id'], $current_product['variation'] ); 1153 if ( $product_data ) { 1154 $products[] = $product_data; 1155 } 1156 } 1157 1158 // Start new product 1159 $current_product = array( 1160 'id' => intval( $param['value'] ), 1161 'variation' => -1, // Default: no variation 1162 ); 1163 } elseif ( 'variation' === $param['key'] && $current_product !== null ) { 1164 // Set variation for current product (convert to 0-based index) 1165 $current_product['variation'] = intval( $param['value'] ) - 1; 1166 } 1167 } 1168 1169 // Don't forget the last product 1170 if ( $current_product !== null ) { 1171 $product_data = $this->process_single_product( $current_product['id'], $current_product['variation'] ); 1172 if ( $product_data ) { 1173 $products[] = $product_data; 1174 } 1175 } 1176 1177 return $products; 1178 } 1179 1180 /** 1181 * Process a single product and return its data 1182 * 1183 * @param int $product_id Product ID 1184 * @param int $variation_index Variation index (-1 for no variation) 1185 * @return array|null Product data or null if invalid 1186 */ 1187 private function process_single_product( $product_id, $variation_index = -1 ) { 1030 1188 $product = get_post( $product_id ); 1031 1189 1032 1190 if ( ! $product || 'digi_product' !== $product->post_type ) { 1033 return ; // Exit if the product is invalid.1034 } 1035 1036 // Determine price and variation details .1191 return null; 1192 } 1193 1194 // Determine price and variation details 1037 1195 $price_mode = get_post_meta( $product_id, 'digi_price_mode', true ); 1038 1196 $price = 0; … … 1041 1199 $has_variations = false; 1042 1200 1043 // Handle variations .1201 // Handle variations 1044 1202 if ( 'variations' === $price_mode && $variation_index >= 0 ) { 1045 1203 $has_variations = true; … … 1070 1228 } 1071 1229 } else { 1072 return ;1230 return null; // Invalid variation 1073 1231 } 1074 1232 } else { 1075 // Handle simple product .1233 // Handle simple product 1076 1234 $regular_price = floatval( get_post_meta( $product_id, 'digi_price', true ) ); 1077 1235 $sale_price = floatval( get_post_meta( $product_id, 'digi_sale_price', true ) ); … … 1094 1252 1095 1253 if ( $price <= 0 ) { 1096 return; 1097 } 1098 1099 // Check if the product (and variation, if applicable) is already in the cart. 1100 $session_key = $this->get_current_session_key(); 1101 $session_data = $this->get_session( $session_key ); 1102 1103 if ( ! $session_data ) { 1104 $session_data = array( 'cart' => array() ); 1105 } 1106 1107 $cart_items = array(); 1108 foreach ( $session_data['cart'] as $cart_item ) { 1109 if ( $cart_item['product_id'] === $product_id ) { 1110 if ( $has_variations ) { 1111 // Skip this product entirely - we'll add the new variation 1112 continue; 1113 } else { 1114 // For non-variation products, if it exists, don't add it 1115 return; 1116 } 1117 } 1118 // Keep all other products 1119 $cart_items[] = $cart_item; 1120 } 1121 1122 // Add product and variation to cart. 1123 $cart_item = array( 1124 'product_id' => $product_id, 1125 'name' => $product->post_title, 1126 'price' => $price, 1127 'variation_name' => $variation_name, 1254 return null; // Invalid price 1255 } 1256 1257 return array( 1258 'product_id' => $product_id, 1259 'price' => $price, 1260 'variation_name' => $variation_name, 1261 'has_variations' => $has_variations, 1262 'subscription_data' => $subscription_data, 1128 1263 ); 1129 1130 // Add subscription data if subscription is enabled1131 if ( ! empty( $subscription_data['subscription_enabled'] ) ) {1132 $cart_item['subscription_enabled'] = $subscription_data['subscription_enabled'];1133 $cart_item['subscription_period'] = $subscription_data['subscription_period'];1134 $cart_item['subscription_free_trial'] = $subscription_data['subscription_free_trial'];1135 $cart_item['subscription_signup_fee'] = $subscription_data['subscription_signup_fee'];1136 1137 // Add PayPal plan flag if needed1138 if ( DigiCommerce()->is_paypal_enabled() ) {1139 $cart_item['needs_paypal_plan'] = true;1140 }1141 }1142 1143 $cart_items[] = $cart_item;1144 $session_data['cart'] = $cart_items;1145 1146 // Save updated session data.1147 $this->save_session( $session_key, $session_data );1148 $this->cart_items = $cart_items;1149 1264 } 1150 1265 … … 1377 1492 $payment_method = sanitize_text_field( $order_data['payment_method'] ?? '' ); 1378 1493 1494 // Validate PayPal cart if PayPal is selected 1495 if ( 'paypal' === $payment_method ) { 1496 try { 1497 $this->validate_paypal_cart( $this->cart_items ); 1498 } catch ( Exception $e ) { 1499 $this->send_paypal_error( $e->getMessage() ); 1500 return; 1501 } 1502 } 1503 1379 1504 // Add $wpdb to update database 1380 1505 global $wpdb; … … 1608 1733 throw $e; 1609 1734 } 1735 } 1736 1737 /** 1738 * Validate PayPal cart before processing 1739 * 1740 * @param array $cart_items Cart items to validate. 1741 */ 1742 private function validate_paypal_cart( $cart_items ) { 1743 $subscription_items = array(); 1744 $one_time_items = array(); 1745 1746 foreach ( $cart_items as $item ) { 1747 if ( ! empty( $item['subscription_enabled'] ) ) { 1748 $subscription_items[] = $item; 1749 } else { 1750 $one_time_items[] = $item; 1751 } 1752 } 1753 1754 // PayPal subscription limitations 1755 if ( ! empty( $subscription_items ) ) { 1756 // PayPal subscriptions require exactly one subscription product 1757 if ( count( $subscription_items ) > 1 ) { 1758 throw new Exception( esc_html__( 'PayPal does not support multiple subscription products in one transaction.', 'digicommerce' ) ); 1759 } 1760 1761 // PayPal subscriptions cannot be mixed with one-time products 1762 if ( ! empty( $one_time_items ) ) { 1763 throw new Exception( esc_html__( 'PayPal subscriptions cannot be combined with one-time products. Please checkout subscription and one-time products separately.', 'digicommerce' ) ); 1764 } 1765 } 1766 1767 return true; 1768 } 1769 1770 /** 1771 * Send properly formatted error response 1772 * 1773 * @param string $message Error message. 1774 * @param string|null $code Error code. 1775 */ 1776 private function send_paypal_error( $message, $code = null ) { 1777 wp_send_json_error( 1778 array( 1779 'message' => $message, 1780 'code' => $code, 1781 'type' => 'paypal_error' 1782 ) 1783 ); 1610 1784 } 1611 1785 -
digicommerce/trunk/includes/gateways/class-digicommerce-paypal.php
r3281979 r3310934 122 122 public function create_paypal_plan() { 123 123 try { 124 125 124 if ( ! check_ajax_referer( 'digicommerce_process_checkout', 'nonce', false ) ) { 126 125 throw new Exception( __( 'Security check failed', 'digicommerce' ) ); … … 136 135 } 137 136 138 // Find subscription item 139 $subscription_item = null; 137 // Find subscription items and one-time items 138 $subscription_items = array(); 139 $one_time_items = array(); 140 140 141 foreach ( $session_data['cart'] as $item ) { 141 142 if ( ! empty( $item['subscription_enabled'] ) ) { 142 $subscription_item = $item; 143 break; 143 $subscription_items[] = $item; 144 } else { 145 $one_time_items[] = $item; 144 146 } 145 147 } 146 148 147 if ( ! $subscription_item ) { 148 throw new Exception( esc_html__( 'No subscription product found', 'digicommerce' ) ); 149 } 149 // PayPal subscriptions only support one subscription product 150 if ( count( $subscription_items ) !== 1 ) { 151 throw new Exception( esc_html__( 'PayPal subscriptions require exactly one subscription product', 'digicommerce' ) ); 152 } 153 154 // We should not have one-time items with subscriptions for PayPal 155 if ( ! empty( $one_time_items ) ) { 156 throw new Exception( esc_html__( 'PayPal subscriptions cannot be mixed with one-time products', 'digicommerce' ) ); 157 } 158 159 $subscription_item = $subscription_items[0]; 150 160 151 161 // Get base price and VAT information … … 183 193 } 184 194 185 // Calculate subscription price (no discount , only VAT)195 // Calculate subscription price (no discount on recurring, only on first payment) 186 196 $subscription_vat_amount = $base_price * $vat_rate; 187 197 $subscription_price = $base_price + $subscription_vat_amount; … … 196 206 } 197 207 198 // Apply discount if exists 208 // Apply discount if exists (only to first payment) 199 209 $has_discount = false; 200 210 $final_subscription_price = $subscription_price; 211 $discounted_first_payment = $subscription_price; 201 212 202 213 if ( ! empty( $session_data['discount'] ) ) { … … 213 224 $final_signup_fee = $signup_fee_with_vat - $discount_amount; 214 225 } else { 215 // Apply discount to subscription priceif no signup fee226 // Apply discount to first subscription payment if no signup fee 216 227 if ( 'percentage' === $discount['type'] ) { 217 228 $discount_amount = ( $subscription_price * floatval( $discount['amount'] ) ) / 100; … … 219 230 $discount_amount = min( floatval( $discount['amount'] ), $subscription_price ); 220 231 } 221 $ final_subscription_price= $subscription_price - $discount_amount;232 $discounted_first_payment = $subscription_price - $discount_amount; 222 233 } 223 234 } 224 235 225 236 // Create PayPal plan 237 $plan_name = $subscription_item['name']; 238 if ( ! empty( $subscription_item['variation_name'] ) ) { 239 $plan_name .= " - {$subscription_item['variation_name']}"; 240 } 241 226 242 $plan_id = $this->create_plan( 227 243 $subscription_item['product_id'], 228 $ subscription_item['name'] . ( $subscription_item['variation_name'] ? " - {$subscription_item['variation_name']}" : '' ),229 $final_subscription_price, // Pass discountedsubscription price244 $plan_name, 245 $final_subscription_price, // Regular subscription price 230 246 array( 231 247 'subscription_enabled' => true, … … 235 251 'has_discount' => $has_discount, 236 252 'regular_price' => $subscription_price, 253 'discounted_first_payment' => $discounted_first_payment, 237 254 ) 238 255 ); … … 243 260 'has_signup_fee' => ( $signup_fee > 0 ), 244 261 'signup_fee_amount' => $final_signup_fee, 262 'has_discount' => $has_discount, 245 263 ) 246 264 ); … … 323 341 'fixed_price' => array( 324 342 'currency_code' => strtoupper( DigiCommerce()->get_option( 'currency', 'USD' ) ), 325 'value' => number_format( $ price, 2, '.', '' ), // Discounted price343 'value' => number_format( $subscription_data['discounted_first_payment'], 2, '.', '' ), // Discounted price 326 344 ), 327 345 ), -
digicommerce/trunk/includes/gateways/class-digicommerce-stripe.php
r3309447 r3310934 103 103 ); 104 104 105 // Calculate initial payment amount (signup fee or first payment) 106 $initial_payment = 0; 107 $has_subscription = false; 108 $has_free_trial = false; 109 $has_signup_fee = false; 110 111 // Track one-time products vs subscription products 105 // Calculate initial payment amount 106 $initial_payment = 0; 107 $has_subscription = false; 108 $has_free_trial = false; 109 $has_signup_fee = false; 110 $charge_subscription_upfront = false; 111 112 // Track products and their details 112 113 $one_time_products_total = 0; 113 114 $subscription_products_total = 0; 115 $subscription_items = array(); 114 116 115 117 foreach ( $cart_items as $item ) { 116 118 if ( ! empty( $item['subscription_enabled'] ) ) { 117 119 $has_subscription = true; 118 119 // If there's a signup fee, charge that as initial payment 120 $subscription_items[] = $item; 121 122 // Check for signup fee 120 123 if ( ! empty( $item['subscription_signup_fee'] ) && floatval( $item['subscription_signup_fee'] ) > 0 ) { 121 $has_signup_fee = true;124 $has_signup_fee = true; 122 125 $initial_payment += floatval( $item['subscription_signup_fee'] ); 123 } else { // phpcs:ignore 124 // If there's a free trial 125 if ( ! empty( $item['subscription_free_trial'] ) && 126 intval( $item['subscription_free_trial']['duration'] ) > 0 ) { 127 $has_free_trial = true; 128 } else { 129 $subscription_products_total += floatval( $item['price'] ); 130 } 126 } 127 128 // Check for free trial 129 if ( ! empty( $item['subscription_free_trial'] ) && 130 intval( $item['subscription_free_trial']['duration'] ) > 0 ) { 131 $has_free_trial = true; 132 } else { 133 // No free trial - charge subscription upfront 134 $subscription_products_total += floatval( $item['price'] ); 135 $charge_subscription_upfront = true; 131 136 } 132 137 } else { 133 // Add one-time product price138 // One-time product 134 139 $one_time_products_total += floatval( $item['price'] ); 135 140 } 136 141 } 137 142 138 // If we only have subscription products with no signup fee, don't do initial payment 139 // Otherwise, add one-time products to initial payment 140 if ( $one_time_products_total > 0 ) { 141 $initial_payment += $one_time_products_total; 143 // Calculate initial payment 144 $initial_payment += $one_time_products_total; 145 146 // For subscriptions without free trial, charge upfront 147 if ( $charge_subscription_upfront ) { 148 $initial_payment += $subscription_products_total; 142 149 } 143 150 … … 190 197 $total = $total_with_vat - $discount_amount; 191 198 192 // IMPORTANT: Create customer once and store it199 // Create or retrieve customer 193 200 $customer = null; 194 201 if ( ! empty( $stripe_payment_data['customer_id'] ) ) { … … 200 207 if ( ! $customer ) { 201 208 $customer = $this->get_or_create_customer( 202 [ // phpcs:ignore209 array( 203 210 'email' => $billing_data['email'], 204 211 'name' => trim( $billing_data['first_name'] . ' ' . $billing_data['last_name'] ), 205 212 'phone' => $billing_data['phone'], 206 'address' => [ // phpcs:ignore213 'address' => array( 207 214 'line1' => $billing_data['address'], 208 215 'city' => $billing_data['city'], … … 210 217 'state' => $billing_data['state'], 211 218 'country' => $billing_data['country'], 212 ],213 'metadata' => [ // phpcs:ignore219 ), 220 'metadata' => array( 214 221 'vat_number' => $billing_data['vat_number'], 215 222 'company' => $billing_data['company'], 216 'user_id' => get_current_user_id() ? : 'guest', // phpcs:ignore217 ],218 ]223 'user_id' => get_current_user_id() ? : 'guest', 224 ), 225 ) 219 226 ); 220 227 } 221 228 222 $response = [ // phpcs:ignore229 $response = array( 223 230 'success' => true, 224 'data' => [ // phpcs:ignore231 'data' => array( 225 232 'customerId' => $customer->id, 226 ],227 ];233 ), 234 ); 228 235 229 236 // Handle subscription creation if payment_method and setup_intent_id exist … … 235 242 $payment_method = \Stripe\PaymentMethod::retrieve( $stripe_payment_data['payment_method'] ); 236 243 if ( $payment_method->customer !== $customer->id ) { 237 $payment_method->attach( [ 'customer' => $customer->id ] ); // phpcs:ignore244 $payment_method->attach( array( 'customer' => $customer->id ) ); 238 245 } 239 246 … … 241 248 \Stripe\Customer::update( 242 249 $customer->id, 243 [ // phpcs:ignore244 'invoice_settings' => [ // phpcs:ignore250 array( 251 'invoice_settings' => array( 245 252 'default_payment_method' => $stripe_payment_data['payment_method'], 246 ],247 ]253 ), 254 ) 248 255 ); 249 256 … … 251 258 if ( $has_subscription ) { 252 259 // Create subscription parameters 253 $subscription_params = [ // phpcs:ignore260 $subscription_params = array( 254 261 'customer' => $customer->id, 255 262 'default_payment_method' => $stripe_payment_data['payment_method'], 256 263 'items' => $this->prepare_subscription_items( $cart_items, $billing_data ), 257 264 'metadata' => $this->prepare_metadata( $cart_items, $billing_data ), 258 'payment_settings' => [ // phpcs:ignore259 'payment_method_types' => [ 'card' ], // phpcs:ignore265 'payment_settings' => array( 266 'payment_method_types' => array( 'card' ), 260 267 'save_default_payment_method' => 'on_subscription', 261 ],268 ), 262 269 'collection_method' => 'charge_automatically', 263 ];264 265 // PREVENT DOUBLE CHARGING - Add discount handling270 ); 271 272 // Handle different subscription scenarios 266 273 if ( $has_free_trial ) { 267 // If there's a trial period specified in the product 268 foreach ( $cart_items as $item ) { 269 if ( ! empty( $item['subscription_enabled'] ) && 270 ! empty( $item['subscription_free_trial'] ) && 274 // Free trial - delay first payment 275 foreach ( $subscription_items as $item ) { 276 if ( ! empty( $item['subscription_free_trial'] ) && 271 277 ! empty( $item['subscription_free_trial']['duration'] ) ) { 272 278 $trial_days = $this->get_trial_period_days( $item['subscription_free_trial'] ); … … 277 283 } 278 284 } 279 } elseif ( $ has_signup_fee || $one_time_products_total > 0 ) {280 // If we're charging an initial payment (signup fee or one-time products),281 // delay the first subscription invoice by using billing cycle anchor282 $subscription_params['billing_cycle_anchor'] = strtotime( '+1 ' . $this->get_stripe_interval( $ item['subscription_period']) );285 } elseif ( $charge_subscription_upfront || $has_signup_fee || $one_time_products_total > 0 ) { 286 // We charged upfront - delay next subscription billing 287 $subscription_period = $subscription_items[0]['subscription_period'] ?? 'month'; 288 $subscription_params['billing_cycle_anchor'] = strtotime( '+1 ' . $this->get_stripe_interval( $subscription_period ) ); 283 289 $subscription_params['proration_behavior'] = 'none'; 284 } elseif ( $subscription_products_total > 0 && $initial_payment == 0 ) { // phpcs:ignore 285 // Only subscription products with no initial payment 286 // Use allow_incomplete so we can confirm the payment manually 290 } else { 291 // Pure subscription with no upfront payment 287 292 $subscription_params['payment_behavior'] = 'allow_incomplete'; 288 293 289 // Handle discount for subscription-only payments with no initial payment294 // Handle discount for subscription-only payments 290 295 if ( ! empty( $session_data['discount'] ) ) { 291 // Create a one-time coupon in Stripe292 296 $coupon = \Stripe\Coupon::create( 293 [ // phpcs:ignore297 array( 294 298 'duration' => 'once', 295 299 'currency' => strtolower( DigiCommerce()->get_option( 'currency', 'USD' ) ), 296 300 'name' => 'One-time discount (' . ( $session_data['discount']['code'] ?? 'custom' ) . ')', 297 // Determine if percentage or fixed amount298 301 'percentage' === $session_data['discount']['type'] 299 302 ? 'percent_off' : 'amount_off' => 'percentage' === $session_data['discount']['type'] 300 303 ? floatval( $session_data['discount']['amount'] ) 301 304 : $this->convert_to_cents( floatval( $session_data['discount']['amount'] ) ), 302 ]305 ) 303 306 ); 304 307 305 // Add discount to subscription using the discounts array parameter 306 $subscription_params['discounts'] = [ // phpcs:ignore 307 [ 'coupon' => $coupon->id ], // phpcs:ignore 308 ]; 308 $subscription_params['discounts'] = array( 309 array( 'coupon' => $coupon->id ), 310 ); 309 311 } 310 312 } … … 313 315 $subscription = \Stripe\Subscription::create( $subscription_params ); 314 316 315 // Check if subscription has a trial period or delayed billing317 // Handle subscription payment scenarios 316 318 if ( ! empty( $subscription_params['trial_period_days'] ) || 317 319 ! empty( $subscription_params['billing_cycle_anchor'] ) ) { 318 // No payment needed for trial subscriptions or when using billing_cycle_anchor320 // No immediate subscription payment needed 319 321 $response['data']['subscriptionId'] = $subscription->id; 320 322 wp_send_json_success( $response['data'] ); … … 324 326 // For immediate payment subscriptions, handle the invoice properly 325 327 if ( $subscription->latest_invoice ) { 326 // Retrieve the invoice327 328 $invoice = \Stripe\Invoice::retrieve( $subscription->latest_invoice ); 328 329 329 // Check if subscription has a pending payment330 330 if ( 'open' === $invoice->status ) { 331 // Retrieve the payment intent ID from the invoice332 // The latest Stripe API might provide it in different ways333 331 $payment_intent_id = null; 334 332 335 333 if ( isset( $invoice->payment_intent ) ) { 336 334 $payment_intent_id = $invoice->payment_intent; 337 } else if ( method_exists( $invoice, 'get' ) && $invoice->get( 'payment_intent' ) ) { 338 $payment_intent_id = $invoice->get( 'payment_intent' ); 335 } 336 337 if ( $payment_intent_id ) { 338 try { 339 $payment_intent = \Stripe\PaymentIntent::retrieve( $payment_intent_id ); 340 341 wp_send_json_success( 342 array( 343 'subscriptionId' => $subscription->id, 344 'requiresAction' => true, 345 'clientSecret' => $payment_intent->client_secret, 346 ) 347 ); 348 return; 349 } catch ( \Exception $e ) { 350 wp_send_json_error( array( 'message' => 'Error retrieving payment intent: ' . $e->getMessage() ) ); 351 return; 352 } 339 353 } else { 340 // If we can't get the payment intent, try to pay the invoice directly354 // Try to pay the invoice directly 341 355 try { 342 // Note: pay() is an instance method, not static343 356 $invoice = $invoice->pay(); 344 345 // If payment was successful, continue346 357 if ( 'paid' === $invoice->status ) { 347 358 $response['data']['subscriptionId'] = $subscription->id; … … 349 360 return; 350 361 } 351 } catch ( \Exception $e ) { // phpcs:ignore352 // If there's an error paying the invoice, continue to handle it below353 // by informing the client to perform the payment confirmation354 }355 }356 357 // If we have a payment intent ID, retrieve it and send the client secret358 if ( $payment_intent_id ) {359 try {360 $payment_intent = \Stripe\PaymentIntent::retrieve( $payment_intent_id );361 362 // Force the client to confirm the payment363 wp_send_json_success(364 [ // phpcs:ignore365 'subscriptionId' => $subscription->id,366 'requiresAction' => true,367 'clientSecret' => $payment_intent->client_secret,368 ]369 );370 return;371 362 } catch ( \Exception $e ) { 372 wp_send_json_error( [ 'message' => 'Error retrieving payment intent: ' . $e->getMessage() ] ); // phpcs:ignore363 wp_send_json_error( array( 'message' => 'Error paying invoice: ' . $e->getMessage() ) ); 373 364 return; 374 365 } … … 377 368 } 378 369 379 // If we reach here, no special handling was needed380 370 $response['data']['subscriptionId'] = $subscription->id; 381 371 } … … 384 374 385 375 } catch ( \Stripe\Exception\CardException $e ) { 386 wp_send_json_error( [ 'message' => $e->getMessage() ] ); // phpcs:ignore376 wp_send_json_error( array( 'message' => $e->getMessage() ) ); 387 377 } catch ( Exception $e ) { 388 wp_send_json_error( [ 'message' => $e->getMessage() ] ); // phpcs:ignore378 wp_send_json_error( array( 'message' => $e->getMessage() ) ); 389 379 } 390 380 } else { 381 // Initial request - create SetupIntent and/or PaymentIntent 382 391 383 // For subscriptions, always create SetupIntent 392 384 if ( $has_subscription ) { 393 385 $setup_intent = \Stripe\SetupIntent::create( 394 [ // phpcs:ignore386 array( 395 387 'customer' => $customer->id, 396 'payment_method_types' => ['card'], // phpcs:ignore388 'payment_method_types' => array( 'card' ), 397 389 'usage' => 'off_session', 398 390 'metadata' => $this->prepare_metadata( $cart_items, $billing_data ), 399 ]391 ) 400 392 ); 401 393 402 $response['data']['setupIntent'] = [ // phpcs:ignore394 $response['data']['setupIntent'] = array( 403 395 'client_secret' => $setup_intent->client_secret, 404 396 'id' => $setup_intent->id, 405 ];397 ); 406 398 } 407 399 … … 409 401 if ( $total > 0 ) { 410 402 $payment_intent = \Stripe\PaymentIntent::create( 411 [ // phpcs:ignore403 array( 412 404 'amount' => $this->convert_to_cents( $total ), 413 405 'currency' => strtolower( DigiCommerce()->get_option( 'currency', 'USD' ) ), 414 406 'customer' => $customer->id, 415 407 'setup_future_usage' => $has_subscription ? 'off_session' : null, 416 'payment_method_types' => ['card'], // phpcs:ignore408 'payment_method_types' => array( 'card' ), 417 409 'metadata' => array_merge( 418 410 $this->prepare_metadata( $cart_items, $billing_data ), 419 [ // phpcs:ignore411 array( 420 412 'subtotal' => $subtotal, 421 413 'vat_amount' => $vat_amount, … … 424 416 'discount_amount' => $discount_amount, 425 417 'total' => $total, 426 ]418 ) 427 419 ), 428 420 'description' => $this->get_payment_description( $cart_items ), 429 ]421 ) 430 422 ); 431 423 432 $response['data']['paymentIntent'] = [ // phpcs:ignore424 $response['data']['paymentIntent'] = array( 433 425 'client_secret' => $payment_intent->client_secret, 434 426 'id' => $payment_intent->id, 435 'requiresAction' => in_array( $payment_intent->status, [ 'requires_action', 'requires_confirmation', 'requires_capture' ] ), // phpcs:ignore436 ];427 'requiresAction' => in_array( $payment_intent->status, array( 'requires_action', 'requires_confirmation', 'requires_capture' ) ), 428 ); 437 429 } 438 430 } … … 441 433 442 434 } catch ( Exception $e ) { 443 wp_send_json_error( [ 'message' => $e->getMessage() ] ); // phpcs:ignore435 wp_send_json_error( array( 'message' => $e->getMessage() ) ); 444 436 } 445 437 } -
digicommerce/trunk/readme.txt
r3309447 r3310934 301 301 * Fixed: Product not selectable for the Bundle Products metabox. 302 302 * Fixed: Product downloads was running without extensions. 303 * Fixed: Account URL wasn't added on account page. 303 304 304 305 = 1.0.1 - June 08, 2025 = -
digicommerce/trunk/resources/js/front/checkout.js
r3309447 r3310934 289 289 // Initialize PayPal if enabled 290 290 if (digicommerceVars.paypalEnabled) { 291 const cartItems = JSON.parse(digicommerceVars.cartItems || '[]'); 292 293 // Check if any item is a subscription 294 const hasSubscription = cartItems.some(item => item.subscription_enabled); 295 const subscriptionItem = hasSubscription ? cartItems.find(item => item.subscription_enabled) : null; 296 297 // PayPal button configuration 298 const paypalConfig = { 299 fundingSource: paypal.FUNDING.PAYPAL, 300 style: { 301 layout: 'vertical', 302 shape: 'rect', 303 label: hasSubscription ? 'subscribe' : 'pay' 304 } 305 }; 306 307 if (hasSubscription) { 308 // Handle subscription flow 309 paypalConfig.createSubscription = async (data, actions) => { 310 try { 311 if (!checkoutForm) throw new Error('Checkout form not found'); 312 313 const formData = new FormData(checkoutForm); 314 DigiUI.toggleLoading(document.getElementById('loading-overlay'), true); 315 316 // First, create the PayPal plan with current pricing 317 const planResponse = await fetch(digicommerceVars.ajaxurl, { 318 method: 'POST', 319 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 320 body: new URLSearchParams({ 321 action: 'digicommerce_create_paypal_plan', 322 nonce: formData.get('checkout_nonce'), 323 first_name: formData.get('billing_first_name'), 324 last_name: formData.get('billing_last_name'), 325 email: formData.get('billing_email'), 326 country: formData.get('billing_country'), 327 vat_number: formData.get('billing_vat_number'), 328 }) 329 }); 330 331 const planResult = await planResponse.json(); 332 333 if (!planResult.success || !planResult.data.plan_id) { 334 throw new Error(planResult.data?.message || 'Failed to create PayPal plan'); 335 } 336 337 // Create subscription configuration 338 const subscriptionConfig = { 339 plan_id: planResult.data.plan_id, 340 application_context: { 341 shipping_preference: 'NO_SHIPPING' 342 }, 343 subscriber: { 344 name: { 345 given_name: formData.get('billing_first_name'), 346 surname: formData.get('billing_last_name') 347 }, 348 email_address: formData.get('billing_email') 349 } 350 }; 351 352 // Create the subscription 353 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 354 return await actions.subscription.create(subscriptionConfig); 355 356 } catch (error) { 357 console.error('Subscription creation error:', error); 358 DigiUI.showMessage(document.getElementById('checkout-message'), error.message); 359 throw error; 360 } 361 }; 362 } else { 363 // Handle one-time payment flow 364 paypalConfig.createOrder = async (data, actions) => { 291 const cartItems = JSON.parse(digicommerceVars.cartItems || '[]'); 292 293 // Check if any item is a subscription 294 const hasSubscription = cartItems.some(item => item.subscription_enabled); 295 const subscriptionItems = cartItems.filter(item => item.subscription_enabled); 296 const oneTimeItems = cartItems.filter(item => !item.subscription_enabled); 297 298 // Check if PayPal can handle this cart 299 const paypalCanHandleCart = hasSubscription ? 300 (subscriptionItems.length === 1 && oneTimeItems.length === 0) : 301 true; // PayPal can handle all one-time products 302 303 // PayPal button configuration 304 const paypalConfig = { 305 fundingSource: paypal.FUNDING.PAYPAL, 306 style: { 307 layout: 'vertical', 308 shape: 'rect', 309 label: hasSubscription ? 'subscribe' : 'pay' 310 } 311 }; 312 313 if (hasSubscription && paypalCanHandleCart) { 314 // Handle subscription flow - only if PayPal can handle it 315 paypalConfig.createSubscription = async (data, actions) => { 365 316 try { 366 if (!checkoutForm) throw new Error('Checkout form not found'); 367 317 if (!checkoutForm) { 318 throw new Error(digicommerceVars.i18n.checkout_form_not_found); 319 } 320 368 321 const formData = new FormData(checkoutForm); 369 370 // Calculate subtotal first 371 const subtotal = cartItems.reduce((sum, item) => sum + parseFloat(item.price), 0); 372 373 // Calculate discount on subtotal first (moved this up) 374 let discountAmount = 0; 375 if (digicommerceVars.cartDiscount) { 376 const discount = JSON.parse(digicommerceVars.cartDiscount); 377 if (discount.type === 'percentage') { 378 discountAmount = (subtotal * discount.amount) / 100; 379 } else { 380 discountAmount = Math.min(discount.amount, subtotal); 381 } 322 DigiUI.toggleLoading(document.getElementById('loading-overlay'), true); 323 324 // Create the PayPal plan with current pricing 325 const planResponse = await fetch(digicommerceVars.ajaxurl, { 326 method: 'POST', 327 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 328 body: new URLSearchParams({ 329 action: 'digicommerce_create_paypal_plan', 330 nonce: formData.get('checkout_nonce'), 331 first_name: formData.get('billing_first_name'), 332 last_name: formData.get('billing_last_name'), 333 email: formData.get('billing_email'), 334 country: formData.get('billing_country'), 335 vat_number: formData.get('billing_vat_number'), 336 }) 337 }); 338 339 const planResult = await planResponse.json(); 340 341 if (!planResult.success) { 342 const errorMessage = planResult.data?.message || digicommerceVars.i18n.paypal_plan_creation_failed; 343 throw new Error(errorMessage); 382 344 } 383 345 384 // Calculate discounted subtotal 385 const discountedSubtotal = subtotal - discountAmount; 346 if (!planResult.data.plan_id) { 347 throw new Error(digicommerceVars.i18n.paypal_plan_creation_failed); 348 } 349 350 // Create subscription configuration 351 const subscriptionConfig = { 352 plan_id: planResult.data.plan_id, 353 application_context: { 354 shipping_preference: 'NO_SHIPPING' 355 }, 356 subscriber: { 357 name: { 358 given_name: formData.get('billing_first_name'), 359 surname: formData.get('billing_last_name') 360 }, 361 email_address: formData.get('billing_email') 362 } 363 }; 386 364 387 // Get VAT rate based on country and VAT number 388 const buyerCountry = formData.get('billing_country'); 389 const sellerCountry = digicommerceVars.businessCountry; 390 const vatNumber = formData.get('billing_vat_number'); 391 let vatRate = 0; 392 393 const countries = digicommerceVars.countries || {}; 394 395 // Check if taxes are enabled 396 if (!digicommerceVars.removeTaxes) { 397 if (buyerCountry === sellerCountry) { 398 // Domestic sale: Always charge seller's country VAT 399 vatRate = countries[sellerCountry]?.tax_rate || 0; 400 } else if (countries[buyerCountry]?.eu && countries[sellerCountry]?.eu) { 401 // EU cross-border sale 402 if (!vatNumber || !window.vatCalculator?.validateVATNumber(vatNumber, buyerCountry)) { 403 // No valid VAT number - charge buyer's country rate 404 vatRate = countries[buyerCountry]?.tax_rate || 0; 405 } 406 // With valid VAT number - no VAT (vatRate remains 0) 407 } 408 // Non-EU sale - no VAT (vatRate remains 0) 409 } 410 411 // Calculate VAT on discounted subtotal (key change here) 412 const vatAmount = discountedSubtotal * vatRate; 413 414 // Calculate final total 415 const finalTotal = discountedSubtotal + vatAmount; 416 417 // Create PayPal order 418 return actions.order.create({ 419 purchase_units: [{ 420 amount: { 421 currency_code: digicommerceVars.currency, 422 value: finalTotal.toFixed(2), 423 breakdown: { 424 item_total: { 425 currency_code: digicommerceVars.currency, 426 value: subtotal.toFixed(2) 427 }, 428 tax_total: vatAmount > 0 ? { 429 currency_code: digicommerceVars.currency, 430 value: vatAmount.toFixed(2) 431 } : undefined, 432 discount: discountAmount > 0 ? { 433 currency_code: digicommerceVars.currency, 434 value: discountAmount.toFixed(2) 435 } : undefined 436 } 437 }, 438 items: cartItems.map(item => ({ 439 name: item.name, 440 unit_amount: { 441 currency_code: digicommerceVars.currency, 442 value: item.price.toFixed(2) 443 }, 444 quantity: 1 445 })) 446 }] 447 }); 365 // Create the subscription 366 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 367 return await actions.subscription.create(subscriptionConfig); 368 448 369 } catch (error) { 449 console.error('Order creation error:', error); 370 console.error('Subscription creation error:', error); 371 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 450 372 DigiUI.showMessage(document.getElementById('checkout-message'), error.message); 451 373 throw error; 452 374 } 453 375 }; 454 } 455 456 // Common handlers for all payment types 457 paypalConfig.onApprove = async (data, actions) => { 458 try { 459 // First, capture the PayPal order 460 let captureResult; 461 462 if (data.orderID && !data.subscriptionID) { // Only capture for one-time payments 463 captureResult = await actions.order.capture(); 464 } 465 466 const formData = new FormData(checkoutForm); 467 const messageEl = document.getElementById('checkout-message'); 468 469 DigiUI.toggleLoading(document.getElementById('loading-overlay'), true); 470 471 const checkoutData = new URLSearchParams({ 472 action: 'digicommerce_process_checkout', 473 checkout_nonce: formData.get('checkout_nonce'), 474 payment_method: 'paypal', 475 paypal_order_id: data.orderID, 476 paypal_subscription_id: data.subscriptionID, 477 email: formData.get('billing_email'), 478 first_name: formData.get('billing_first_name'), 479 last_name: formData.get('billing_last_name'), 480 company: formData.get('billing_company'), 481 country: formData.get('billing_country'), 482 address: formData.get('billing_address'), 483 city: formData.get('billing_city'), 484 postcode: formData.get('billing_postcode'), 485 state: formData.get('billing_state'), 486 phone: formData.get('billing_phone'), 487 vat_number: formData.get('billing_vat_number'), 488 }); 489 490 // Add mailing list subscription status if the checkbox exists 491 const mailingListCheckbox = document.getElementById('subscribe_mailing_list'); 492 if (mailingListCheckbox) { 493 checkoutData.append('subscribe_mailing_list', mailingListCheckbox.checked ? '1' : '0'); 494 } 495 376 } else { 377 // Handle one-time payment flow (or mixed cart that PayPal will treat as one-time) 378 paypalConfig.createOrder = createOneTimeOrder; 379 } 380 381 // Common one-time order creation function 382 async function createOneTimeOrder(data, actions) { 383 try { 384 if (!checkoutForm) { 385 throw new Error(digicommerceVars.i18n.checkout_form_not_found); 386 } 387 388 const formData = new FormData(checkoutForm); 389 390 // Calculate totals properly for multiple products 391 const subtotal = cartItems.reduce((sum, item) => sum + parseFloat(item.price), 0); 392 393 // Calculate discount on subtotal first 394 let discountAmount = 0; 395 if (digicommerceVars.cartDiscount) { 396 const discount = JSON.parse(digicommerceVars.cartDiscount); 397 if (discount.type === 'percentage') { 398 discountAmount = (subtotal * discount.amount) / 100; 399 } else { 400 discountAmount = Math.min(discount.amount, subtotal); 401 } 402 } 403 404 // Calculate discounted subtotal 405 const discountedSubtotal = subtotal - discountAmount; 406 407 // Get VAT rate based on country and VAT number 408 const buyerCountry = formData.get('billing_country'); 409 const sellerCountry = digicommerceVars.businessCountry; 410 const vatNumber = formData.get('billing_vat_number'); 411 let vatRate = 0; 412 413 const countries = digicommerceVars.countries || {}; 414 415 // Check if taxes are enabled 416 if (!digicommerceVars.removeTaxes) { 417 if (buyerCountry === sellerCountry) { 418 // Domestic sale: Always charge seller's country VAT 419 vatRate = countries[sellerCountry]?.tax_rate || 0; 420 } else if (countries[buyerCountry]?.eu && countries[sellerCountry]?.eu) { 421 // EU cross-border sale 422 if (!vatNumber || !window.vatCalculator?.validateVATNumber(vatNumber, buyerCountry)) { 423 // No valid VAT number - charge buyer's country rate 424 vatRate = countries[buyerCountry]?.tax_rate || 0; 425 } 426 // With valid VAT number - no VAT (vatRate remains 0) 427 } 428 // Non-EU sale - no VAT (vatRate remains 0) 429 } 430 431 // Calculate VAT on discounted subtotal 432 const vatAmount = discountedSubtotal * vatRate; 433 434 // Calculate final total 435 const finalTotal = discountedSubtotal + vatAmount; 436 437 // Validate totals 438 if (finalTotal <= 0) { 439 throw new Error(digicommerceVars.i18n.invalid_order_total); 440 } 441 442 // Create PayPal order with proper breakdown 443 const orderConfig = { 444 purchase_units: [{ 445 amount: { 446 currency_code: digicommerceVars.currency, 447 value: finalTotal.toFixed(2), 448 breakdown: { 449 item_total: { 450 currency_code: digicommerceVars.currency, 451 value: subtotal.toFixed(2) 452 } 453 } 454 }, 455 items: cartItems.map(item => ({ 456 name: item.name + (item.variation_name ? ` (${item.variation_name})` : ''), 457 unit_amount: { 458 currency_code: digicommerceVars.currency, 459 value: parseFloat(item.price).toFixed(2) 460 }, 461 quantity: 1, 462 category: 'DIGITAL_GOODS' 463 })) 464 }] 465 }; 466 467 // Add VAT to breakdown if applicable 468 if (vatAmount > 0) { 469 orderConfig.purchase_units[0].amount.breakdown.tax_total = { 470 currency_code: digicommerceVars.currency, 471 value: vatAmount.toFixed(2) 472 }; 473 } 474 475 // Add discount to breakdown if applicable 476 if (discountAmount > 0) { 477 orderConfig.purchase_units[0].amount.breakdown.discount = { 478 currency_code: digicommerceVars.currency, 479 value: discountAmount.toFixed(2) 480 }; 481 } 482 483 return actions.order.create(orderConfig); 484 } catch (error) { 485 console.error('Order creation error:', error); 486 DigiUI.showMessage(document.getElementById('checkout-message'), error.message); 487 throw error; 488 } 489 } 490 491 // Common handlers for all payment types 492 paypalConfig.onApprove = async (data, actions) => { 493 try { 494 // First, capture the PayPal order if it's a one-time payment 495 let captureResult; 496 497 if (data.orderID && !data.subscriptionID) { 498 captureResult = await actions.order.capture(); 499 } 500 501 const formData = new FormData(checkoutForm); 502 const messageEl = document.getElementById('checkout-message'); 503 504 DigiUI.toggleLoading(document.getElementById('loading-overlay'), true); 505 506 const checkoutData = new URLSearchParams({ 507 action: 'digicommerce_process_checkout', 508 checkout_nonce: formData.get('checkout_nonce'), 509 payment_method: 'paypal', 510 paypal_order_id: data.orderID, 511 paypal_subscription_id: data.subscriptionID, 512 email: formData.get('billing_email'), 513 first_name: formData.get('billing_first_name'), 514 last_name: formData.get('billing_last_name'), 515 company: formData.get('billing_company'), 516 country: formData.get('billing_country'), 517 address: formData.get('billing_address'), 518 city: formData.get('billing_city'), 519 postcode: formData.get('billing_postcode'), 520 state: formData.get('billing_state'), 521 phone: formData.get('billing_phone'), 522 vat_number: formData.get('billing_vat_number'), 523 }); 524 525 // Add mailing list subscription status if the checkbox exists 526 const mailingListCheckbox = document.getElementById('subscribe_mailing_list'); 527 if (mailingListCheckbox) { 528 checkoutData.append('subscribe_mailing_list', mailingListCheckbox.checked ? '1' : '0'); 529 } 530 496 531 // Add abandoned cart params from URL if they exist 497 532 if (urlParams.get('from_abandoned') === '1') { … … 501 536 } 502 537 } 503 504 // Process checkout with PayPal data 505 const response = await fetch(digicommerceVars.ajaxurl, { 506 method: 'POST', 507 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 508 body: checkoutData 509 }); 510 511 const result = await response.json(); 512 513 if (result.success && result.data.redirect) { 514 DigiUI.showMessage(messageEl, digicommerceVars.i18n.success, false); 515 516 if (result.data.order_id) { 517 localStorage.setItem('last_order_id', result.data.order_id); 518 } 519 520 setTimeout(() => { 521 window.location.href = result.data.redirect; 522 }, 1500); 523 } else { 524 throw new Error(result.data?.message || 'Payment processing failed'); 525 } 526 527 } catch (error) { 528 console.error('PayPal payment processing error:', error); 529 DigiUI.showMessage(document.getElementById('checkout-message'), error.message); 530 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 531 } 532 }; 533 534 paypalConfig.onError = (err) => { 535 console.error('PayPal error:', err); 536 DigiUI.showMessage(document.getElementById('checkout-message'), 'PayPal payment failed'); 537 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 538 }; 539 540 paypalConfig.onCancel = () => { 541 DigiUI.showMessage(document.getElementById('checkout-message'), 'Payment cancelled'); 542 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 543 }; 544 545 // Render PayPal buttons 546 paypal.Buttons(paypalConfig).render('#paypal-button-container'); 547 } 538 539 // Process checkout with PayPal data 540 const response = await fetch(digicommerceVars.ajaxurl, { 541 method: 'POST', 542 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 543 body: checkoutData 544 }); 545 546 const result = await response.json(); 547 548 if (result.success && result.data.redirect) { 549 DigiUI.showMessage(messageEl, digicommerceVars.i18n.success, false); 550 551 if (result.data.order_id) { 552 localStorage.setItem('last_order_id', result.data.order_id); 553 } 554 555 setTimeout(() => { 556 window.location.href = result.data.redirect; 557 }, 1500); 558 } else { 559 const errorMessage = result.data?.message || digicommerceVars.i18n.paypal_processing_failed; 560 throw new Error(errorMessage); 561 } 562 563 } catch (error) { 564 console.error('PayPal payment processing error:', error); 565 const errorMessage = error.message || digicommerceVars.i18n.paypal_processing_failed; 566 DigiUI.showMessage(document.getElementById('checkout-message'), errorMessage); 567 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 568 } 569 }; 570 571 paypalConfig.onError = (err) => { 572 console.error('PayPal error:', err); 573 const errorMessage = err?.message || digicommerceVars.i18n.paypal_failed; 574 DigiUI.showMessage(document.getElementById('checkout-message'), errorMessage); 575 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 576 }; 577 578 paypalConfig.onCancel = () => { 579 DigiUI.showMessage(document.getElementById('checkout-message'), digicommerceVars.i18n.paypal_cancelled); 580 DigiUI.toggleLoading(document.getElementById('loading-overlay'), false); 581 }; 582 583 // Always render PayPal buttons - let backend validation handle unsupported scenarios 584 paypal.Buttons(paypalConfig).render('#paypal-button-container'); 585 586 // Add payment method change handler to show PayPal limitations when PayPal is selected 587 const paypalRadio = document.getElementById('payment_method_paypal'); 588 if (paypalRadio) { 589 paypalRadio.addEventListener('change', function() { 590 if (this.checked && !paypalCanHandleCart) { 591 const messageEl = document.getElementById('checkout-message'); 592 const errorMessage = subscriptionItems.length > 1 593 ? digicommerceVars.i18n.multiple_subscriptions_error 594 : digicommerceVars.i18n.mixed_cart_error; 595 596 DigiUI.showMessage(messageEl, errorMessage); 597 } 598 }); 599 } 600 601 // Clear error message when switching to Stripe 602 const stripeRadio = document.getElementById('payment_method_stripe'); 603 if (stripeRadio) { 604 stripeRadio.addEventListener('change', function() { 605 if (this.checked) { 606 const messageEl = document.getElementById('checkout-message'); 607 messageEl.classList.add('hidden'); 608 } 609 }); 610 } 611 } 548 612 } 549 613 -
digicommerce/trunk/resources/js/front/delete-button.js
r3308154 r3310934 10 10 } 11 11 }); 12 13 // Function to check if PayPal is the selected payment method 14 function isPayPalSelected() { 15 const paypalRadio = document.getElementById('payment_method_paypal'); 16 return paypalRadio && paypalRadio.checked; 17 } 12 18 13 19 const removeButtons = document.querySelectorAll('.remove-item-btn'); … … 35 41 36 42 if (result.success && result.data) { 43 // If PayPal is selected, reload page with clean URL after successful deletion 44 if (isPayPalSelected()) { 45 window.location.href = window.location.pathname; 46 return; 47 } 48 49 // Continue with existing Stripe logic 37 50 // Remove the cart item from DOM 38 51 const parentElement = this.closest('.cart-item');
Note: See TracChangeset
for help on using the changeset viewer.