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.
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:
- Customer completes a booking on your site and clicks Pay Now.
- They are sent to a secure Fygaro checkout page.
- They enter card details. Funds are held, not charged. ?
- They are redirected to a confirmation landing page on Young Estates' site.
- Young Estates receives the booking, reviews it, then either captures the payment (charge confirmed) or releases the hold (nothing charged).
- The customer is contacted by Young Estates within 24 hours to confirm.
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.
Architecture
The integration has two halves. You implement one. Young Estates hosts the other.
with snippet
with secret key
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.
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.
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.
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.
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.
If you want to test the integration without writing code, scroll down to the URL Builder — it generates a ready-to-paste link.
<!-- 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
| Attribute | Required | What 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:
| Field | Required | Format / Example |
|---|---|---|
| property | Yes | Property name as a string. e.g. "Bluff House" |
| arrival | Yes | Check-in date as YYYY-MM-DD. e.g. "2026-07-12" |
| departure | Yes | Check-out date as YYYY-MM-DD. e.g. "2026-07-19" |
| guests | Recommended | Number of guests. e.g. 4 |
| bedrooms | Recommended | Number of bedrooms. e.g. 2 |
| subtotal | Optional | String, 2dp. e.g. "1200.00" |
| levy | Optional | String, 2dp. e.g. "150.00" |
| total | Optional | String, 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
$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.
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:
// 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.
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.
The endpoint URL inside the script is what makes the integration secure. If you point it elsewhere, payments will fail.
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.
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.
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.
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.
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.
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:
| Field | Required? | Source |
|---|---|---|
| Booking ID (reference) | Yes | Your booking system / database |
| Amount to hold | Yes | Your pricing logic |
| Property name | Yes | Your property record |
| Arrival date | Yes | Your booking record |
| Departure date | Yes | Your booking record |
| Guests | Recommended | Your booking record |
| Bedrooms | Recommended | Your property record |
| Subtotal | Optional | Your pricing logic |
| Levy & service charge | Optional | Your pricing logic |
| Total | Optional | Your 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:
| Field | Required? | Why |
|---|---|---|
| Cardholder name | Yes | Required by the card network |
| Email address | Yes | Used for the customer's booking confirmation email |
| Card details | Yes | Number, expiry, CVV — handled entirely by Fygaro under PCI compliance |
| Phone number | Yes | So Young Estates can reach the guest if there's a question |
| Billing address | Yes | Address verification reduces fraud and chargebacks |
| Client note | Optional | Free-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:
| Field | How it's detected |
|---|---|
| Booking source (your site) | From the browser's Referer header — identifies which partner site the booking came from |
| Self-documenting reference | Built by combining your booking ID + property name + arrival date + site shortcode (e.g. pvr-bluff-house-2026-07-12-9876) |
| Transaction ID, auth code, timestamp | Returned by Fygaro after a successful authorization |
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.comwith the full booking record for review and approval. - Stores the booking in Young Estates' system marked as pending review.
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.
Parameters reference
Full list of values exchanged between systems.
Snippet → signing endpoint (URL parameters)
| Param | Required | Format |
|---|---|---|
| amount | Yes | Decimal string with 2dp, e.g. 1350.00 |
| reference | Yes | Your unique booking ID, e.g. 9876 |
| booking | Recommended | URL-encoded JSON string with property, dates, etc. |
Booking JSON fields
| Field | Required | Format |
|---|---|---|
| property | Yes | String. e.g. "Bluff House" |
| arrival | Yes | Date as YYYY-MM-DD |
| departure | Yes | Date as YYYY-MM-DD |
| guests | Recommended | Integer |
| bedrooms | Recommended | Integer |
| subtotal | Optional | Decimal string with 2dp |
| levy | Optional | Decimal string with 2dp |
| total | Optional | Decimal 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:
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→ tagpvrthewebsitespace.com→ tagtwsyoungestates.com→ tagye
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-confirmedwith acustomReferencein the URL. - If you tamper with
data-amountin 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
hrefattribute in DevTools. Confirm theamount=in the URL matches the new total — not the original page-load value.
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.
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.
Fygaro's own integration docs are available at help.fygaro.com if you want background on the underlying system.