Skip to content

Billing Profiles

Overview

Billing profiles are how a merchant manages the platform subscriptions they pay Upvendo for. Each profile is a Stripe customer that groups company billing details (name, address, VAT/Tax ID), payment methods, the merchant's Upvendo subscriptions (Kiosk, Kitchen Display, Online Ordering), and the invoice history ("Past Bills"). Locations are assigned to a billing profile so their subscriptions are charged and invoiced through it.

Loyalty Program is free, not a billable subscription. Enabling loyalty for a location no longer creates a Stripe or reseller-managed subscription — it only requires that the location's POS integration supports loyalty reward reconciliation (currently MplusKassa, Kassanet, Hendrickx, Vanhoutte). "Loyalty Program" still appears as a subscription-type filter option in the Subscriptions table for historical/legacy subscriptions created before this change, and Upvendo is winding those down (canceling them at period end via an internal repair job) rather than charging for them going forward. See Subscription Types below.

This is distinct from Payment Profiles (see invoice-collection / payments), which configure how the merchant collects money from their own customers. Billing profiles are about what the merchant pays Upvendo.

Purpose

This page lets you create and manage billing profiles that handle company billing details, payment methods, subscriptions, and invoices for your Upvendo account.

Key Concepts

  • Billing Profile: A named Stripe customer holding company billing details (name, address, VAT/Tax ID), payment methods, subscriptions, and invoices. A merchant can have multiple profiles (e.g. per legal entity).
  • Payment Method: A payment instrument saved in Stripe for recurring subscription charges — a credit/debit card or SEPA Direct Debit. The dialog uses Stripe's Payment Element by default, so the exact set on offer depends on the billing country. Up to 2 payment methods per profile, one marked Primary.
  • Subscription: A per-location Upvendo service billed through the profile (Kiosk, Kitchen Display, Online Ordering). Loyalty Program is not a billed subscription anymore — see below.
  • Past Bills: The profile's invoice history, with multi-select export to a ZIP of PDFs.
  • Running Total: The sum of active subscription charges for the current billing cycle, shown before the next invoice.
  • Default Profile: One profile flagged as default for the merchant.

Route

  • Backoffice Route: /settings/billing (route name settings-billing) — lists all billing profiles
  • Profile Detail: /settings/billing/profiles/:id (route name settings-billing-profiles-detail-id)
  • Subscriptions: /settings/billing/subscriptions/:id (route name settings-billing-subscriptions)
  • Past Bills: /settings/billing/past-bills/:id (route name settings-billing-profiles-past-bills-id)
  • Navigation: Settings → Billing (icon tabler-file-euro)

Actions

Create Billing Profile

Click "New Profile" to open the New Billing Profile dialog. The only field is the profile name; click "Setup Profile" to create it. You are then taken to the profile detail page to add billing details and a payment method.

Add / Edit Billing Details

On the profile detail page, click "Add Billing Details" (or Edit) to enter company name, contact first/last name, contact email, billing address, country, VAT/Tax ID and — optionally — a separate shipping address in the Billing Details dialog.

Set as Default

Mark a profile as the default profile for the merchant.

Delete Billing Profile

Open the profile, then use the menu → Delete. A confirmation dialog asks you to type the profile name; its confirm button is labelled Deactivate. Deletion is rejected if the profile has active subscriptions ("Cannot delete billing profile with active subscriptions") or if it is the merchant's only profile ("Cannot delete the only billing profile"). If the deleted profile was the default, another profile is promoted to default automatically.

View Subscriptions

Open the subscriptions list for the profile (Kiosk, Kitchen Display, Online Ordering, plus any legacy Loyalty Program subscriptions still being wound down) to view status and unsubscribe / resubscribe.

View Past Bills

Open the invoice history for the profile, where invoices can be selected and exported.


Billing Profile Card

On /settings/billing, each profile is shown as a card with:

ElementDescription
Profile NameName of the billing profile
Default Badge"Default" chip shown when the profile is the default
Current Billing CycleShown when there are current charges: billing period plus the Running Total and a "View Current Charges" link
Payment MethodWhen a payment method exists: brand logo, brand name, last 4 digits, and a "Primary" chip, with a "View Past Bills" button
Billing Details summaryWhen billing details exist but no payment method: company name (or "Billing Details Saved") and address/email, with a "View Details" button
No Billing DetailsWhen nothing is set up yet: a prompt with an "Add Billing Details" button
SubscriptionsShown when the profile has subscriptions: a "View Subscriptions" button

Profile Detail

Profile Name

PropertyValue
Field IDname
TypeText
RequiredYes

Description: Display name for the billing profile. This is the only field collected when the profile is first created.


Payment Methods

Each profile can have up to 2 payment methods. The "Add Payment Method" button is hidden once 2 exist, and is disabled until billing details have been added.

A payment method is not necessarily a card: SEPA Direct Debit is supported alongside credit/debit cards, and the dialog's default mode is Stripe's Payment Element, which offers whatever methods Stripe has enabled for the billing country.

FieldDescription
BrandVisa, Mastercard, Amex, SEPA Debit, etc. (brand logo + brand name)
NumberLast 4 digits shown (card number or IBAN)
Primary"Primary" chip on the default payment method

Actions (per payment-method menu):

  • Add payment method (max 2; requires billing details first)
  • Change Primary Method (when it is not already primary)
  • Delete

Payment methods are added via a Stripe setup flow (ModifyPaymentMethodDialog / Stripe setup intent). In the dialog's fallback card-or-SEPA mode, choosing SEPA Direct Debit requires an IBAN, an e-mail address, and ticking the SEPA mandate-acceptance checkbox before the method can be saved.


Billing Details

Entered in the Billing Details dialog (not at profile creation). Fields include:

FieldNotes
Company nameCompany / legal name
First NameContact first name (contact_first_name, optional, max 255)
Last NameContact last name (contact_last_name, optional, max 255)
Contact emailUsed for billing
Address Line 1 / Line 2Billing address
City
Postal Code
CountryDrives the VAT vs Tax ID label
State
VAT / Tax IDLabeled VAT for EU countries, Tax ID for non-EU. EU numbers are format-checked and verified against VIES — see below
Shipping AddressOptional separate address block (line 1/2, city, state, postal code, country). A "Same as billing address" checkbox copies the billing address into it

VAT verification (VIES)

An EU VAT number entered on a billing profile is checked twice: first against a per-country format pattern, then live against VIES, the European Commission's own VAT register.

  • A save is rejected — with "This VAT number is not registered in the EU VIES database. Please check it and try again." — only when VIES definitively reports that the number does not exist.
  • The check is fail-open. If VIES is unavailable, the country is not an EU member, the country cannot be resolved from the address, or VIES checking is switched off platform-wide, the save goes through unverified. A VIES outage never blocks you.
  • While you type, the dialog shows live status ("Checking VAT number…" / "Valid VAT number" / "Not a registered VAT number" / "Couldn't verify right now — you can still save"). When VIES returns a registered business, it also shows "Registered as: {name}" with a Use "{name}" button and a Use registered address button that autofill the company name and address for you.
  • The verification result is stored on the profile, and the profile detail page shows a badge next to the VAT number: Valid VAT, Invalid VAT, or Not yet verified. Profiles saved while VIES was down are re-checked by a nightly job, so a badge can change from "Not yet verified" to "Valid VAT" without you doing anything.
  • Results are cached platform-wide for 14 days (VAT validity is a public EU-register fact, identical for every merchant).

The same VAT verification applies to reseller records, and Greek numbers are sent to VIES under the EL prefix. (Backend: app/Rules/EuVatNumber.php, app/Rules/ValidEuVat.php, app/Services/Common/ViesVatValidator.php; nightly re-check: vies:reverify, 04:30, 200 rows per run.)

How the live check behaves while you type. Typing is debounced 400ms, then the dialog POSTs { country, vat } to POST /back-office/settings/vat/verify (throttled 30/min). That endpoint is a read-only pass-through and always returns 200 with valid / invalid / unavailable / skipped — it can never block the dialog. Two details worth knowing:

  • The registered company name only backfills the Company Name field when that field is still empty — it never overwrites something you already typed.
  • The address VIES returns is free-form text, split into Address Line 1 / Postal Code / City by a best-effort parser (it understands NL alphanumeric and BE/DE/FR numeric postal codes). Anything it cannot split confidently is kept whole in the City field, so no data is ever silently dropped — check the split before saving.

(Front-end: src/@core/utils/viesVerify.ts; BillingDetailsDialog.vue:79-101,196-215; the same live-check UI is reused in the reseller form dialog.)


Subscriptions

Subscriptions are per-location Upvendo services billed through the profile. The subscriptions table (/settings/billing/subscriptions/:id) has columns: Subscription Type, Name, Status, Location, € (amount), and Actions. It can be filtered by status, subscription type, and location.

Subscription Types

TypeDescriptionBilled?
KioskSelf-service kiosk terminalYes
Kitchen DisplayKDS for kitchen ordersYes
Online OrderingWeb ordering channelYes
Loyalty ProgramCustomer loyalty featuresNo — free (legacy only, see below)

(Internally these map to product SKUs such as kiosk_first, kiosk_additional, kds, loyalty_program, online_ordering; additional kiosks beyond the first are billed as kiosk_additional.)

Online Ordering under "reseller collects" activates on the first real order, not at signup. For resellers on the reseller-collects billing model, an Online Ordering subscription is created pending activation (no activated_at), and only becomes active when the location takes its first genuine customer order on the Online Ordering channel. Until it activates it is skipped by the monthly receivable job and by commission backfill, so a reseller is not billed for a channel that has never taken an order.

What does not trigger activation:

  • an order placed in payment test mode;
  • an order whose customer email belongs to the reseller's or the merchant's own users — a staff or partner test order;
  • an order with no customer email at all, which cannot be classified and so leaves the subscription pending.

Activation stamps activated_at and creates the commission entry; every later order short-circuits. (Activation is idempotent, so a concurrent double-activation is harmless.)

Loyalty Program is free. Enabling the loyalty program for a location (Loyalty settings → toggle a program on) no longer creates a Stripe or reseller-managed subscription. Access is gated only by the location's POS integration — loyalty is only available where reward-discount reconciliation is verified, currently MplusKassa (pushes discountAmount) and Kassanet-family integrations (Hendrickx, Vanhoutte — the discount is absorbed into UnitPrice). Any other POS (or no POS) is blocked with "Loyalty is not yet available for this POS integration." The loyalty_program type still appears as a filter option in the Subscriptions table because existing paid loyalty subscriptions (created before loyalty became free) are being canceled at period end by an internal repair job rather than being charged going forward — canceling the old subscription does not remove loyalty functionality from the location, since access is now decoupled from subscription status.

Subscription Status

StatusDescription
ActiveCurrently active and billing
TrialingIn trial period (typically 30 days for new subscriptions)
CancelingActive but set to cancel at the end of the current period
Past DueA charge failed and is pending retry
PausedPaused
CanceledCanceled
IncompleteSetup not yet completed (awaiting payment confirmation)
Incomplete ExpiredIncomplete setup that expired
UnpaidInvoice unpaid after retries
ExpiredA grace period lapsed on a subscription that never got a Stripe subscription attached (set by the backend's ExpireSubscriptionJob)

The Status filter dropdown offers only the eight Stripe statuses (Active, Canceled, Incomplete, Incomplete Expired, Past Due, Paused, Trialing, Unpaid). Canceling and Expired appear as chips in the table but cannot be filtered on.

Subscription Actions

  • Unsubscribe: Cancel an active subscription. It is set to cancel at the end of the current billing period (the service stays active until then, and shows as "Canceling").
  • Resubscribe: Re-enable a subscription that is set to cancel (shown when the subscription can be reactivated).

Past Bills (Invoices)

Invoice List

The Past Bills table (/settings/billing/past-bills/:id) has these columns:

ColumnDescription
Bill #Invoice number
DateInvoice date
Bill typeInvoice type
TotalAmount
Payment StatusPayment status badge

The list is cursor-paginated (rows per page 10 / 25 / 50 / 100, with Previous / Next).

Invoice Status

StatusColorDescription
PaidGreenSuccessfully charged
ProcessingYellowPayment in progress
FailedRedPayment failed

Export Past Bills

  • Select rows with the checkboxes (maximum 10 at a time — selecting more shows a warning and trims the selection). At least one row must be selected; there is no "export everything" mode
  • Click "Export Selected" to download the chosen invoices as a ZIP file of PDFs, named invoices_<ProfileName>_<timestamp>.zip

Business Rules

  • Multiple profiles: A merchant can create several billing profiles (e.g. per legal entity); one is flagged as default.
  • Profile creation is name-only: The create dialog only asks for a name; billing details and payment methods are added afterward on the detail page.
  • Max 2 payment methods: Each profile can have up to 2 payment methods (cards and/or SEPA Direct Debit).
  • Primary payment method: One payment method is the primary one used for charges.
  • Billing details required before adding a payment method: The "Add Payment Method" button is disabled until billing details exist.
  • VAT vs Tax ID: The tax field is labeled VAT for EU countries and Tax ID otherwise.
  • EU VAT is verified against VIES: A save is rejected only when VIES definitively reports the number does not exist; VIES downtime, a non-EU country or an unresolvable country all pass through unverified.
  • Profile deletion guards: A profile cannot be deleted while it has active subscriptions, and the merchant's only remaining profile cannot be deleted. Deleting the default profile promotes another profile to default.
  • Subscription cancellation: Takes effect at the end of the billing period; the subscription shows as "Canceling" until then.
  • No manual payment retry: Failed subscription charges are retried by Stripe on its own schedule; the back office has no retry action.
  • Invoice export limit: Maximum 10 invoices per export, and at least one must be selected.
  • Loyalty Program is not billed: Enabling loyalty for a location never creates a new billing-profile subscription; it is gated by POS integration only (MplusKassa, Kassanet, Hendrickx, Vanhoutte). Existing paid loyalty subscriptions from before this change are being canceled at period end; that cancellation does not affect loyalty functionality on the location.

Logic Flows

New Billing Profile

Create profile (name only → "Setup Profile")


Add billing details (company, contact name, email, address, country, VAT/Tax ID)


Add payment method (card or SEPA Direct Debit via Stripe)


Assign profile to locations (from each location's settings)


Subscriptions billed to this profile

Subscription Billing

Billing cycle progresses (subscriptions accrue running charges)


Stripe charges the primary payment method
├── Success → Invoice paid

└── Failed → Stripe automatic retries (not-verified-here: Stripe-managed schedule)
             ├── Success → Invoice paid
             └── Still failing → Subscription goes Past Due

Retry scheduling and the number of automatic attempts are handled by Stripe (not-verified-here). There is no manual "retry payment" button in the back office — the Billing pages offer no retry action.


Customer Impact

  • Subscriptions: Services are active based on subscription status (active / trialing keep the service available).
  • Payment failures: A failed charge moves the subscription to Past Due and can interrupt the service if not resolved.
  • Invoices: Available under the profile's Past Bills.

FAQs

  • "What is a billing profile?"
    A billing profile in Upvendo is a company-level billing entity (a Stripe customer) that stores your billing details (company name, contact name, email, address, VAT/Tax ID), payment methods, subscriptions, and invoice history. Locations are assigned to a billing profile so their subscriptions are charged and invoiced through it. It is for what you pay Upvendo, not for collecting money from your own customers.

  • "How do I add a billing profile?"
    Go to Settings → Billing, click "New Profile", enter a name and click Setup Profile. You are then taken to the profile's detail page, where you click Add Billing Details to enter your company info, contact name, address, country and VAT/Tax ID, and then add a payment method. Finally, assign locations to this profile from each location's settings.

  • "How do I change my payment card?"
    Open Settings → Billing → [Billing Profile], go to the Payment Methods section, add a new payment method, set it as Primary (Change Primary Method), and delete the old one if it is no longer needed. Each profile can have up to 2 payment methods (card or SEPA Direct Debit), and charges use the primary one.

  • "Where can I download my invoices?"
    Open Settings → Billing → [Billing Profile] → Past Bills. Select up to 10 invoices and click "Export Selected" to download them as a ZIP file of PDFs (invoices_<ProfileName>_<timestamp>.zip).

  • "How do I cancel a subscription?"
    Open Settings → Billing → [Billing Profile] → Subscriptions, find the subscription (Kiosk, Kitchen Display, Online Ordering) and click Unsubscribe. It is set to cancel at the end of the current billing period; until then it shows as Canceling and the service stays active.

  • "Do I have to pay for the Loyalty Program?"
    No. Loyalty is free of charge — enabling it does not create a billing-profile subscription. It's only available on locations whose POS integration supports the required reward-discount reconciliation (currently MplusKassa, Kassanet, Hendrickx, Vanhoutte); on other POS integrations you'll see "Loyalty is not yet available for this POS integration." If you see a Loyalty Program entry in the Subscriptions list, it's a legacy subscription from before loyalty became free and is being canceled automatically — canceling it does not disable loyalty on the location.

  • "Can I have multiple billing profiles?"
    Yes. You can create multiple billing profiles (for example per legal entity) and assign different locations to each. One profile is marked as default, but each location is billed through the profile it is assigned to.

  • "How do I update my company VAT number?"
    Open the billing profile in Settings → Billing, open the Billing Details dialog, edit the VAT/Tax ID field, and save. (The field is labeled VAT for EU countries and Tax ID elsewhere.)

  • "My VAT number was rejected when I saved."
    VIES — the EU's own VAT register — reported that the number does not exist. Check the digits and that the billing country is right. If VIES is temporarily unreachable you'll instead see "Couldn't verify right now — you can still save": the save goes through unverified and is re-checked automatically overnight.

  • "Why was my payment declined?"
    A charge can fail if the card is expired, has insufficient funds, or is declined by the bank/Stripe. In Settings → Billing → [Billing Profile], update or replace the payment method and set the working one as Primary. Stripe then retries on its own schedule — there is no manual retry button. While a charge is failing, the related subscription may show Past Due.


Troubleshooting

  • Payment failed / Subscription shows Past Due → Add or set a different Primary payment method in Settings → Billing → [Profile] → Payment Methods. Stripe retries the charge automatically on its own schedule; there is no manual retry button in the back office.
  • Can't add a payment method → Add billing details first (the button is disabled until then) and ensure you have fewer than 2 payment methods.
  • Invoice not found → Open the profile's Past Bills and export the invoice you need.
  • "This VAT number is not registered in the EU VIES database" → VIES says the number does not exist. Correct the number or the billing country and save again.
  • "Couldn't verify right now — you can still save" → VIES is temporarily unreachable. Saving is not blocked; the number is stored unverified and re-checked by the nightly job, after which the badge on the profile updates on its own.

Assistant Guidance

When answering questions about billing:

  • Clarify the difference: billing profiles = what the merchant pays Upvendo (subscriptions, company invoicing); payment profiles = how the merchant collects money from their own customers.
  • For payment-method issues: guide to Settings → Billing → [Profile] → Payment Methods. Say "payment method", not "card" — SEPA Direct Debit is supported too. Never tell a merchant to "retry" a failed charge from the back office; there is no such button, only Stripe's own automatic retries.
  • For invoices: guide to Settings → Billing → [Profile] → Past Bills (select up to 10, Export Selected = ZIP of PDFs).
  • For a rejected VAT number: it is the EU VIES register saying the number does not exist, not an Upvendo rule. A VIES outage never blocks a save.
  • Note that the billing profile's company name and VAT number are also published on the storefront's General Conditions page (see Compliance) — so a wrong value there is fixed here.
  • For subscriptions: explain they are per-location and per-service (Kiosk, Kitchen Display, Online Ordering). Loyalty Program is not a paid subscription — do not tell merchants they need to buy or pay for loyalty; access is gated purely by POS integration (MplusKassa, Kassanet, Hendrickx, Vanhoutte). Any "Loyalty Program" row a merchant sees in Subscriptions is a legacy charge being wound down, not something new they need to set up.
  • Note that profile creation only asks for a name; billing details and payment methods are added afterward.
  • Note that subscription cancellations take effect at period end (shown as "Canceling").

Relations

Depends On

  • Stripe: Payment methods and subscription billing (each profile is a Stripe customer).
  • Locations: Subscriptions are per-location, and locations are assigned to a profile.

Affects

  • Subscriptions: Services billed through profiles.
  • Invoices: Generated per billing profile.
  • Locations: Each location is assigned to a billing profile.