Embedded Fields (EF)¶
Introduction¶
This is a guide on how to integrate Embedded Fields (EF) into the merchant’s checkout page. It provides detailed instructions on EF frontend and backend integration, including:
- Customization Options
- Handling Callbacks
- Ensuring PCI Compliance
Additionally, it offers best practices for optimizing the checkout flow and enhancing security measures to provide an effortless payment experience for customers.
What are Embedded fields (EF)?¶
Embedded fields are a method of integrating payment forms directly into a merchant's website or application, rather than redirecting users to an external payment page.
Pre-Integration Requirements¶
Before integrating the Hosted Payment Page (HPP) and Embedded Fields (EF) into your merchant's checkout page, make sure you have the following requirements:
-
Extended API Key
To obtain an Extended API Key, you must access the Merchant Portal. -
Authorization Header
Add an Authorization header in the API requests containing a Bearer token. This token is similar to the OpenID Connect JSON Web Token (OIDC JWT). -
x-api-key for Payment Gateway APIs
Each merchant is assigned a unique x-api-key. That key is an authentication for backend-to-backend communication with the payment gateway APIs. -
x-client-key for Client Libraries/APIs
This is the merchant's public key and it serves the purpose of identifying the merchant.
Setting Up Hosted Payment Page¶
This guide provides a walkthrough for setting up a Hosted Payment Page, incorporating both Frontend and Backend Setup.
Frontend Setup¶
Here is a guide on how to set up a Hosted Payment Page through the frontend.
Setting up a Hosted Payment Page through the frontend requires ensuring that, prior to the application loading, the window object contains both the client_key and session_id.
client_key can be obtained from the dashboard.
session_id can be obtained from the session endpoint.
JavaScript example:
window.InitData = {
"client_key": "client_key",
"session_id": "session_id"
}
Backend Setup¶
Here is a guide on how to set up a Hosted Payment Page through the
backend.
The integration involves obtaining an authentication token and creating
a session for transaction processing.
- The first step is obtaining an Authentication Token.
Authentication Token can be obtained using the backend API. For that, you will need a username and password which we will create for you through email.
JavaScript example:
function createToken() {
return loadJsonFile('[path]/secret.json')
.then((secretData) => {
return fetch(
'/api/oauth2/login/token',//endpoint for token
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
username: secretData.username,
password: secretData.password
})
}
).then(response => {
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.status}`);
}
return response.json();
})
})
}
- After successfully obtaining the token, you can create a session.
To create a session, you must obtain x-api-key and access_token.
x-api-key can be obtained from the dashboard.
access_token can be obtained from the previous request.
JavaScript example:
function createSession(data) {// data -> result from token endpoint
const randomString = `date-${new Date().getTime()}`;//something for
reference
return loadJsonFile('[path]/secret.json')
.then((secretData) => {
return fetch(
'/api/sessions',//endpoint for session
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-api-key': secretData.xApiKey, //xApiKey available on the dashboard
'Authorization': `Bearer ${data?.access_token}` //access_token from token endpoint
},
body: JSON.stringify({ // Data that will be available once the front end obtain the session.
"terminal_id": "DEV02",
"reference": randomString,
"description": "f2aed380-b8bb-481f-92be-3060cc1ed4a2",
"currency": "EUR",
"amount": 25600,
"transaction_type": "AUTHORIZE", //”PURCHASE”
"success_url": "https://google.com/success-url",
"cancel_url": "https://google.com/failed-url",
"customer": {
"first_name": "John",
"last_name": "Doe",
"address": "Address",
"city": "City",
"country": "BA",
"postal_code": "10000",
"email": "email@email.com",
"phone": "00000"
},
"country": "BA",
"metadata": {
"simulated_flow": "VERSIONING_FINGERPRINT_Y_CHALLENGE",
"response_code": "APPROVED", //DECLINED, for declined
"payment_provider_response_message": "approved", //declined, for declined
"payment_provider_response_code": "approved-code", //declined-code, fo declined
"approval_code": "N/A"
}
})
}
).then(response => {
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.status}`);
}
return response.json();//session id
})
})
}
Configuring Embedded Fields¶
This guide provides a walkthrough for configuring Embedded Fields, incorporating both Frontend and Backend integration.
Frontend Integration¶
Here is a guide on how to integrate Embedded Fields into your frontend.
To integrate Embedded Fields into your frontend, you will need the following:
-
sessionId This is the session ID obtained from your backend's session endpoint.
-
clientKey This is the merchant client key, available on the dashboard.
Follow these steps to complete the integration:
-
Load the embedded-fields.js script.
-
Initialize the checkout process using the obtained sessionId and clientKey.
-
Create a payment component for card payments.
-
Mount the newly created card payment component in your frontend.
JavaScript example:
this.loadScriptByURL("embedded-fields-script-id", "https://api-dev.finese.ioembedded-fields.js?k-1", () => {
//sessionId from session endpoint, clientKey available on dashboard
merchant
this.initCheckout(sessionId, clientKey)
.then(resolve => {
console.log('Resolve:', resolve)
}, reason => {
console.log('Reject:', reason)
})
});
readonly initCheckout = async (sessionId: string, clientKey: string) => {
const paymentComponent = await (window as any).PaymentComponent({
locale: 'en-US',
environment: 'test', //production when you are ready for production
clientKey: clientKey,
sessionId: sessionId
})
// Here, you can create a component that allows you to pay with a new card.
// Optional lifecycle events (onChange, onError, customerConfig) are available.
// you can simply use paymentComponent.create('card') and it will work as expected.
const componentConfig = {
componentConfig: {
customerConfig: {
hasHolderEmail: true, //show/hide email
holderEmailRequired: false, // email is (not)required (validation will be triggered)
// hasHolderName: true, //show field for name
// holderNameRequired: true //name required….
}
},
componentListeners: {
onChange: (e) => {
console.log('Client side on change:', e)
},
onError: (e) => {
console.log('Client side error:', e)
}
}
}
cardPaymentComponent = paymentComponent.create('card', componentConfig)
//Mount your newly created component somewhere, for example, on a <div> with the ID 'card-wrapper'.
cardPaymentComponent.mount('#card-wrapper')
}
Submit the payment when you are ready to proceed.
function submitPayment() {
const isValid = cardPaymentComponent.validate()
const validationObject = cardPaymentComponent.getDataWithValidation()
// If you want to know which field is not correct and what’s the error message for certain field.
if (isValid) {
const customer = cardPaymentComponent.getCustomer()
cardPaymentComponent.submitPayment({
customer: {
...customer, // You can override the customer information if needed.
firstName: 'buyer firstName',
lastName: 'buyer lastName',
address: 'buyer address',
city: 'buyer city',
zip: 'buyer zip',
country: 'buyer country',
phone: 'buyer phone',
email: 'buyer email'
},
callback: (response, error) => {
// Payment completed
if (response?.approved) {
// ...
} else {
// ...
}
if (error) {
// ...
}
}
})
}
}
Backend Integration¶
To integrate Embedded Fields into your backend, you will follow the same steps as you would for setting up a Hosted Payment Page.
Authentication and Transaction Processing¶
Messages for the API calls¶
The Hosted Payment Page API enables secure authentication and
transaction processing for merchants.
This document outlines the messages exchanged during the authentication
and transaction processing.
Authenticate with API¶
Before initiating any transaction, merchants need to authenticate themselves using their credentials.
Merchants can authenticate by sending a POST request with their username and password to the authentication endpoint.
Endpoint: {baseUrl}/api/oauth2/login/token
Request Method: POST
Request Headers:
-
Content-Type: application/json
-
Accept: application/json
Request Body:
{
"username": "dev01@finese.io",
"password": "123456789Aa*"
}
Response Example:
{
"access_token": "`eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJzNk5TbUpxTDNGZHRaOHVsWk1BUVIxRGE5Rl8wam1OczFPRm9BZmdIVWVVIn0.eyJleHAiO",
"token_type": "Bearer",
"expires_in": 300,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI5YjQ2OGIyNi0yYzdkLTQ0ZGYtODJhNS00NDZmZDFkNWVlMGMifQ.eyJleHAiOjE3MDY2MT",
"scope": "email profile"
}
Create Payment Session¶
Once authenticated, merchants can create a payment session by providing the necessary attributes.
Required Attributes:
Name | Location | Type | Description | Required |
---|---|---|---|---|
x-api-key | header | string | x-api-key available in the merchant portal | yes |
terminal_id | body | string | A terminal ID | yes |
Authorization | header | string | Bearer \${access_token} | yes |
reference | body | string(40) | Order reference has to be unique for the terminal | yes |
description | body | string | Order reference has to be unique for the terminal | yes |
currency | body | string(3) | ISO currency code e.g., EUR | yes |
amount | body | int64 | Order Amount | yes |
transaction_type | body | enumeration | Authorize or Purchase | yes |
success_url | body | url | A URL user is redirected to after a successful payment | yes |
cancel_url | body | url | A URL user is redirected to after cancellation or failed payment | yes |
country | body | string(2) | User's country - used to pre-load country-specific payment methods | no |
customer | body | object | Customer details - pre-load if provided, requested if not | no |
Endpoint: {baseUrl}/api/sessions
Request Method: POST
Request Headers:
-
Content-Type: application/json
-
Accept: application/json
-
x-api-key: \<x-api-key>
-
Authorization: Bearer \<access_token>
Request Body:
{
"id": "tcNyatfpvOjxxIDEdcYH",
"terminal_id": "DEV01",
"reference": "00893e62-c536-4e35-887e-79f23ac4c971",
"description": "5f0da071-c27e-4b15-beea-f3071740ade1",
"currency": "EUR",
"amount": 25600,
"success_url": "https://google.com/success-url?payload=H4Yje-
YA91s15xdQIVzNXlY3xL_p4Aey7IgqVbgbsW__Czv9TrvpwnxaIh1LmaSZHLKdZEbmHaDBEddq3E",
"cancel_url": "https://google.com/failed-url?payload=hVUXvUugEL9gX14-
4l4dWkgr88RQH0eBiBysx8fmwB1DbRvegoxQrtvKVlbb2ZJgnuqh_f3LVPmIjb9jjKz4",
"error_url": null,
"customer": {
"first_name": "John",
"last_name": "Doe",
"address": "Address",
"city": "City",
"country": "BA",
"postal_code": "10000",
"email": "email@email.com",
"phone": "00000",
"id": null
},
"country": "BA",
"expires_at": null,
"status": "CREATED",
"transaction_type": "AUTHORIZE"
}
Use Session ID to Load the Payment Form¶
After receiving the session ID, merchants can use it to load the payment
form for the customer.
The base URL for the payment form is:
https://api-dev.finese.io/payment/\${id}.
We are still continuously developing the payment form. The rest of the flow like getting an access token and creating a session will not change.
Customization Options¶
Customization is key to ensuring that the payment field aligns perfectly with each merchant's individual needs and branding. Here, we will explore customization options available through our payment system.
Embedded Fields Customization¶
This document shows customization options available for Embedded Fields.
Embedded Fields consist of different elements such as card input fields, labels, and warning messages.
These elements can be customized by overriding CSS variables.
Here is an example:
embedded-fields-card, #card-wrapper {
--lib-font-family: var(--app-font-family);
--lib-input-font-size: 1.7rem;
--lib-accent-color: #556a61;
--lib-accent-background-color: #DFE8E1;
--lib-label-font-size: 1rem;
--lib-warning-color: #ff8c70;
--lib-warning-background-color: #fff6ee;
--lib-input-color: #556a61;
--lib-input-focus-border-color: #86a599;
--lib-input-border-color: #d4d7d6;
--lib-input-focus-color: #179261;
--lib-place-holder-color: #e1e1e1;
--lib-input-border-radius: 0.5rem;
--lib-button-border-radius: 0.7rem;
--lib-button-font-size: 1.1rem;
}
In addition to overriding CSS variables, customization can be applied
using CSS selectors to target specific elements within the payment
fields.
Here is an example:
embedded-fields-card div.input-container.lib-input-root div.lib-input-wrapper
input {
font-family: var(--app-font-family)
}
lib-input .lib-input-wrapper, lib-iframe-input div.iframe-input-wrapper {
border-style: initial !important;
border-bottom: 1px solid var(--lib-input-border-color) !important;
border-radius: initial !important;
}
Handling Redirects and Callbacks¶
For online transactions, providing a good payment experience is important for both merchants and customers. As part of this, handling redirects and callbacks is important to ensure that users navigate through the payment process without any issues.
Redirect is a technique that is used to redirect your domain's
visitors to a different URL.
When a customer makes a purchase, they are redirected to a different
page so they can complete the transaction, making the transaction more
secure.
Callback refers to a process by which a payment gateway or a payment processor informs a merchant's server about the status of a payment transaction.
Embedded Fields¶
When integrating embedded fields for payment processing, it is important to manage redirects and callbacks effectively.
-
Event Handling:
-
onChange: This function logs any changes that are occurring during the payment process on the client side.
-
onError: Handles any errors that may happen during the payment process.
-
-
Customer Configuration:
- customerConfig allows setting options related to customer details, such as whether the holder's email is required and if it's mandatory.
-
Redirect Decision:
- After the “callback”, the merchant decides where to redirect the user based on the payment outcome.
Example:
const componentConfig = {
componentConfig: {
customerConfig: {
hasHolderEmail: true,
holderEmailRequired: false,
//...
}
},
componentListeners: {
onChange: (e) => {
console.log('Client side on change:', e)
},
onError: (e) => {
console.log('Client side error:', e)
}
}
}
cardPaymentComponent = paymentComponent.create('card', componentConfig)
cardPaymentComponent.submitPayment({
customer: {
...customer,
},
callback: (response, error) => {
//Payment completed
}
})
Ensuring PCI Compliance¶
PCI Compliance, short for Payment Card Industry Data Security Standard (PCI DSS) compliance, is a set of security standards designed to ensure that all companies that accept, process, store, or transmit credit card information maintain a secure environment. Compliance with PCI DSS helps to protect cardholder data from theft and fraud.
Compliance with PCI DSS is important for merchants and service providers for multiple reasons:
-
Protection of Cardholder Data: PCI DSS compliance helps protect sensitive cardholder information, reducing the risk of data breaches and fraud.
-
Maintaining Trust: Compliance demonstrates to customers that their payment information is being handled securely.
-
Legal Requirements: Non-compliance with PCI DSS can result in legal consequences, including fines, penalties, and legal action.
-
Avoiding Financial Loss: PCI Compliance reduces the risk of financial losses associated with data breaches, including costs related to investigations, fines, and customer compensation.
PCI Compliance Validation¶
Validation of PCI DSS compliance varies depending on the merchant level and the volume of transactions processed. Merchants are categorized into four levels based on their transaction volume per year:
-
Level 1: Merchants with over 6 million transactions annually, across all channels.
-
Level 2: Merchants with between 1 million and 6 million transactions annually, across all channels.
-
Level 3: Merchants with between 20,000 and 1 million online transactions annually.
-
Level 4: Merchants with fewer than 20,000 online transactions annually or up to 1 million regular transactions per year.
Validation methods include self-assessment questionnaires (SAQs) and external audits conducted by Qualified Security Assessors (QSAs).
Consequences of Non-Compliance¶
Failure to comply with PCI DSS requirements can have serious consequences. It poses financial risks and it also threatens a merchant's ability to handle business effectively.
If the merchant fails to comply with PCI DSS requirements, here are some of the consequences:
-
Fines: Merchants who fail to comply with PCI DSS standards can be expected to pay fines. The fine amount depends on the volume of transactions, merchant level, and the duration of non-compliance.
-
Loss of Payment Processing Privileges: If a merchant does not resolve compliance issues to the satisfaction of the card company, they may have their ability to accept card payments revoked.
-
Legal Action by Card Companies and Regulatory Bodies: The Federal Trade Commission (FTC) monitors organizations for PCI DSS compliance. Noncompliant companies may face legal action.
-
Reputation Damage: Noncompliance can damage a merchant's reputation among customers and business partners.
-
Increased Risk of Data Breaches and Fraud: Failure to comply with PCI DSS standards increases the risk of data breaches and fraudulent activities.
Before using our Hosted Payment Page, you must confirm that you meet the
necessary PCI compliance standards based on how you operate and the
volume of transactions you process.
This ensures that your data stays safe and that you're in line with all
the necessary rules and regulations.
Best Practices For Integration¶
Integrating Hosted Payment Pages (HPP) and Embedded Fields (EF) into your merchant's checkout page requires careful attention to pre-integration requirements and setup procedures. Following Best Practices makes your customer payment experience smooth and secure.
Before the integration make sure that you have all of the Pre-Requirements:
-
Extended API Key
-
Authorization Header
-
x-api-key
-
x-client-key
Follow the best practices for the integration process:
EF Frontend Integration¶
-
Obtain Required Parameters: Retrieve sessionId and clientKey from the backend's session endpoint and dashboard.
-
Load Embedded Fields Script: Load the embedded-fields.js script and initialize the checkout process with sessionId and clientKey.
-
Create Payment Component: Use paymentComponent.create('card') to create a payment component for card payments.
-
Mount Component: Ensure proper mounting of the card payment component on the frontend.
EF Backend Integration¶
To integrate Embedded Fields into your backend, you will follow the same steps as you would for setting up a Hosted Payment Page.
Troubleshooting and FAQ¶
Troubleshooting¶
This guide aims to assist merchants with identifying and resolving common issues during the Integration process of the Hosted Payment Page (HPP) and Embedded Fields (EF).}
Here we will go over the most common issues and how to resolve them.
Unable to create a Token¶
Failure to create a token will cause authentication issues. The easiest way to resolve this issue is by following these steps:
-
Verify that the username and password provided in the secret.json file are correct.
-
Make sure that the network connection is stable and capable of reaching the endpoint.
-
Double-check the endpoint configuration in the createToken()
Unable to Create a Session¶
The easiest way to resolve this issue is to follow these steps:
-
Confirm that the x-api-key and Authorization headers are correctly set.
-
Review the endpoint URL and method specified in the createSession()
-
Check for any inconsistencies or errors in the request payload, such as missing or incorrect values.
Most of the issues can be caused by poor or unstable network connection
or incorrect credentials.
Make sure that your network is stable and that your username and
password are correct.
Embedded Fields Troubleshooting¶
The easiest way to troubleshoot Embedded Fields is by checking
callbacks like onError and onPaymentCompleted. They are available to
handle different stages of the payment process.
If the transaction is already completed, the onPaymentCompleted callback
will be triggered. Additionally, in case of a rejected transaction,
there will be a status provided with the reason for rejection.
Frequently Asked Questions (FAQ)¶
What is the difference between the Hosted Payment Page (HPP) and Embedded Fields (EF)?¶
Hosted Payment Page (HPP) is a section where customers are directed
to complete their purchase. It can be integrated using an iframe or a
redirect to an external payment page.
Embedded Fields (EF) are payment forms integrated directly into a
merchant's website or application, avoiding redirection to an external
payment page.
How do I obtain the necessary API keys for integrating HPP and EF?¶
You can obtain the Extended API key on the merchant portal.
For more information, you can check the Setting Up Hosted Payment
Page.
How can I make sure that I am PCI compliant while integrating HPP and EF?¶
To ensure PCI compliance:
-
Adhere to the Payment Card Industry Data Security Standard (PCI DSS).
-
Obtain PCI DSS compliance validation based on transaction volume.
¶
What customization options are available for HPP and EF?¶
Embedded Fields (EF) Customization options include CSS variable overrides and CSS selector targeting for specific elements like card input fields, labels, buttons, and warning messages.
Hosted Payment Page (HPP) Customization options are currently not supported.