Add payment widget to home page

This commit is contained in:
2023-09-14 14:29:05 +02:00
parent cc90ccec48
commit 91ea334cf4
29 changed files with 359 additions and 94 deletions

View File

@@ -1,3 +1,7 @@
<script>
import MollieDeposit from "../user_home/MollieDeposit.svelte";
</script>
<header id="prepaid">
<div class="header_image_container"></div>
</header>
@@ -15,16 +19,20 @@
<img src="/res/img/misc/sunrise.webp" class="float_right" alt="Sunrise">
<h2>Simple and affordable</h2>
<span class="keyword">€4 per TB per month for storage</span><br/>
<span class="keyword">€2 per TB for data transfer</span><br/>
<p>
You are only charged for what you use. And it's only 1.4% the price of
Amazon AWS. Yea, seriously, you could save 98% on your bandwidth bill by
switching!
</p>
<p>
Cheaper storage is also available with file expiry enabled.
</p>
No file expiry:
<ul>
<li><span class="keyword">€2.00 per month</span> base price<br/></li>
<li><span class="keyword">€4.00 per TB per month</span> for storage<br/></li>
<li><span class="keyword">€2.00 per TB</span> for data transfer<br/></li>
</ul>
<hr/>
240 day file expiry:
<ul>
<li><span class="keyword">€1.00 per month</span> base price<br/></li>
<li><span class="keyword">€0.50 per TB per month</span> for storage<br/></li>
<li><span class="keyword">€2.00 per TB</span> for data transfer<br/></li>
</ul>
<br style="clear: right;"/>
<br/>
@@ -38,19 +46,34 @@
and circumvent the download page completely.
</p>
<br style="clear: both;"/>
<h2>Interested?</h2>
<p>
To get started we will need the name and address of your business, and
the name of your pixeldrain account. We will prepare an invoice for you.
Your deposit needs to be at least €100 to save on administrative work.
We accept SEPA, PayPal and Bitcoin.
</p>
<p style="text-align: center;">
<a href="mailto:sales@pixeldrain.com" class="button button_highlight round" style="font-size: 1.4em">
<i class="icon">mail</i>
Contact sales@pixeldrain.com
</a>
</p>
<h2>Get started</h2>
{#if window.user.username !== ""}
{#if window.user.subscription.id !== ""}
<p>You already have a subscription active</p>
{:else}
<p>
You are currently logged in as {window.user.username}. Use the
form below to activate a prepaid subscription on this account.
</p>
<MollieDeposit/>
{/if}
{:else}
<p>
You are currently not logged in to a pixeldrain account. Log in to
get started.
</p>
<p style="text-align: center;">
<a href="/login?redirect=checkout" class="button button_highlight" style="font-size: 1.2em">
<i class="icon">login</i>
Log in
</a>
or
<a href="/register?redirect=checkout" class="button button_highlight" style="font-size: 1.2em">
<i class="icon">how_to_reg</i>
Register
</a>
</p>
{/if}
</section>
@@ -75,7 +98,7 @@ header {
background-position: center;
}
.keyword {
font-size: 1.1em;
font-weight: bold;
}
h2 {
border-bottom: none;

View File

@@ -2,6 +2,7 @@
import Footer from "../layout/Footer.svelte";
import AddressReputation from "./AddressReputation.svelte";
import FeatureTable from "./FeatureTable.svelte";
import ForCreators from "./ForCreators.svelte";
import OtherPlans from "./OtherPlans.svelte";
import UploadWidget from "./UploadWidget.svelte";
</script>
@@ -68,17 +69,18 @@ import UploadWidget from "./UploadWidget.svelte";
<OtherPlans></OtherPlans>
<br/>
</section>
</div>
<div class="page_content">
<Footer></Footer>
<ForCreators/>
</div>
<Footer/>
<style>
.page_content {
margin-top: 5px;
margin-bottom: 10px;
margin-top: 16px;
margin-bottom: 16px;
}
@media (max-width: 1100px) {
.page_content {

View File

@@ -35,13 +35,3 @@ import Twitter from "../icons/Twitter.svelte";
</span>
</div>
</footer>
<style>
.footer_content {
background-color: var(--body_background);
color: var(--body_text_color);
display: inline-block;
border-radius: 8px;
margin: 160px 0 60px 0;
}
</style>

View File

@@ -72,7 +72,7 @@ onMount(() => {
<LoadingIndicator loading={loading}/>
<section>
<h2>Deposit credits</h2>
<h2 id="deposit">Deposit credits</h2>
<p>
Pixeldrain credits can be used for our prepaid plans, which are
different from the Patreon plans. With prepaid you only pay for what you
@@ -81,11 +81,10 @@ onMount(() => {
</p>
<p>
Use the form below to deposit credit on your pixeldrain account using
Mollie. The minimum deposit is €10. <b>Mollie payments are currently
only available in Europe</b>.
Mollie. The minimum deposit is €10.
</p>
<MollieDeposit on:checkout={e => checkout("mollie", e.detail.amount, e.detail.country)}/>
<MollieDeposit/>
<h3>Crypto payments</h3>
<p>
@@ -116,7 +115,7 @@ onMount(() => {
</button>
</div>
<h3>Past invoices</h3>
<h3 id="invoices">Past invoices</h3>
<p>
Invoices are deleted after one year of inactivity.
</p>

View File

@@ -1,18 +1,18 @@
<script>
import { createEventDispatcher } from 'svelte';
import {
At, Be, Bg, Hr, Cy, Cz, Dk, Ee, Fi, Fr, De, Gr, Hu, Ie, It, Lv, Lt, Lu, Mt,
Nl, Pl, Pt, Ro, Sk, Si, Es, Se,
} from 'svelte-flag-icons';
import Euro from '../util/Euro.svelte';
import LoadingIndicator from '../util/LoadingIndicator.svelte';
let dispatch = createEventDispatcher()
let credit_amount = 10
$: credit_micro = credit_amount*1e6
$: vat_micro = country === null ? 0 : (credit_amount*1e6)*(country.vat/100)
let loading = false
let amount = 20
let country = null
$: credit_micro = amount*1e6
$: vat_micro = country === null ? 0 : (amount*1e6)*(country.vat/100)
let countries = [
{name: "Austria", code: At, vat: 20},
{name: "Belgium", code: Be, vat: 21},
@@ -41,28 +41,75 @@ let countries = [
{name: "Slovenia", code: Si, vat: 22},
{name: "Spain", code: Es, vat: 21},
{name: "Sweden", code: Se, vat: 25},
{name: "Other", code: null, vat: 0},
]
let amounts = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000]
const checkout = () => {
dispatch("checkout", {country: country.name, amount: credit_amount})
const checkout = async () => {
loading = true
if (amount < 10) {
alert("Amount needs to be at least €10")
return
}
const form = new FormData()
form.set("amount", amount*1e6)
form.set("network", "mollie")
form.set("country", country.name)
try {
const resp = await fetch(
window.api_endpoint+"/user/invoice",
{method: "POST", body: form},
)
if(resp.status >= 400) {
let json = await resp.json()
throw json.message
}
window.location = (await resp.json()).checkout_url
} catch (err) {
alert(err)
} finally {
loading = false
}
}
</script>
<div class="highlight_border">
<LoadingIndicator loading={loading}/>
{#if country === null}
<div>Please pick your country of residence</div>
<div class="countries">
{#each countries as c}
<button on:click={() => country = c}>
<svelte:component this={c.code} size="1.5em" />
{#if c.code}
<svelte:component this={c.code} size="1.5em" />
{:else}
<i class="icon">public</i>
{/if}
<span>{c.name}</span>
</button>
{/each}
</div>
<div>
We support the following payment processors<br/>
<img class="bankicon" src="/res/img/payment_providers/ideal.svg" alt="iDEAL"/>
<img class="bankicon" src="/res/img/payment_providers/klarna.svg" alt="Klarna"/>
<img class="bankicon" src="/res/img/payment_providers/bancontact.svg" alt="Bancontact"/>
<img class="bankicon" src="/res/img/payment_providers/banktransfer.svg" alt="SEPA"/>
<img class="bankicon" src="/res/img/payment_providers/sofort.svg" alt="SOFORT"/>
<img class="bankicon" src="/res/img/payment_providers/kbc.svg" alt="KBC/CBC"/>
<img class="bankicon" src="/res/img/payment_providers/belfius.svg" alt="Belfius"/>
<img class="bankicon" src="/res/img/payment_providers/giropay.svg" alt="Giropay"/>
<img class="bankicon" src="/res/img/payment_providers/eps.svg" alt="EPS"/>
<img class="bankicon" src="/res/img/payment_providers/przelewy24.svg" alt="Przelewy24"/>
</div>
{:else}
@@ -74,7 +121,11 @@ const checkout = () => {
<div style="flex: 1 1 auto;"></div>
<div style="flex: 0 0 auto; display: flex; gap: 0.25em; align-items: center;">
<span>Paying from</span>
<svelte:component this={country.code} size="1.5em" />
{#if country.code}
<svelte:component this={country.code} size="1.5em" />
{:else}
<i class="icon">public</i>
{/if}
<span>{country.name} ({country.vat}% VAT)</span>
</div>
</div>
@@ -82,14 +133,14 @@ const checkout = () => {
<form class="amount_grid" on:submit|preventDefault={checkout}>
<div class="span3">Please choose an amount</div>
{#each amounts as a}
<button on:click|preventDefault={() => credit_amount = a} style="font-size: 1.1em;" class:button_highlight={credit_amount === a}>
<button on:click|preventDefault={() => amount = a} style="font-size: 1.1em;" class:button_highlight={amount === a}>
<div style="padding: 6px;">{a}</div>
</button>
{/each}
<div class="span3 mollie_checkout">
<div>Custom amount €</div>
<input type="number" bind:value={credit_amount} min="10"/>
<input type="number" bind:value={amount} min="10"/>
</div>
<div class="span2" style="text-align: initial;">
@@ -145,4 +196,9 @@ const checkout = () => {
.mollie_checkout > input[type="number"] {
flex: 1 1 auto;
}
.bankicon {
width: 40px;
height: 30px;
}
</style>

View File

@@ -50,8 +50,17 @@ onMount(() => {
<div class="highlight_green">
<h2>Payment successful!</h2>
<p>
The credit has been added to your account balance. Activate a
subscription plan below to finish upgrading your account.
Thank you for supporting pixeldrain! The credit has been added
to your account balance. Activate a subscription plan below to
finish upgrading your account.
</p>
<p>
If your account credit has not been updated, please check the
status of your invoice on <a
href="/user/prepaid/deposit#invoices">the invoices page</a>.
Depending on the payment processor you used to can take a while
before your credit is deposited. If it takes too long contact
support@pixeldrain.com.
</p>
</div>
{/if}