This commit is contained in:
parent
7098ac75cb
commit
df91762271
29 changed files with 3079 additions and 838 deletions
|
|
@ -23,11 +23,13 @@ No permission is granted to copy, modify, distribute, or create derivative works
|
|||
// them at build time (fediverse fetch, ECB rates), and shell writes JSON,
|
||||
// not C++.
|
||||
//
|
||||
// PRICING RULE (the user's): retail = supplier price + markup, exactly, and
|
||||
// PRICING RULE (the owner's): retail = supplier price + markup, exactly, and
|
||||
// the markup is what Catcrafts walks away with AFTER shipping and VAT — €50
|
||||
// net, with Mollie's transaction fee as the only accepted leak. Supplier
|
||||
// prices are what the retailer currently charges (incl VAT); change one
|
||||
// number when the supplier moves and the margin stays put.
|
||||
// net. The stated leak used to be the payment provider's transaction fee;
|
||||
// since both rails became self-hosted (2026-08-20) the leaks are a bank
|
||||
// transfer's zero and, on the crypto rail, gas plus whatever an exchange takes
|
||||
// at cash-out. Supplier prices are what the retailer currently charges (incl
|
||||
// VAT); change one number when the supplier moves and the margin stays put.
|
||||
|
||||
export module Catcrafts.Shared:Content;
|
||||
import std;
|
||||
|
|
@ -70,6 +72,28 @@ export const std::vector<Product>& Products() {
|
|||
p.tagline = "A repairable Android phone, reflashed to run mainline Linux with a working IMS/VoLTE stack.";
|
||||
// Launch day is this one line: "coming-soon" -> "available". The page
|
||||
// shows launch prices either way; only the order form is held back.
|
||||
//
|
||||
// ── BEFORE FLIPPING THIS, TWO THINGS ARE OWED ────────────────────
|
||||
//
|
||||
// 1. THE WITHDRAWAL BUTTON (herroepingsknop). Since 2026-06-19, art.
|
||||
// 11a of the Consumer Rights Directive — art. 6:230oa BW — has
|
||||
// required a clearly labelled button in the interface for a
|
||||
// consumer to withdraw from a distance contract. Email alone is no
|
||||
// longer enough. It must stay available for the whole withdrawal
|
||||
// period, ask only for essentials, NOT require an account, and
|
||||
// confirm immediately on a durable medium.
|
||||
// **If it is missing, the 14-day withdrawal period becomes ONE
|
||||
// YEAR** — every EU phone sale unwindable for twelve months.
|
||||
// It does not bite today only because the sole purchasable item is
|
||||
// the donation, and a gift carries no withdrawal right. Flipping
|
||||
// this line is exactly the moment it starts to.
|
||||
// The order page is the natural home: it already identifies one
|
||||
// order by an unguessable link, so no account is needed.
|
||||
//
|
||||
// 2. THE SHIPPING RATE TABLE. Without SENDCLOUD_* credentials (or a
|
||||
// hand-placed cache) there is no rate table, and checkout refuses
|
||||
// every order that ships. Donations skip that branch, which is why
|
||||
// the shop looks fine today. See deploy/README.md.
|
||||
p.status = "coming-soon";
|
||||
// Boxed shipping weight, grams: the FP6 retail box (~450 g) plus the
|
||||
// outer carton and padding. Rounded UP on purpose — this number picks
|
||||
|
|
@ -351,7 +375,7 @@ export const std::vector<LegalPage>& LegalPages() {
|
|||
{
|
||||
.slug = "privacy",
|
||||
.title = "Privacy",
|
||||
.updated = "2026-08-14",
|
||||
.updated = "2026-08-20",
|
||||
.lede = "What this site collects, why, and how to get rid of it. Written to describe what the code actually does. If you find a discrepancy, the code is the bug and a report is very welcome.",
|
||||
.sections = {
|
||||
{ "Who is responsible",
|
||||
|
|
@ -361,7 +385,8 @@ export const std::vector<LegalPage>& LegalPages() {
|
|||
{ "Orders",
|
||||
{
|
||||
"Placing an order stores what fulfilling it requires: your email address, the recipient name and shipping address, the country, and the order itself (product, amounts, timestamps, payment reference and status). Nothing else is asked for and nothing else is kept. The legal basis is the contract: this data is what shipping you a phone and issuing an invoice consist of.",
|
||||
"Bank and card payment happens on Mollie's own pages, Mollie is a Dutch licensed payment institution, and Catcrafts never sees card numbers or bank credentials, only which order was paid, for how much, and by which method. What Mollie processes about you is between you and them under their own privacy policy. Cryptocurrency payment involves no provider at all: the order page shows a receiving address that belongs to Catcrafts, and paying it is a transaction on a public blockchain. Only the order record described above connects them to you, and that record stays with Catcrafts.",
|
||||
"Neither payment method involves a payment processor, so there is no third party that Catcrafts hands your data to in order to get paid. Bank payment is an ordinary transfer from your bank to the account named on the order page: your own bank and Catcrafts' bank handle it, as they would any transfer you make, and Catcrafts has engaged nobody in between. Cryptocurrency payment involves no provider either: the order page shows a receiving address that belongs to Catcrafts, and paying it is a transaction on a public blockchain. Only the order record described above connects a payment to you, and that record stays with Catcrafts.",
|
||||
"What Catcrafts records about a bank transfer is deliberately narrow: the payment reference you quoted, the amount, the date and the method. Your name and IBAN are visible to Catcrafts on its own bank statement, as they are to anyone who receives a transfer, but they are not copied into the shop's records and are not needed to confirm an order. The reference is what matches your payment to your order.",
|
||||
"The order status page lives at an unguessable link. Anyone holding the link can read that order's status and totals, so treat it like a receipt on your desk and don't post it anywhere public.",
|
||||
} },
|
||||
{ "How long it is kept",
|
||||
|
|
@ -373,7 +398,7 @@ export const std::vector<LegalPage>& LegalPages() {
|
|||
{ "What this site does not do",
|
||||
{
|
||||
"No analytics in your browser. No cookies, none at all, which is why there is no cookie banner. No third-party scripts, no fonts loaded from anyone else's server, no embedded video, no social buttons, no advertising, no profiling, no automated decision-making.",
|
||||
"Everything the browser loads comes from catcrafts.net. Following a link out (to a fediverse thread, to Forgejo, to the Mollie payment page) puts you on that site under its terms, and Catcrafts has no visibility into what happens there.",
|
||||
"Everything the browser loads comes from catcrafts.net. Paying does not send you anywhere else either: both payment methods are completed from the order page itself, so there is no payment provider's site in the middle. Following a link out, to a fediverse thread or to Forgejo, puts you on that site under its terms, and Catcrafts has no visibility into what happens there.",
|
||||
} },
|
||||
{ "Server logs",
|
||||
{
|
||||
|
|
@ -428,15 +453,16 @@ export const std::vector<LegalPage>& LegalPages() {
|
|||
.sections = {
|
||||
{ "Ordering and payment",
|
||||
{
|
||||
"Submitting the order form creates an order with a Mollie payment link for bank and card, or with a receiving address of its own for cryptocurrency. The order is an offer to buy; the contract forms when the payment arrives. Until then nothing is owed: an unpaid order simply lapses and can be ignored. A cryptocurrency order's address stays reserved for about a day; after that the order lapses like any other unpaid one.",
|
||||
"Submitting the order form creates an order and shows you how to pay it: account details and a payment reference for a bank transfer, or a receiving address for cryptocurrency. The order is an offer to buy; the contract forms when the payment arrives. Until then nothing is owed: an unpaid order simply lapses and can be ignored. An unpaid bank-transfer order is held for about two weeks and a cryptocurrency order's address stays reserved for about a day; after that each lapses like any other unpaid order. In both cases a payment that arrives late is not lost, because the account and the address remain Catcrafts', and it is settled by hand on request.",
|
||||
"Prices are in euros, and euros are what is charged; any amount shown in another currency is indicative only, converted at the ECB reference rate of the date shown. Inside the EU the shown price includes 21% Dutch VAT. Outside the EU the sale is a zero-rated export at the derived ex-VAT price, and the price then excludes import duty, import VAT, tariffs and any carrier handling or brokerage fee. Those charges arise on arrival in your country, are levied by the carrier or your customs authority, and are solely a matter between you and them: Catcrafts does not collect them, cannot bindingly estimate them, is not a party to their assessment, and refusal to pay them does not undo the sale. Your bank or card sets the actual euro conversion rate for whatever you pay with.",
|
||||
"Bank and card payments are handled by Mollie, a Dutch licensed payment institution, on its own pages. Catcrafts never sees your card number or bank credentials. Cryptocurrency payments involve no provider: they are made in EURC, a euro-denominated stablecoin, directly to a wallet address held by Catcrafts and shown on the order page. Catcrafts never sees your wallet keys.",
|
||||
"Paying in cryptocurrency changes how the money moves, not what is owed or what you are owed. Payment is accepted in EURC only, which is denominated in euros: the amount to send is exactly the euro price, with no exchange rate involved, and it must arrive in full on one of the networks the order page lists. A payment split across several networks cannot be accepted automatically. Every refund under the sections below is likewise owed in euros and is paid in EURC, to a wallet address you give at the time, since there is nothing to send it back to otherwise.",
|
||||
"Neither method involves a payment provider. A bank payment is an ordinary transfer you make yourself, from your own bank to the account shown on the order page, quoting the reference shown with it: that reference is what matches your payment to your order, and a transfer without it cannot be matched. Cryptocurrency payments are made in EURC, a euro-denominated stablecoin, directly to a wallet address held by Catcrafts and shown on the order page. Catcrafts never sees your card details, your bank credentials or your wallet keys, because at no point are you asked for them. Cards are not accepted.",
|
||||
"Paying in cryptocurrency changes how the money moves, not what is owed or what you are owed. Payment is accepted in EURC only, which is denominated in euros: the amount to send is exactly the euro price, with no exchange rate involved, and it must arrive in full on one of the networks the order page lists. A payment split across several networks cannot be accepted automatically.",
|
||||
"Every refund under the sections below is owed in euros, and is paid back the way you paid. A bank transfer is refunded by transfer to the account it came from. A cryptocurrency payment is refunded in EURC to a wallet address you give at the time, since there is nothing to send it back to otherwise.",
|
||||
"For support related to orders please contact orders@catcrafts.net"
|
||||
} },
|
||||
{ "Donations",
|
||||
{
|
||||
"The shop also takes donations: you name the amount, and the same payment methods apply. Mollie for bank and card, EURC for cryptocurrency. A donation is a gift that funds the open-source work; nothing is supplied in return, so no VAT is charged and no invoice is issued. The order page for a donation is its receipt.",
|
||||
"The shop also takes donations: you name the amount, and the same two payment methods apply, a bank transfer or EURC. A donation is a gift that funds the open-source work; nothing is supplied in return, so no VAT is charged and no invoice is issued. The order page for a donation is its receipt.",
|
||||
"Because nothing ships, no name or address is asked for. An email address is optional and is used only to send the confirmation. Donations appear on the financials page as an aggregate running total, never individually.",
|
||||
"A donation is not a purchase, so the returns section below does not apply to it.",
|
||||
} },
|
||||
|
|
|
|||
Loading…
Reference in a new issue