worldline

Documentation

Go SDK

Introduction

The Go SDK helps you to communicate with the  Acquiring API . More specifically, it offers a fluent Go API that provides access to all the functionality of the RESTful API. Below, we discuss the following topics in detail.

  • Initialization of the SDK

  • Errors

  • Logging

  • Advanced use: Connection pooling

  • Advanced use: Customization of the communication

  • Notes

The source code of the SDK is available on  Github . There you can find installation instructions.

The API documentation of the latest version of the SDK is available  here .

Initialization of the Go SDK

All Go code snippets presented in the API Reference assume you have initialized the Go SDK before using them in your Development Environment. This section details the initialization of the Go SDK.

Initializing is simple, and requires only one key task: use our  acquiringsdk.CreateClient  function to create an  acquiringsdk.Client  instance, which contains the actual methods to communicate with the Acquiring API.

The  acquiringsdk.CreateClient  function needs the following input information to provide you with an initialized  acquiringsdk.Client .

  • The oAuth2TokenURI , oauth2ClientID and oauth2ClientSecret .

  • The name of the integrator, e.g. your company name

You can create an instance of  acquiringsdk.Client  using the  acquiringsdk.CreateClient  function with this code snippet:

conf, _ := acquiringsdk.CreateOAuth2Configuration("oauth2ClientId", "oauth2ClientSecret', "oath2TokenURI", "integrator")
client, _ := acquiringsdk.CreateClientFromConfiguration(conf)

Using CommunicatorConfiguration

You can specify more options by using a  configuration.CommunicatorConfiguration  object. You can configure extra properties on this object as needed. For example, using an in-memory  TOML  file:

// The oauth2TokenURI can remain empty here, it will be overwritten from the TOML data
conf, _ := acquiring.CreateOAuth2Configuration("oauth2ClientID", "oauth2ClientSecret", "", "integrator")
tomlData := `
ConnectTimeout = 5000000000
SocketTimeout = 300000000000
MaxConnections = 10
AuthorizationType = "OAuth2"
OAuth2TokenURI = "https://auth-test-eu-west-1.aws.bambora.com/connect/token"
[APIEndpoint]
    host = "api.preprod.acquiring.worldline-solutions.com"
`
toml.Decode(tomlData, conf)
client, _ := acquirngsdk.CreateClientFromConfiguration(conf)

These values are the default values. We recommend keeping the timeout values at these values. See  API endpoints  for the possible hosts and token URIs.

If a proxy should be used, the  configuration.CommunicatorConfiguration  object should have one extra property set, Proxy * url.URL . If the proxy requires authentication, then this should be set as the  Userinfo  of the URL.

Errors

All calls can return one of the following errors:

  • An  errors.ValidationError  if the request was not correct and couldn't be processed (HTTP status code 400)

  • An  errors.AuthorizationError  if the request was not allowed (HTTP status code 403)

  • An  errors.IdempotenceError  if an idempotent request caused a conflict (HTTP status code 409)

  • An  errors.ReferenceError  if an object was attempted to be referenced that doesn't exist or has been removed, or there was a conflict (HTTP status code 404, 409 or 410)

  • An  errors.PlatformError  if something went wrong on the Worldline platform. The Worldline platform was unable to process a message from a downstream system or the service that you're trying to reach is temporary unavailable (HTTP status code 500, 502 or 503)

  • An  errors.APIError  if the RESTful API returned any other error

A payment attempt can now be handled as follows:

response, err := client.V1().Acquirer(acquirerID).Merchant(merchantID).Payments().ProcessPayment(request, nil)
switch e := err.(type)
case *errors.ValidationError:
    fmt.Println("Input validation error:", e.Detail())
case *errors.AuthorizationError:
    fmt.Println("Authorization error:", e.Detail())
case *errors.ReferenceError:
    fmt.Println("Incorrect object reference:", e.Detail())
case *errors.PlatformError:
    fmt.Println("Error occurred at Worldline or a downstream partner/acquirer:", e.Detail())
case errors.APIError:
    fmt.Println("Worldline error:", e.StatusCode(), ",", e.Detail())
default:
    // An internal error

Error overview

The following table is a summary that shows when each of these errors will be returned:

HTTP status code

Meaning

Description

Error Type

200

Successful

Your request was processed correctly

N/A

201

Created

Your request was processed correctly and a new resource was created.
The URI of this created resource is returned in the Location header of the response.

N/A

204

No Content

Your request was processed correctly

N/A

400

Bad Request

Your request is not correct and can't be processed. Please correct the mistake and try again.

errors.ValidationError

403

Not Authorized

You're trying to do something that is not allowed or that you're not authorized to do.

errors.AuthorizationError

404

Not Found

The object you were trying to access could not be found on the server.

errors.ReferenceError

409

Conflict

Your idempotent request resulted in a conflict. The first request has not finished yet.

errors.IdempotenceError

409

Conflict

Your request resulted in a conflict. Either you submitted a duplicate request or you're trying to create something with a duplicate key.

errors.ReferenceError

500

Internal Server Error

Something went wrong on the Worldline platform.

errors.PlatformError

502

Bad Gateway

The Worldline platform was unable to process a message from a downstream partner/acquirer.

errors.PlatformError

503

Service Unavailable

The service that you're trying to reach is temporary unavailable.
Please try again later.

errors.PlatformError

other

Unexpected error

An unexpected error has occurred

errors.APIError

Logging

The Go SDK supports logging of requests, responses, and errors of the API communication.

In order to start using the logging feature, an implementation of the  logging.CommunicatorLogger  interface should be provided. The SDK provides two example implementations for logging to  os.Stdout  ( logging.StdOutCommunicatorLogger ) and logging to a standard Go logger ( logging.DefaultLogCommunicatorLogger ).

Logging can be enabled by calling the  EnableLogging  method on an  acquiringsdk.Client  object, and providing the logger as an argument. The logger can subsequently be disabled by calling the  DisableLogging  method.

The following code exemplifies the use of adding a logger:

conf, _ := acquiringsdk.CreateOAuth2Configuration("oauth2ClientId", "oauth2ClientSecret', "oath2TokenURI", "integrator")
client, _ := acquiringsdk.CreateClientFromConfiguration(conf)
logger, _ := logging.NewDefaultLogCommunicatorLogger(log.Logger{})
client.EnableLogging(logger)
//... Do some calls
client.DisableLogging()

Advanced use: Connection pooling

An  acquiringsdk.Client  created using the  acquiringsdk.CreateClient  or  acquiringsdk.CreateClientFromConfiguration  function will use its own connection pool. If multiple clients should share a single connection pool, the  acquiringsdk.CreateCommunicatorFromConfiguration  function should be used to first create a shared  communicator.Communicator , then the  acquiringsdk.CreateClientFromCommunicator  function should be used to create  acquiringsdk.Client  instances that use that  communicator.Communicator :

conf, _ := acquiringsdk.CreateOAuth2Configuration("oauth2ClientId", "oauth2ClientSecret', "oath2TokenURI", "integrator")
communicator, _ := acquiringsdk.CreateCommunicatorFromConfiguration(conf)
// create one or more clients using the shared communicator
client, _ := acquiringsdk.CreateClientFromCommunicator(communicator)

Instead of closing these  acquiringsdk.Client  instances, you should instead close the  communicator.Communicator  when it is no longer needed. This will close all  acquiringsdk.Client  instances that use the  communicator.Communicator .

Connection management

Just like  acquiringsdk.Client communicator.Communicator  also has method  CloseExpiredConnections  that can be used to evict expired HTTP connections. You can call this method on the  communicator.Communicator  instead of on any of the  acquiringsdk.Client  instances. The effect will be the same.

Advanced use: Customization of the communication

An  acquiringsdk.Client  uses a  communicator.Communicator  to communicate with the RESTful API. A  communicator.Communicator  contains all the logic to transform a request object to an HTTP request and an HTTP response to a response object. The functionality of the  communicator.Communicator  is built on the following:

  • The RESTful Server API endpoint URI.

  • communicator.Connection , which represents one or more HTTP connections to the Worldline server.

  • An  authentication.Authenticator , which is used to sign your requests.

  • communicator.MetadataProvider , which constructs the header with metadata of your server that is sent in requests for BI and fraud prevention purposes.

  • json.Marshaller , which is used to marshal and unmarshal request and response objects to and from JSON.

For your convenience, an  acquiringsdk.CommunicatorBuilder  is provided to easily replace one or more of these components. For example, to instantiate an  acquiringsdk.Client  that uses your own implementation of  communicator.Connection , you can use the following code snippet:

connection := YourConnection{}
conf, _ := acquiringsdk.CreateOAuth2Configuration("oauth2ClientId", "oauth2ClientSecret', "oath2TokenURI", "integrator")
communicatorBuilder, _ := acquiringsdk.CreateCommunicatorBuilderFromConfiguration(conf)
communicator, _ := communicatorBuilder.WithConnection(connection).Build()
client, _ := acquiringsdk.CreateClientFromCommunicator(communicator)

Logging

To facilitate implementing logging in a custom  communicator.Connection , the SDK provides utility structs  logging.RequestLogMessageBuilder  and  logging.ResponseLogMessageBuilder . These can be used to easily construct request and response messages. For instance:

// In the below code, logger is the logging.CommunicatorLogger set using EnableLogging.
// Note that it may be null if EnableLogging is not called.
requestID := createRequestID() // Create a unique id; function to be provided by you
requestLogMessageBuilder, _ := NewRequestLogMessageBuilder(requestID, method, uri,
    obfuscation.DefaultBodyObfuscator(), obfuscation.DefaultHeaderObfuscator()
)
// add request headers to requestLogMessageBuilder
// if present, set the request body on requestLogMessageBuilder
logger.LogRequestLogMessage(requestLogMessageBuilder.BuildMessage().String())
start := time.Now()
// send the request
end := time.Now()
duration := end.Sub(start)
statusCode := ...
responseLogMessageBuilder, _ := NewResponseLogMessageBuilder(requestID, statusCode, duration,
    obfuscation.DefaultBodyObfuscator(), obfuscation.DefaultHeaderObfuscator())
// add response headers to responseLogMessageBuilder
// if present, set the response body on responseLogMessageBuilder
logger.LogResponseLogMessage(responseLogMessageBuilder.BuildMessage().String())

Notes

Error handling

Many of the code snippets presented on this page ignore errors returned by function or method calls for simplicity. When using the SDK in production, make sure that all errors are properly handled.

Renaming of properties

The Go SDK uses Go naming conventions as much as possible. The first letter of each property is turned into upper case, and several acronyms in properties have been turned into upper case. For example,  paymentId  is called  PaymentID .