Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
60a74b4
Migrate Hub billing from store to api and add invoice checkout
tobihagemann Jun 5, 2026
ce563d4
Add missing billing service prefix to api endpoint URLs
tobihagemann Jun 11, 2026
147bd6c
Merge remote-tracking branch 'origin/develop' into feature/hub-billin…
tobihagemann Jul 6, 2026
78b57b1
Adopt session-first billing flow: customer lookup, session links, ses…
tobihagemann Jul 6, 2026
f722818
Add invoice order summary with exact EspoCRM pricing and prorated sea…
tobihagemann Jul 7, 2026
535f7f2
Merge branch 'develop' into feature/hub-billing-api-migration
tobihagemann Jul 8, 2026
aa42f11
Turn invoice checkout into a Paddle-style modal and make billing dial…
tobihagemann Jul 16, 2026
1b0159e
expect custom_billing: null from store instead of the contract 404
tobihagemann Jul 21, 2026
4497467
own the billing page's error texts instead of displaying backend mess…
tobihagemann Jul 21, 2026
40457e8
Merge branch 'develop' into feature/hub-billing-api-migration
overheadhunter Aug 4, 2026
3a47f92
fix TypeError: Currency code is required
overheadhunter Aug 6, 2026
905f158
show available credit in the seat-change confirmation, dropping the u…
tobihagemann Aug 17, 2026
f3e66fe
show seat-change amounts as tax-inclusive and what is credited on a d…
tobihagemann Aug 19, 2026
4f4d9fa
prefill the invoice checkout read-only from the account on file, taki…
tobihagemann Aug 20, 2026
597e3c9
set the production EspoCRM product ids for the two self-checkout Hub …
tobihagemann Aug 20, 2026
04dd196
bound the checkout seats by the range the api reports
tobihagemann Aug 21, 2026
8136073
keep the localized price error instead of showing the api's message
tobihagemann Aug 21, 2026
eeecde2
bound the change-seats stepper by the contractual range from the api
tobihagemann Aug 21, 2026
cab815f
let a manually-invoiced Hub reach the checkout, since the plan decide…
tobihagemann Aug 22, 2026
35b6995
point a returning customer at sales when the api cannot settle their tax
tobihagemann Aug 22, 2026
2d817b3
disable the seat-change confirmation until a quote arrives, so no unp…
tobihagemann Aug 23, 2026
2c7bab7
drop the contact name fields from the invoice checkout, which the pur…
tobihagemann Aug 24, 2026
11c6773
lock the card checkout email to the verified session address, in our …
tobihagemann Aug 24, 2026
13a9ce7
drop the early access opt-in and labels, since Hub 2.0.0 is no longer…
tobihagemann Aug 24, 2026
1c09b10
give a failed load its own screen, so an error never strands the page…
tobihagemann Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions assets/js/const.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const PADDLE_HUB_MANAGED_MONTHLY_PLAN_ID = {{ .Site.Params.paddleHubManagedMonth
const PADDLE_PRICES_URL = '{{ .Site.Params.paddlePricesUrl }}';
const PADDLE_DESKTOP_SALE_PRICE_ID = '{{ .Site.Params.paddleDesktopSalePriceId }}';
const PADDLE_ANDROID_SALE_PRICE_ID = '{{ .Site.Params.paddleAndroidSalePriceId }}';
const ESPOCRM_HUB_SELF_HOSTED_PRODUCT_ID = '{{ .Site.Params.espocrmHubSelfHostedProductId }}';
const ESPOCRM_HUB_MANAGED_PRODUCT_ID = '{{ .Site.Params.espocrmHubManagedProductId }}';
const LEGACY_STORE_URL = '{{ .Site.Params.legacyStoreUrl }}';
const HUB_MANAGED_DOMAIN = '{{ .Site.Params.hubManagedDomain }}';
const STRIPE_PK = '{{ .Site.Params.stripePk }}';
570 changes: 379 additions & 191 deletions assets/js/hubsubscription.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions config/_default/hugo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ module:
target: assets/js/jquery
- source: node_modules/alpinejs/dist
target: assets/js/alpinejs
- source: node_modules/@alpinejs/focus/dist
target: assets/js/alpinejs-focus
- source: node_modules/lazysizes
target: assets/js/lazysizes
- source: node_modules/js-yaml/dist
Expand Down
4 changes: 4 additions & 0 deletions config/development/params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@ paddleHubManagedYearlyPlanId: 42235
paddleHubManagedMonthlyPlanId: 82379
paddlePricesUrl: https://sandbox-checkout.paddle.com/api/2.0/prices

# ESPOCRM
espocrmHubSelfHostedProductId: 69bd302d5c65eabaa
espocrmHubManagedProductId: 69bd302d521a70103

# STRIPE
stripePk: pk_test_51RCM24IBZmkR4F9UiLBiSmsAnJvWqmHcDLxXR8ABKK1MNsZk3zCk2VJW7ZfaBlD81zpQxCX243sS3LEp9dABwiG800kJnGykDF
4 changes: 4 additions & 0 deletions config/production/params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@ paddleHubManagedYearlyPlanId: 807339
paddleHubManagedMonthlyPlanId: 914173
paddlePricesUrl: https://checkout.paddle.com/api/2.0/prices

# ESPOCRM
espocrmHubSelfHostedProductId: 6a4fd3f914e21a1a7
espocrmHubManagedProductId: 6a4fd3f9039df8c27

Comment thread
coderabbitai[bot] marked this conversation as resolved.
# STRIPE
stripePk: pk_live_eSasX216vGvC26GdbVwA011V
4 changes: 4 additions & 0 deletions config/staging/params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@ paddleHubManagedYearlyPlanId: 42235
paddleHubManagedMonthlyPlanId: 82379
paddlePricesUrl: https://sandbox-checkout.paddle.com/api/2.0/prices

# ESPOCRM
espocrmHubSelfHostedProductId: 69bd302d5c65eabaa
espocrmHubManagedProductId: 69bd302d521a70103

# STRIPE
stripePk: pk_test_51RCM24IBZmkR4F9UiLBiSmsAnJvWqmHcDLxXR8ABKK1MNsZk3zCk2VJW7ZfaBlD81zpQxCX243sS3LEp9dABwiG800kJnGykDF
54 changes: 54 additions & 0 deletions data/de/eu_countries.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
- code: AT
name: Österreich
- code: BE
name: Belgien
- code: BG
name: Bulgarien
- code: HR
name: Kroatien
- code: CY
name: Zypern
- code: CZ
name: Tschechien
- code: DK
name: Dänemark
- code: EE
name: Estland
- code: FI
name: Finnland
- code: FR
name: Frankreich
- code: DE
name: Deutschland
- code: GR
name: Griechenland
- code: HU
name: Ungarn
- code: IE
name: Irland
- code: IT
name: Italien
- code: LV
name: Lettland
- code: LT
name: Litauen
- code: LU
name: Luxemburg
- code: MT
name: Malta
- code: NL
name: Niederlande
- code: PL
name: Polen
- code: PT
name: Portugal
- code: RO
name: Rumänien
- code: SK
name: Slowakei
- code: SI
name: Slowenien
- code: ES
name: Spanien
- code: SE
name: Schweden
54 changes: 54 additions & 0 deletions data/en/eu_countries.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
- code: AT
name: Austria
- code: BE
name: Belgium
- code: BG
name: Bulgaria
- code: HR
name: Croatia
- code: CY
name: Cyprus
- code: CZ
name: Czechia
- code: DK
name: Denmark
- code: EE
name: Estonia
- code: FI
name: Finland
- code: FR
name: France
- code: DE
name: Germany
- code: GR
name: Greece
- code: HU
name: Hungary
- code: IE
name: Ireland
- code: IT
name: Italy
- code: LV
name: Latvia
- code: LT
name: Lithuania
- code: LU
name: Luxembourg
- code: MT
name: Malta
- code: NL
name: Netherlands
- code: PL
name: Poland
- code: PT
name: Portugal
- code: RO
name: Romania
- code: SK
name: Slovakia
- code: SI
name: Slovenia
- code: ES
name: Spain
- code: SE
name: Sweden
106 changes: 84 additions & 22 deletions i18n/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
translation: "Ich bin damit einverstanden, Neuigkeiten von Cryptomator Hub zu erhalten, und akzeptiere die <a class=\"text-link\" href=\"/de/privacy/\">Datenschutzerklärung</a>."
- id: accept_hub_newsletter_optional
translation: "Ich bin damit einverstanden, Neuigkeiten von Cryptomator Hub per E-Mail zu erhalten (optional)."
- id: accept_hub_managed_early_access_optional
translation: "<span class=\"inline-flex px-2 py-0.5 rounded-full text-xs font-medium uppercase bg-primary-l2 text-dark\">Early Access</span> <a class=\"text-link\" href=\"https://docs.cryptomator.org/hub/early-access/\" target=\"_blank\">Cryptomator Hub 2.0.0</a> mit brandneuen Features und einer verlängerten kostenlosen 60-Tage-Testphase testen (optional)."
- id: accept_privacy
translation: "Ich akzeptiere die <a class=\"text-link\" href=\"/de/privacy/\">Datenschutzerklärung</a>."
- id: accept_privacy_implicitly
Expand Down Expand Up @@ -408,10 +406,6 @@
translation: "Jetzt anmelden"
- id: hub_header_managed_cta_description
translation: "Startet eure kostenlose 30-Tage-Testversion noch heute, keine Kreditkarte erforderlich."
- id: hub_header_kicker_early_access
translation: "Hub 2.0.0 Early Access*"
- id: hub_header_early_access_note
translation: "<a class=\"text-link\" href=\"https://docs.cryptomator.org/hub/early-access/\" target=\"_blank\">Early Access</a> beinhaltet brandneue Features und eine verlängerte kostenlose 60-Tage-Testphase."
- id: hub_header_group_magic_alt
translation: "Cryptobot verbindet eine Gruppe von Menschen mit seinen magischen Fähigkeiten durch Zero-Knowledge-Verschlüsselung"

Expand Down Expand Up @@ -540,12 +534,13 @@
- id: hub_billing_linkexpired_description
translation: "Dieser Link ist nicht mehr gültig. Bestätigungslinks können nur einmal verwendet werden und verfallen nach einer Weile. Bitte fordere über deine Hub-Instanz einen neuen Link an."

- id: hub_billing_loadfailed_description
translation: "Wir konnten deine Abonnement-Informationen nicht laden. Bitte kontaktiere uns, falls das Problem weiterhin besteht."

- id: hub_billing_manage_status_title
translation: "Status"
- id: hub_billing_manage_status_active
translation: "Aktiv"
- id: hub_billing_manage_status_pastdue
translation: "Überfällig"
- id: hub_billing_manage_status_trialing
translation: "Testphase"
- id: hub_billing_manage_status_paused
Expand All @@ -568,12 +563,10 @@

- id: hub_billing_manage_payment_info_title
translation: "Zahlungsinformationen"
- id: hub_billing_manage_payment_info_credit_card
translation: "Kreditkarte"
- id: hub_billing_manage_payment_info_credit_card_last_four_digits_description
translation: "Endet mit"
- id: hub_billing_manage_payment_info_paypal
translation: "PayPal"
- id: hub_billing_manage_payment_info_card
translation: "Karte / PayPal"
- id: hub_billing_manage_payment_info_invoice
translation: "Rechnung"
- id: hub_billing_manage_payment_info_update_action
translation: "Zahlungsmethode aktualisieren"

Expand All @@ -586,8 +579,6 @@
- id: hub_billing_manage_license_key_retry_action
translation: "Erneut versuchen"

- id: hub_billing_manage_modal_charge_amount_description
translation: "Rechnungsbetrag"
- id: hub_billing_manage_modal_continue
translation: "Weiter"
- id: hub_billing_manage_modal_confirm
Expand All @@ -610,8 +601,22 @@
translation: "Neue Anzahl der Sitze"
- id: hub_billing_manage_change_quantity_confirmation_increase_warning
translation: "Du bist dabei, das Sitzplatzlimit zu erhöhen. Wenn du dies bestätigst, wird die die Differenz sofort in Rechnung gestellt."
- id: hub_billing_manage_change_quantity_confirmation_increase_warning_invoice
translation: "Du bist dabei, das Sitzplatzlimit zu erhöhen. Wenn du dies bestätigst, werden die zusätzlichen Sitze per Rechnung abgerechnet."
- id: hub_billing_manage_change_quantity_confirmation_decrease_warning
translation: "Du bist dabei, das Sitzplatzlimit zu verringern. Wenn du dies bestätigst, wird deine nächste Zahlung um die Differenz reduziert."
- id: hub_billing_manage_change_quantity_confirmation_decrease_warning_invoice
translation: "Du bist dabei, das Sitzplatzlimit zu verringern. Wenn du dies bestätigst, wird die Reduzierung auf deiner nächsten Rechnung berücksichtigt."
- id: hub_billing_manage_change_quantity_confirmation_prorated_invoice
translation: "Jetzt in Rechnung gestellter Betrag"
- id: hub_billing_manage_change_quantity_confirmation_credited_invoice
translation: "Gutschrift auf dein Konto"
- id: hub_billing_manage_change_quantity_confirmation_incl_vat
translation: "inkl. {rate} % USt."
- id: hub_billing_manage_change_quantity_confirmation_available_credit_invoice
translation: "Verfügbares Guthaben (wird mit einer künftigen Rechnung verrechnet, keine Rückzahlung)"
- id: hub_billing_manage_change_quantity_confirmation_new_recurring_invoice
translation: "Neuer Jahresbetrag (netto)"

- id: hub_billing_checkout_description
translation: "Schöpfe das volle Potenzial deiner Hub-Instanz aus und hol dein Team mit der clientseitigen Verschlüsselung für deinen Cloud-Speicher an Bord."
Expand Down Expand Up @@ -643,13 +648,74 @@
translation: "Nur Nutzer, die Zugang zu Tresoren haben, werden auf die Anzahl der Sitze angerechnet."
- id: hub_billing_checkout_standard_email
translation: "E-Mail"
- id: hub_billing_checkout_standard_email_placeholder
translation: "E-Mail-Adresse"
- id: hub_billing_checkout_standard_instruction
translation: "Zahlungen werden über Paddle abgewickelt."
- id: hub_billing_checkout_standard_submit
translation: "Zur Zahlung"

- id: hub_billing_checkout_payment_method
translation: "Zahlungsmethode"
- id: hub_billing_checkout_payment_method_card
translation: "Per Karte zahlen"
- id: hub_billing_checkout_payment_method_invoice
translation: "Kauf auf Rechnung"

- id: hub_billing_checkout_invoice_email
translation: "E-Mail"
- id: hub_billing_checkout_invoice_email_hint
translation: "Mit dieser E-Mail-Adresse verwaltest du später dein Abonnement."
- id: hub_billing_checkout_invoice_account_name
translation: "Firmenname"
- id: hub_billing_checkout_invoice_address_street
translation: "Straße und Hausnummer"
- id: hub_billing_checkout_invoice_address_postal_code
translation: "Postleitzahl"
- id: hub_billing_checkout_invoice_address_city
translation: "Stadt"
- id: hub_billing_checkout_invoice_address_country
translation: "Land"
- id: hub_billing_checkout_invoice_address_country_placeholder
translation: "Bitte auswählen"
- id: hub_billing_checkout_invoice_non_eu_hint
translation: "Kauf auf Rechnung ist nur innerhalb der EU möglich. Außerhalb der EU? Kontaktiere uns bitte über die Enterprise-Option."
- id: hub_billing_checkout_invoice_vat_id
translation: "USt-IdNr."
- id: hub_billing_checkout_invoice_details_on_file
translation: "Dies sind die Rechnungsdaten, die wir zu deiner E-Mail-Adresse gespeichert haben. Melde dich bei uns, wenn sie geändert werden müssen."
- id: hub_billing_checkout_invoice_vat_id_hint
translation: "Erforderlich für EU-Länder außerhalb Deutschlands."
- id: hub_billing_checkout_invoice_instruction
translation: "Eine Rechnung wird ausgestellt und an deine E-Mail-Adresse gesendet."
- id: hub_billing_checkout_invoice_submit
translation: "Auf Rechnung kaufen"
- id: hub_billing_checkout_invoice_total_suffix
translation: "pro Jahr (netto)"
- id: hub_billing_checkout_invoice_total_vat_hint
translation: "zzgl. 19 % USt."
- id: hub_billing_checkout_invoice_total_reverse_charge_hint
translation: "Reverse-Charge-Verfahren – Steuerschuldnerschaft des Leistungsempfängers"
- id: hub_billing_checkout_invoice_confirm_title
translation: "Bestellübersicht"
- id: hub_billing_checkout_invoice_confirm_unit_price
translation: "Preis pro Seat"
- id: hub_billing_checkout_invoice_quantity_decrease
translation: "Anzahl der Seats verringern"
- id: hub_billing_checkout_invoice_quantity_increase
translation: "Anzahl der Seats erhöhen"
- id: hub_billing_checkout_invoice_price_loading
translation: "Preis wird geladen …"
- id: hub_billing_checkout_invoice_price_error
translation: "Der Preis konnte nicht geladen werden."
- id: hub_billing_checkout_invoice_price_retry
translation: "Erneut versuchen"

- id: hub_billing_checkout_success_description
translation: "Vielen Dank für deinen Kauf! Dein Abonnement ist jetzt aktiv."
- id: hub_billing_checkout_success_invoice_description
translation: "Eine Rechnung wird ausgestellt und an deine E-Mail-Adresse gesendet."
- id: hub_billing_checkout_success_relicense_description
translation: "Um deine Lizenz zu erhalten, kehre bitte zu deiner Hub-Instanz zurück und starte den Abonnementvorgang erneut."

- id: hub_billing_checkout_community_title
translation: "Community"
- id: hub_billing_checkout_community_statement
Expand Down Expand Up @@ -677,10 +743,6 @@
- id: hub_billing_checkout_enterprise_action
translation: "Kontaktiere uns"

- id: hub_billing_manualinvoice_description
translation: "Um dein Abonnement zu verwalten, wende dich bitte an unser Support-Team."
- id: hub_billing_manualinvoice_action
translation: "Kontaktiere uns"

# Hub Demo
- id: hub_demo_description
Expand Down
Loading