Use existing token
Our platform allows you to store your customers' credit card data permanently for 1‑click payments. By pre‑filling the Hosted Fields with the stored data, your customers' payment experience will become even smoother and improve your conversion rate.
As the token is already existing at the time of the transaction request, the payment flow is different:
- Step 1: Instruct our platform you want to use an existing token. To do so, modify the request CreateHostedFieldsSession by adding the property tokens. List all the identifiers for existing tokens for your customer:
{"locale":"en-GB", "tokens": "Your_token"} - Step 2 : Load the JavaScript library to checkout page.
- Step 3 : Initialise the Hosted Fields on your checkout page. As the card data will be pre-filled, only display the CVV. var config = { "sessionData": "apiResponse.sessionData", "logLevel": "debug", "style": { "input": { "color": "#000000", "font-family": "courier, monospace", "font-size": "14px" }, "input::placeholder": { "color": "#999999" } }, "fields": { "csc": { "id": "csc", "title": "Your card security code", "caption": "Your card security code", "placeholder": "123" } } }
- Step 4 : Populate the hostedFields instance with the token to be used:
hostedFields.useToken(existingTokenId); Mind that the same session can be loaded multiple times on the same page.
Make sure to call useToken on the right instance if you choose to load more than one token. - Step 5 : Listen for validation events, submit and create the payment like in the regular flow.
Flows
Find a full transaction flow involving every party and (optional) steps in this overview:
- Your customers go to your check-out page and finalise the purchase.
- You send a CreateHostedFields session to our platform. Our platform returns the sdkUrl / hostedFieldsSessionId.
- You load the sdkUrl library to initialise the Hosted Fields in the input fields on your checkout page.
- Your customers enter their card details in the input fields and submit the card data to our platform.
- Our platform tokenises the card data.
- You send a CreatePayment request to our to our platform using our Server-to-server integration method, including the mandatory 3-D Secure properties.
6'(optional).We perform a fraud prevention check. - Our platform sends a response containing a merchantAction object, instructing you how to proceed. These scenarios are possible:
a) 3-D Secure frictionless flow (merchantAction.actionType=null). The flow continues at step 13).
b) 3-D Secure challenge flow (merchantAction.actionType="REDIRECT"). The flow continues at step 8).
c) No 3-D Secure authentication (merchantAction.actionType=null). The flow continues at step 13). - You redirect the customer to her/his issuing bank for 3-D Secure authentication. The customer identifies herself/himself.
- Our platform receives the 3-D Secure authentication result from the issuer. Based on the result, two scenarios are possible:
a) If the identification was unsuccessful, we redirect your customers to your returnUrl, ending the flow. You request/show the transaction result as described in step 12.
b) If the identification was successful, the flow continues at step 10. - We process the transaction and receive the result from the acquirer.
- We redirect your customer to your returnUrl.
- You request the transaction result from our platform and show it on your returnUrl/in your webshop.
- If the transaction was successful, you can deliver the goods/services.
What is PCI DSS Compliance?
PCI DSS is a security standard designed to protect cardholder data. Compliance prevents fraud, maintains customer trust, and avoids penalties.
To become PCI DSS compliant, merchants must follow specific steps to ensure their payment data security and adherence to standards:
- Understand PCI DSS Requirements: Familiarize yourself with the PCI DSS standards that protect cardholder data and ensure secure payment transactions.
- Consultation and Training: Utilize Worldline services to gain insights into the criteria you need to meet.
- Use PCI DSS Validated Solutions: Implement validated third-party solutions for payment data processing.
- Implement Security Standards: Process card data in accordance with security standards and ensure your equipment and systems meet these requirements.
- Identify the Relevant SAQ: Complete the appropriate Self-Assessment Questionnaire (SAQ) based on your card payment processing methodology (see SAQ types on the first slide).
- Compliance Reporting: Depending on your merchant level (from 1 to 4), regularly submit compliance reports through the respective methods like audits, ASV scans, or SAQs.
- Use Worldline Portals: Leverage the Worldline's web-based, self-service portal that offers tools to validate PCI DSS compliance and provides the needed resources for a comprehensive compliance journey.
- Contractual Obligations: Remember that compliance obligations are part of the general conditions for merchants using Worldline services.
By following these steps, merchants can ensure they meet PCI DSS requirements, thereby securing payment data and complying with regulatory standards.
Maintaining Compliance
Regularly update your security measures, review policies, and keep staff informed on best practices. We are here to assist with expert guidance. Contact us for more information.
The SDK has a lot more to offer. Have a look at the following features, as they will help you build the perfect solution.
- Get available payment methods
- Send idempotent requests
- Use logging
- Connection pooling
- Customise communication
- Webhooks
Get available payment methods
Before you initiate the actual payment process, you should send a GetPaymentProducts request to our platform. The response contains a list of available payment methods in your PSPID. Depending on your customers’ preferences, you can offer a selection on our Hosted Checkout Page or on your own webshop environment using subsequent CreatePayment requests.
- GetPaymentProductsParams
/*
*…. Initialisation....
*/
$merchantClient = $client->merchant($merchantId);
// Prepare the request to get all active payment methods in your PSPID
$queryParams = new GetPaymentProductsParams();
// Example params
$queryParams->setCountryCode("BE");
$queryParams->setCurrencyCode("EUR");
// Send the request and get the response
$paymentProductsResponse = $merchantClient
->products()
->getPaymentProducts($queryParams);
Send idempotent requests
One of the main REST API features is its ability to detect and prevent sending requests (i.e. payment requests) accidentally twice. The SDK makes it very easy for you to ensure that you send only unique – idempotent – requests to our platform.
Use the additional argument CallContext and set its property named $idempotenceKey by call setIdempotenceKey() setter on the object previously created and call the CreatePayment API function. The SDK will send an X-GCS-Idempotence-Key header with the idempotence key as its value.
If you send requests this way to our platform, we will check the following
- If you send subsequent request with the same idempotence key, the response contains an X-GCS-Idempotence-Request-Timestamp header. The SDK will set the $idempotenceRequestTimestamp property of the CallContext argument
- If the first request is not finished yet, the RESTful Server API returns a 409 status code. Then the SDK throws an IdempotenceException with the original idempotence key and the idempotence request timestamp
- CallContext
- IdempotenceException
/*
*…. Initialisation....
*/
$merchantClient = $client->merchant($merchantId);
$createPaymentRequest = new CreatePaymentRequest();
$idempotenceKey = "YourKeyForThePayment";
$callContext = new CallContext();
$callContext->setIdempotenceKey($idempotenceKey);
try {
$createPaymentResponse = $merchantClient
->payments()
->createPayment(
$createPaymentRequest,
$callContext
);
} catch (IdempotenceException $e) {
// a request with the same $idempotenceKey is still in progress, try again after a short pause
// $e->getIdempotenceRequestTimestamp() contains the value of the
// X-GCS-Idempotence-Request-Timestamp header
} finally {
$idempotenceRequestTimestamp =
$callContext->getIdempotenceRequestTimestamp();
// $idempotenceRequestTimestamp contains the value of the
// X-GCS-Idempotence-Request-Timestamp header
// if $idempotenceRequestTimestamp is not empty, this was not the first request
}
Use logging
The SDK supports logging of requests, responses, and exceptions. These can be helpful for troubleshooting or tracing individual steps in the payment flow.
The SDK offers two implementations of the logging feature:
- SplFileObjectLogger (by use of SplFileObject)
- ResourceLogger
- ResourceLogger
You can enable/ disable the logging by calling:
/*
*…. Initialisation....
*/
$client = new Client($communicator);
// You can enter a file pointer of the file you
// would like to save data to instead of STDOUT
$logger = new ResourceLogger(STDOUT);
$client->enableLogging($logger);
//... Do some calls
$client->disableLogging();
Connection pooling
You can manage your network resources by limiting the number of possible connections the SDK creates and maintains. The Client instances created as discussed in the Initialise SDK chapter will have their own connection pool. The Client instances created with the same Communicator object share a connection pool.
If you use multiple Client instances to share a single connection pool, make sure to follow these steps:
- Create a shared Communicator
- Create Client instances with that Communicator
/*
*…. Initialisation....
*/
// Create CommunicatorConfiguration instance
// with proper settings
$sharedCommunicatorConfiguration =
new CommunicatorConfiguration(
$apiKey,
$apiSecret,
$apiEndpoint,
$integrator,
$proxyConfiguration
);
$connection = new DefaultConnection();
// Communicator instance
$communicator = new Communicator(
$connection,
$sharedCommunicatorConfiguration
);
$client1 = new Client($communicator);
$client2 = new Client($communicator);
Customise communication
The Client instances use an Communicator instance to communicate with our platform. Whereas, Communicator uses Connection to perform the actual HTTP requests and a ConnectionResponse to hold the HTTP response.
Connection and ConnectionResponse are interfaces. The SDK provides a default implementation of those interfaces via the classes DefaultConnection and DefaultConnectionResponse.
- DefaultConnection class uses cURL via the standard PHP/cURL bindings to implement the get(), delete(), post() and put() methods
- DefaultConnectionResponse offers a straightforward implementation of the getHttpStatusCode(), getHeaders(), getHeaderValue() and getBody() methods, and is used by DefaultConnection
You can provide your own implementation of the interface of Connection to use in Communicator object as for example YourConnection class.
/*
*…. Initialisation....
*/
$communicatorConfiguration =
new CommunicatorConfiguration(
$apiKey,
$apiSecret,
$apiEndpoint,
$integrator,
$proxyConfiguration
);
// Use you own implementation of the Connection interface
$connection = new YourConnection();
// Communicator instance
$communicator = new Communicator(
$connection,
$communicatorConfiguration
);
Webhooks
The part of the SDK that handles the webhooks support is called the webhooks helper. It transparently handles both validation of signatures against the event bodies sent by the webhooks system (including finding the secret key for key IDs - not to be confused with the API Key and API Secret), and unmarshalling of these bodies to objects. This allows you to focus on the essentials, without going through all the additional information and extracting the desired ones by yourself. To learn more about webhooks, read our dedicated guide.
Provide secret keys
Configure the "WebhooksKey" / "WebhooksKeySecret" and your server webhooks endpoints in the Merchant Portal:
$keyId = "WebhooksKey";
$secretKey = "WebhooksKeySecret";
Secret keys are provided using a function that takes two arguments:
- The key ID to return the secret key for
- A callback function that either takes an error as its first argument, or the secret key for the given key ID as its second argument (in which case the first argument must be null)
The SDK provides one implementation for this function: InMemorySecretKeyStore::getSecretKey($keyId). This will retrieve secret keys from an in-memory key store for proper $keyId.
Keys can be added or removed using the following functions:
- InMemorySecretKeyStore::storeSecretKey($keyId, $secretKey) to store a secret key for a key ID
- InMemorySecretKeyStore::removeSecretKey($keyId) to remove the stored secret key for a key ID
- InMemorySecretKeyStore::clear() to remove all stored secret keys
If more advanced storage is required, e.g. using a database or file system, we recommend writing your own implementation.
Initialise webhooks helper
Include and initialise the webhooks helper as follows:
$keyId = 'dummy-key-id';
$secretKey = 'dummy-secret-key’';
$secretKeys = array(
$keyId => $secretKey
);
$secretKeyStore = new InMemorySecretKeyStore($secretKeys);
// At this moment $secretKeys are stored because they are given to constructor
// but you can set empty array of $secretKeys and after that you can
// manage InMemorySecretKeyStore functions as mentioned above
// or even you can extend InMemorySecretKeyStore class to
// implement your own methods to manage $secretKeys
$helper = new WebhooksHelper($secretKeyStore);
Use webhooks helper
From an entry point that you have created on your own, call the unmarshal method of the webhooks helper. It takes the following arguments:
- The body, as a string or Buffer. This should be the raw body as received from the webhooks system
- An object containing the request headers as received from the webhooks system. The keys should be the header names
// Initialisation
$bodyOfRequest = 'JSON_Body_Of_The_Request';
// Retrieve the headers from the Webhook message, depends on your implementation.
$webhookHeaders = $request->getHeaders();
// Transform the received headers
$requestHeaders = [];
foreach ($webhookHeaders as $webhookHeader) {
$requestHeaders[$webhookHeader->getName()] = $webhookHeader->getValue();
}
try {
$webhook_event = $helper->unmarshal($bodyOfRequest, $requestHeaders);
} catch (SignatureValidationException $e) {
// Your code to handle errors
}
You can provide your own implementation of the interface of Connection to use in Communicator object as for example YourConnection class.
/*
*…. Initialisation....
*/
$communicatorConfiguration = new CommunicatorConfiguration(
$apiKey,
$apiSecret,
$apiEndpoint,
$integrator,
$proxyConfiguration
);
// Use you own implementation of the Connection interface
$connection = new YourConnection();
// Authenticator instance
$authenticator = new V1HmacAuthenticator($communicatorConfiguration);
// Communicator instance
$communicator = new Communicator(
$communicatorConfiguration,
$authenticator,
$connection
);
Webhooks
The part of the SDK that handles the webhooks support is called the webhooks helper. It transparently handles both validation of signatures against the event bodies sent by the webhooks system (including finding the secret key for key IDs - not to be confused with the API Key and API Secret), and unmarshalling of these bodies to objects. This allows you to focus on the essentials, without going through all the additional information and extracting the desired ones by yourself. To learn more about webhooks, read our dedicated guide.
Provide secret keys
Configure the "WebhooksKey" / "WebhooksKeySecret" and your server webhooks endpoints in the Merchant Portal:
$keyId = "WebhooksKey";
$secretKey = "WebhooksKeySecret";
Secret keys are provided using a function that takes two arguments:
- The key ID to return the secret key for.
- A callback function that either takes an error as its first argument, or the secret key for the given key ID as its second argument (in which case the first argument must be null).
The SDK provides one implementation for this method: InMemorySecretKeyStore::getSecretKey($keyId). This will retrieve secret keys from an in-memory key store for proper $keyId.
Keys can be added or removed using the following methods:
- InMemorySecretKeyStore::storeSecretKey($keyId, $secretKey) to store a secret key for a key ID.
- InMemorySecretKeyStore::removeSecretKey($keyId) to remove the stored secret key for a key ID.
- InMemorySecretKeyStore::clear() to remove all stored secret keys.
If more advanced storage is required, e.g. using a database or file system, we recommend writing your own implementation.
Initialise webhooks helper
Include and initialise the webhooks helper as follows:
$keyId = 'dummy-key-id';
$secretKey = 'dummy-secret-key’';
$secretKeys = [
$keyId => $secretKey
];
$secretKeyStore = new InMemorySecretKeyStore($secretKeys);
// At this moment $secretKeys are stored because they are given to constructor
// but you can set empty array of $secretKeys and after that you can
// manage InMemorySecretKeyStore functions as mentioned above
// or even you can extend InMemorySecretKeyStore class to
// implement your own methods to manage $secretKeys
$helper = new WebhooksHelper($secretKeyStore);
Use webhooks helper
From an entry point that you have created on your own, call the unmarshal method of the webhooks helper. It takes the following arguments:
- The body, as a string or Buffer. This should be the raw body as received from the webhooks system.
- An object containing the request headers as received from the webhooks system. The keys should be the header names.
// Initialisation
$bodyOfRequest = 'JSON_Body_Of_The_Request';
// Retrieve the headers from the Webhook message, depends on your implementation.
$webhookHeaders = $request->getHeaders();
// Transform the received headers
$requestHeaders = [];
foreach ($webhookHeaders as $webhookHeader) {
$requestHeaders[$webhookHeader->getName()] = $webhookHeader->getValue();
}
try {
$webhookEvent = $helper->unmarshal($bodyOfRequest, $requestHeaders);
} catch (SignatureValidationException $e) {
// Your code to handle errors
}
Warning about support
For security and stability, Worldline does not support plugins whose code has been modified by the merchant or a third party. Plugins are provided as-is (official version). Any unauthorised modification voids support and warranty and may cause malfunctions, security gaps, or incompatibilities with PSP updates.