summaryrefslogtreecommitdiffstats
path: root/donation-calc
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-05-06 09:36:41 -0400
committerDrew DeVault <sir@cmpwn.com>2019-05-06 09:36:41 -0400
commit7d21723b0e2649016f46fe37dacbdf00a9dc5bd3 (patch)
tree0cc859a5dc4d1ea942f17e3b5988360021fbce8f /donation-calc
parent8d45fb169c23961b9b6e5727bc84f4ee2984aaa2 (diff)
Add patreon fees article
Diffstat (limited to 'donation-calc')
-rw-r--r--donation-calc/index.js794
1 files changed, 372 insertions, 422 deletions
diff --git a/donation-calc/index.js b/donation-calc/index.js
index 08faee2..c24ef82 100644
--- a/donation-calc/index.js
+++ b/donation-calc/index.js
@@ -6,351 +6,152 @@
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
+const vatRates = {
+ "Austria": 0.020,
+ "Belgium": 0.021,
+ "Bulgaria": 0.020,
+ "Croatia": 0.025,
+ "Cyprus": 0.019,
+ "Czech Republic": 0.021,
+ "Denmark": 0.025,
+ "Estonia": 0.020,
+ "Finland": 0.024,
+ "France": 0.020,
+ "Germany": 0.019,
+ "Greece": 0.024,
+ "Hungary": 0.027,
+ "Ireland": 0.023,
+ "Italy": 0.022,
+ "Latvia": 0.021,
+ "Lithuania": 0.021,
+ "Luxembourg": 0.017,
+ "Malta": 0.018,
+ "Netherlands": 0.021,
+ "Poland": 0.023,
+ "Portugal": 0.023,
+ "Romania": 0.019,
+ "Slovakia": 0.020,
+ "Slovenia": 0.022,
+ "Spain": 0.021,
+ "Sweden": 0.025,
+};
+
class Calculator extends Component {
constructor() {
super();
this.state = {
- provider: "fosspay",
+ country: "Germany",
amount: "5.00",
- inMethod: "card-usd",
- inAmount: "100.00",
- frequency: "month",
- outMethod: "usd",
+ paypal: false,
+ vat: false,
patreonCreators: [
- { "id": 0, "username": "SirCmpwn", "amount": "5.00" }
+ {
+ id: 0,
+ username: "SirCmpwn",
+ amount: 5,
+ displayAmount: "5.00",
+ founding: true,
+ plan: "pro",
+ upfront: false,
+ }
]
};
- this.renderFosspay = this.renderFosspay.bind(this);
- this.renderLiberapay = this.renderLiberapay.bind(this);
this.renderPatreon = this.renderPatreon.bind(this);
}
- renderFosspay() {
- const { amount } = this.state;
- let amt = parseFloat(amount);
- const stripe = amt * 0.029 + 0.30;
- const creator = amt - stripe;
- return (
- <div>
- <div class="form-group">
- <label for="amount">Amount</label>
- <div class="input-group">
- <span class="input-group-addon">$</span>
- <input
- type="text"
- class="form-control"
- aria-label="Amount"
- onChange={e => this.setState({ amount: e.target.value })}
- value={amount}
- />
- <span class="input-group-addon">per month</span>
- </div>
- </div>
- <table class="table">
- <thead>
- <tr>
- <th style={{ width: "12rem" }}>You pay</th>
- <th></th>
- <th
- style={{ textAlign: "right" }}
- >${amt.toFixed(2)}</th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Stripe fee</td>
- <td>2.9% + 30¢</td>
- <td
- style={{ textAlign: "right" }}
- >${stripe.toFixed(2)}</td>
- <td></td>
- </tr>
- <tr class="active">
- <th>Creator earns (pre-tax)</th>
- <th></th>
- <th
- style={{ textAlign: "right" }}
- >${creator.toFixed(2)}</th>
- <td>per month</td>
- </tr>
- <tr>
- <th></th>
- <th></th>
- <th
- style={{ textAlign: "right" }}
- >{(creator / amt * 100).toFixed(0)}%</th>
- <td>of your donation</td>
- </tr>
- </tbody>
- </table>
- </div>
- );
+ patreonFee(creator) {
+ let text, rate, fixed;
+ if (creator.founding) {
+ return {
+ text: "5%",
+ fee: creator.amount * 0.05,
+ };
+ } else {
+ switch (creator.plan) {
+ case "lite":
+ return {
+ text: "5%",
+ fee: creator.amount * 0.05,
+ };
+ case "pro":
+ if (creator.founding) {
+ return {
+ text: "5%",
+ fee: creator.amount * 0.05,
+ };
+ }
+ return {
+ text: "8%",
+ fee: creator.amount * 0.08,
+ };
+ case "premium":
+ if (creator.founding) {
+ return {
+ text: "9%",
+ fee: creator.amount * 0.09,
+ };
+ }
+ return {
+ text: "12%",
+ fee: creator.amount * 0.12,
+ };
+ }
+ }
}
- renderLiberapay() {
- const { amount, inMethod, frequency, outMethod } = this.state;
- let amt = parseFloat(this.state.amount);
- let inAmount = parseFloat(this.state.inAmount);
- let inFee;
- switch (inMethod) {
- case "card-usd":
- inFee = inAmount * 0.02925 + 0.35;
- break;
- case "card-euro":
- inFee = inAmount * 0.02106 + 0.26;
- break;
- case "wire":
- inFee = inAmount * 0.00585;
- break;
- case "debit":
- inFee = 0.72;
- break;
+ transactionFee(creator, paypal) {
+ let text, rate, fixed;
+ if (creator === null) {
+ return {
+ text: paypal ? "3.9% + 30¢" : "2.9% + 30¢",
+ };
+ }
+ if (creator.founding && creator.upfront) {
+ return {
+ text: paypal ? "3.9% + 30¢" : "2.9% + 30¢",
+ fee: creator.amount * (paypal ? 0.039 : 0.029) + 0.30,
+ };
+ } else {
+ if (creator.amount <= 3) {
+ return {
+ text: paypal ? "5% + 10¢" : "5% + 10¢",
+ fee: creator.amount * (paypal ? 0.06 : 0.05) + 0.10,
+ };
+ } else {
+ return {
+ text: paypal ? "3.9% + 30¢" : "2.9% + 30¢",
+ fee: creator.amount * 0.029 + 0.30,
+ };
+ }
}
- let lpBalance = inAmount - inFee;
- const creator = amt;
- const outFee = ({
- "sepa": 0,
- "euro": 2.93,
- "usd": 3.51
- })[outMethod];
- const creatorOut = lpBalance - outFee;
- const duration = Math.floor(lpBalance / amt);
- const inTypes = {
- "card-usd": "Card",
- "card-euro": "Card",
- "wire": "Wire",
- "debit": "Debit",
- };
- const humanInFee = {
- "card-usd": "2.925%+35¢",
- "card-euro": "2.106%+€0.21",
- "wire": "0.585%",
- "debit": "€0.59",
- };
- return (
- <div>
- <p>
- If you transfer this amount into your Liberapay wallet:
- </p>
- <div class="form-group">
- <label for="amount">Amount</label>
- <div class="input-group">
- <span class="input-group-addon">$</span>
- <input
- type="text"
- class="form-control"
- aria-label="Amount"
- onChange={e => this.setState({ inAmount: e.target.value })}
- value={this.state.inAmount}
- />
- </div>
- <div style={{marginTop: "1rem"}}>
- <label>Transfer method</label>
- </div>
- <fieldset class="form-group">
- <label class="radio-inline">
- <input
- type="radio"
- name="inMethod"
- checked={inMethod === "card-usd"}
- onChange={e => this.setState({ inMethod: "card-usd" })}
- />
- Card - USD (2.925%+35¢)
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="inMethod"
- checked={inMethod === "card-euro"}
- onChange={e => this.setState({ inMethod: "card-euro" })}
- />
- Card - Euro (2.106%+€0.21)
- </label>
- </fieldset>
- <fieldset class="form-group">
- <label class="radio-inline">
- <input
- type="radio"
- name="inMethod"
- checked={inMethod === "wire"}
- onChange={e => this.setState({ inMethod: "wire" })}
- />
- Wire transfer (0.585%)
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="inMethod"
- checked={inMethod === "debit"}
- onChange={e => this.setState({ inMethod: "debit" })}
- />
- Direct debit - Euro (€0.59)
- </label>
- </fieldset>
- </div>
- <p>Your <strong>transaction fees</strong> will be:</p>
- <table class="table">
- <thead>
- <tr>
- <th style={{ width: "12rem" }}>You pay</th>
- <th></th>
- <th>${inAmount.toFixed(2)}</th>
- </tr>
- </thead>
- <tbody>
- <tr class="active">
- <td>{inTypes[inMethod]} fee</td>
- <td>{humanInFee[inMethod]}</td>
- <td>(${inFee.toFixed(2)})</td>
- </tr>
- <tr>
- <td>Liberapay balance</td>
- <td></td>
- <td>${lpBalance.toFixed(2)}</td>
- </tr>
- </tbody>
- </table>
- <p>If you support your creators for this amount:</p>
- <div class="form-group">
- <label for="amount">Amount</label>
- <div class="input-group">
- <span class="input-group-addon">$</span>
- <input
- type="text"
- class="form-control"
- aria-label="Amount"
- onChange={e => this.setState({ amount: e.target.value })}
- value={amount}
- />
- </div>
- </div>
- <fieldset class="form-group" style={{ marginTop: "1rem" }}>
- <label class="radio-inline">
- <input
- type="radio"
- name="frequency"
- checked={frequency === "week"}
- onChange={e => this.setState({ frequency: "week" })}
- /> Per week
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="frequency"
- checked={frequency === "month"}
- onChange={e => this.setState({ frequency: "month" })}
- /> Per month
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="frequency"
- checked={frequency === "year"}
- onChange={e => this.setState({ frequency: "year" })}
- /> Per year
- </label>
- </fieldset>
- <p>
- Your creators earn <strong>${
- creator.toFixed(2)}</strong> per {
- frequency} for <strong>{duration} {frequency}(s)</strong>.
- If they wait until the end of this timeframe to withdraw their funds,
- their <strong>withdrawal fees</strong> will look like this:
- </p>
- <fieldset class="form-group" style={{ marginTop: "1rem" }}>
- <label class="radio-inline">
- <input
- type="radio"
- name="outMethod"
- checked={outMethod === "sepa"}
- onChange={e => this.setState({ outMethod: "sepa" })}
- />
- <a href="https://en.wikipedia.org/wiki/Single_Euro_Payments_Area">
- SEPA
- </a> (Europe): Free
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="outMethod"
- checked={outMethod === "euro"}
- onChange={e => this.setState({ outMethod: "euro" })}
- /> Other Europe: €2.93
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="outMethod"
- checked={outMethod === "usd"}
- onChange={e => this.setState({ outMethod: "usd" })}
- /> USD: $3.51
- </label>
- </fieldset>
- <table class="table">
- <thead>
- <tr>
- <th style={{ width: "12rem" }}>You pay</th>
- <th></th>
- <th
- style={{ textAlign: "right" }}
- >${lpBalance.toFixed(2)}</th>
- <th></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>Withdrawal fee</td>
- <td></td>
- <td
- style={{ textAlign: "right" }}
- >(${outFee.toFixed(2)})</td>
- <th></th>
- </tr>
- <tr class="active">
- <th>Creator earns (pre-tax)</th>
- <th></th>
- <th
- style={{ textAlign: "right" }}
- >${creatorOut.toFixed(2)}</th>
- <td>
- over {duration} {frequency}(s)
- </td>
- </tr>
- <tr>
- <th></th>
- <th></th>
- <th
- style={{ textAlign: "right" }}
- >{(creatorOut / inAmount * 100).toFixed(0)}%</th>
- <td>of your donation</td>
- </tr>
- </tbody>
- </table>
- <div class="alert alert-info">
- Fees in euros are for reference only. All amounts should be input in
- USD and all computed amounts are shown in USD based on the (probably
- dated) assumption that €1 EUR = $1.22 USD. Sorry.
- </div>
- </div>
- );
}
renderPatreon() {
- const creators = this.state.patreonCreators.sort(c => c.id);
- const total = creators.map(c => parseFloat(c.amount))
- .reduce((i, acc) => acc + i, 0);
- const tx_fee = total * 0.029 + 0.30;
+ const creators = this.state.patreonCreators.slice()
+ .sort((a, b) => a.id - b.id);
+ const { country, paypal, vat } = this.state;
+ const total = creators.reduce((a, c) => a + c.amount, 0);
+ const batch_total = creators
+ .filter(c => c.founding && !c.upfront)
+ .reduce((a, c) => a + c.amount, 0);
+ const batch_tx_fee = batch_total ? batch_total *
+ (this.state.paypal ? 0.039 : 0.029) + 0.30 : 0;
+ const tx_fees = creators.filter(c => !c.founding || c.upfront)
+ .reduce((a, c) => a + this.transactionFee(c, paypal).fee, 0) + batch_tx_fee;
+ const patreon_fees =
+ creators.reduce((a, c) => a + this.patreonFee(c).fee, 0);
+ const total_fees = tx_fees + patreon_fees;
+ const total_after_fees = total - total_fees;
return (
<div>
{creators.map(creator =>
<div key={creator.id}>
- <div class="form-group">
- <label for={`user-${creator.id}`}>Creator</label>
+ <div className="form-group">
+ <label htmlFor={`user-${creator.id}`}>Creator</label>
<input
id={`user-${creator.id}`}
type="text"
- class="form-control"
+ className="form-control"
aria-label="Username"
onChange={e => this.setState({
patreonCreators: [
@@ -361,46 +162,143 @@ class Calculator extends Component {
value={creator.username}
/>
</div>
- <div class="form-group">
- <label for="amount">Amount</label>
- <div class="input-group">
- <span class="input-group-addon">$</span>
+ <div className="form-group">
+ <label className="checkbox-inline">
+ <input type="checkbox"
+ name={"founding-" + creator.id}
+ name={"founding-" + creator.id}
+ checked={creator.founding}
+ onChange={e => this.setState({
+ patreonCreators: [
+ { ...creator, founding: e.target.checked },
+ ...creators.filter(c => c.id != creator.id)
+ ]
+ })}
+ /> Founding creator
+ {" "}
+ <a
+ href="#founding-creators"
+ >(?)</a>
+ </label>
+ <label className="checkbox-inline">
+ <input type="checkbox"
+ name={"upfront-" + creator.id}
+ name={"upfront-" + creator.id}
+ checked={creator.upfront}
+ onChange={e => this.setState({
+ patreonCreators: [
+ { ...creator, upfront: e.target.checked },
+ ...creators.filter(c => c.id != creator.id)
+ ]
+ })}
+ /> Charge up front
+ {" "}
+ <a
+ href="#charge-up-front"
+ >(?)</a>
+ </label>
+ </div>
+ <div className="form-group">
+ <label className="radio-inline">
+ <input type="radio"
+ name={"type-" + creator.id}
+ name={"type-" + creator.id}
+ value="lite"
+ checked={creator.plan === "lite"}
+ onChange={e => this.setState({
+ patreonCreators: [
+ { ...creator, plan: "lite" },
+ ...creators.filter(c => c.id != creator.id)
+ ]
+ })}
+ /> Lite
+ </label>
+ <label className="radio-inline">
+ <input type="radio"
+ name={"type-" + creator.id}
+ name={"type-" + creator.id}
+ value="pro"
+ checked={creator.plan === "pro"}
+ onChange={e => this.setState({
+ patreonCreators: [
+ { ...creator, plan: "pro" },
+ ...creators.filter(c => c.id != creator.id)
+ ]
+ })}
+ /> Pro
+ </label>
+ <label className="radio-inline">
+ <input type="radio"
+ name={"type-" + creator.id}
+ name={"type-" + creator.id}
+ value="premium"
+ checked={creator.plan === "premium"}
+ onChange={e => this.setState({
+ patreonCreators: [
+ { ...creator, plan: "premium" },
+ ...creators.filter(c => c.id != creator.id)
+ ]
+ })}
+ /> Premium
+ {" "}
+ <a
+ href="#which-plan"
+ >(?)</a>
+ </label>
+ </div>
+ <div className="form-group">
+ <label htmlFor="amount">Amount</label>
+ <div className="input-group">
+ <span className="input-group-addon">$</span>
<input
type="text"
- class="form-control"
+ className="form-control"
aria-label="Amount"
onChange={e => this.setState({
patreonCreators: [
- { ...creator, amount: e.target.value },
+ {
+ ...creator,
+ amount: parseFloat(e.target.value),
+ displayAmount: e.target.value,
+ },
...creators.filter(c => c.id != creator.id)
]
})}
- value={creator.amount}
+ value={creator.displayAmount}
/>
- <span class="input-group-addon">per month</span>
+ <span className="input-group-addon">per month</span>
</div>
</div>
+ {creator.plan === "premium" ?
+ <p>
+ <strong>Note</strong>: Large creators with a premium plan may
+ receive a special rate.
+ </p>
+ : null}
</div>
)}
- <div class="form-group">
+ <div className="form-group">
<button
- class="btn btn-default"
+ className="btn btn-default"
onClick={e => {
e.preventDefault();
this.setState({
patreonCreators: [
...creators,
{
- "id": Math.max(...creators.map(c => c.id)) + 1,
- "username": "",
- "amount": "5.00",
+ id: Math.max(...creators.map(c => c.id)) + 1,
+ username: "",
+ amount: 5,
+ plan: "pro",
+ founding: false,
+ upfront: false,
}
]
});
}}
>Add another creator</button>
{creators.length > 1 && <button
- class="btn btn-default"
+ className="btn btn-default"
style={{marginLeft: "1rem"}}
onClick={e => {
e.preventDefault();
@@ -411,56 +309,151 @@ class Calculator extends Component {
>Remove a creator</button>}
</div>
<p>
- You only pay one <strong>transaction fee</strong> for all of your
- creators:
+ You only pay one <strong>transaction fee</strong> between all of your
+ founding creators, except for creators which use the "charge up
+ front" option. You get charged a separate transaction fee for each
+ non-founding creator you support, based on your pledge amount.
</p>
- <table class="table">
+ <div class="form-group">
+ <label className="checkbox-inline">
+ <input type="checkbox"
+ name="paypal"
+ checked={paypal}
+ onChange={e => this.setState({ paypal: e.target.checked })}
+ /> Pay with PayPal
+ </label>
+ <label className="checkbox-inline">
+ <input type="checkbox"
+ name="vat"
+ checked={vat}
+ onChange={e => this.setState({ vat: e.target.checked })}
+ /> Pay from EU (add VAT)
+ </label>
+ </div>
+ {vat ?
+ <div className="form-group">
+ <label htmlFor="country">Country</label>
+ <select
+ className="form-control"
+ name="country"
+ value={country}
+ onChange={e => this.setState({ country: e.target.value })}
+ >
+ {Object.keys(vatRates).map(country =>
+ <option value={country}>{country}</option>
+ )}
+ </select>
+ <p>
+ Unlike other fees, adding VAT increases the amount you actually
+ pay, rather than subtracting more fees from your base pledge.
+ </p>
+ </div>
+ : null}
+ <table className="table">
<thead>
<tr>
- <th style={{ width: "12rem" }}>You pay</th>
+ <th style={{ width: "16rem" }}>You pay</th>
<th></th>
<th
style={{ textAlign: "right" }}
- >${total.toFixed(2)}</th>
+ >${(vat ? total * vatRates[country] + total : total).toFixed(2)}</th>
<th></th>
</tr>
</thead>
<tbody>
- <tr>
- <td>Transaction fee</td>
- <td>2.9% + 30¢</td>
- <td
+ {vat ?
+ <tr key={-3}>
+ <td>VAT</td>
+ <td>{(vatRates[country] * 100).toFixed(2)}%</td>
+ <td
+ style={{ textAlign: "right" }}
+ >(${(total * vatRates[country]).toFixed(2)})</td>
+ <td></td>
+ </tr>
+ : null}
+ {batch_tx_fee !== 0 ?
+ <tr key={-1}>
+ <td>Transaction fee (batch)</td>
+ <td>{this.transactionFee(null, paypal).text}<a href="#fn:2"><sup>2</sup></a></td>
+ <td
+ style={{ textAlign: "right" }}
+ >(${batch_tx_fee.toFixed(2)})</td>
+ <td></td>
+ </tr>
+ : null}
+ {creators.filter(c => !c.founding || c.upfront).map(c => {
+ return <tr key={c.id}>
+ <td>Transaction fee ({c.username})</td>
+ <td>{this.transactionFee(c, paypal).text}<a href="#fn:2"><sup>2</sup></a></td>
+ <td
+ style={{ textAlign: "right" }}
+ >(${this.transactionFee(c, paypal).fee.toFixed(2)})</td>
+ <td></td>
+ </tr>;
+ })}
+ <tr key={-2}>
+ <th>Payment processing fees</th>
+ <th style={{textAlign: "right"}}>=</th>
+ <th
style={{ textAlign: "right" }}
- >(${tx_fee.toFixed(2)})</td>
- <td></td>
+ >${tx_fees.toFixed(2)}</th>
+ <th></th>
</tr>
+ </tbody>
+ </table>
+ <p>
+ Patreon also charges its own fees, depending on the creator's plan
+ and founder status.
+ </p>
+ <table className="table">
+ <thead>
<tr>
+ <th style={{ width: "16rem" }}>You pay</th>
+ <th></th>
+ <th
+ style={{ textAlign: "right" }}
+ >${total.toFixed(2)}</th>
<th></th>
+ </tr>
+ </thead>
+ <tbody>
+ {creators.map(c => {
+ return <tr key={c.id}>
+ <td>Patreon fee ({c.username})</td>
+ <td>{this.patreonFee(c).text}</td>
+ <td
+ style={{ textAlign: "right" }}
+ >(${this.patreonFee(c).fee.toFixed(2)})</td>
+ <td></td>
+ </tr>;
+ })}
+ <tr key={-2}>
+ <th>Patreon fees</th>
<th style={{textAlign: "right"}}>=</th>
<th
style={{ textAlign: "right" }}
- >${(total - tx_fee).toFixed(2)}</th>
+ >${patreon_fees.toFixed(2)}</th>
<th></th>
</tr>
</tbody>
</table>
<p>
- Your total minus the transaction fee is distributed to your creators
- like so:
+ Your total minus the transaction fees &amp; Patreon fees is
+ distributed to your creators like so:
</p>
- <table class="table">
+ <table className="table">
<tbody>
{creators.map(c => {
- const amt = parseFloat(c.amount);
- const share = (amt / total) * (total - tx_fee);
- const patreon_fee = share * 0.05;
- const after_patreon = share - patreon_fee;
+ const tx_fee = this.transactionFee(c, paypal);
+ if (c.founding && !c.upfront) {
+ tx_fee.fee = (c.amount / batch_total) * batch_tx_fee;
+ }
+ const patreon_fee = this.patreonFee(c);
const clamp = (value, min, max) =>
Math.min(Math.max(min, value), max);
- const withdrawl_fee = clamp(after_patreon * 0.01, 0.25, 20);
- const creator_total = after_patreon - withdrawl_fee;
+ const creator_total = c.amount - tx_fee.fee - patreon_fee.fee;
return [
- <tr class="active">
+ <tr className="active" key={c.id}>
<th>{c.username}</th>
<td></td>
<td></td>
@@ -471,35 +464,29 @@ class Calculator extends Component {
<td></td>
<td
style={{textAlign: "right"}}
- >${amt.toFixed(2)}</td>
+ >${c.amount.toFixed(2)}</td>
<td></td>
</tr>,
<tr>
- <td>Transaction fee</td>
- <td>(see above)</td>
+ <td>Transaction fees</td>
+ <td>
+ {c.founding && !c.upfront ? '(see above)' : tx_fees.text}
+ </td>
<td
style={{textAlign: "right"}}
- >(${(amt - share).toFixed(2)})</td>
+ >(${tx_fee.fee.toFixed(2)})</td>
<td></td>
</tr>,
<tr>
- <td>Patreon fee</td>
- <td>5%</td>
+ <td>Patreon fees</td>
+ <td>{patreon_fee.text}</td>
<td
style={{ textAlign: "right" }}
- >(${patreon_fee.toFixed(2)})</td>
+ >(${patreon_fee.fee.toFixed(2)})</td>
<td></td>
</tr>,
<tr>
- <td>Withdrawal fee*</td>
- <td>1% (25¢ min, $20 max)</td>
- <td
- style={{ textAlign: "right" }}
- >(${withdrawl_fee.toFixed(2)})</td>
- <td></td>
- </tr>,
- <tr>
- <th>Creator earns (pre-tax)</th>
+ <th>Creator earns</th>
<th></th>
<th
style={{ textAlign: "right" }}
@@ -511,68 +498,31 @@ class Calculator extends Component {
<th></th>
<th
style={{ textAlign: "right" }}
- >{(creator_total / amt * 100).toFixed(0)}%</th>
+ >{(creator_total / c.amount * 100).toFixed(0)}%</th>
<td>of your donation</td>
</tr>
];
})}
</tbody>
</table>
- <small>
- * Withdrawal fee assumes payout via PayPal. Numbers for payout via
- Stripe are not available, and numbers for Payoneer are different. <a
- href="https://patreon.zendesk.com/hc/en-us/articles/203913489-What-are-my-options-to-receive-payout-">Details here</a>.
- Withdrawal fees are also applied on the total sum of the creator's
- earnings, and capped at $20 across all earnings.
- </small>
+ <p>
+ After all is said and done, of the ${total.toFixed(2)} you spend on
+ Patreon, ${total_after_fees.toFixed(2)}, or
+ <strong> {(total_after_fees / total * 100).toFixed(0)}%</strong> makes
+ it to your creators.
+ </p>
</div>
);
}
render() {
- const { amount, provider } = this.state;
return (
- <form class="calculator panel panel-default">
- <div class="panel-heading">
- Fee Calculator (based on 2018-01-16 fees)
+ <form className="calculator panel panel-default">
+ <div className="panel-heading">
+ Fee Calculator (based on 2019-05-07 fees)
</div>
- <div class="panel-body">
- <div>
- {/* I know this is supposed to be a legend inside the fieldset */}
- <label>Platform</label>
- </div>
- <fieldset class="form-group">
- <label class="radio-inline">
- <input
- type="radio"
- name="platform"
- checked={provider === "fosspay"}
- onChange={e => this.setState({ provider: "fosspay" })}
- />
- fosspay
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="platform"
- checked={provider === "liberapay"}
- onChange={e => this.setState({ provider: "liberapay" })}
- />
- Liberapay
- </label>
- <label class="radio-inline">
- <input
- type="radio"
- name="platform"
- checked={provider === "patreon"}
- onChange={e => this.setState({ provider: "patreon" })}
- />
- Patreon
- </label>
- </fieldset>
- {provider === "fosspay" && this.renderFosspay()}
- {provider === "liberapay" && this.renderLiberapay()}
- {provider === "patreon" && this.renderPatreon()}
+ <div className="panel-body">
+ {this.renderPatreon()}
</div>
</form>
);