Skip to main content

payment.yaml reference

This page walks through payment.yaml top to bottom, in the order the blocks appear in the file. Every excerpt is taken from the Meridian Travel Co. baseline — the configuration your tenant starts from. For the capability model (enabled / disabled stub / fork-time) see the overview.

The file begins with the tenant identifier:

tenant_id: meridian

salesforce

Controls how the payment platform talks to your Salesforce org.

salesforce:
mode: live
kaptio_namespace: KaptioTravel
rest_endpoint: /services/apexrest/edge/payments
itinerary_extra_select_fields:
- KaptioTravel__Subtotal__c
- KaptioTravel__Total_Price__c
- KaptioTravel__TotalAmountNet__c
- KaptioTravel__GrossInvoicing__c
- Insurance__c
- Total_Discount__c
FieldPurpose
modelive queries the org in real time.
kaptio_namespaceThe managed-package namespace used when resolving field API names.
rest_endpointThe Apex REST endpoint in your org that the platform calls for payment operations. See Salesforce integration.
itinerary_extra_select_fieldsAdditional itinerary fields fetched alongside the standard set.

The itinerary_extra_select_fields list matters more than it looks: any field you want to display in the price summary panel must be declared here first. The summary_breakdown block (below) can only reference fields that are part of the itinerary query — if a breakdown line points at a field that is not selected, the line cannot render. When you add a breakdown line, add its field here in the same change.

branding

The visual identity of the payment page: logo, color palette, and fonts.

branding:
name: Meridian Travel Co.
logo:
url: "https://assets.example.com/meridian/logo.svg"
alt: Meridian Travel Co.
height: 48
colors:
primary: '#034955'
secondary: '#FFBC42'
background: '#F9FAF8'
text: '#212121'
# ...plus hover, surface, success, error, warning, and border tokens
fonts:
heading: '"Lexend", sans-serif'
body: '"Lexend", sans-serif'
urls:
- https://fonts.googleapis.com/css2?family=Lexend:wght@300;400;600;700&display=swap

The baseline palette is deliberately aligned with the CSS design tokens used by the document templates, so payment pages and documents present a single coherent brand. When you rebrand, change both together — see Rebranding. In multi-brand tenants this root branding block is the default; per-brand overrides live under brands: (see Brands, currencies & 3DS).

The kaptio_pay block

Between branding and gateways, your file contains a kaptio_pay block that routes payment processing to the Kaptio Pay service. It is provisioned and managed by Kaptio — do not edit it.

gateways.braintree

Gateway credentials and currency configuration for Braintree.

gateways:
braintree:
public_key: "vault::braintree_public_key"
private_key: "vault::braintree_private_key"
merchant_id: "vault::braintree_merchant_id"
environment: sandbox
merchant_accounts:
DEFAULT: "vault::braintree_merchant_id"
USD: meridian_travel_usd
GBP: meridian_travel_gbp
EUR: meridian_travel_eur
AUD: meridian_travel_aud
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

Three rules apply here:

  • Credentials are vault:: references only. The keys name entries in the platform's secret vault, provisioned by Kaptio during onboarding. Raw credentials must never appear in payment.yaml — the configuration repository's CI rejects them.
  • environment is sandbox or production. Sandbox during implementation and testing; production at go-live.
  • merchant_accounts maps each acquiring currency to a Braintree merchant account name. These are account names, not secrets, so they appear in plain text. DEFAULT is the fallback used when a transaction's currency is not listed. Declare every currency you will acquire in at onboarding — retrofitting a currency later is painful. See Brands, currencies & 3DS for the full discussion, including the per-currency 3D Secure policy.

payment_methods

Each payment method is a named entry. The baseline enables card and stubs everything else.

payment_methods:
braintree_card:
enabled: true
label: Credit / Debit Card
gateway: kaptio_pay
provider: braintree
surcharge_percent: 0
icon: credit-card
accepted_cards: [visa, mastercard, amex, discover]
three_d_secure:
enabled: true
required: false
# per_currency mirrors the gateway-level 3DS policy

Points to note on braintree_card:

  • accepted_cards controls which card brands the hosted form accepts.
  • surcharge_percent is a first-class field on every method, shipped at 0. Operators in markets where card surcharging is standard practice (for example, Australia) typically set 1–2%; the platform applies it to the charged amount and displays it to the guest.
  • The method-level three_d_secure block carries the same per_currency map as the gateway-level policy, so the rules travel with the method configuration.

Disabled stubs

PayPal, Apple Pay, and Google Pay are present as complete stubs — enabling each is a flag flip once the corresponding merchant setup is done:

braintree_paypal:
enabled: false # Enable when PayPal is contracted
braintree_apple_pay:
enabled: false # Enable after Apple Pay domain verification
display_name: Meridian Travel Co.
braintree_google_pay:
enabled: false # Enable after Google Pay merchant setup

Each stub carries the same gateway, provider, and surcharge_percent fields as the card method.

The bank_transfer stub is the slot for deferred-settlement rails — BPay, ACH, SEPA, depending on your market. It shows the full pattern such rails need: a biller code, a customer reference number generated per payment, a settlement notice, and a templated confirmation email carrying the reference:

bank_transfer:
enabled: false # Deferred-settlement rail slot: BPay/ACH/SEPA per market
label: Bank Transfer
gateway: manual
provider: bpay
biller_code: "00000"
reference_prefix: "MT"
crn_algorithm: MOD10V01
settlement_notice: Please allow 1–3 business days for your bank transfer to be processed.
confirmation_email:
enabled: true
subject: "Bank Transfer Instructions — {{tourName}} ({{bookingReference}})"
body: |
# HTML template with {{crn}}, {{currency}}, {{amountFormatted}},
# and {{settlementNotice}} placeholders

Because settlement happens outside the card flow, the guest's payment is acknowledged with instructions rather than an immediate confirmation; crn_algorithm (here MOD10V01) defines how the customer reference number is generated and validated.

payment_model

Deposit versus full payment, and auto-pay behavior.

payment_model:
allow_full_payment: true
allow_deposit_only: true
deposit:
enabled: true
from_salesforce: true # Schedule rows drive deposit/final amounts
full_payment:
enabled: true
label: Pay Full Amount
auto_schedule:
mode: disabled
label: Automatically charge my card for the final balance on {due_date}

The key principle is from_salesforce: true: payment schedule rows in your Salesforce org drive deposit and final amounts. A booking can have any number of installments — the payment page presents what the schedule defines. There is never a hardcoded binary "deposit or full" split in configuration; amounts always come from the org.

auto_schedule controls whether the guest can opt to have the final balance charged automatically to their saved card. Four modes:

ModeBehavior
disabledNo auto-charge UI is shown.
opt_inCheckbox shown, unchecked by default.
opt_outCheckbox shown, checked by default.
requiredAuto-charge is mandatory for the final balance.

The baseline ships disabled. Both opt_in and disabled are proven in production.

scenarios

Scenarios are the entry points into the payment page. Two are enabled in the baseline; two are stubs.

scenarios:
payment_link:
enabled: true
description: Secure payment link sent to the customer from a document or email
allow_custom_amount: true
custom_amount_label: Pay Other Amount
show_expiry_notice: true
default_expiry_days: 7
call_center:
enabled: true
description: Call centre payment — agent selects schedules and may vault the card
stored_card:
enabled: true # MOTO / card-on-file for agents
auto_schedule_remaining:
enabled: true
mode: opt_in
label: Pay selected and schedule remaining
  • payment_link — the guest-facing flow. Links can allow a custom amount (allow_custom_amount, governed by custom_amount_rules below) and expire after default_expiry_days.
  • call_center — the agent-assisted flow. stored_card enables MOTO / card-on-file so an agent can take a payment over the phone and vault the card; auto_schedule_remaining lets the agent pay selected schedule rows now and schedule the rest.

The stubs:

ecommerce:
enabled: false # Wire ecommerce API base URL and webhook when web checkout goes live
description: E-commerce checkout integration (web session + webhook)
tokenize:
enabled: false # Quote-acceptance card vault without charge
captureMode: tokenize
authorization_amount: 0
vault_card: true
skip_sf_writeback: true
button_text: Accept Quote and Save Card

tokenize deserves a note: it is a zero-amount card vault flow for quote acceptance, proven in production. The guest "accepts" a quote by validating and saving a card — no charge is made and no payment is written back to Salesforce until the booking is confirmed.

custom_amount_rules

Governs what a guest may enter when a payment link allows a custom amount.

custom_amount_rules:
default: deposit_floor
channel_overrides: {}

deposit_floor prevents paying less than the current schedule minimum. channel_overrides lets specific sales channels relax this — for example, group or trade channels can be set to no_floor so partial payments of any size are accepted.

payment_eligibility

SOQL-backed rules evaluated against your org before the payment form renders. If a rule blocks, the guest sees the configured message instead of the form.

payment_eligibility:
enabled: true
scenarios: [payment_link, call_center]
rules:
- id: itinerary_status_check
description: Block payment unless the booking is in Option or Booked status
query: >-
SELECT KaptioTravel__Status__c FROM KaptioTravel__Itinerary__c WHERE Id
= :itineraryId AND KaptioTravel__Status__c NOT IN ('Option', 'Booked')
block_if: results_exist
message:
title: Payment Not Available
body: >-
This booking is not eligible for payment. The booking status must be
Option or Booked before payment can be accepted.
icon: shield-exclamation

The pattern: the query returns rows when the booking is in a blocking state, and block_if: results_exist turns any result into a block. The itinerary_status_check rule above is enabled in the baseline.

Two further rules ship as disabled stubs, each with a required_setup note explaining what must be mapped before enabling:

- id: on_request_confirmed
enabled: false
description: Block payment while any On Request services remain unconfirmed
required_setup: >
Replace :onRequestStatusId and :confirmedStatusId with your org's
InventoryStatus and ConfirmationStatus record IDs. These values are
org-specific and must be mapped before enabling this rule.
query: |
# Selects itinerary items where InventoryStatusId = :onRequestStatusId
# and ConfirmationStatusId != :confirmedStatusId
block_if: results_exist
- id: final_payment_due
enabled: false
description: Block partial payments when the final balance due date has passed
required_setup: >
Confirm PaymentSchedule field API names and schedule type picklist value
for the final balance row match your org before enabling this rule.

Placeholder tokens such as :onRequestStatusId are intentional: they must be replaced with your org's actual record IDs before the rule is enabled. Enabling a stub without completing its required_setup will produce queries that fail or silently match nothing. Your Salesforce administrator supplies these values — see Salesforce integration.

payer_details

Fields collected from the payer before the card form is shown. These feed fraud screening / AVS and are written back to Salesforce with the payment.

payer_details:
enabled: true
fields:
first_name: { enabled: true, required: true }
last_name: { enabled: true, required: true }
email: { enabled: true, required: true }
postal_code: { enabled: true, required: true }
country: { enabled: true, required: true }
# street_address, city, state: enabled but optional in the baseline

Tighten or relax required per market during implementation.

summary_breakdown

The line items shown in the price summary panel.

summary_breakdown:
enabled: true
lines:
- key: subtotal
label: 'SUBTOTAL:'
source: sf_field
field: Subtotal__c
- key: total
label: 'TOTAL DUE:'
source: session
field: totalAmount
style: highlight
separator_before: true

Each line has:

FieldPurpose
sourcesf_field reads an itinerary field from Salesforce; session reads a value computed for this payment session (such as the amount due now).
fieldThe field API name (for sf_field) or session key (for session).
styleOptional presentation hint — highlight for emphasized totals, discount for credit lines.
separator_beforeDraws a rule above the line.
show_if / show_if_zeroConditional display — show_if compares another field to a value; show_if_zero: false hides a line when its amount is zero.

For example, a net-price line that only appears for net-invoiced bookings:

- key: net_price
label: 'NET PRICE:'
source: sf_field
field: TotalAmountNet__c
style: highlight
show_if:
field: GrossInvoicing__c
equals: false

The same pattern with show_if_zero: false adds insurance or credit lines that only appear when non-zero. Remember the dependency called out under salesforce: every sf_field referenced here must be declared in itinerary_extra_select_fields first.

group_payments

A disabled stub for group bookings where payment is collected per room, cabin, or berth rather than as a lump sum. The shape is proven in production for cruise and rail multi-room flows.

group_payments:
enabled: false
mode: per_room
source: itinerary_groups
fallback: lump_sum
display:
group_label: Guest # Configurable per vertical e.g. Cabin, Room, Berth
show_guest_names: true
show_group_totals: true
selection:
allow_multi_select: true
allow_select_all: true
select_all_label: Pay All Deposits
amounts:
deposit_source: per_passenger
minimum_per_group: deposit

group_label is configurable per vertical — a cruise operator labels groups "Cabin", a touring operator "Room", a rail operator "Berth". fallback: lump_sum keeps single-unit bookings on the standard flow.

insurance

A disabled stub for travel-protection upsell at payment time. The vendor integration itself is fork-time work; when enabled, all vendor endpoints and credentials are vault:: references — never literal URLs or secrets in configuration.

insurance:
enabled: false
# Enable and configure the provider block at implementation time.
# All vendor credentials are vault:: references.

brand_routing and brands

Multi-brand routing is enabled in the baseline with a single default brand. This is covered in depth in Brands, currencies & 3DS; in short:

brand_routing:
default_brand: default
resolve_from:
- source: url_param
param: brand
- source: session_field
field: brand_code
brands:
default: {} # Empty brand = root-level config; add per-brand overrides at fork time

features

Conservative feature flags, all off in the baseline:

features:
auto_pay_opt_in: false
save_card: false
receipt_email: false

Production tenants commonly run all three enabled — auto_pay_opt_in surfaces the auto-pay choice, save_card lets guests vault a card for later use, and receipt_email sends a receipt on success.

post_payment_documents

Documents offered on the success screen, generated by Edge Docs:

post_payment_documents:
- doc_type: financial_summary
label: Financial Summary
button_label: Download Financial Summary
generate_on: success
mode: generate_only

Any doc_type listed here must exist in your blueprint's document configuration — see Blueprint.

gtm

Google Tag Manager containers, mapped per payment domain. Empty in the baseline; populate at implementation time:

gtm:
containers: {}

copy, card_form, billing_address, validation

Every guest-visible string on the payment page is configurable — nothing is hardcoded in the platform. Four blocks cover the page:

copy:
page_title: Complete Your Booking
deposit_label: Pay Deposit
deposit_tagline: Pay your deposit today; the remaining balance is due by {date}
full_payment_label: Pay in Full
submit_button: Confirm Payment
success_title: Payment Confirmed
success_message: >-
Thank you for booking with Meridian Travel Co. We look forward to
welcoming you on your journey.
# ...plus headers, balance labels, processing text, and trust badges

card_form:
card_number_label: Card Number
expiry_label: Expiry Date
cvv_label: Security Code
cardholder_label: Name on Card
# ...plus a placeholder string per field

billing_address:
enabled: true
collapsed_by_default: false
fields:
postal_code: { label: Postal Code, required: true }
country: { label: Country, required: true }
# street / city / state optional in the baseline

validation:
card_number_required: Card number is required
card_number_invalid: Please enter a valid card number
expiry_invalid: Please enter a valid expiry date (MM/YY)
cvv_required: Security code is required
# ...one required/invalid message per field

Copy strings support placeholders where noted (for example {date} in the deposit tagline). When you localize or rebrand, these four blocks are where the language of the page lives — see Rebranding.

Verifying changes

Configuration changes to payment.yaml should be verified against the QA harness before merging — see QA overview and the test harness.