TDZ Whop Checkout Embed Codes
All 18 checkout embeds + Cloudflare worker. Click to view, copy to clipboard.
IT-DISC-PIF
<!-- IT - DISC - PIF | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_bLnPWarPS0N8T"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $24,000.00 USD today for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Disc-PIF" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Disc-PIF" target="_blank">https://drzfma.com/Terms-InnerTable-Disc-PIF</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_bLnPWarPS0N8T';
var CHECKOUT_NAME = 'IT - DISC - PIF';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Disc-PIF',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - DISC - PIF checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-EVENT-2PAY
<!-- IT - EVENT - 2PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_9JPOxSkp7c33h"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $12,500.00 today, followed by one (1) payment of $12,500.00 after 30 days for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Event-2Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Event-2Pay" target="_blank">https://drzfma.com/Terms-InnerTable-Event-2Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_9JPOxSkp7c33h';
var CHECKOUT_NAME = 'IT - EVENT - 2PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Event-2Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - EVENT - 2PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-EVENT-3PAY
<!-- IT - EVENT - 3PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_qD9YZawhhTQy8"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $8,500.00 today, followed by two (2) monthly payments of $8,500.00 each for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Event-3Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Event-3Pay" target="_blank">https://drzfma.com/Terms-InnerTable-Event-3Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_qD9YZawhhTQy8';
var CHECKOUT_NAME = 'IT - EVENT - 3PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Event-3Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - EVENT - 3PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-EVENT-4PAY
<!-- IT - EVENT - 4PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_WKGFivREGKoQ3"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $6,500.00 today, followed by three (3) monthly payments of $6,500.00 each for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Event-4Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Event-4Pay" target="_blank">https://drzfma.com/Terms-InnerTable-Event-4Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_WKGFivREGKoQ3';
var CHECKOUT_NAME = 'IT - EVENT - 4PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Event-4Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - EVENT - 4PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-EVENT-PIF
<!-- IT - EVENT - PIF | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_bLnPWarPS0N8T"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $24,000.00 USD today for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Event-PIF" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Event-PIF" target="_blank">https://drzfma.com/Terms-InnerTable-Event-PIF</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_bLnPWarPS0N8T';
var CHECKOUT_NAME = 'IT - EVENT - PIF';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Event-PIF',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - EVENT - PIF checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-REG-2PAY
<!-- IT - REG - 2PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_HsnrT34J2HZb5"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $13,000.00 today, followed by one (1) payment of $13,000.00 after 30 days for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Reg-2Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Reg-2Pay" target="_blank">https://drzfma.com/Terms-InnerTable-Reg-2Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_HsnrT34J2HZb5';
var CHECKOUT_NAME = 'IT - REG - 2PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Reg-2Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - REG - 2PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-REG-3PAY
<!-- IT - REG - 3PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_yb0CloXCI5WOS"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $8,800.00 today, followed by two (2) monthly payments of $8,800.00 each for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Reg-3Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Reg-3Pay" target="_blank">https://drzfma.com/Terms-InnerTable-Reg-3Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_yb0CloXCI5WOS';
var CHECKOUT_NAME = 'IT - REG - 3PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Reg-3Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - REG - 3PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-REG-4PAY
<!-- IT - REG - 4PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_GfHA0LbmgwtzK"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $6,750.00 today, followed by three (3) monthly payments of $6,750.00 each for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Reg-4Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Reg-4Pay" target="_blank">https://drzfma.com/Terms-InnerTable-Reg-4Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_GfHA0LbmgwtzK';
var CHECKOUT_NAME = 'IT - REG - 4PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Reg-4Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - REG - 4PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
IT-REG-PIF
<!-- IT - REG - PIF | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_01ZquFQRCiWKy"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<!-- BUG 2 FIX: button starts disabled, enabled when checkout state = ready -->
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $25,000.00 USD today for the Inner Table, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-InnerTable-Reg-PIF" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-InnerTable-Reg-PIF" target="_blank">https://drzfma.com/Terms-InnerTable-Reg-PIF</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_01ZquFQRCiWKy';
var CHECKOUT_NAME = 'IT - REG - PIF';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-InnerTable-Reg-PIF',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('IT - REG - PIF checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-DISC-2PAY
<!-- TM 3.0 - DISC - 2PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_b3os76a8dMHEX"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $3,900.00 today, followed by one (1) payment of $3,900.00 after 30 days for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Disc-2Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Disc-2Pay" target="_blank">https://drzfma.com/Terms-Mentorship-Disc-2Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_b3os76a8dMHEX';
var CHECKOUT_NAME = 'TM 3.0 - DISC - 2PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Disc-2Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - DISC - 2PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-DISC-PIF
<!-- TM 3.0 - DISC - PIF | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_cOpaIgjW4UCUi"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $7,800.00 USD today for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Disc-PIF" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Disc-PIF" target="_blank">https://drzfma.com/Terms-Mentorship-Disc-PIF</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_cOpaIgjW4UCUi';
var CHECKOUT_NAME = 'TM 3.0 - DISC - PIF';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Disc-PIF',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - DISC - PIF checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-EVENT-2PAY
<!-- TM 3.0 - EVENT - 2PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_tarApr1am7t2j"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $4,200.00 today, followed by one (1) payment of $4,200.00 after 30 days for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Event-2Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Event-2Pay" target="_blank">https://drzfma.com/Terms-Mentorship-Event-2Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_tarApr1am7t2j';
var CHECKOUT_NAME = 'TM 3.0 - EVENT - 2PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Event-2Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - EVENT - 2PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-EVENT-3PAY
<!-- TM 3.0 - EVENT - 3PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_C1o7ogmwuqQ81"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $2,933.33 today, followed by two (2) monthly payments of $2,933.33 each for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Event-3Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Event-3Pay" target="_blank">https://drzfma.com/Terms-Mentorship-Event-3Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_C1o7ogmwuqQ81';
var CHECKOUT_NAME = 'TM 3.0 - EVENT - 3PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Event-3Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - EVENT - 3PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-EVENT-4PAY
<!-- TM 3.0 - EVENT - 4PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_3uLXBTOyLbbcE"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $2,300.00 today, followed by three (3) monthly payments of $2,300.00 each for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Event-4Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Event-4Pay" target="_blank">https://drzfma.com/Terms-Mentorship-Event-4Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_3uLXBTOyLbbcE';
var CHECKOUT_NAME = 'TM 3.0 - EVENT - 4PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Event-4Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - EVENT - 4PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-EVENT-PIF
<!-- TM 3.0 - EVENT - PIF | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_cOpaIgjW4UCUi"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $7,800.00 USD today for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Event-PIF" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Event-PIF" target="_blank">https://drzfma.com/Terms-Mentorship-Event-PIF</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_cOpaIgjW4UCUi';
var CHECKOUT_NAME = 'TM 3.0 - EVENT - PIF';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Event-PIF',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - EVENT - PIF checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-REG-2PAY
<!-- TM 3.0 - REG - 2PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_5KdBfCN0bjutS"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $4,400.00 today, followed by one (1) payment of $4,400.00 after 30 days for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Reg-2Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Reg-2Pay" target="_blank">https://drzfma.com/Terms-Mentorship-Reg-2Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_5KdBfCN0bjutS';
var CHECKOUT_NAME = 'TM 3.0 - REG - 2PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Reg-2Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - REG - 2PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-REG-3PAY
<!-- TM 3.0 - REG - 3PAY | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_6rAONsB6bmd5B"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $3,135.00 today, followed by two (2) monthly payments of $3,135.00 each for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Reg-3Pay" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Reg-3Pay" target="_blank">https://drzfma.com/Terms-Mentorship-Reg-3Pay</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_6rAONsB6bmd5B';
var CHECKOUT_NAME = 'TM 3.0 - REG - 3PAY';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Reg-3Pay',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - REG - 3PAY checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
TM-3.0-REG-PIF
<!-- TM 3.0 - REG - PIF | Whop Checkout Embed with Terms -->
<style>
.terms-section {
margin: 16px 0 0 0;
}
.checkbox-group {
margin-bottom: 14px;
display: flex;
align-items: flex-start;
}
.checkbox-group input[type="checkbox"] {
margin-right: 12px;
margin-top: 4px;
min-width: 20px;
min-height: 20px;
cursor: pointer;
accent-color: #0a7e91;
}
.checkbox-group label {
cursor: pointer;
font-size: 14px;
line-height: 1.6;
color: #4b5563;
}
.checkbox-group a {
text-decoration: none;
color: #0a7e91;
}
.checkbox-group a:hover {
text-decoration: underline;
}
.terms-links {
margin-top: 12px;
padding-left: 32px;
font-size: 13px;
line-height: 1.8;
color: #6b7280;
}
.terms-links a {
color: #0a7e91;
text-decoration: none;
}
.terms-links a:hover {
text-decoration: underline;
}
.terms-links ul {
list-style: disc;
padding-left: 18px;
margin: 6px 0 0 0;
}
.terms-links li {
margin-bottom: 2px;
}
.terms-credit {
margin-top: 14px;
padding-left: 32px;
font-size: 12px;
color: #9ca3af;
line-height: 1.5;
}
.button-container {
margin-top: 20px;
}
#custom-submit-btn {
width: 100%;
padding: 18px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#custom-submit-btn .button-title {
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
}
#custom-submit-btn:hover:not(:disabled) {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
}
#custom-submit-btn:disabled {
background-color: #cccccc !important;
cursor: not-allowed;
transform: none;
}
.error-message {
color: #d32f2f;
text-align: center;
margin-top: 10px;
font-size: 14px;
display: none;
}
.success-message {
color: #059669;
background: #d1fae5;
padding: 12px;
border-radius: 6px;
margin-top: 12px;
font-size: 14px;
text-align: center;
display: none;
}
</style>
<!-- BUG 1 FIX: data-whop-checkout-on-state-change for proper state tracking -->
<!-- BUG 4 FIX: data-whop-checkout-return-url set dynamically in JS below -->
<script>
window.tdzCheckoutState = 'loading';
window.tdzOnCheckoutStateChange = function(state) {
console.log('Checkout state:', state);
window.tdzCheckoutState = state;
var btn = document.getElementById('custom-submit-btn');
if (!btn) return;
if (state === 'ready') {
// Only enable if not mid-submission
if (!window.tdzSubmitting) {
btn.disabled = false;
}
} else {
btn.disabled = true;
}
};
</script>
<div class="checkout-wrapper">
<div class="whop-checkout-embed"
id="whop-embedded-checkout"
data-whop-checkout-plan-id="plan_uoxec2Mf7Laly"
data-whop-checkout-theme="light"
data-whop-checkout-theme-accent-color="mint"
data-whop-checkout-hide-submit-button="true"
data-whop-checkout-on-state-change="tdzOnCheckoutStateChange"
style="min-height: 600px;">
</div>
<div class="button-container">
<button id="custom-submit-btn" disabled style="background-color: #0a7e91; color: #ffffff;">
<span class="button-title">Complete Purchase</span>
</button>
<div class="error-message" id="error-message">
Please accept all terms to continue
</div>
<div class="success-message" id="success-message"></div>
</div>
<div class="terms-section">
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-1" required>
<label for="terms-checkbox-1" id="terms-label-1">
I agree to pay $8,800.00 USD today for the Mentorship 120-Day Intensive, and understand my membership will automatically continue at $996.00 USD per month upon completion of the initial four (4)-month term unless and until I cancel. <a href="https://drzfma.com/Terms-Mentorship-Reg-PIF" target="_blank">Terms of Service</a>
</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="terms-checkbox-2" required>
<label for="terms-checkbox-2" id="terms-label-2">
I agree to the Terms of Service and Privacy Policy. I understand there are NO REFUNDS for the FMA programs, nor any FMA class purchases nor certification. I understand that The Mentorship is a mix of live calls/classes and will make every effort to attend the live events, along with recorded videos and handouts that I may access during the time I am an active member in The Mentorship program. All other Terms of Use, Privacy Policy & Disclaimer contents is found on the FMA <a href="https://thedrz.com" target="_blank">website</a> links below and purchasing any FMA product indicates your understanding and agreement.
</label>
</div>
<div class="terms-links">
<ul>
<li>Terms: <a href="https://drzfma.com/Terms-Mentorship-Reg-PIF" target="_blank">https://drzfma.com/Terms-Mentorship-Reg-PIF</a></li>
<li>Disclaimer: <a href="https://thedrz.com/disclaimer/" target="_blank">https://thedrz.com/disclaimer/</a></li>
<li>Return policy: <a href="https://thedrz.com/return-policy/" target="_blank">https://thedrz.com/return-policy/</a></li>
<li>Privacy policy: <a href="https://thedrz.com/privacy-policy/" target="_blank">https://thedrz.com/privacy-policy/</a></li>
</ul>
</div>
<div class="terms-credit">
The Dr. Z Functional Medicine, LLC dba TheDrZ.com with lead instructor: Dr. Brandy Zachary, DC, IFMCP
</div>
</div>
</div>
<script>
(function() {
var WORKER_URL = 'https://custom-terms.team-15b.workers.dev';
var PLAN_ID = 'plan_uoxec2Mf7Laly';
var CHECKOUT_NAME = 'TM 3.0 - REG - PIF';
var TERMS_COUNT = 2;
var TERMS_URLS = [
'https://drzfma.com/Terms-Mentorship-Reg-PIF',
'https://thedrz.com/disclaimer/'
];
var REDIRECT_URL = 'https://ev.thefmacademy.com/welcome';
var STORAGE_KEY = 'tdz_terms_' + PLAN_ID;
window.tdzSubmitting = false;
var submitBtn = document.getElementById('custom-submit-btn');
var checkboxes = [];
var termsLabels = [];
for (var i = 1; i <= TERMS_COUNT; i++) {
checkboxes.push(document.getElementById('terms-checkbox-' + i));
termsLabels.push(document.getElementById('terms-label-' + i));
}
var errorMessage = document.getElementById('error-message');
var successMessage = document.getElementById('success-message');
var checkoutEl = document.getElementById('whop-embedded-checkout');
function allChecked() {
return checkboxes.every(function(cb) { return cb && cb.checked; });
}
function resetSubmitButton() {
window.tdzSubmitting = false;
if (submitBtn && window.tdzCheckoutState === 'ready') {
submitBtn.disabled = false;
}
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Complete Purchase</span>';
}
}
// ==========================================================
// ON PAGE LOAD: Set return URL + check if returning from payment
// ==========================================================
// BUG 4 FIX: Set return URL to current page (survives redirect)
if (checkoutEl) {
var baseUrl = window.location.href.split('?')[0];
checkoutEl.setAttribute('data-whop-checkout-return-url', baseUrl);
}
// Check if we're returning from a successful payment
var params = new URLSearchParams(window.location.search);
var status = params.get('status');
if (status === 'success') {
// Grab every possible receipt param name
var receiptId = params.get('receipt') || params.get('receiptId') || params.get('receipt_id') || params.get('id') || null;
// Read stored terms from localStorage
var storedJson = null;
try { storedJson = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson) {
var termsData = JSON.parse(storedJson);
console.log('Found stored terms after redirect:', termsData);
console.log('Receipt ID from URL:', receiptId);
var payload = { checkout_name: CHECKOUT_NAME };
if (receiptId) payload.receiptId = receiptId;
Object.keys(termsData).forEach(function(k) { payload[k] = termsData[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL:', d);
// Redirect to thank-you page after webhook fires
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
// Still redirect even if webhook fails
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
console.log('Payment success but no stored terms found');
// No terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
// ==========================================================
// BACKUP: postMessage listener (works if page doesn't redirect)
// ==========================================================
window.addEventListener('message', function(event) {
if (!event.origin || !event.origin.endsWith('.whop.com')) return;
if (!event.data || typeof event.data !== 'object' || !event.data.type) return;
if (typeof event.data.type !== 'string') return;
if (event.data.type === 'whop_checkout_complete') {
console.log('PAYMENT COMPLETE (postMessage):', event.data.receiptId);
window.tdzSubmitting = false;
if (submitBtn) {
submitBtn.innerHTML = '<span class="button-title">Payment Complete!</span>';
submitBtn.style.backgroundColor = '#22c55e';
submitBtn.disabled = true;
}
if (successMessage) {
successMessage.textContent = 'Payment successful! Terms recorded.';
successMessage.style.display = 'block';
}
if (errorMessage) errorMessage.style.display = 'none';
var storedJson2 = null;
try { storedJson2 = localStorage.getItem(STORAGE_KEY); } catch(e) {}
if (storedJson2) {
var terms2 = JSON.parse(storedJson2);
var payload2 = { checkout_name: CHECKOUT_NAME };
if (event.data.receiptId) payload2.receiptId = event.data.receiptId;
Object.keys(terms2).forEach(function(k) { payload2[k] = terms2[k]; });
fetch(WORKER_URL + '/checkout-complete', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload2)
}).then(function(r) { return r.json(); }).then(function(d) {
console.log('Terms + payment sent to GHL (postMessage):', d);
window.location.href = REDIRECT_URL;
}).catch(function(e) {
console.error('Failed to send to GHL:', e);
window.location.href = REDIRECT_URL;
});
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
} else {
// No stored terms but payment succeeded - still redirect
window.location.href = REDIRECT_URL;
}
}
});
// ==========================================================
// BUTTON CLICK: validate terms → save to localStorage → submit
// ==========================================================
function initCustomCheckout() {
if (!submitBtn) return;
submitBtn.addEventListener('click', function() {
if (errorMessage) errorMessage.style.display = 'none';
if (successMessage) successMessage.style.display = 'none';
if (!allChecked()) {
if (errorMessage) {
errorMessage.textContent = 'Please accept all terms to continue';
errorMessage.style.display = 'block';
}
return;
}
// BUG 2 FIX: Check checkout is actually ready before submitting
if (window.tdzCheckoutState !== 'ready') {
if (errorMessage) {
errorMessage.textContent = 'Checkout is still loading. Please wait a moment.';
errorMessage.style.display = 'block';
}
return;
}
// Build terms data and persist to localStorage (survives page redirect)
var termsData = {
terms_accepted_at: new Date().toISOString()
};
for (var j = 0; j < TERMS_COUNT; j++) {
termsData['terms_' + (j + 1) + '_accepted'] = String(checkboxes[j].checked);
termsData['terms_' + (j + 1) + '_text'] = termsLabels[j].innerText.trim();
termsData['terms_' + (j + 1) + '_url'] = TERMS_URLS[j] || '';
}
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(termsData));
console.log('Terms saved to localStorage:', termsData);
} catch(e) {
console.error('Failed to save terms:', e);
}
// Disable button and submit
window.tdzSubmitting = true;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="button-title">Processing...</span>';
// BUG 5 FIX: No arbitrary timeouts. Just submit.
wco.submit('whop-embedded-checkout');
});
checkboxes.forEach(function(cb) {
if (cb) cb.addEventListener('change', function() {
if (allChecked() && errorMessage) errorMessage.style.display = 'none';
});
});
}
// BUG 6 FIX: loader.js is now at the bottom with just defer,
// so by the time it runs, this script has already executed.
// But we still wait for DOMContentLoaded as a safety net.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { initCustomCheckout(); });
} else {
initCustomCheckout();
}
console.log('TM 3.0 - REG - PIF checkout loaded');
})();
</script>
<!-- BUG 6 FIX: loader.js at BOTTOM with just defer (no async) -->
<!-- This guarantees inline scripts above run first, eliminating the race condition -->
<script defer src="https://js.whop.com/static/checkout/loader.js"></script>
Cloudflare Worker
// Cloudflare Worker - Whop Checkout Terms → GHL
// The embed handles checkout directly via plan_id (no session creation needed)
// This worker only handles post-payment: fetches payment details + sends terms to GHL
const CORS_HEADERS = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
};
const GHL_WEBHOOK_URL = 'https://services.leadconnectorhq.com/hooks/C5wwKC0quMkFI90rruQT/webhook-trigger/f871a37e-da15-427b-9cf4-531cffcea2f1';
export default {
async fetch(request, env) {
const url = new URL(request.url);
const path = url.pathname;
if (request.method === 'OPTIONS') {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
try {
// ========================================================================
// ROUTE: Checkout complete - HTML calls this after payment succeeds
// Fetches payment details from Whop, combines with terms, sends to GHL
// ========================================================================
if (path === '/checkout-complete' && request.method === 'POST') {
const body = await request.json();
const { receiptId, checkout_name, ...termsFields } = body;
console.log('Checkout complete - receipt:', receiptId || 'pre-payment');
let email = 'not_available';
let name = 'not_available';
let phone = 'not_available';
let planId = 'unknown';
let userId = 'unknown';
let membershipId = 'unknown';
let amount = 0;
let currency = 'USD';
// Try to fetch payment details from Whop API (only if we have a receipt)
if (receiptId && env.WHOP_API_KEY) {
try {
const paymentResponse = await fetch(`https://api.whop.com/api/v1/payments/${receiptId}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${env.WHOP_API_KEY}`,
'Content-Type': 'application/json',
},
});
if (paymentResponse.ok) {
const paymentData = await paymentResponse.json();
console.log('Payment data:', JSON.stringify(paymentData));
email = paymentData.member?.email || paymentData.email || paymentData.user?.email || 'not_available';
name = paymentData.member?.name || paymentData.member?.username || paymentData.user?.name || paymentData.user?.username || 'not_available';
phone = paymentData.member?.phone || paymentData.member?.phone_number || paymentData.user?.phone || 'not_available';
amount = paymentData.amount || paymentData.final_amount || (paymentData.total ? (paymentData.total / 100) : (paymentData.subtotal || 0));
currency = paymentData.currency || 'USD';
planId = paymentData.plan_id || paymentData.plan || 'unknown';
membershipId = paymentData.membership_id || paymentData.membership || 'unknown';
userId = paymentData.user_id || paymentData.user || paymentData.member_id || paymentData.member?.id || 'unknown';
} else {
const errData = await paymentResponse.json();
console.log('Payment fetch failed:', JSON.stringify(errData));
}
} catch (err) {
console.log('Payment fetch error:', err.message);
}
}
// Build the complete payload for GHL
const ghlPayload = {
receiptId: receiptId || 'unknown',
checkout_name: checkout_name || 'unknown',
email,
name,
phone,
planId,
userId,
membershipId,
amount,
currency,
...termsFields,
timestamp: new Date().toISOString(),
};
console.log('Sending to GHL:', JSON.stringify(ghlPayload));
try {
const ghlRes = await fetch(GHL_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(ghlPayload),
});
console.log('GHL response status:', ghlRes.status);
} catch (ghlErr) {
console.log('GHL webhook failed:', ghlErr.message);
}
return new Response(JSON.stringify({ success: true }), {
headers: { ...CORS_HEADERS, 'Content-Type': 'application/json' },
});
}
// ========================================================================
// Health check / info
// ========================================================================
if (path === '/' && request.method === 'GET') {
return new Response(JSON.stringify({
status: 'ok',
service: 'TDZ Whop Checkout Terms Worker',
endpoints: ['POST /checkout-complete'],
}), {
headers: { ...CORS_HEADERS, 'Content-Type': 'application/json' },
});
}
// ========================================================================
// Invalid route
// ========================================================================
return new Response(JSON.stringify({
error: 'Invalid endpoint',
available_endpoints: [
'POST /checkout-complete [Payment done - fetches details + sends terms to GHL]',
'GET / [Health check]',
]
}), {
status: 404,
headers: { ...CORS_HEADERS, 'Content-Type': 'application/json' },
});
} catch (error) {
console.error('Worker error:', error);
return new Response(JSON.stringify({
error: error.message,
type: 'WORKER_ERROR'
}), {
status: 500,
headers: { ...CORS_HEADERS, 'Content-Type': 'application/json' },
});
}
},
};