Estimated gross payout
{hasInput && {rateNum.toFixed(2)} × {hoursNum}h}
${gross.toLocaleString('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
})}
{hasInput ? `Released by Mercor • Via ${provInfo.label}` : 'Enter your hourly rate and hours above to see the full payment journey'}
```
--------------------------------
### Adjustment Panel CSS
Source: https://talent.docs.mercor.com/how-to/payments
Styles for toggleable adjustment panels and reset links.
```css
.pc-adjust-row { display: flex; align-items: center; justify-content: space-between; margin-top: 16px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,0.2); flex-wrap: wrap; gap: 10px; }
.pc-toggle { background: rgba(255,255,255,0.14); border: 1px solid rgba(255,255,255,0.25); padding: 8px 14px; border-radius: 999px; font-size: 12.5px; font-weight: 500; color: white; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: background 0.15s; }
.pc-toggle:hover { background: rgba(255,255,255,0.22); }
.pc-chev { transition: transform 0.15s; }
.pc-toggle.pc-open .pc-chev { transform: rotate(180deg); }
.pc-adjust-panel { margin-top: 14px; padding: 16px; background: rgba(255,255,255,0.95); border-radius: 12px; border: 1px solid rgba(255,255,255,0.4); }
.pc-reset-link { background: none; border: none; padding: 10px 0; font-size: 13px; font-weight: 500; color: var(--pc-indigo); cursor: pointer; text-align: left; }
.pc-reset-link:hover { text-decoration: underline; }
```
--------------------------------
### Bonus Result CSS
Source: https://talent.docs.mercor.com/how-to/payments
Styles for displaying bonus amount results.
```css
.pc-bonus-result { margin-top: 16px; padding: 16px 18px; background: var(--pc-indigo-soft); border: 1px solid #E0E7FF; border-radius: 12px; }
.pc-bonus-amount { font-size: 22px; font-weight: 700; color: var(--pc-indigo-dark); letter-spacing: -0.01em; margin-bottom: 4px; }
.pc-bonus-detail { font-size: 13.5px; color: var(--pc-gray-700); line-height: 1.55; }
```
--------------------------------
### Date and Time Utility Functions
Source: https://talent.docs.mercor.com/how-to/payments
Functions for time zone-aware date manipulation, including work week calculations, business day addition, and localized date formatting.
```javascript
const zMin = +parts.find(p => p.type === 'minute').value;
return new Date(guessMs - (Date.UTC(zY, zM - 1, zD, zH, zMin) - guessMs));
};
const zonedParts = (date, tz) => {
const fmt = new Intl.DateTimeFormat('en-US', {
timeZone: tz,
year: 'numeric',
month: '2-digit',
day: '2-digit',
weekday: 'short',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23'
});
const p = fmt.formatToParts(date);
return {
year: +p.find(x => x.type === 'year').value,
month: +p.find(x => x.type === 'month').value,
day: +p.find(x => x.type === 'day').value,
weekday: p.find(x => x.type === 'weekday').value,
hour: +p.find(x => x.type === 'hour').value,
minute: +p.find(x => x.type === 'minute').value
};
};
const workWeekStartFor = moment => {
const p = zonedParts(moment, 'Asia/Kolkata');
const daysSinceSat = ({
Sat: 0,
Sun: 1,
Mon: 2,
Tue: 3,
Wed: 4,
Thu: 5,
Fri: 6
})[p.weekday];
const base = new Date(Date.UTC(p.year, p.month - 1, p.day));
base.setUTCDate(base.getUTCDate() - daysSinceSat);
return dateFromZonedWallClock('Asia/Kolkata', base.getUTCFullYear(), base.getUTCMonth() + 1, base.getUTCDate(), 0, 0);
};
const workWeekEnd = satStart => {
const p = zonedParts(satStart, 'Asia/Kolkata');
const base = new Date(Date.UTC(p.year, p.month - 1, p.day));
base.setUTCDate(base.getUTCDate() + 6);
return dateFromZonedWallClock('Asia/Kolkata', base.getUTCFullYear(), base.getUTCMonth() + 1, base.getUTCDate(), 23, 59);
};
const nextWedReleaseAfter = moment => {
const p = zonedParts(moment, 'America/Los_Angeles');
const dayIdx = ({
Sun: 0,
Mon: 1,
Tue: 2,
Wed: 3,
Thu: 4,
Fri: 5,
Sat: 6
})[p.weekday];
const daysToWed = (3 - dayIdx + 7) % 7;
const base = new Date(Date.UTC(p.year, p.month - 1, p.day));
base.setUTCDate(base.getUTCDate() + daysToWed);
let candidate = dateFromZonedWallClock('America/Los_Angeles', base.getUTCFullYear(), base.getUTCMonth() + 1, base.getUTCDate(), 12, 0);
if (candidate <= moment) {
base.setUTCDate(base.getUTCDate() + 7);
candidate = dateFromZonedWallClock('America/Los_Angeles', base.getUTCFullYear(), base.getUTCMonth() + 1, base.getUTCDate(), 12, 0);
}
return candidate;
};
const addBusinessDays = (date, days) => {
const d = new Date(date);
let added = 0;
while (added < days) {
d.setUTCDate(d.getUTCDate() + 1);
const dow = d.getUTCDay();
if (dow !== 0 && dow !== 6) added++;
}
return d;
};
const fmtFullDate = (date, tz) => new Intl.DateTimeFormat('en-US', {
timeZone: tz,
weekday: 'short',
month: 'short',
day: 'numeric',
year: 'numeric'
}).format(date);
const fmtShortDate = (date, tz) => new Intl.DateTimeFormat('en-US', {
timeZone: tz,
weekday: 'short',
month: 'short',
day: 'numeric'
}).format(date);
const fmtTime = (date, tz) => new Intl.DateTimeFormat('en-US', {
timeZone: tz,
hour: 'numeric',
minute: '2-digit',
hour12: true
}).format(date);
const fmtDateTimeLong = (date, tz) => new Intl.DateTimeFormat('en-US', {
timeZone: tz,
weekday: 'short',
month: 'short',
day: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: '2-digit',
hour12: true
}).format(date);
const nowInTzAsLocalString = tz => {
const fmt = new Intl.DateTimeFormat('en-CA', {
timeZone: tz,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23'
});
const p = fmt.formatToParts(new Date());
return `${p.find(x => x.type === 'year').value}-${p.find(x => x.type === 'month').value}-${p.find(x => x.type === 'day').value}T${p.find(x => x.type === 'hour').value}:${p.find(x => x.type === 'minute').value}`;
};
const parseLocalDateTime = (value, tz) => {
if (!value) return null;
const [date, time] = value.split('T');
if (!date || !time) return null;
const [y, m, d] = date.split('-').map(Number);
const [h, mn] = time.split(':').map(Number);
return dateFromZonedWallClock(tz, y, m, d, h, mn);
};
const providerInfo = p => {
if (p === 'stripe-instant') return {
label: 'Stripe Instant Payout',
businessDays: 0,
instant: true,
minutes: 30,
isWise: false
};
if (p === 'wise') return {
label: 'Wise (after you accept)',
businessDays: 0,
instant: false,
minutes: 60,
isWise: true
};
return {
label: 'Stripe bank transfer',
businessDays: 3,
instant: false,
isWise: false
};
};
const detectedTz = typeof Intl !== 'undefined' ? Intl.DateTimeFormat().resolvedOptions().timeZone : 'America/Los_Angeles';
const defaultCountry = COUNTRIES.find(c => c.tz === detectedTz) || COUNTRIES[0];
```
--------------------------------
### Status Badge CSS
Source: https://talent.docs.mercor.com/how-to/payments
Styles for status indicators representing current, past, or future states.
```css
.pc-status { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.pc-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; }
.pc-status.pc-current { background: rgba(255,255,255,0.18); color: white; }
.pc-status.pc-current::before { background: white; }
.pc-status.pc-past { background: rgba(255,255,255,0.18); color: white; opacity: 0.85; }
.pc-status.pc-past::before { background: rgba(255,255,255,0.7); }
.pc-status.pc-future { background: rgba(255,255,255,0.18); color: white; }
.pc-status.pc-future::before { background: #BAE6FD; }
```
--------------------------------
### Render Wise payout notification
Source: https://talent.docs.mercor.com/how-to/payments
Displays a conditional section informing users about the manual action required for Wise payouts.
```jsx
{provInfo.isWise &&
Wise process — important
Your Wise payout requires action from you
Unlike Stripe, which auto-deposits to your linked account, Wise sends you an email after Mercor releases the payout. You must accept it for the transfer to actually happen.
Mercor releases the payout on Wednesday ~12 PM PST. Wise then emails you at the address registered with your Mercor account.
Open the email from wise.com and click the link. Check your spam folder if you don't see it within 24h.
Register (if first time) or log in. Select Personal account, set 2FA, and add your bank details in your local currency.
Accept the transfer. Money typically arrives ~1 hour later, though some countries can take longer based on local banking.
If you ignore the email, the payout stalls on Wise's side — Mercor cannot push it through for you. Always action the email.
}
```
--------------------------------
### Date Conversion Utility
Source: https://talent.docs.mercor.com/how-to/payments
A function that converts a wall-clock time in a specific timezone to a UTC timestamp using Intl.DateTimeFormat.
```javascript
const dateFromZonedWallClock = (tz, year, month, day, hour, minute) => {
const guessMs = Date.UTC(year, month - 1, day, hour, minute);
const fmt = new Intl.DateTimeFormat('en-US', {
timeZone: tz,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23'
});
const parts = fmt.formatToParts(new Date(guessMs));
const zY = +parts.find(p => p.type === 'year').value;
const zM = +parts.find(p => p.month === 'month').value;
const zD = +parts.find(p => p.type === 'day').value;
const zH = +parts.find(p => p.type === 'hour').value;
```