Young Estates Young Estates Booking Integration
v1.0
Young Estates · Manual Capture · JWT-signed

Take secure booking payments through Young Estates.

Add a payment button to your booking site. When a customer clicks it, their card is held — not charged — and Young Estates reviews and approves the booking before any money changes hands. This guide walks you through installing the snippet on your site.

Audience Web developers Stack HTML / JS / PHP Reading time ~10 minutes Setup time ~30 minutes
§ 01

Overview

When a customer clicks the Pay Now button on your site, their card is verified and the booking amount is held — but no money is taken until Young Estates approves the booking. If the booking can't be honoured, the hold is released and nothing is charged.

The customer flow looks like this:

  1. Customer completes a booking on your site and clicks Pay Now.
  2. They are sent to a secure Fygaro checkout page.
  3. They enter card details. Funds are held, not charged. ?
  4. They are redirected to a confirmation landing page on Young Estates' site.
  5. Young Estates receives the booking, reviews it, then either captures the payment (charge confirmed) or releases the hold (nothing charged).
  6. The customer is contacted by Young Estates within 24 hours to confirm.
Why a hold and not a charge?

Holds let Young Estates confirm card validity and reserve the funds without committing the customer until the booking is verified. If a booking can't be honoured, the hold is released and the customer is never charged.

§ 02

Architecture

The integration has two halves. You implement one. Young Estates hosts the other.

Your site Booking page
with snippet
Young Estates Signs JWT
with secret key
Fygaro Verifies & holds
the funds

The reason for the middle hop: the payment amount must be cryptographically signed before Fygaro will accept it. Signing requires Young Estates' secret key, which can never appear in browser-visible code. Your snippet calls Young Estates' endpoint, the endpoint signs the request, and the customer is redirected onward to Fygaro.

Why this matters for security

If the amount were sent unsigned, a customer could open their browser dev tools, change $200.00 to $1.00, and pay one dollar. The JWT signature makes that impossible — any tampering invalidates the token and Fygaro rejects it.

§ 03

Prerequisites

Before you start, confirm you have:

  • FTP / SFTP or server file access to your booking site. You'll need to edit (or create) a PHP template file to render the payment button dynamically.
  • Working knowledge of PHP — at minimum, comfort reading and writing basic PHP, calling json_encode(), and accessing booking data from your existing system (database, Woo order object, ACF fields, etc.).
  • Access to your booking data at render time: property name, dates, guests, prices, and a unique booking ID.
  • The endpoint URL provided by Young Estates — see below.

About the endpoint URL

Young Estates hosts a small server-side endpoint that securely signs each payment request before it reaches Fygaro. The URL looks like this:

https://youngestates.com/fygaro-sign.php

You do not need to host this, build it, or modify it — Young Estates runs and maintains it. Your snippet calls this URL when a customer clicks Pay Now, the endpoint signs the request with Young Estates' secret key, and the customer is redirected to Fygaro's checkout. This is the only URL you'll be referencing in your code.

Why it has to be Young Estates' URL

The signing process requires a secret key that must never appear in browser-visible code. By calling Young Estates' endpoint instead of building your own, you avoid handling any payment credentials and any compliance burden that comes with them.

You do not need a Fygaro account, API keys, or any payment-processing setup. Young Estates handles all of that.

§ 04

Step 1 — The embed snippet

This is the part you actually install. Paste it into the booking page where you want the payment button to appear. The endpoint URL is already filled in for you.

Tip — use the URL Builder below

If you want to test the integration without writing code, scroll down to the URL Builder — it generates a ready-to-paste link.

HTML Embed on your booking page
<!-- Booking Payment Button -->
<a href="#"
   class="booking-pay-button"
   data-amount="1350.00"
   data-reference="9876"
   data-booking='{"property":"Bluff House","arrival":"2026-07-12","departure":"2026-07-19","guests":4,"bedrooms":2,"subtotal":"1200.00","levy":"150.00","total":"1350.00"}'>
    Pay Now
</a>

<style>
.booking-pay-button {
    display: inline-block;
    padding: 14px 32px;
    background: #6c9e81;
    color: #fff;
    font: 600 16px system-ui, sans-serif;
    text-decoration: none;
    border-radius: 6px;
}
.booking-pay-button:hover { background: #4f7a62; }
</style>

<script>
(function() {
    var SIGN_ENDPOINT = 'https://youngestates.com/fygaro-sign.php';

    document.querySelectorAll('.booking-pay-button').forEach(function(btn) {
        var amount    = parseFloat(btn.dataset.amount || '0').toFixed(2);
        var reference = btn.dataset.reference || ('BOOKING-' + Date.now());
        var booking   = btn.dataset.booking || '';
        btn.textContent = 'Pay $' + amount;
        var url = SIGN_ENDPOINT
            + '?amount='    + encodeURIComponent(amount)
            + '&reference=' + encodeURIComponent(reference);
        if (booking) url += '&booking=' + encodeURIComponent(booking);
        btn.href = url;
    });
})();
</script>

What each attribute does

AttributeRequiredWhat it does
data-amount Yes The price to charge in USD, 2 decimal places. Example: 1350.00
data-reference Yes Your existing booking ID — must be unique per booking. Pull this from your booking system / database, never let a customer pick it. Example: 9876 or BK-2026-001.
data-booking Recommended JSON string with booking details. Used to build a meaningful reference and populate booking confirmations and emails. Use the URL Builder to generate it.

The booking JSON

The data-booking attribute holds a JSON object describing the booking. Here are the supported fields:

FieldRequiredFormat / Example
propertyYesProperty name as a string. e.g. "Bluff House"
arrivalYesCheck-in date as YYYY-MM-DD. e.g. "2026-07-12"
departureYesCheck-out date as YYYY-MM-DD. e.g. "2026-07-19"
guestsRecommendedNumber of guests. e.g. 4
bedroomsRecommendedNumber of bedrooms. e.g. 2
subtotalOptionalString, 2dp. e.g. "1200.00"
levyOptionalString, 2dp. e.g. "150.00"
totalOptionalString, 2dp. Falls back to data-amount if not set.

Server-side rendering example

If your site is dynamic, render the values from your booking record:

PHP Dynamic example
<?php
$booking_json = json_encode([
    'property'  => $booking->property_name,
    'arrival'   => $booking->arrival_date,    // 'YYYY-MM-DD'
    'departure' => $booking->departure_date,  // 'YYYY-MM-DD'
    'guests'    => $booking->guests,
    'bedrooms'  => $booking->bedrooms,
    'subtotal'  => number_format($booking->subtotal, 2, '.', ''),
    'levy'      => number_format($booking->levy,     2, '.', ''),
    'total'     => number_format($booking->total,    2, '.', ''),
]);
?>

<a href="#"
   class="booking-pay-button"
   data-amount="<?= number_format($booking->total, 2, '.', '') ?>"
   data-reference="<?= htmlspecialchars($booking->id) ?>"
   data-booking='<?= htmlspecialchars($booking_json, ENT_QUOTES) ?>'>
    Pay Now
</a>

If your prices update live (AJAX / dynamic pricing)

If your booking page recalculates the price, dates, or any other detail without a full page reload — e.g. a date picker that updates the total via AJAX — you must update the button's data-* attributes and rebuild its href whenever those values change. Otherwise the customer will be charged the original price, not the updated one.

Why this matters

The script builds the button's URL once when the page loads. If the price later changes via JavaScript and you don't refresh the URL, clicking Pay Now will send the old values to Young Estates — meaning the customer is charged the wrong amount. This is a critical bug that will happen if you skip this step.

The safest pattern: after any update to your pricing/dates, call a small refresh function on the button. Example:

JS Refreshing the button after AJAX
// Call this after any AJAX update that changes price/dates/etc.
function refreshPaymentButton(newBookingData) {
    var btn = document.querySelector('.booking-pay-button');
    if (!btn) return;

    // 1. Update the data-* attributes with the new values
    btn.dataset.amount    = newBookingData.total.toFixed(2);
    btn.dataset.reference = newBookingData.bookingId;
    btn.dataset.booking   = JSON.stringify({
        property:  newBookingData.property,
        arrival:   newBookingData.arrival,    // 'YYYY-MM-DD'
        departure: newBookingData.departure,  // 'YYYY-MM-DD'
        guests:    newBookingData.guests,
        bedrooms:  newBookingData.bedrooms,
        subtotal:  newBookingData.subtotal.toFixed(2),
        levy:      newBookingData.levy.toFixed(2),
        total:     newBookingData.total.toFixed(2),
    });

    // 2. Rebuild the href so the next click sends the new data
    var SIGN_ENDPOINT = 'https://youngestates.com/fygaro-sign.php';
    btn.textContent = 'Pay $' + btn.dataset.amount;
    btn.href = SIGN_ENDPOINT
        + '?amount='    + encodeURIComponent(btn.dataset.amount)
        + '&reference=' + encodeURIComponent(btn.dataset.reference)
        + '&booking='   + encodeURIComponent(btn.dataset.booking);
}

// Example: hook into your existing date-picker / quote-update event
dateRangePicker.on('change', function() {
    fetch('/api/quote', { ... })
        .then(r => r.json())
        .then(refreshPaymentButton);  // ← call this every time
});

Alternative pattern: rebuild the URL at click-time instead of on page load — read the current values from your form/state right before redirecting. Either approach works; the key is that the URL reflects the current values at the moment the customer clicks.

How to test you've got this right

On your booking page, change the dates/price via your live updater, open the browser inspector, and check the payment button's href attribute. The amount in the URL should match the new total exactly. If it still shows the old number, you've missed a refresh step.

Do not change the SIGN_ENDPOINT URL

The endpoint URL inside the script is what makes the integration secure. If you point it elsewhere, payments will fail.

§ 05

URL Builder For testing only

Use this tool to build a working test URL or copy a sample embed snippet. It's intended for sandbox testing — in production, the values must be generated dynamically from the actual booking record.

This is a fixed-value tool — not a production solution

Hard-coding values like booking ID, property name, and dates into your HTML is unsafe and won't work for real bookings. In production, your server must populate these attributes from the live booking record using PHP (or your backend language of choice). See the Server-side rendering example in Step 1 for the right way to do it.

String. Pulled from your property database.
Must be unique per booking. Use your existing system's booking number — never something a customer picks.
Format: YYYY-MM-DD
Format: YYYY-MM-DD
Whole number.
Whole number.
Decimal, 2 places. Optional.
Decimal, 2 places. Optional.
Decimal, 2 places. This is the amount held on the customer's card.
Test URL
Embed Snippet

                    
How to test the URL

Click the URL above to test the payment flow end-to-end. The customer will be sent through Fygaro's secure checkout and back to the Young Estates confirmation page.

§ 06

Step 2 — What happens after payment

The customer is redirected to Young Estates

Once the hold is placed, Fygaro redirects the customer to a confirmation landing page at youngestates.com/booking-confirmed. The customer is not returned to your site at this stage — the booking flow concludes on the Young Estates side so review and approval are handled consistently across all partner sites. The booking reference is passed in the URL and a personalized confirmation is shown.

Young Estates is notified automatically

A webhook fires with the authorization details. The Young Estates team is alerted by email and the booking enters a pending review state.

Young Estates approves and captures

Within the review window, Young Estates either captures the held funds (charging the card for real) or releases the hold (no money changes hands). The customer's bank statement reflects the outcome and they receive an email confirming what happened.

Hold expiry

Authorization holds last roughly 7 days. Young Estates captures or releases well within that window. After expiry, the hold drops off automatically and no charge is made.

§ 07

What data is captured

Every booking ends up with a complete record assembled from three sources: data you send from your booking page, data Fygaro collects at checkout, and data Young Estates detects automatically.

1. Data your site sends (in the embed snippet)

These are the values you provide via data-amount, data-reference, and data-booking attributes on the payment button:

FieldRequired?Source
Booking ID (reference)YesYour booking system / database
Amount to holdYesYour pricing logic
Property nameYesYour property record
Arrival dateYesYour booking record
Departure dateYesYour booking record
GuestsRecommendedYour booking record
BedroomsRecommendedYour property record
SubtotalOptionalYour pricing logic
Levy & service chargeOptionalYour pricing logic
TotalOptionalYour pricing logic

2. Data Fygaro collects from the customer

When the customer reaches Fygaro's secure checkout page, they enter the following — you don't need to capture any of this on your site:

FieldRequired?Why
Cardholder nameYesRequired by the card network
Email addressYesUsed for the customer's booking confirmation email
Card detailsYesNumber, expiry, CVV — handled entirely by Fygaro under PCI compliance
Phone numberYesSo Young Estates can reach the guest if there's a question
Billing addressYesAddress verification reduces fraud and chargebacks
Client noteOptionalFree-text for arrival time, accessibility needs, requests, etc.

3. Data Young Estates detects automatically

No action needed on your part — these are detected by the Young Estates endpoint:

FieldHow it's detected
Booking source (your site)From the browser's Referer header — identifies which partner site the booking came from
Self-documenting referenceBuilt by combining your booking ID + property name + arrival date + site shortcode (e.g. pvr-bluff-house-2026-07-12-9876)
Transaction ID, auth code, timestampReturned by Fygaro after a successful authorization
What this means for you

You only need to send three attributes from your site: data-amount, data-reference, and data-booking (the JSON). Everything else is collected at the Fygaro checkout step or detected automatically by Young Estates.

How this data flows after payment

Once a customer completes the Fygaro checkout, Young Estates' webhook receives all of the above and automatically:

  • Emails the guest a branded "booking pending" confirmation with their reference, property, dates, hold amount, and any note they left.
  • Emails the internal Young Estates team at stay@youngestates.com with the full booking record for review and approval.
  • Stores the booking in Young Estates' system marked as pending review.
Privacy note

Card numbers are never sent to your site or to Young Estates' systems — only the brand and last 4 digits are forwarded. Full card data is held only by Fygaro under PCI compliance.

§ 08

Parameters reference

Full list of values exchanged between systems.

Snippet → signing endpoint (URL parameters)

ParamRequiredFormat
amountYesDecimal string with 2dp, e.g. 1350.00
referenceYesYour unique booking ID, e.g. 9876
bookingRecommendedURL-encoded JSON string with property, dates, etc.

Booking JSON fields

FieldRequiredFormat
propertyYesString. e.g. "Bluff House"
arrivalYesDate as YYYY-MM-DD
departureYesDate as YYYY-MM-DD
guestsRecommendedInteger
bedroomsRecommendedInteger
subtotalOptionalDecimal string with 2dp
levyOptionalDecimal string with 2dp
totalOptionalDecimal string with 2dp

What gets generated from your data

The Young Estates endpoint takes your booking ID and combines it with the booking JSON to produce a self-documenting reference for tracking, dashboards, and emails:

Reference format

Your reference of 9876 + booking with property: "Bluff House" and arrival: "2026-07-12" becomes pvr-bluff-house-2026-07-12-9876 (assuming the booking originated from privatevillarentals.com).

Booking source detection

Young Estates automatically detects which partner site each booking came from, based on the page that hosted the payment button. No action needed on your side — the source is captured from the browser's Referer header and shown in Young Estates' internal review tools and emails. Currently recognized partner sites:

  • privatevillarentals.com → tag pvr
  • thewebsitespace.com → tag tws
  • youngestates.com → tag ye
§ 09

Testing checklist

Before going live on production bookings, verify:

  • The button appears with the correct dynamic price for at least three different bookings.
  • Clicking the button takes you through the signing endpoint and lands on the Fygaro checkout page (the URL bar will briefly show a redirect).
  • Completing a test payment redirects you to youngestates.com/booking-confirmed with a customReference in the URL.
  • If you tamper with data-amount in the browser, the JWT signature breaks and Fygaro rejects the request — it does not charge the tampered amount.
  • The booking reference appearing on the landing page matches what you sent in data-reference.
  • Live-pricing test (critical if you use AJAX): change the dates or other booking details on your page so the price recalculates, then inspect the button's href attribute in DevTools. Confirm the amount= in the URL matches the new total — not the original page-load value.
§ 10

Troubleshooting

Button shows "Pay $0.00"

data-amount is missing or not a valid number. Check that your template is rendering the price correctly. View the page source to confirm the attribute is populated.

Click does nothing

The script tag is probably not loading. Open the browser console (F12) and check for errors. The most common cause is a Content Security Policy blocking inline scripts — if so, move the script to an external file.

Fygaro shows "Invalid token" or "Expired"

The customer waited longer than 15 minutes between clicking and paying, or the JWT was tampered with. Have them refresh the booking page to get a new token.

Customer was charged the wrong amount

Almost always caused by a stale URL when prices update via AJAX. The button's href was built once on page load and never refreshed when the customer changed dates / guests / etc. See the "If your prices update live" section for the fix — you need to rebuild the button's href after every AJAX update, or build it at click-time instead.

Customer didn't reach the confirmation page

Customers should be redirected to youngestates.com/booking-confirmed after the hold is placed. If they're not, contact Young Estates with the booking reference — they'll check the Fygaro return URL configuration.

§ 11

Support

If you hit anything not covered here, get in touch:

  • Email — stay@youngestates.com
  • For urgent payment issues, include the booking reference and a screenshot of any error message.
Reference docs

Fygaro's own integration docs are available at help.fygaro.com if you want background on the underlying system.