Brands, currencies & 3D Secure
Edge Pay is multi-brand and multi-currency by design. A single tenant can present several commercial brands, acquire in several currencies, and apply different 3D Secure policies per currency — all from the same payment.yaml. This page explains how the three mechanisms fit together.
Brand routing
The brand_routing block decides which brand a payment session belongs to:
brand_routing:
default_brand: default
resolve_from:
- source: url_param
param: brand
- source: session_field
field: brand_code
Resolution walks the resolve_from chain in order:
url_param— if the payment URL carries?brand=<code>, that brand is used.session_field— otherwise, thebrand_codebound to the payment session (set when the link was issued from a document or by an agent) is used.- If neither resolves,
default_brandapplies.
default_brand should be set to your primary commercial brand at implementation time.
The brands map
Brands live in the brands map. The baseline ships a single empty default:
brands:
default: {} # Empty brand = root-level config; add per-brand entries at fork time
An empty brand inherits the root configuration — the root-level branding and copy blocks apply unchanged. This is the correct shape for a single-brand tenant: one brand, no duplication.
Multi-brand tenants add named entries during implementation, each carrying only the overrides that differ from root — typically branding (logo, colors) and copy (brand voice, sign-offs):
brands:
default: {}
meridian-uk:
branding:
name: Meridian Travel UK
logo:
url: "https://assets.example.com/meridian-uk/logo.svg"
copy:
success_message: Thank you for booking with Meridian Travel UK.
meridian-us:
branding:
name: Meridian Travel US
A common implementation pattern is a dedicated brand for the trade channel — an "agent portal" brand set as the default when agents, rather than guests, are the primary payers. This pattern is proven in production.
Brand is identity, not presentation
A core platform rule: in document and session data, a brand is identity only — a {code, name} pair. Hex colors, fonts, and logo URLs never travel in data. Instead, the brand code is the key into the brands map (and the equivalent map in your document configuration), and all presentation resolves from tenant config at render time.
This matters for two reasons:
- Consistency — a rebrand is a config change in one place, not a data migration.
- Integrity — payment pages cannot be styled by whoever constructs a URL; only codes that exist in your
brandsmap resolve, and unknown codes fall back to the default brand.
The same meta.brand object that drives document rendering in Edge Docs drives payment-page branding, so a guest moving from a proposal to its payment link stays inside one visual identity. See Schemas for how meta.brand is structured in document data.
Per-currency merchant accounts
Braintree settles each currency into a dedicated merchant account. The merchant_accounts map names one account per acquiring currency:
gateways:
braintree:
merchant_accounts:
DEFAULT: "vault::braintree_merchant_id"
USD: meridian_travel_usd
CAD: meridian_travel_cad
GBP: meridian_travel_gbp
AUD: meridian_travel_aud
EUR: meridian_travel_eur
NZD: meridian_travel_nzd
- Values are Braintree merchant account names, not secrets — they appear in plain text.
DEFAULTis the fallback when a transaction's currency has no explicit entry.- At payment time, the platform selects the account matching the booking's currency; the guest is charged in that currency with no conversion surprise.
List every currency you will acquire in when the tenant is first set up, even ones you will not use immediately. Adding a currency later means provisioning a new Braintree merchant account, updating configuration, and re-verifying the payment flow for that currency — retrofitting is consistently more painful than declaring up front.
Per-currency 3D Secure
3D Secure (3DS) policy is also set per acquiring currency:
three_d_secure:
per_currency:
DEFAULT: false
GBP: true # SCA regulation — keep true for UK/EU acquiring
EUR: true # SCA regulation — keep true for UK/EU acquiring
The baseline reflects the regulatory reality: GBP and EUR are true because Strong Customer Authentication (SCA) applies to UK and EU acquiring — do not disable 3DS for these currencies. Other currencies default to false, where 3DS is optional and often traded off against checkout friction; enable it per currency if your fraud posture warrants it.
The same per_currency structure appears both at gateway level and on the braintree_card payment method, so the policy travels with the method configuration.
How a payment resolves brand and currency
When a payment link is opened, the platform combines the mechanisms above:
- The payment session carries the booking's
meta.currency(an ISO 4217 code) andmeta.brand({code, name}) — the same metadata that drove the source document. - Currency selects the merchant account from
merchant_accounts(falling back toDEFAULT) and the 3DS policy fromthree_d_secure.per_currency. - Brand is resolved through
brand_routing(URL parameter, then session field, then default) and selects the branding and copy overrides from thebrandsmap.
The result: a guest paying a GBP booking under your UK brand sees the UK logo and copy, is charged through the GBP merchant account, and is challenged with 3DS — while a USD booking under another brand of the same tenant takes a different path through the same configuration, with no per-brand or per-currency code anywhere.
Related pages
- payment.yaml reference — the full
gatewaysandbrand_routingblocks in context - Salesforce integration — where currency and brand originate on the org side
- Rebranding — updating brand assets across documents and payment pages together