This feature must be enabled by your account manager and is not available by default.
In order to create a payment on your website, 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 embed a payment without one. You will
need to implement the following to undertake payments,
1. Install the SDK
2. Authenticating
3. Create a booking
4. Create an ecommerce instance
5. Render the payment form and handle events
An example of our SDK (and embedded payments) can be found here on our demo site.
The full API specification for the ecommerce object can be found here .
Further information regarding the SDK and its methods cam be found here .
Installing the SDK via the command line (with Yarn)
yarn add @felloh-org/payment-sdk
You will need to install our SDK using a package manager on your frontend. We recommend either using NPM or Yarn. Our
SDK can be found at https://www.npmjs.com/package/@felloh-org/payment-sdk .
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
import os
def get_token ( ) :
url = 'https://api.felloh.com/token'
public_key = os . environ . get ( 'PUBLIC_KEY' )
private_key = os . environ . get ( 'PRIVATE_KEY' )
payload = {
'public_key' : public_key ,
'private_key' : private_key
}
headers = {
'Content-Type' : 'application/json'
}
response = requests . post ( url , json = payload , headers = headers )
response . raise_for_status ( )
token = response . json ( ) [ 'data' ]
return token
token = get_token ( )
print ( token )
using System ;
using System . Net . Http ;
using System . Text ;
using System . Threading . Tasks ;
class Program
{
static async Task Main ( )
{
var token = await GetToken ( ) ;
Console . WriteLine ( token ) ;
}
static async Task < string > GetToken ( )
{
using ( var httpClient = new HttpClient ( ) )
{
var url = "https://api.felloh.com/token" ;
var publicKey = Environment . GetEnvironmentVariable ( "PUBLIC_KEY" ) ;
var privateKey = Environment . GetEnvironmentVariable ( "PRIVATE_KEY" ) ;
var requestData = new
{
public_key = publicKey ,
private_key = privateKey
} ;
var jsonContent = new StringContent ( Newtonsoft . Json . JsonConvert . SerializeObject ( requestData ) , Encoding . UTF8 , "application/json" ) ;
var response = await httpClient . PostAsync ( url , jsonContent ) ;
response . EnsureSuccessStatusCode ( ) ;
var responseData = await response . Content . ReadAsStringAsync ( ) ;
var token = Newtonsoft . Json . JsonConvert . DeserializeObject < dynamic > ( responseData ) . data ;
return token ;
}
}
}
This should be done as part of your backend code and not be exposed to your users.
you will need to authenticate against our 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 .
Creating a booking
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' ;
$bookingID = createBooking ( $token ) ;
import requests
import json
def create_booking ( token ) :
url = 'https://api.felloh.com/agent/bookings'
payload = {
'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' : f 'Bearer {token}'
}
response = requests . put ( url , data = json . dumps ( payload ) , headers = headers )
response . raise_for_status ( )
booking_id = response . json ( ) [ 'data' ] [ 'id' ]
return booking_id
booking_id = create_booking ( token )
print ( booking_id )
using System ;
using System . Net . Http ;
using System . Text ;
using System . Threading . Tasks ;
class Program
{
static async Task Main ( )
{
var token = await GetToken ( ) ;
var bookingID = await CreateBooking ( token ) ;
Console . WriteLine ( bookingID ) ;
}
static async Task < string > CreateBooking ( string token )
{
using ( var httpClient = new HttpClient ( ) )
{
var url = "https://api.felloh.com/agent/bookings" ;
var requestData = 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 jsonContent = new StringContent ( Newtonsoft . Json . JsonConvert . SerializeObject ( requestData ) , Encoding . UTF8 , "application/json" ) ;
httpClient . DefaultRequestHeaders . Add ( "Content-Type" , "application/json" ) ;
httpClient . DefaultRequestHeaders . Add ( "Authorization" , $ "Bearer {token}" ) ;
var response = await httpClient . PutAsync ( url , jsonContent ) ;
response . EnsureSuccessStatusCode ( ) ;
var responseData = await response . Content . ReadAsStringAsync ( ) ;
var bookingId = Newtonsoft . Json . JsonConvert . DeserializeObject < dynamic > ( responseData ) . data . id ;
return bookingId ;
}
}
}
This should be done as part of your backend code and not be exposed to your users.
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 an ecommerce instance
const response = await axios (
{
method : 'put' ,
url : ` https://api.felloh.com/agent/ecommerce ` ,
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 ,
} ) ,
headers : {
'Content-Type' : 'application/json' ,
Authorization : ` Bearer ${ token } ` ,
} ,
} ,
) ;
const ecommerceID = response . data . data . id ;
use GuzzleHttp \ Client ;
function createEcommerce ( $token , $bookingID ) {
$client = new Client ( ) ;
$response = $client - > put ( 'https://api.felloh.com/agent/ecommerce' , [
'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 ,
] ,
] ) ;
$data = json_decode ( $response - > getBody ( ) , true ) ;
return $data [ 'data' ] [ 'id' ] ;
}
$token = 'YOUR_TOKEN_HERE' ;
$bookingID = 'YOUR_BOOKING_ID_HERE' ;
$ecommerceID = createEcommerce ( $token , $bookingID ) ;
import requests
import json
def create_ecommerce ( token , booking_id ) :
url = 'https://api.felloh.com/agent/ecommerce'
payload = {
'organisation' : 'X9876' ,
'customer_name' : 'James Dean' ,
'email' : 'james@felloh.org' ,
'booking_id' : booking_id ,
'amount' : 20000 ,
'open_banking_enabled' : True ,
'card_enabled' : True
}
headers = {
'Content-Type' : 'application/json' ,
'Authorization' : f 'Bearer {token}'
}
response = requests . put ( url , data = json . dumps ( payload ) , headers = headers )
response . raise_for_status ( )
ecommerce_id = response . json ( ) [ 'data' ] [ 'id' ]
return ecommerce_id
ecommerce_id = create_ecommerce ( token , booking_id )
print ( ecommerce_id )
using System ;
using System . Net . Http ;
using System . Text ;
using System . Threading . Tasks ;
class Program
{
static async Task Main ( )
{
var token = await GetToken ( ) ;
var bookingId = await CreateBooking ( token ) ;
var ecommerceId = await CreateEcommerce ( token , bookingId ) ;
Console . WriteLine ( ecommerceId ) ;
}
static async Task < string > CreateEcommerce ( string token , string bookingId )
{
using ( var httpClient = new HttpClient ( ) )
{
var url = "https://api.felloh.com/agent/ecommerce" ;
var requestData = new
{
organisation = "X9876" ,
customer_name = "James Dean" ,
email = "james@felloh.org" ,
booking_id = bookingId ,
amount = 20000 ,
open_banking_enabled = true ,
card_enabled = true
} ;
var jsonContent = new StringContent ( Newtonsoft . Json . JsonConvert . SerializeObject ( requestData ) , Encoding . UTF8 , "application/json" ) ;
httpClient . DefaultRequestHeaders . Add ( "Content-Type" , "application/json" ) ;
httpClient . DefaultRequestHeaders . Add ( "Authorization" , $ "Bearer {token}" ) ;
var response = await httpClient . PutAsync ( url , jsonContent ) ;
response . EnsureSuccessStatusCode ( ) ;
var responseData = await response . Content . ReadAsStringAsync ( ) ;
var ecommerceId = Newtonsoft . Json . JsonConvert . DeserializeObject < dynamic > ( responseData ) . data . id ;
return ecommerceId ;
}
}
}
This should be done as part of your backend code and not be exposed to your users.
You can now create the ecommerce instance. Once generated, you will pass this ID to your frontend and to the SDK.
More information on creating an ecommerce object can be found here .
Creating an ecommerce instance in react
import SDK from '@felloh-org/payment-sdk' ;
import Axios from 'axios' ;
export default function Basic ( ) {
useEffect ( ( ) => {
const generatePayment = async ( ) => {
const fellohSDK = new SDK ( 'payment-iframe' , 'your-public-key' ) ;
const response = await axios . post ( 'https://your.api' ) ;
fellohSDK . render ( response . data . data . id ) ;
fellohSDK . onSuccess ( ( ) => {
window . location . success = 'https://mysite.com/payment-success'
} ) ;
} ;
generatePayment ( ) ;
} , [ ] ) ;
return (
< div id = "payment-iframe" / >
)
}
import SDK from '@felloh-org/payment-sdk' ;
import Axios from 'axios' ;
export default function Basic ( ) {
useEffect ( ( ) => {
const generatePayment = async ( ) => {
const fellohSDK = new SDK ( 'payment-iframe' , 'your-public-key' ) ;
const response = await axios . post ( 'https://your.api' ) ;
fellohSDK . render ( response . data . data . id ) ;
fellohSDK . onSuccess ( ( ) => {
window . location . success = 'https://mysite.com/payment-success'
} ) ;
} ;
generatePayment ( ) ;
} , [ ] ) ;
return (
< div id = "payment-iframe" / >
)
}
import SDK from '@felloh-org/payment-sdk' ;
import Axios from 'axios' ;
export default function Basic ( ) {
useEffect ( ( ) => {
const generatePayment = async ( ) => {
const fellohSDK = new SDK ( 'payment-iframe' , 'your-public-key' ) ;
const response = await axios . post ( 'https://your.api' ) ;
fellohSDK . render ( response . data . data . id ) ;
fellohSDK . onSuccess ( ( ) => {
window . location . success = 'https://mysite.com/payment-success'
} ) ;
} ;
generatePayment ( ) ;
} , [ ] ) ;
return (
< div id = "payment-iframe" / >
)
}
import SDK from '@felloh-org/payment-sdk' ;
import Axios from 'axios' ;
export default function Basic ( ) {
useEffect ( ( ) => {
const generatePayment = async ( ) => {
const fellohSDK = new SDK ( 'payment-iframe' , 'your-public-key' ) ;
const response = await axios . post ( 'https://your.api' ) ;
fellohSDK . render ( response . data . data . id ) ;
fellohSDK . onSuccess ( ( ) => {
window . location . success = 'https://mysite.com/payment-success'
} ) ;
} ;
generatePayment ( ) ;
} , [ ] ) ;
return (
< div id = "payment-iframe" / >
)
}
This should be done as part of your backend code and not be exposed to your users.
You can now render the payment iframe and take payment.
More information on using the SDK and it's methods can be found here .