Skip to content

Customization

What every link inherits from your account, and what each one controls on its own.

Your brand, set once for the account, gives every link its logo, colours, font and radius. Each link controls its own content: images, wording, button, questions, languages and who may open it.

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 Design Customization 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.

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.

Two questions on the page
{
"extra_fields": [
{
"name": "size",
"label": "Size",
"type": "select",
"required": true,
"options": [
"S",
"M",
"L"
]
},
{
"name": "note",
"label": "Note to the seller",
"type": "textarea",
"required": false
}
]
}

Give every field a name and a type. 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; file_url on POST /links takes an address of yours, not a file uploaded in the Dashboard.

The email's Download now button is a link bound to that payment, never the file's own address, and the page shows the file only after payment. The download works for the access period you set in the Dashboard, or for good without one, even once the link is closed or archived, and stops when the payment is refunded in full. With single_use_access: true the buyer downloads the file once: the download page asks them to keep it, and a later visit says the download was used. That is the buyer's access, not the link's: the next buyer can still buy, unless the link is a single-use link. When file_url is your own address, the buyer is sent on to it, so protect it as you would any download.

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.

The same link, in two languages
{
"default_locale": "fr",
"supported_locales": [
"fr",
"en"
],
"translations": {
"en": {
"title": "Amina Coffee, 250 g",
"description": "Roasted in Douala, ground to order.",
"custom_cta_text": "Order now",
"thank_you_message": "Thank you, we ship within 48 hours."
}
}
}

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

Five independent gates, and the page closes when any one of them trips.

SetThe page answers
is_public set to false404, the link is unpublished
access_passwordA password prompt before anything else is shown
max_views reached410, the view limit is spent
expiry_date past, or is_archived410, the link is over
single_use_link, once paidThat the link has already been used to pay

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.

TypeWhat you can tune
productproduct_variants, stock, shipping, weight, and for a service the duration, location and meeting URL
eventTicket types with their own name, price and quantity, event_capacity, generate_qr_tickets, attendee_info_fields, refund_policy
fundraisingshow_progress, show_contributors, allow_overflow, impact_tiers, campaign_deadline, fundraising_milestones
donationsuggested_amounts, allow_custom_amount, min_amount, max_amount, allow_anonymous, show_donor_wall

A service's meeting URL is never on the page before payment: the payer gets it in the confirmation email of their payment, with what to prepare, and the page offers to join it once they have paid.

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}.

FieldCreate via APIUpdate via APIDashboard
title, description, priceYesYesYes
currencyYesNoYes
target_amount, min_amount, max_amountYesYesYes
callback_urlYesYesNo
cta_type, custom_cta_textYesYesYes
custom_url, tagsYesYesYes
category_idNoNoYes
is_public, is_archived, expiry_date, sales_limitYesYesYes
accept (payment methods offered)YesYesYes
extra_fields, thank_you_messageYesNoYes
poster, galleryYes, as URLsNoYes, as uploads
Type-specific fields, event and fundraisingYesNoYes
supported_locales, default_locale, translationsNoNoYes
supported_currenciesNoNoYes
access_password, max_viewsNoNoYes
single_use_link, single_use_accessYesNoYes
file_url, a digital product's file at your own addressYesNoYes, or an upload
Promo codesNoNoYes
Custom domain, ticket typesNoNoYes

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. A delivery counts only when the endpoint answers with a 2xx: any other answer, a redirect included, is logged as failed and retried, and a redirect is never followed. The test send tells you only whether the endpoint accepted it.

What did you think of this content?