Create a Payment Link

In order to create a payment link for your customer, there are a couple of steps you will need to undertake. This guide assumes that you have a booking for your customer, however you can create a payment link without one. The steps are as follows.

1. Authenticate - Authenticate your user and get a bearer token to be able to undertake actions against the API

2. Create a booking - Create a booking for your customer

3. Create a payment link - Create a payment link for your customer

1. Authenticating

Authenticating against the API

import axios from 'axios';
const getToken = async () => {
const response = await axios({
method: 'post',
url: 'https://api.felloh.com/token',
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify({
public_key: process.env.PUBLIC_KEY,
private_key: process.env.PRIVATE_KEY,
},
),
});
return response.data.data;
};
const { token } = await getToken();
use GuzzleHttp\Client;
function getToken() {
$client = new Client();
$response = $client->post('https://api.felloh.com/token', [
'headers' => [
'Content-Type' => 'application/json',
],
'json' => [
'public_key' => getenv('PUBLIC_KEY'),
'private_key' => getenv('PRIVATE_KEY'),
],
]);
$data = json_decode($response->getBody(), true);
return $data['data'];
}
$token = getToken()['token'];
import requests
def get_token(public_key, private_key):
api_url = 'https://api.felloh.com/token'
headers = {
'Content-Type': 'application/json'
}
data = {
'public_key': public_key,
'private_key': private_key
}
response = requests.post(api_url, json=data, headers=headers)
response.raise_for_status()
return response.json()['data']['token']
public_key = '<YOUR PUBLIC KEY>'
private_key = '<YOUR PRIVATE KEY>'
token = get_token(public_key, private_key)
print(f'Token: {token}')
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
public class TokenService
{
private readonly IConfiguration _configuration;
private readonly HttpClient _httpClient;
public TokenService(IConfiguration configuration)
{
_configuration = configuration;
_httpClient = new HttpClient();
}
public async Task<string> GetTokenAsync()
{
var publicKey = _configuration["PUBLIC_KEY"];
var privateKey = _configuration["PRIVATE_KEY"];
var requestContent = new StringContent(
Newtonsoft.Json.JsonConvert.SerializeObject(new
{
public_key = publicKey,
private_key = privateKey
}),
Encoding.UTF8,
"application/json"
);
var response = await _httpClient.PostAsync("https://api.felloh.com/token", requestContent);
if (!response.IsSuccessStatusCode)
{
throw new Exception($"Failed to get token. Status code: {response.StatusCode}");
}
var responseData = await response.Content.ReadAsStringAsync();
return responseData;
}
}

The following code will authenticate you against the api and get the bearer token, you can then use this for all future calls against the API.

You will need to get your public and private keys from the dashboard and them set these either in the environment or via another method.

More information on authentication can be found here.

2. Creating a booking

Creating a booking

const token = 'YOUR TOKEN HERE (FROM STEP 1)';
const response = await axios(
{
method: 'put',
url: `https://api.felloh.com/agent/bookings`,
data : JSON.stringify({
organisation: 'X9876',
customer_name: 'James Dean',
email: 'james@felloh.org',
booking_reference: 'XXX123789',
departure_date: '2022-07-18',
return_date: '2022-07-25',
gross_amount: 1000000,
}),
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
},
);
const bookingID = response.data.data.id;
use GuzzleHttp\Client;
function createBooking($token) {
$client = new Client();
$response = $client->put('https://api.felloh.com/agent/bookings', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $token,
],
'json' => [
'organisation' => 'X9876',
'customer_name' => 'James Dean',
'email' => 'james@felloh.org',
'booking_reference' => 'XXX123789',
'departure_date' => '2022-07-18',
'return_date' => '2022-07-25',
'gross_amount' => 1000000,
],
]);
$data = json_decode($response->getBody(), true);
return $data['data']['id'];
}
$token = 'YOUR TOKEN HERE (FROM STEP 1)';
$bookingID = createBooking($token);
import requests
def create_booking(token):
api_url = 'https://api.felloh.com/agent/bookings'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
}
data = {
'organisation': 'X9876',
'customer_name': 'James Dean',
'email': 'james@felloh.org',
'booking_reference': 'XXX123789',
'departure_date': '2022-07-18',
'return_date': '2022-07-25',
'gross_amount': 1000000
}
response = requests.put(api_url, json=data, headers=headers)
response.raise_for_status()
return response.json()['data']['id']
token = 'YOUR TOKEN HERE (FROM STEP 1)'
booking_id = create_booking(token)
print(f'Booking ID: {booking_id}')
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string token = "YOUR TOKEN HERE (FROM STEP 1)";
var bookingId = await CreateBooking(token);
Console.WriteLine($"Booking ID: {bookingId}");
}
static async Task<string> CreateBooking(string token)
{
using (HttpClient client = new HttpClient())
{
string apiUrl = "https://api.felloh.com/agent/bookings";
client.DefaultRequestHeaders.Add("Content-Type", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var data = new
{
organisation = "X9876",
customer_name = "James Dean",
email = "james@felloh.org",
booking_reference = "XXX123789",
departure_date = "2022-07-18",
return_date = "2022-07-25",
gross_amount = 1000000
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var httpResponse = await client.PutAsync(apiUrl, content);
httpResponse.EnsureSuccessStatusCode();
var responseData = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(await httpResponse.Content.ReadAsStringAsync());
return responseData.data.id;
}
}
}

As mentioned, this step can be skipped if you do not currently have a booking and would just like to create a payment link, however you will need to use the assign endpoint at a later stage to get payouts on the booking.

More information on creating a booking can be found here.

Creating a payment link

const token = 'YOUR TOKEN HERE (FROM STEP 1)'
const bookingID = 'FELLOH BOOKING ID HERE (FROM STEP 2)';
const response = await axios(
{
method: 'put',
url: `https://api.felloh.com/agent/payment-links`,
data : JSON.stringify({
organisation: 'X9876',
customer_name: 'James Dean',
email: 'james@felloh.org',
booking_id: bookingID,
amount: 20000,
open_banking_enabled: true,
card_enabled: true,
description: 'Final payment for cruise holiday'
}),
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
},
);
const paymentLinkID = response.data.data.id;
const paymentURL = `https://pay.felloh.com/${paymentLinkID}`
use GuzzleHttp\Client;
function createPaymentLink($token, $bookingID) {
$client = new Client();
$response = $client->put('https://api.felloh.com/agent/payment-links', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $token,
],
'json' => [
'organisation' => 'X9876',
'customer_name' => 'James Dean',
'email' => 'james@felloh.org',
'booking_id' => $bookingID,
'amount' => 20000,
'open_banking_enabled' => true,
'card_enabled' => true,
'description' => 'Final payment for cruise holiday',
],
]);
$data = json_decode($response->getBody(), true);
return $data['data']['id'];
}
$token = 'YOUR TOKEN HERE (FROM STEP 1)'; // Replace with the actual token obtained from the previous step
$bookingID = 'FELLOH BOOKING ID HERE (FROM STEP 2)'; // Replace with the actual booking ID obtained from the previous step
$paymentLinkID = createPaymentLink($token, $bookingID);
$paymentURL = "https://pay.felloh.com/$paymentLinkID";
import requests
def create_payment_link(token, booking_id):
api_url = 'https://api.felloh.com/agent/payment-links'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
}
data = {
'organisation': 'X9876',
'customer_name': 'James Dean',
'email': 'james@felloh.org',
'booking_id': booking_id,
'amount': 20000,
'open_banking_enabled': True,
'card_enabled': True,
'description': 'Final payment for cruise holiday'
}
response = requests.put(api_url, json=data, headers=headers)
response.raise_for_status()
return response.json()['data']['id']
token = 'YOUR TOKEN HERE (FROM STEP 1)'
booking_id = 'FELLOH BOOKING ID HERE (FROM STEP 2)'
payment_link_id = create_payment_link(token, booking_id)
print(f'Payment Link ID: {payment_link_id}')
payment_url = f'https://pay.felloh.com/{payment_link_id}'
print(f'Payment URL: {payment_url}')
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string token = "YOUR TOKEN HERE (FROM STEP 1)";
string bookingId = "FELLOH BOOKING ID HERE (FROM STEP 2)";
var paymentLinkId = await CreatePaymentLink(token, bookingId);
Console.WriteLine($"Payment Link ID: {paymentLinkId}");
var paymentUrl = $"https://pay.felloh.com/{paymentLinkId}";
Console.WriteLine($"Payment URL: {paymentUrl}");
}
static async Task<string> CreatePaymentLink(string token, string bookingId)
{
using (HttpClient client = new HttpClient())
{
string apiUrl = "https://api.felloh.com/agent/payment-links";
client.DefaultRequestHeaders.Add("Content-Type", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var data = new
{
organisation = "X9876",
customer_name = "James Dean",
email = "james@felloh.org",
booking_id = bookingId,
amount = 20000,
open_banking_enabled = true,
card_enabled = true,
description = "Final payment for cruise holiday"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var httpResponse = await client.PutAsync(apiUrl, content);
httpResponse.EnsureSuccessStatusCode();
var responseData = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(await httpResponse.Content.ReadAsStringAsync());
return responseData.data.id;
}
}
}

You can now create the payment link, with this ID you can then send this link to the customer or alternatively display in your system.

More information on creating a payment link can be found here.