Customization
What every link inherits from your account, and what each one controls on its own.
Two different things shape a link's page, and confusing them is what makes this feel harder than it is.
Your brand is set once for the whole account and applies to every payment page you will ever serve: logo, colours, font, radius. Your link controls its own content: the images, the wording, the button, the questions asked, the languages offered, who is allowed to open it.
So the answer to "can I make this link look different from that one" is: not in its colours, yes in almost everything else.
What comes from the account, once
Logo, palette, font, corner radius and appearance mode live in Settings → Branding. Change them there and every link updates at once, alongside your hosted checkout and your invoices. The full table is on Hosted Checkout, since it is the same setting serving all three.
Branding needs a paid plan
Settings → Branding needs the Branding feature, which starts at Growth. On Pay as you go
every link keeps the default appearance. Serving links from your own domain instead of
wajub.link is a separate feature, Custom domain, starting at Scale.
What belongs to the link
Everything below is per link, and two links in the same account can differ on every one of them.
Images
A poster is the banner at the top of the page, and gallery holds up to ten more shown beneath
it. For a product this is the difference between a page that sells and a page that states a price.
The two routes differ in what they take. The Dashboard uploads files, JPEG, PNG, GIF or WebP up to 10 MB each, and hosts them for you. The API takes URLs you already host, up to 2 048 characters each, and never uploads anything. Point them at images you serve yourself.
The button, and what follows the payment
cta_type sets the button wording from buy_now, pay, donate, register, or custom paired
with your own custom_cta_text of up to 50 characters.
thank_you_message replaces the default confirmation once the payment succeeds. It is the last
thing the payer reads, so it is the right place for a delivery time or a next step.
Questions for the payer
extra_fields adds inputs to the page: a table number, a size, a note for the kitchen.
A field has a name, lowercase letters, digits and underscores, a label, a type among
text, email, tel, textarea, select and checkbox, a required flag, an optional
placeholder, and for a select its options. A link takes up to ten fields. The page asks
for the payer's email on top of them, always: a payment on a link cannot be made without one.
The Dashboard checks that shape. POST /links stores extra_fields as you send it, without
checking, so a field without a name or a type will not render as you expect. The answers travel
with the payment, nested rather than flattened: read metadata.extra_fields.size in your webhook
handler, not metadata.size.
Promo codes
A link carries up to twenty promo codes, set in the Dashboard. Each has a code, 3 to 32
uppercase letters, digits, dashes or underscores, unique across your links, a discount that is a
percentage or a fixed amount, and optionally a cap on redemptions and an expiry date. The payer
types the code on the page and sees the discount before paying.
Digital products
A digital product is delivered by email once the payment succeeds, so the payer must give an
email address. In the Dashboard you either upload the file, from the Growth plan, or give an
https URL to it, on every plan.
Languages
A link can be bilingual. supported_locales lists which of fr and en the page offers,
default_locale says which one opens first, and translations carries the other version keyed by
locale.
Only four fields translate: title, description, custom_cta_text and thank_you_message. The
base fields on the link are what the default locale shows, so you only ever write the second
language into translations.
Currencies
supported_currencies lets the payer switch currency on the page. The link's own currency is
always offered, and whatever you add joins it.
Who is allowed in
Four independent gates, and the page closes when any one of them trips.
| Set | The page answers |
|---|---|
is_public set to false | 404, the link is unpublished |
access_password | A password prompt before anything else is shown |
max_views reached | 410, the view limit is spent |
expiry_date past, or is_archived | 410, the link is over |
A password-protected link asks for the password, then issues a short-lived token for that visitor.
Note that a blocked attempt is not counted as a view, so the password gate does not eat into
max_views.
What each type adds
The type brings its own controls, and they only exist on that type.
| Type | What you can tune |
|---|---|
product | product_variants, stock, shipping, weight, and for a service the duration, location and meeting URL |
event | Ticket types with their own name, price and quantity, event_capacity, generate_qr_tickets, attendee_info_fields, refund_policy |
fundraising | show_progress, show_contributors, allow_overflow, impact_tiers, campaign_deadline, fundraising_milestones |
donation | suggested_amounts, allow_custom_amount, min_amount, max_amount, allow_anonymous, show_donor_wall |
What the API can set, and what it cannot
This is the part worth knowing before you automate anything. The API and the Dashboard do not reach
the same fields, and POST /links reaches more than PUT /links/{id}.
| Field | Create via API | Update via API | Dashboard |
|---|---|---|---|
title, description, price | Yes | Yes | Yes |
currency | Yes | No | Yes |
target_amount, min_amount, max_amount | Yes | Yes | Yes |
callback_url | Yes | Yes | No |
cta_type, custom_cta_text | Yes | Yes | Yes |
custom_url, tags | Yes | Yes | Yes |
category_id | Before API version 2026-10-12 | Before 2026-10-12 | Yes |
is_public, is_archived, expiry_date, sales_limit | Yes | Yes | Yes |
accept (payment methods offered) | Yes | Yes | Yes |
extra_fields, thank_you_message | Yes | No | Yes |
poster, gallery | Yes, as URLs | No | Yes, as uploads |
| Type-specific fields, event and fundraising | Yes | No | Yes |
supported_locales, default_locale, translations | No | No | Yes |
supported_currencies | No | No | Yes |
access_password, max_views | No | No | Yes |
| Promo codes, a digital product's file | No | No | Yes |
| Custom domain, ticket types | No | No | Yes |
Updating through the API is narrower than creating
PUT /links/{id} accepts seventeen fields, not the hundred that creation does. A field it
does not list is silently ignored rather than rejected, so a call that changes poster or
extra_fields returns 200 and changes nothing. Anything outside that table is edited in the
Dashboard.
From API version 2026-10-12, a link has no category_id: no endpoint lists the categories it
would name, so the API neither takes it on POST and PUT, nor filters GET /links on it, nor
returns it. Earlier versions keep it. Versioning
In the Dashboard
Links → a link → Edit is where the whole surface lives, with a preview beside the fields. It is the only place that reaches languages, currencies, the access password, the view limit, a custom domain and event ticket types.
Each link also carries its own webhook endpoints, separate from your account-wide ones, with their own secret, a test send and a retry. Use them when one campaign needs to notify a system the rest of your account does not.
Related pages
- Payment LinksWhat the product is, and when a link beats an integration.
- QuickstartCreate a link, publish it, share it.
- Tracking and conversionsViews, conversion rate, and the life of a link.
- Hosted Checkout brandingThe account-wide settings every payment page inherits.
- Payment Links API referenceEvery field the API accepts, endpoint by endpoint.