Examples

Practical examples showing common operations with the Felloh Perl SDK. Each example assumes you have already created a client instance.

Client Setup

use Felloh::Client;

my $client = Felloh::Client->new(
    public_key  => $ENV{FELLOH_PUBLIC_KEY},
    private_key => $ENV{FELLOH_PRIVATE_KEY},
);

Bookings

Create a booking, then list and retrieve bookings. Amounts should be in the lowest currency denomination (e.g. pence for GBP).

Create a Booking

my $created = $client->bookings->create(
    organisation      => 'org-id',
    booking_reference => 'REF-001',
    customer_name     => 'James Dean',
    email             => 'james@example.com',
    currency          => 'GBX',
    gross_amount      => 100000,
    departure_date    => '2025-08-01',
    return_date       => '2025-08-15',
);

print "Booking ID: $created->{data}{id}\n";

List & Search Bookings

my $bookings = $client->bookings->list(
    organisation => 'org-id',
    keyword      => 'james@example.com',
    take         => 20,
);

print "Found $bookings->{meta}{count} bookings\n";

Update a Booking

$client->bookings->update('booking-id',
    customer_name  => 'Jane Dean',
    departure_date => '2025-09-01',
);

Delete a Booking

$client->bookings->delete('booking-id');

Booking Components

Add and remove components (e.g. flights, hotels) on a booking.

Add a Component

my $component = $client->booking_components->create('booking-id',
    supplier          => 'supplier-id',
    amount            => 50000,
    currency          => 'GBX',
    booking_reference => 'REF-001',
    destination_air   => 'AMS',
    type              => 'flights',
);

Remove a Component

$client->booking_components->delete('booking-id', 'component-id');

Transactions

List transactions, issue refunds, and manage pre-authorisations.

List Transactions

my $transactions = $client->transactions->list(
    organisation => 'org-id',
    statuses     => ['COMPLETE'],
    date_from    => '2025-01-01',
    date_to      => '2025-12-31',
);

Refund a Transaction

# Amount in lowest denomination (e.g. pence)
$client->transactions->refund('transaction-id',
    amount      => 5000,
    description => 'Customer requested refund',
);

Complete Pre-Auth

# Capture held funds on a pre-authorised transaction
$client->transactions->complete('transaction-id');

Reverse Pre-Auth

# Release held funds on a pre-authorised transaction
$client->transactions->reverse('transaction-id');

Re-assign to Different Booking

$client->transactions->reassign('transaction-id',
    booking_id => 'new-booking-id',
);

Create payment links to send to customers for card or open banking payments.

Create a Payment Link

my $link = $client->payment_links->create(
    customer_name        => 'John Doe',
    email                => 'john@example.com',
    organisation         => 'org-id',
    amount               => 50000,
    type                 => 'CARD',
    booking_id           => 'booking-id',
    open_banking_enabled => 1,
    card_enabled         => 1,
    description          => 'Holiday deposit',
    currency             => 'GBX',
);

Assign a Payment Link to a Booking

$client->payment_links->assign('payment-link-id',
    organisation      => 'org-id',
    customer_name     => 'John Doe',
    email             => 'john@example.com',
    booking_reference => 'REF-002',
);

Ecommerce Sessions

Create ecommerce sessions for use with the browser-side JavaScript SDK.

Create an Ecommerce Session

my $session = $client->ecommerce->create(
    customer_name        => 'Jane Smith',
    email                => 'jane@example.com',
    organisation         => 'org-id',
    amount               => 75000,
    booking_id           => 'booking-id',
    open_banking_enabled => 1,
    card_enabled         => 1,
);

# Pass session ID to the browser SDK
print "Ecommerce ID: $session->{data}{id}\n";

Customers

Create and list customer records.

Create a Customer

my $customer = $client->customers->create(
    organisation  => 'org-id',
    customer_name => 'Jane Smith',
    email         => 'jane@example.com',
    address_1     => '123 High Street',
    city          => 'London',
    county        => 'Greater London',
    post_code     => 'SW1A 1AA',
);

Search Customers

my $customers = $client->customers->list(
    organisation => 'org-id',
    keyword      => 'jane@example.com',
);

Refunds

List pending refunds and authorise or decline them.

List and Authorise Refunds

my $refunds = $client->refunds->list(
    organisation => 'org-id',
);

# Authorise a pending refund
$client->refunds->authorise('authorisation-code');

# Or decline it
$client->refunds->decline('authorisation-code');

Scheduled Payments

Manage stored-card (MOTO) payments and generate customer approval links.

Fetch Available Tokens

# Get stored card tokens for a booking
my $tokens = $client->scheduled_payments->available_tokens(
    'booking-id',
);

for my $token (@{ $tokens->{data} }) {
    print "$token->{id} - $token->{cardholder_name}\n";
}

Create a Scheduled Payment

my $payment = $client->scheduled_payments->create_payment(
    'booking-id',
    token  => 'token-id',
    amount => 25000,
    date   => '2025-09-01',  # optional: schedule for future
);

Generate an Approval Link

my $approval = $client->scheduled_payments->approval_link(
    'booking-id',
    amount => 25000,
    token  => 'token-id',
);

print "Send to customer: $approval->{data}{url}\n";

Credit Notes

Create credit notes and assign them to bookings.

Create and Assign a Credit Note

my $note = $client->credit_notes->create(
    organisation  => 'org-id',
    customer_name => 'James Dean',
    amount        => 15000,
    currency      => 'GBX',
);

# Assign to a booking
$client->credit_notes->assign($note->{data}{id},
    organisation      => 'org-id',
    customer_name     => 'James Dean',
    email             => 'james@example.com',
    booking_reference => 'REF-003',
);

Suppliers & Beneficiaries

Manage suppliers for booking components and beneficiary bank accounts for disbursements.

Suppliers

# Create a supplier
my $supplier = $client->suppliers->create(
    organisation  => 'org-id',
    supplier_name => 'Felloh Airlines',
);

# List suppliers
my $suppliers = $client->suppliers->list(
    organisation => 'org-id',
    keyword      => 'airlines',
);

Beneficiaries

# Create a beneficiary bank account
my $beneficiary = $client->beneficiaries->create(
    organisation   => 'org-id',
    account_name   => 'Felloh Travel Ltd',
    account_number => '12345678',
    sort_code      => '112233',
);

# Activate a beneficiary
$client->beneficiaries->activate('beneficiary-id');

Organisations & API Keys

List accessible organisations and manage API keys programmatically.

Organisations

my $orgs = $client->organisations->list();

for my $org (@{ $orgs->{data} }) {
    print "$org->{id} $org->{name}\n";
}

API Keys

# Create a new API key pair
my $key = $client->api_keys->create(
    organisation => 'org-id',
    name         => 'Production Server',
);

# Store these securely — secret_key is only returned once
print "Public: $key->{data}{public_key}\n";
print "Secret: $key->{data}{secret_key}\n";

# Delete a key
$client->api_keys->delete('key-id');

Logging

Pass a logger callback to observe every HTTP request made by the SDK.

Each log entry hash ref includes:

  • Name
    method
    Type
    string
    Description

    HTTP method (GET, POST, PUT, DELETE).

  • Name
    url
    Type
    string
    Description

    Full request URL including query string.

  • Name
    status_code
    Type
    integer
    Description

    HTTP status code, or undef if the request failed before receiving a response.

  • Name
    duration_ms
    Type
    integer
    Description

    Request duration in milliseconds.

  • Name
    attempt
    Type
    integer
    Description

    Retry attempt number (0 for the first attempt).

Request Logging

my $client = Felloh::Client->new(
    public_key  => 'your-public-key',
    private_key => 'your-private-key',
    logger      => sub {
        my ($entry) = @_;
        printf "%s %s → %s (%dms) [attempt %d]\n",
            $entry->{method},
            $entry->{url},
            $entry->{status_code} // 'N/A',
            $entry->{duration_ms},
            $entry->{attempt};
    },
);