Tip

How Tip works

Last updated: 2026-08-03

Tip is the tip jar built into the web apps operated by Bellissimo, Inc., dba Tip. This page covers both sides of it: leaving a tip, and how the box is added to one of our apps. Tip serves only apps we operate — it is not a public platform and there is nothing to sign up for.

Leaving a tip

  1. Pick an amount — the preset tiers, or Other amount for anything from $1 to $500.
  2. Choose One-time or Monthly.
  3. The box shows the exact charge and the exact statement line, then Continue opens Stripe's secure checkout — card, Apple Pay, Google Pay, or Cash App Pay, depending on your device. Card details never touch our servers.
  4. Stripe emails your receipt. That is the end of it, unless you chose monthly.

What appears on your statement

Card charges show the TIP prefix plus the app you tipped, for example TIP* APP1.COM or TIP* APP345.COM. The box shows you this string before you pay. If a charge ever looks unfamiliar, email sent.tip.web.app@gmail.com before disputing it — we refund faster than your bank can.

Monthly tips

A monthly tip charges the same amount each month until you cancel. You can cancel at any time from the subscription portal — enter your email, no account needed — or by emailing sent.tip.web.app@gmail.com. Cancellation stops all future charges immediately.

The Venmo button

The blue venmo button is a direct link to our Venmo business profile with the amount and app name prefilled. It is not processed by Stripe: the charge appears as VENMO on your statement, you get Venmo's receipt rather than ours, and a refund is arranged by email.

Refunds

Any tip is refundable on request, for any reason, within 60 days — see the refund policy.

Adding the tip box to an app

For our own apps. An app must be registered with the Tip service first — the service refuses requests from origins it does not recognize, so pasting the snippet on an unregistered site renders nothing.

The embed

One line, placed where someone finishes reading:

<script src="https://sent-tip.web.app/widget.js" data-site="your-app.com" async></script>

With no data-mount, the box renders exactly where the tag sits. Everything renders inside a shadow root: the app's CSS cannot break the box, and the box cannot leak styles into the app.

Every attribute

<div id="support"></div>
<script
  src="https://sent-tip.web.app/widget.js"
  data-site="your-app.com"
  data-mount="#support"
  data-theme="auto"
  data-accent="#0f766e"
  data-kicker="Was this useful?"
  data-heading="Support this app"
  data-blurb="If you'd like to support this free app, send a tip below:"
  async></script>
AttributeRequiredWhat it does
data-siteyesRegistry id of the app. Everything else is optional.
data-mountnoCSS selector for the container; omit to render in place.
data-themenoauto (default), light, or dark.
data-accentnoAny CSS color; the whole box recolors from it.
data-kickernoHook line above the heading.
data-headingnoOverrides "Support <name>".
data-blurbnoOverrides the line under the heading.
data-endpointnoOnly when serving the widget from a different origin.

Prices, tiers, copy, the Venmo handle, and the statement descriptor are deliberately not attributes. They live in the server-side registry — one entry per app — so changing a price never means editing app pages.

Theming

Custom properties cross the shadow boundary from any ancestor:

:root {
  --tip-accent:    #0f766e;   /* one variable recolors the whole box */
  --tip-radius:    14px;
  --tip-max-width: 44rem;
}

Also available: --tip-fg, --tip-muted, --tip-surface, --tip-raised, --tip-border, --tip-font, --tip-danger, --tip-reserve. Dark mode is automatic.

Single-page apps

Auto-mount runs on DOMContentLoaded, before a framework renders. Omit data-site and mount manually instead:

<script src="https://sent-tip.web.app/widget.js" async></script>

<script>
  // After your framework has rendered the container:
  window.Tip.mount('#support', {
    site: 'your-app.com',
    endpoint: 'https://sent-tip.web.app',
  });
</script>

Content-Security-Policy

Apps with a strict CSP need two grants. Nothing else: the box injects no third-party scripts, sets no cookies, and applies its styles via constructed stylesheets, so style-src 'self' can stay.

script-src  'self' https://sent-tip.web.app
connect-src 'self' https://sent-tip.web.app

If nothing appears

The box deliberately renders nothing when its configuration request fails — a broken box is worse than no box. The browser console says why, prefixed [tip]:

Console messageCause
config request failed (404)The app is not registered.
config request failed (403)The page's origin is not on that app's allowlist.
no element matches "#support"The data-mount selector found nothing.
Renders, but Continue does nothingThe service needs a redeploy with this app's registry entry.

Questions

Email sent.tip.web.app@gmail.com — a human reads it.