Common implementations manual

This common implementations manual contains information of everything you need to stort intergrating your system to PayEx Connect.

You can also use the PDF manual found here.

Prerequisites

Before you start intregrating a system with PayEx Connect please make sure that:

  • You have basic knowledge of Web Services, including WSDL, Soap and WS-Security.
  • You understand that PayEx Connect is designed to simplify integration for clients using Microsoft .Net, Java Axis or other frameworks that have built-in support for WS-Security and other W3C standars.

Detailed documentation is available on a per service level. Detailed documentation for the Sample service is always supplied by default.

Security

This section describes the security concepts  that PayEx Connect use.

Service authentication

Username and password is used for authentication. Your company number provided by PayEx is used as username. The password is client unique and provided by PayEx. Replay attacks is prevented by using message timestamps and nonces.

The security token consists of the following elements:

Element Notes 
UsernameCompany number provided by PayEx.
PasswordAuthentication key provided by PayEx.
NonceA random value, and protection against replay attacks, that the sender creates and includes in each UserNameToken sent. 
CreatedA timestamp value, and protection against replay attacks, that the sender generates to include in each UserNameToken sent. 
Sample token
<S11:Envelope xmlns:S11="..." xmlns:wsse="...">
 <S11:Header>
    ...
   <wsse:Security>
     <wsse:UsernameToken>
       <wsse:Username>1234</wsse:Username>
       <wsse:Password>MyKey1</wsse:Password>
       <wsse:Nonce>WScqanjCEAC4mQoBE07sAQ==</wsse:Nonce>
       <wsu:Created>2006-01-01T01:24:32Z</wsu:Created>
     </wsse:UsernameToken>
   </wsse:Security>
  ...
</S11:Header>

A failed authentication will generate error code 3011 (see Custom error codes below). Possible causes for a failed authentication may be invalid client IP, invalid company number or invalid password.

Role based security header

The role based security header is used to restrict the usage of services to predefined levels and enable trace logging. It contains EndUserName and EndUserRole. EndUserRole is used if the referrer IP is associated with a ServiceConsumer. EndUserName is only used for logging purpose. Contact PayEx to learn more of the proper solution for your company.

The RoleBasedSecurityHeader consists of the following elements:

Element Notes 
EndUserNameThe identifier for log tracing
EndUserRolePredefined role that grants access to requested service.
Sample header
<S11:Envelope xmlns:S11="..." xmlns:wsse="...">
 <S11:Header>
  ...
 <wsse:Security>
  ...
 </wsse:Security>
  ...
 <ns1:RoleBasedSecurityHeader
   EndUserName="name" EndUserRole="role"
   xmlns:ns1="http://faktab.se/B2B/RoleBasedSecurity"/>
  ...
 </S11:Header>
 ...
</S11:Envelope>

Service Authorization

PayEx Connect restrict the company numbers allowed for each client. Different company numbers may have a different subsets of services available through PayEx Connect. Requests to an unauthorized service will generate error code 3011 (see Custom error codes below).

The functionality provided by some services may differ based on company level rules. This may result in unused input variables or empty data responses.

SOAP Request

This is a sample SOAP request.

Sample request
< ?xml version="1.0" encoding="utf-8"? >
<soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:wsa=”http://schemas.xmlsoap.org/ws/2004/08/addressing” xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <soap:Header>
    <wsa:Action>http://faktab.se/B2B/[SERVICE]/[ACTION]</wsa:Action>
    <wsa:MessageID>urn:uuid:[MESSAGEID]</wsa:MessageID>
    <wsa:ReplyTo>
      <wsa:Address>
         http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
      </wsa:Address>
    </wsa:ReplyTo>
    <wsa:To> https://connect.payex.com/[SERVICE].asmx</wsa:To>
    <wsse:Security soap:mustUnderstand="1">
      <wsu:Timestamp wsu:Id="Timestamp-[ID]">
          <wsu:Created>[CREATED]</wsu:Created>
          <wsu:Expires>[EXPIRES]</wsu:Expires>
      </wsu:Timestamp>
      <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-[ID]">
        <wsse:Username>[USERNAME]</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">[PASSWORD]</wsse:Password>
        <wsse:Nonce>[NONCE]</wsse:Nonce>
        <wsu:Created>[CREATED]</wsu:Created>
      </wsse:UsernameToken>
    </wsse:Security>
  </soap:Header>
  <soap:Body>
    <[ACTION] xmlns="http://faktab.se/B2B/[SERVICE]">
      <req />
    </[ACTION]>
  </soap:Body>
</soap:Envelope>
Element ValueNotes 
[SERVICE]Name of the service you are using.
[ACTION]Name of the action you are calling.
[MESSAGEID]A unique id in the following format aaaabbbb-ccc-ddd-eee-ffffffffffff.
[ID]A random unique id. Each occuring Id must be unique per request and occurence, if you have more than one id in a document they can't be identical.
[USERNAME]Your PayEx Username.
[PASSWORD]Your PayEx Password.
[NONCE]A random unique id for each request.
[CREATED]A timestamp for when the request was created. It uses the following format: yyyy-MM-ddTHH:mm:ssZ (2010-12-31T18:35:50Z).
[EXPIRES]Should be the same value as [CREATED] but with five additional minutes, +5 minutes. (2010-12-31T18:40:50Z)

Error handling

All errors is formatted according to the current standard for SOAP Faults. Detailed information such as error code, description and id can be found in the detail element.

Element Notes 
faultCode

The faultCode element is intended for use by software to provide an algorithmic mechanism for identifying the fault. Possible values are VersionMismatch, MustUnderstand, Client and Server.
In PayEx Connect the faultcode element is extended to also provide detailed error codes. See a list of custom error codes below.

ActorThe actor element is intented to provide information about the actor who caused the fault.
DetailThe detail element is carries application specific error information, Error code, description and Guid.
Sample error detail element
<detail>
 <Error
   ErrorCode="3011"
   Description="Access denied for client 1.2.1.2"
   Guid="37ab9f0a-f261-4a8b-8bca-a4dcaa70de8a"  
   xmlns="http://faktab.se" />
</detail>

Custom error codes

DetailErrorCodeFaultCodeDescription
3001

Server.3001

Service unavailable due to maintainance, etc.
3002Server.3002Service timed out while processing request.
3010Client.3010Request data validation failed. Possibe causes might be missing required value, invalid date format etc.
3011Client.3011Required service not allowed for specified client or company number. Possible causes may be unauthorized client IP, invalid company number or invalid password.
3021Client.3021Requested item not found.
3022Client.3022The requested item is to large for processing.
4001Client.4001Concurrency control failure. Update not allowed for items not loaded into session state.
4002Client.4002Concurrency control failure. Failed to update item due to version mismatch between session state item and database item.
9998Client.9998Undefined client error.
9999Server.9999Undefined server error.

Input and Output formats

Date, time and amounts are all formatted to a commonformat before returned to the client.

Data type Notes 
DateFormatted as a sortable string according to the ISO 8601 specification. 2006-01-01T00:00:00.
DateTimeFormatted as a sortable string according to the ISO 8601 specification. 2006-01-01T23:01:30.
AmountFormatted as a four decimal string with '.' as decimal place holder. 12345.1234

Session and versioning support

Some Crm web methods utilizes optimistic versioning concurrency control to ensure object consistency. This requires per-user session management by the service consumer. Sessions state is supported through standard Http cookies.

The session sliding timeout limit is 30 minutes.

Multiple users on the consumer system can’t share the same session against PayEx Connect. If the service consumer handles multiple simultaneous users, one Http session cookie must be managed for each end user.

The SampleService web service contains sample web methods supporting per-user sessions. The Sample service can be used for testing and developing per-user sessions support in the consuming application. See the sample service manual for details about sample methods.

Usage Samples

Microsoft DotNet 2.0 and WSE 3.0

Enabling WSE support

Before adding any Web references you need to enable WSE. This is done by right-clicking the project in the Solution explorer and selecting “WSE Settings 3.0..”. This brings up the “WSE settings 2.0 tool” that helps you to configure all the settings for WSE.

Enable WSE by selecting “Enable this project for Web Services Enhancements”. This option adds the required settings to the applications configuration file and ensures that all Web references added later will support WSE.

1-wse-settings-tool.png
Fig. Enabling WSE Support

Defining security policy

Next define the Policy to be used in all web method requests. Click the Policy tab and select “Enable Policy”. Press the “Add” button and provide a name for the policy, i.e. “PayExConnectPolicy”, and click OK. This brings up the “WSE Security Settings Wizard”.

Select “Secure a client application”. Select “Username” to support the UsernameToken model used by PayEx Connect, as shown in the image below.

2-security-wizard-authentication.png
Fig. Autentication settings

Specify if the username and password should be managed from code our through the policy file. In this example we manage these properties through code, as shown in the image below. Click Next.

3-username-and-password.png
Fig. Specify Username Token in code

Validate that WS-Security Extensions are enabled and select the “None (rely on transport protection” option, as shown in the image below. Transport protection is managed through the SSL protocol. Thus there is no need for additional signing and encryption of SOAP messages between the client and PayEx Connect.

4-message-protection.png
Fig. Message Protection

After the wizard has completed, the policy will be listed in the “WSE settings 2.0 tool” as shown in the image below. The wizard also adds the file wse3policyCache.config  to your project in Visual Studio.

5-policy-listing.png
Fig. Application policy

Adding Web Reference

The Web Reference must be added after WSE support is enabled. Any Web References added before enabling WSE, will be missing the proxy classes that supports WSE.

Start the “Add Web Reference” wizard by right-clicking the project in Solution explorer and selecting “Add Web Reference..” from the popup menu.

Enter the URL to the sample Web service in PayEx Connect,
https://connect.payex.com/SampleService.asmx. Specify a name that identifies the service, i.e. “SampleService”, and click Add Reference.

6-sample-service.PNG
Fig. Adding web reference

Calling service

The final part of this sample is the code that prepares the request and invokes the web method. This code consists of four different parts: setting credentials, preparing and submitting the request, processing the response and error handling.

7-calling-service.png
Fig. Sample code

Setting credentials

Create a new UsernameTokenProvider and set the username and password properties (The username represents the company number supplied by PayEx). Add the newly created token as the client credentials through the SetClientCredentials method. Refer to the policy name, specified when defining the security policy, through the SetPolicy method.

Preparing and submitting the request

Create a new instance of the SampleMethodRequestType class and set the properties. Execute the web method and store the response in a SampleMethodResponseType object.

Processing the response

The response object encapsulates all the information supplied by the service request. The information can be accessed through properties and sub-objects of the response object.

Error handling

Separate SoapExceptions from other error types when catching errors. A SoapException triggered by PayEx Connect contains additional information in the detail-element such as error code, description and unique id.

Microsoft .NET WCF and WSE

Adding service reference

Right-click on the project and select "Add Service Reference..."

8-add-service-reference.png
Fig. Adding service reference

Open app.config/web.config and change Security mode to TransportWithMessageCredential.

web.config
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="SampleServiceSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
                   receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                   bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                   maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                   messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                   useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" 
                maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="TransportWithMessageCredential">
                    <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://connect.payex.com/SampleService.asmx"
            binding="basicHttpBinding" bindingConfiguration="SampleServiceSoap"
            contract="Connect.SampleServiceSoap" name="SampleServiceSoap" />
    </client>
</system.serviceModel>

Example application

Example application
using System;
namespace PayExConnectSample {
    class Program {
        static void Main(string[] args) {
            string username = "USERNAME";
            string password = "PASSWORD";

            Connect.SampleServiceSoapClient sampleProxy = new Connect.SampleServiceSoapClient();
            sampleProxy.ClientCredentials.UserName.UserName = username;
            sampleProxy.ClientCredentials.UserName.Password = password;
           
            Connect.SampleMethodRequestType request = new Connect.SampleMethodRequestType();
            Connect.SampleMethodResponseType response = null;
           
            request.SampleText = "Hello Connect!";

            try {
                response = sampleProxy.SampleMethod(request);
                Console.WriteLine(response.SampleText);
            } catch (Exception ex) {
                Console.Write(ex);
            }
        }
    }
}

Java 5 JWSDP 2.0

This sample uses Java Web Services Developer Pack 2.0 from Sun Microsystems.

Installing JWSDP

Java Web Services Developer Pack enables web services for the Java5 platform. Installation packages can be obtained here:

https://www.oracle.com/technetwork/java/webservicespack-jsp-140788.html

Download and install using default install options.

Project setup

Create a new project in your favorite IDE and add the following files to your classpath:

<JWSDP-HOME>/jaxb/lib/*.jar

<JWSDP-HOME>/jaxp/lib/*.jar

<JWSDP-HOME>/jwsdp-shared/lib/*.jar

<JWSDP-HOME>/sjsxp/lib/*.jar

<JWSDP-HOME>/saaj/lib/*.jar

<JWSDP-HOME>/xws-security/lib/*.jar

Security configuration

Create a new file named client-wss-config.xml and add the following content:

Security configuration
<xwss:JAXRPCSecurity xlmns:xwss="http://java.sun.com/xml/ns/xwss/config">

   <xwss:Service>
           <!--
                Dump all messages to stout.
            -->

       <xwss:SecurityConfiguration dumpMessages="true">
           <!--
                Default: Digested password will not be sent.
            -->

           <xwss:UsernameToken name="1000" digestPassword="false" password="159x"/>
       </securityConfguration>
   </xwss:Service>

   <xwss:SecurityEnvironmentHandler>
        se.faktab.b2b.SecurityEnvironmentHandler
   </xwss:SecurituEnvironmentHandler>

</xwss:JAXRPCSecurity>      

A sample SecurityEnvironmentHandler can be found here:

<JWSDP-HOME>/xws-security/samples/jaxws2.0/simple/src/simple/client

Generate client proxies

JWSDP ships a utility called wsimport that generates client proxies from a wsdl-url. Use the following command to generate proxies:

wsimport.bat –keep https://connect.payex.com/SampleService.asmx?wsdl

Proxies will be generated in the current directory. Make sure the generated proxies are added to project classpath.

Sample application

The following code snippet resembles a sample application calling sampleMethod:

Sample application
//specify the security configuration file..
FileInputStrem configFile = new FileInputStream( "/foo/bar/client-wss-config.xml");
XWSSecurityConfiguratio config = SecurityConfigurationFactory.newXWSSecurityConfiguration( configFile );

//Create sample service port..
SampleServiceSoap port = new SampleService().getSampleServiceSoap();
//set security configuration..
((BindingProvider)port).getRequestContext().put(XWSSecurityConfiguration.MESSAGE_SECURITY_CONFIGURATION, config );

//call sampleMethod..
SampleMethodRequestType reqType = new ObjectFactory().createSampleMethodRequestType();
reqType.setSampleText( "Sample text" );
SampleMethodResponseType response = port.sampleMethod( reqType );
System.out.println( response.getSampleText() );
System.out.println( response.getSampleAmount() );
System.out.println( response.getSampleDate() );
System.out.println( response.getSampleDateTime() );

Notice that the sample code expects to find the security configuration file in /foo/bar/. Adjust to your own environment.

PHP

NuSOAP library can be found at http://sourceforge.net/projects/nusoap/

The following code will call the SampleMethod in the SampleService with the argument “Hello Connect!”.

PHP call
http://faktab.se/B2B/SampleService/SampleMethod</wsa:Action>
<wsa:MessageID>urn:uuid:' . GUID() . '</wsa:MessageID>
<wsa:ReplyTo>
  <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>https://connect.payex.com/SampleService.asmx</wsa:To>
<wsse:Security SOAP-ENV:mustUnderstand="1">
  <wsu:Timestamp wsu:Id="Timestamp-' . GUID() . '">
      <wsu:Created>' . $created . '</wsu:Created>
      <wsu:Expires>' . $expires . '</wsu:Expires>
  </wsu:Timestamp>
  <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-' . GUID() . '">
    <wsse:Username>' . $username . '</wsse:Username>
    <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">' . $password . '</wsse:Password>
    <wsse:Nonce>' . base64_encode(GUID()) . '</wsse:Nonce>
    <wsu:Created>' . $created . '</wsu:Created>
  </wsse:UsernameToken>
</wsse:Security>
';

$body = '
<SampleMethod xmlns="http://faktab.se/B2B/SampleService">
  <req>
    <SampleText>Hello Connect!</SampleText>
  </req>
</SampleMethod>
';

/* Connect to the SOAP Server */
$client = new nusoap_client('https://connect.payex.com/SampleService.asmx?wsdl', 'WSDL');

/* Set encoding */
$client->soap_defencoding = 'utf-8';

/* namespaces */
$client->namespaces['wsa'] = 'http://schemas.xmlsoap.org/ws/2004/08/addressing';
$client->namespaces['wsse'] = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
$client->namespaces['wsu'] = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';

/* Check for error */
$error = $client->getError();
if($error) { die('<h2>Constructor Error</h2><pre>' . $error . '</pre>'); }

/* Set header */
$client->setHeaders($header);

/* Make the call */
$result = $client->call('SampleMethod', $body);

/* Check for fault/error */
if($client->fault) { print_r('<h2>Fault</h2><pre>' . $client->fault . '</pre>'); }
if($client->getError()) { print_r('<h2>Error</h2><pre>' . $client->getError() . print_r($result) . '</pre>'); }

/* Print result */
print_r($result);

echo '<h1>Request:</h1>';
echo '<div><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre></div>';
echo '<h1>Response:</h1>';
echo '<div><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre></div>';
echo '<h1>Debug:</h1>';
echo '<div><pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre></div>';
?>

 

Created by David Persson on 2020/01/21 09:28