Server-to-Server Integration
The Server-to-Server solution enables direct exchange of transaction data between your server and Worldline's payment platform. This gives you full control over the customer experience while handling payments directly.
Benefits
- Full Control - Design your own payment page
- Seamless Experience - Customers stay in your environment
- Flexibility - Complete customization of the checkout flow
This method involves handling card data, which requires PCI DSS compliance. Consider using Hosted Tokenization to reduce your PCI scope significantly.
Prerequisites
Before implementing this integration, ensure you have:
- An active Worldline Direct account
- At least one payment method activated in the Merchant Portal
- Configured API Key and API Secret
- PCI DSS compliance (if handling card data directly)
- Server capable of processing RESTful API requests
Integration Flow
Step-by-Step Implementation
Step 1: Initialize SDK
Configure your Server SDK with your credentials:
- C#
- Java
- PHP
var configuration = new CommunicatorConfiguration
{
ApiEndpoint = new Uri("https://payment.preprod.direct.worldline-solutions.com"),
AuthorizationType = AuthorizationType.V1HMAC,
ApiKeyId = "YOUR_API_KEY",
SecretApiKey = "YOUR_API_SECRET"
};
var client = Factory.CreateClient(configuration);
CommunicatorConfiguration configuration = new CommunicatorConfiguration()
.withApiEndpoint(URI.create("https://payment.preprod.direct.worldline-solutions.com"))
.withAuthorizationType(AuthorizationType.V1HMAC)
.withApiKeyId("YOUR_API_KEY")
.withSecretApiKey("YOUR_API_SECRET");
Client client = Factory.createClient(configuration);
$communicatorConfiguration = new CommunicatorConfiguration(
'YOUR_API_KEY',
'YOUR_API_SECRET',
'https://payment.preprod.direct.worldline-solutions.com',
'OnlinePayments'
);
$client = Factory::createClient($communicatorConfiguration);
Environment Endpoints:
| Environment | URL |
|---|---|
| Test | https://payment.preprod.direct.worldline-solutions.com |
| Production | https://payment.direct.worldline-solutions.com |
Step 2: Create Payment Request
Collect card details from your checkout page and send a CreatePayment request:
- C#
- Java
var body = new CreatePaymentRequest
{
Order = new Order
{
AmountOfMoney = new AmountOfMoney
{
Amount = 2980,
CurrencyCode = "EUR"
},
Customer = new Customer
{
MerchantCustomerId = "customer123",
ContactDetails = new ContactDetails
{
EmailAddress = "customer@example.com"
},
BillingAddress = new Address
{
CountryCode = "NL",
City = "Amsterdam"
}
},
References = new OrderReferences
{
MerchantReference = "order-12345"
}
},
CardPaymentMethodSpecificInput = new CardPaymentMethodSpecificInput
{
PaymentProductId = 1, // Visa
Card = new Card
{
CardNumber = "4111111111111111",
Cvv = "123",
ExpiryDate = "1225",
CardholderName = "John Doe"
},
ThreeDSecure = new ThreeDSecure
{
RedirectionData = new RedirectionData
{
ReturnUrl = "https://yoursite.com/return"
}
}
}
};
var response = await client.WithNewMerchant("YOUR_MERCHANT_ID")
.Payments
.CreatePaymentAsync(body);
CreatePaymentRequest body = new CreatePaymentRequest();
// Amount
AmountOfMoney amountOfMoney = new AmountOfMoney();
amountOfMoney.setAmount(2980L);
amountOfMoney.setCurrencyCode("EUR");
// Order
Order order = new Order();
order.setAmountOfMoney(amountOfMoney);
OrderReferences references = new OrderReferences();
references.setMerchantReference("order-12345");
order.setReferences(references);
body.setOrder(order);
// Card details
CardPaymentMethodSpecificInput cardInput = new CardPaymentMethodSpecificInput();
cardInput.setPaymentProductId(1); // Visa
Card card = new Card();
card.setCardNumber("4111111111111111");
card.setCvv("123");
card.setExpiryDate("1225");
card.setCardholderName("John Doe");
cardInput.setCard(card);
// 3-D Secure
ThreeDSecure threeDSecure = new ThreeDSecure();
RedirectionData redirectionData = new RedirectionData();
redirectionData.setReturnUrl("https://yoursite.com/return");
threeDSecure.setRedirectionData(redirectionData);
cardInput.setThreeDSecure(threeDSecure);
body.setCardPaymentMethodSpecificInput(cardInput);
CreatePaymentResponse response = client
.withNewMerchant("YOUR_MERCHANT_ID")
.payments()
.createPayment(body);
Step 3: Handle Response
The response includes a merchantAction object that indicates the next step:
{
"payment": {
"id": "000000123400000012340000100001",
"status": "PENDING_AUTHENTICATION",
"statusOutput": {
"statusCode": 50
}
},
"merchantAction": {
"actionType": "REDIRECT",
"redirectData": {
"redirectURL": "https://issuer-bank.com/3ds/authenticate"
}
}
}
| Scenario | merchantAction.actionType | Next Step |
|---|---|---|
| Frictionless 3DS | null | Transaction complete, check status |
| 3DS Challenge | REDIRECT | Redirect customer to URL |
| No 3DS | null | Transaction complete, check status |
Step 4: Handle 3-D Secure (if required)
If actionType is REDIRECT, redirect the customer to the authentication URL:
if (response.merchantAction?.actionType === 'REDIRECT') {
window.location.href = response.merchantAction.redirectData.redirectURL;
}
After authentication, the customer returns to your returnUrl.
Step 5: Retrieve Payment Status
After the customer returns, retrieve the final payment status:
- C#
- Java
var paymentDetails = await client.WithNewMerchant("YOUR_MERCHANT_ID")
.Payments
.GetPaymentDetailsAsync(paymentId);
var statusCode = paymentDetails.StatusOutput.StatusCode;
PaymentDetailsResponse paymentDetails = client
.withNewMerchant("YOUR_MERCHANT_ID")
.payments()
.getPaymentDetails(paymentId);
Integer statusCode = paymentDetails.getStatusOutput().getStatusCode();
Step 6: Display Results
Handle the payment status appropriately:
| Status Code | Meaning | Action |
|---|---|---|
| 0-99 | Pending | Show processing message |
| 100-199 | Authorized | Confirm order, capture later |
| 500-599 | Rejected | Show error, offer retry |
| 800-899 | Captured | Confirm and fulfill order |
Using Tokens
Reduce PCI scope by using tokens instead of raw card data:
Permanent Tokens (Card-on-File)
Store customer cards for future purchases:
CardPaymentMethodSpecificInput = new CardPaymentMethodSpecificInput
{
Token = "stored_token_from_previous_transaction"
}
Temporary Tokens (Hosted Tokenization)
Use temporary tokens from the Hosted Tokenization Page:
CardPaymentMethodSpecificInput = new CardPaymentMethodSpecificInput
{
Token = "temporary_token_from_tokenization"
}
Using tokens significantly reduces your PCI DSS compliance requirements while maintaining a seamless checkout experience.
Webhooks
Implement webhooks for reliable payment status notifications:
[HttpPost("webhook")]
public IActionResult HandleWebhook([FromBody] WebhookEvent webhookEvent)
{
var payment = webhookEvent.Payment;
var paymentId = payment.Id;
var statusCode = payment.StatusOutput.StatusCode;
// Update order status in your database
UpdateOrderStatus(paymentId, statusCode);
return Ok();
}
Webhooks are asynchronous. Always use them as a backup notification mechanism, not for real-time checkout decisions.
Best Practices
- Use Tokens - Minimize PCI scope by using tokenization
- Implement 3-D Secure - Always include 3DS properties for card payments
- Include Customer Email - Required for conversion tracking in MyPerformance
- Use Consistent References - Keep
merchantReferenceconsistent for analytics - Handle All Statuses - Implement proper handling for all possible outcomes
- Set Up Webhooks - Never rely solely on return redirects
Client SDKs
For collecting card details on the client side:
| Platform | SDK |
|---|---|
| JavaScript | GitHub |
| iOS (Swift) | GitHub |
| Android | GitHub |
| Flutter | pub.dev |
| React Native | npm |
Next Steps
- Set up webhooks for reliable notifications
- Implement 3-D Secure for enhanced security
- Explore payment methods to enable more options