Tuesday, December 30, 2008

Basic introduction

Recently I came across a project which is developed for Campaigning Purpose.   The users were given three options for campaigning those are Text Messaging, Voice messaging and Emailing. For Text messaging the services Ericsson is used for United States, while the  esendex services used for United Kingdom. 

Here I will be giving a detailed way to register for service, implementing and using it successfully.
 Ericsson IPX 
Internet Payment eXchange (IPX) is a solution and technology for micro payments. IPX acts as a transparent, white-label Content Acquirer and Transaction Router between Operators and Content Providers. Content Providers are provided with an easily implemented interface to connect to IPX, which handles integration to the Operators. The Content Provider’s interface to IPX is independent of the Consumer’s device type (PC, mobile phone, PDA, etc.).

The IPX system provides the following basic functionality for short messaging:

  • Sending mobile terminated (MT) short messages, such as text or binary.(e.g. EMS) messages, premium and non-premium.
  • Receiving delivery reports for submitted MT messages.
  • Receiving mobile originated (MO) short messages, premium and nonpremium.

Steps involved in sending message
  1. The Content Provider makes a request to send an SM to the IPX system.
  2. IPX handles routing, charging (in case of premium message) and delivers the message to the addressed Consumer.
  3. A message ID is returned to the Content Provider synchronously. This ID can be used for tracing a certain message.

    Step 4 and 5 are executed if the Content Provider requested a delivery report in step 1.
     4.  A delivery report is triggered, e.g. when the message is delivered to the Consumer’s mobile station.
     5. The delivery report is sent to the Content Provider (the report contains the same message ID as returned in step 3.

Steps involved in receiving message
  1. The Consumer sends an SM to a short number.
  2. IPX transmits the SM to the Content Provider.
  3. The Content Provider acknowledges the SM.
Installation

IPX provides an API exposed as a web service with a SOAP interface. The SOAP protocol and the IPX server are independent of the platform used on the client side, although the installation of the SOAP tools could be different. The web service API is described in WSDL. For those not familiar with web services, IPX also provides a set of Java classes generated from the web service WSDL description. These classes can be used as an SDK and are provided by IPX upon request.
System requirements
The Content Provider needs the following:
  • Web server with a fixed domain name or IP address
  • SOAP Toolkit/SDK

Reason,Responce codes and variables

Sending SM

The send request element is formatted as follows:

Element


Type

Default Value


Max

length

Description


correlationId


string



100


Correlation ID to keep track of SOAP

requests and responses (WS-I

recommendation). The server echoes

whatever value is provided.


originatingAddress


string


If omitted, this value

is set by IPX (it is

however highly

recommended that

this value always is

set by the Content

Provider)


16


The originating address for the

outgoing SM. Type of originating

address is defined by the

orginatorTON parameter.

Short number max length is 16.

Alpha numeric sender is limited to

GSM default Alphabet with max length

11 characters.

MSISDN sender max length is 16


originatorTON

integer



1


The originating address. type of

number (TON):

0 . Short number

1 . Alpha numeric (max length 11)

2 . MSISDN

Behaviour may vary with Operator

integrations.


destinationAddress


string


40


The MSISDN that the SM should be

sent to, starting with country code.

Example: 46762050312.

For some markets (where the

Consumer MSISDN must be

obfuscated) this value can also be an

alphanumeric alias, prefixed with.#..

Sending SM to multiple recipients is

supported by providing a distribution

list of semi-colon separated MSISDNs

(e.g. 46762050312;46762050313).

Note that no white-spaces are

allowed, the recipients must be unique

within a list and the distribution list is

limited to 1000 entries.


userData


string

Empty message.


280


The message content,


userDataHeader


string


No user data header.


280


User Data Header together with the

User Data can contain up to 140 (i.e.

280 when hex-encoded) octets. This

parameter is always hex-encoded.


DCS


integer


17


3


Data coding scheme. See [5] for more

information.

Behaviour may vary with Operator

integrations.


PID


integer




Use .1 until supported.


relativeValidityTime


integer


172800 (48 hours)


10


Relative validity time in seconds

(relative to the time for the submission

to IPX).

Behaviour may vary with Operator

integrations.


deliveryTime


string


Immediately.


25


The message can be delivered with

delayed delivery time.

Format: yyyy-MM-dd HH:mm:ss Z,

example: 2000-01-01 01:01:01 .0000.

Behaviour may vary with Operator

integrations.


statusReportFlags


integer


0


1


Deliver report request:

0 . No delivery report

1 . Delivery report requested


accountName


string


#NULL#


50


This field allows IPX to route

messages in a flexible manner, which

may or may not be content provider

specific.

For normal usage, #NULL# should be

supplied.

Note: Usage of this field must be

provisioned by IPX.


tariffClass


string



40


Tariff class for the message,

representing the price of a premium

message. Valid market tariff classes

are provided by IPX.

For non-premium messages, the

market.s zero tariff class must be

supplied, e.g. SGD0, EUR0 or

corresponding


VAT


double


-1


5


Set to -1 for normal usage (apply for

most Content Providers).

Specifies the requested (non-default)

VAT.

Note that the VAT finally used is

returned in the submit response.

Behaviour may vary with Operator

integrations.

IPX support should be contacted

before usage.


referenceId


string




150


Referenced order of the premium

message, normally a message ID

from an MO message


contentCategory


string


#NULL#


40


The content category. Set to #NULL#

if not used or not supported by the

market.

Market specific information. Contact

IPX support for further information.


contentMetaData


string


#NULL#


1000


The content meta data. Set to

#NULL# if not used or not supported

by the market.

Market specific information. Contact

IPX support for further information.


Username


string



64


The Content Provider.s username

provided by IPX.


Password


string



64


The Content Provider.s password

provided by IPX.



Receiving SM


Parameter


Type


Max

length


Description


DestinationAddress


string


11


The short number the SM was sent to.

Example: 72160.


OriginatorAddress


string


40


The Consumer.s MSISDN, starting

with the country code (sender of the

SM). Example: 46762050312.

For some markets (where the

Consumer MSISDN must be

obfuscated) this value can also be an

alphanumeric alias, prefixed with .#..


Message


string


280


The message text,


MessageId


string


22


A unique ID for the message. This

message ID should be used as

reference ID when sending premium

MT message.


TimeStamp


string


20


Time of arrival of the SM at the

Operator.s SMSC.

The time zone of the timestamp is

CET or CEST (with summer time as

defined for the EU).

Format: yyyy-MM-dd HH:mm:ss.


Operator


string


100


The name of the Consumer.s Mobile

Operator (a list of available operators

is provided by IPX) or the account

name used when sending the

message.


UserDataHeader


string


280


User Data can contain up to 140 (i.e.

280 when hex-encoded) octets. This

parameter is always hex-encoded.

See [6] for more information.

Behaviour may vary with Operator

integrations. IPX always forwards the

received data unchanged or empty if

not available.

Note: Access to this parameter must

be provisioned by IPX support.


MessageAlphabet


int


2

Indicates the message alphabet used

in the SM:

0 . Default (GSM)

1 . 8 bit (binary)

2 . UCS2

The Message Alphabet is part of the

Data coding scheme as described in

[5].

Note: Access to this parameter must

be provisioned by IPX support.



Related Responce Codes

Code


Text

0

Success


1

Invalid login or un-authorized API

usage


2

Consumer is blocked by IPX


3

Operation is not provisioned by

IPX


4

The consumer is unknown to IPX


5

Consumer has blocked

service in IPX


6

The originating address is not

supported


7

Alpha originating address not

supported by account


8

MSISDN originating address not

supported by account


9


GSM extended not supported by

account


10

Unicode not supported by

account


11

Status report not supported by

account


12

Required capability not


13

Could not route message


14

The content provider max

throttling rate is exceeded


15

The account max throttling rate is

exceeded


50

Partial success: (<1>;<2>;)


99

Internal server error


100

Invalid destination address


101

Invalid tariff class (price)


102

Invalid referenced (linked) ID


103

Invalid account name


104

Invalid content category


105

Invalid content meta data


106

Invalid originating address


107

Invalid alphanumeric originating

address


108

Invalid validity time


109

Invalid delivery time


110

Invalid message content/user

data


111


Invalid message length


112

Invalid user data header


113

Invalid data coding scheme


114

Invalid protocol ID


115

Invalid status report flags


116

Invalid TON


117

Invalid VAT


200

Operator integration error


201

Communication problems


202

Read timeout


209

Integration error



Reason codes


Reason code



Text

0

Not applicable


1000

The consumer is not

recognized as a subscriber

(from operator)


1001

The subscriber is blocked

(from operator)


1002

The subscriber has insufficient

funds for the requested

transaction (from operator)


1003

The mobile subscribers

message queue is full (from

operator)


1004


Invalid content meta data


1006

Charging error

1007

The subscriber has blocked

this service (from operator)


1008

The subscriber is not

registered (from operator)


working with rails

Sending message:
 
In the Ruby on Rails implementation using Soap4r gem, the SOAP Toolkit  has been
used together with ruby Script Version 1.8.6 . The SOAP Toolkit can be downloaded from http://dev.ctor.org/soap4r.
         The code in ruby is listed here.
require 'rubygems'
gem 'soap4r'
require 'soap/rpc/driver'
require "soap/wsdlDriver"

wsdl_url="http://us.ipx.com/api/services2/SmsApi51?wsdl"
soap = SOAP::WSDLDriverFactory.new(wsdl_url).create_rpc_driver
h=Hash.new
h['originatingAddress']= short_code #provided by ericsson 
h['originatorTON'] = '0' 
h['userDataHeader'] =N
h['DCS'] = '17'
h['PID'] = '-1'
h['relativeValidityTime'] = '-1'
h['deliveryTime'] =N
h['statusReportFlags'] = '0'
h['accountName'] = N
h['tariffClass'] = 'USD0'
h['VAT'] ='-1'
h['referenceId'] = N
h['contentCategory'] =N
h['contentMetaData'] =N
h['username']= USERNAME # provided by IPX
h['password'] = PASSWORD # provided by IPX
h['correlationId'] = sms.correlation_id # set by user sending message
h['destinationAddress'] = sms.destination_address # destination addess
h['userData'] = sms.message #actual message
responce=soap.send(h)
puts responce

You can then find the responce codes and reason code as per the table listed in part 2.
Receiving message:
User have to set the callback url from its IPX account. on which the received message will be forwarded by the IPX. The variables those will be received are listed in part 2 of this blog.
 


Other languages and text messaging

Java code example

In the Java implementation the IPX java API (api-smsapi50.jar) and Axis 1.1 have been used together with J2SE 1.4.2.

try {
// If using proxy
// System.setProperty("http.proxyHost", "proxyhost");
// System.setProperty("http.proxyPort", "8080");
// Change endpoint URL if other than service location specified in
WSDL
URL aPortUrl = new URL("http://host:port/path");
SmsApiServiceLocator aLocator = new SmsApiServiceLocator();
SmsApiPort anSmApi = aLocator.getSmsApi51(aPortUrl);
((Stub) anSmApi).setTimeout(10*60*1000); // Set read timeout to 10
minutes
SendRequest aRequest = new SendRequest();
aRequest.setCorrelationId("corrID");
aRequest.setOriginatingAddress("72160");
aRequest.setOriginatorTON(0);
aRequest.setDestinationAddress("msisdn");
aRequest.setUserData("Test message");
aRequest.setUserDataHeader("#NULL#");
aRequest.setDCS(-1);
aRequest.setPID(-1);
aRequest.setRelativeValidityTime(-1);
aRequest.setDeliveryTime("#NULL#");
aRequest.setStatusReportFlags(0);
aRequest.setAccountName("#NULL#");
aRequest.setTariffClass("EUR0");
aRequest.setVAT(-1);
aRequest.setReferenceId("#NULL#");
aRequest.setContentCategory("#NULL#");
aRequest.setContentMetaData("#NULL#");
aRequest.setUsername("username");
aRequest.setPassword("password");
SendResponse aResult = anSmApi.send(aRequest);
// System.out.println("Response: " + aResponse);
System.out.println("Result: correlationId: "
+ aResult.getCorrelationId());
System.out.println("Result: messageId: "
+ aResult.getMessageId());
System.out.println("Result: responseCode: "
+ aResult.getResponseCode());
System.out.println("Result: responseMessage: "
+ aResult.getResponseMessage());
System.out.println("Result: temporaryError: "
+ aResult.isTemporaryError());
} catch (Exception e) {
e.printStackTrace();
}

PHP code example

In the PHP implementation a toolkit called NuSOAP version 0.6.7 (download for
free at http://dietrich.ganx4.com/nusoap/) has been used together with PHP 4.3.5.

require_once(’../nusoap.php’);
# Load wsdl and reuse the client instance or set all parameters when invoking
service
$soapclient = new soapclient(’http://host:port/path?wsdl’,true);
# If using proxy
# $soapclient = new soapclient(’http://host:port/path?wsdl’,true,
# ’proxyhost’, 8080);
# print_r($soapclient->getOperationData(’send’));
# Change endpoint URL if other than service location specified in WSDL
$soapclient->operations[’send’][’endpoint’] = ’http://host:port/path’;
# print_r($soapclient->getOperationData(’send’));
$soapclient->response_timeout = 600; // Set read timeout to 10 minutes
$params = array(
’correlationId’ => ’corrID’,
’originatingAddress’ => ’72160’,
’originatorTON’ => ’0’,
’destinationAddress’ => ’msisdn’,
’userData’ => ’Test message’,
’userDataHeader’ => ’#NULL#’,
’DCS’ => ’-1’,
’PID’ => ’-1’,
’relativeValidityTime’ => ’-1’,
’deliveryTime’ => ’#NULL#’,
’statusReportFlags’ => ’0’,
’accountName’ => ’#NULL#’,
’tariffClass’ => ’EUR0’,
’VAT’ => ’-1’,
’referenceId’ => ’#NULL#’,
’contentCategory’ => ’#NULL#’,
’contentMetaData’ => ’#NULL#’,
’username’ => ’username’,
’password’ => ’password’);
# print "Request:";
# print_r($params);
$outparams = $soapclient->call(’send’,array(’request’ => $params));
# print "Result:";
# print_r($outparams);
if ($soapclient->getError() != null) {
print "Error: ";
print $soapclient->getError()."\n";
}
else {
print "Result: correlationId: ".$outparams[’correlationId’]."\n";
print "Result: messageId: ".$outparams[’messageId’]."\n";
print "Result: responseCode: ".$outparams[’responseCode’]."\n";
print "Result: responseCode: ".$outparams[’reasonCode’]."\n";
print "Result: responseMessage: ".$outparams[’responseMessage’]."\n";
}
?>

VBScript code example

In the Microsoft implementation using VBScript, the SOAP Toolkit 3.0 has been
used together with Windows Script Host Version 5.6 (cscript.exe). The SOAP
Toolkit can be downloaded from http://www.microsoft.com/downloads/.

Option Explicit
On Error Resume Next
Dim SoapClient ’ As SoapClient30
Dim SendReturn ’ As IXMLDOMSelection
Dim Dom ’ As New DOMDocument3
Dim Request ’ As IXMLDOMNodeList
Set Soapclient = CreateObject("MSSOAP.SoapClient30")
’ In case of Soap Toolkit 2.0
’ Set Soapclient = CreateObject("MSSOAP.SoapClient")
Call SoapClient.mssoapinit("hhttp://host:port/path?wsdl")
’ If using proxy
’ SoapClient.ConnectorProperty("ProxyServer") = "proxyhost:8080"
’ See SOAP Toolkit API for info about this property
SoapClient.ClientProperty("ServerHTTPRequest") = True
’ Change endpoint URL if other than service location specified in WSDL
SoapClient.ConnectorProperty("EndPointURL") = "hhttp://host:port/path"
’ Set read timeout to 10 minutes
SoapClient.ConnectorProperty("Timeout") = 60*10*1000
Set Dom = CreateObject("Msxml2.DOMDocument")
’ Use this as container when creating the request
Set Dom.documentElement = Dom.createElement("tempDoc")
’ Add parameters
Call AppendChildElement(Dom, "correlationId", "corrID")
Call AppendChildElement(Dom, "originatingAddress", "72160")
Call AppendChildElement(Dom, "originatorTON", "0")
Call AppendChildElement(Dom, "destinationAddress", "msisdn")
Call AppendChildElement(Dom, "userData", "Test message")
Call AppendChildElement(Dom, "userDataHeader", "#NULL#")
Call AppendChildElement(Dom, "DCS", "-1")
Call AppendChildElement(Dom, "PID", "-1")
Call AppendChildElement(Dom, "relativeValidityTime", "-1")
Call AppendChildElement(Dom, "deliveryTime", "#NULL#")
Call AppendChildElement(Dom, "statusReportFlags", "0")
Call AppendChildElement(Dom, "accountName", "#NULL#")
Call AppendChildElement(Dom, "tariffClass", "EUR0")
Call AppendChildElement(Dom, "VAT", "-1")
Call AppendChildElement(Dom, "referenceId", "#NULL#")
Call AppendChildElement(Dom, "contentCategory", "#NULL#")
Call AppendChildElement(Dom, "contentMetaData", "#NULL#")
Call AppendChildElement(Dom, "username", "username")
Call AppendChildElement(Dom, "password", "password")
Set Request = Dom.documentElement.childNodes
’ Invoke web service
Set SendReturn = SoapClient.send(Request)
If err <> 0 Then
wscript.echo "Error: "
wscript.echo err.description
wscript.echo "faultcode=" + Soapclient.faultcode
wscript.echo "faultstring=" + Soapclient.faultstring
wscript.echo "faultactor=" + Soapclient.faultactor
wscript.echo "detail=" + Soapclient.detail
Else
’ Call PrintResponseParams(SendReturn)
wscript.echo "Result: correlationId " & GetResponseParam(SendReturn,
"correlationId")
wscript.echo "Result: messageId: " & GetResponseParam(SendReturn, "messageId")
wscript.echo "Result: responseCode: " & GetResponseParam(SendReturn,
"responseCode")
wscript.echo "Result: reasonCode: " & GetResponseParam(SendReturn,
"reasonCode")
wscript.echo "Result: responseMessage: " & GetResponseParam(SendReturn,
"responseMessage")
End If
’ Helper functions
’ Parse a DOM for a specific element and return its value
Function GetResponseParam(oDom, strKey)
Dim j
For j = 0 to oDom.length
If oDom.item(j).nodeName = strKey Then
GetResponseParam = oDom.item(j).text
Exit Function
End If
Next
End Function
’ Parse a DOM and print all node names and their values
Sub PrintResponseParams(oDom)
Dim j
For j = 0 to oDom.length
wscript.echo oDom.item(j).nodeName & ": " & oDom.item(j).text
Next
End Sub
’ Append a child element to a DOM, with specified name and value.
Sub AppendChildElement(byRef oDom, strElementName, strElementValue)
Dim Elm
Set Elm = oDom.createNode(1, strElementName,
"http://www.ipx.com/api/services/smsapi51/types")
Elm.text = strElementValue
oDom.documentElement.appendChild Elm
End Sub

PERL code example

In the PERL implementation a toolkit called SOAP::Lite version 0.55 (download
for free at http://www.soaplite.com/) has been used together with ActivePerl-
5.8.3.809.

#!perl -w
# If using proxy
# $ENV{HTTP_proxy} = "http://proxyhost:8080/";
# use SOAP::Lite +trace => ’debug’;
use SOAP::Lite;
# Target URL. Set read timeout to 10 minutes
my $client = SOAP::Lite ->proxy(’http://host:port/path’, timeout => 600);
# Force the SDK not to guess types of the SOAP elements
$client->autotype(0);
my @parameters =
(SOAP::Data->name(correlationId => ’correlationId’)->value(’corrID’),
SOAP::Data->name(originatingAddress => ’originatingAddress’)->value(’72160’),
SOAP::Data->name(originatorTON => ’originatorTON’)->value(’0’),
SOAP::Data->name(destinationAddress => ’destinationAddress’)->value(’msisdn’),
# Note: the toolkit does not automatically escape XML unsafe characters,
# use encode_data
SOAP::Data->name(userData => ’userData’)
->value(SOAP::Utils::encode_data(’Test message’)),
SOAP::Data->name(userDataHeader => ’userDataHeader’)->value(’#NULL#’),
SOAP::Data->name(DCS => ’DCS’)->value(’-1’),
SOAP::Data->name(PID => ’PID’)->value(’-1’),
SOAP::Data->name(relativeValidityTime => ’relativeValidityTime’)->value(’-1’),
SOAP::Data->name(deliveryTime => ’deliveryTime’)->value(’#NULL#’),
SOAP::Data->name(statusReportFlags => ’statusReportFlags’)->value(’0’),
SOAP::Data->name(accountName => ’accountName’)->value(’#NULL#’),
SOAP::Data->name(tariffClass => ’tariffClass’)->value(’EUR0’),
SOAP::Data->name(VAT => ’VAT’)->value(’-1’),
SOAP::Data->name(referenceId => ’referenceId’)->value(’#NULL#’),
SOAP::Data->name(contentCategory => ’contentCategory’)->value(’#NULL#’),
SOAP::Data->name(contentMetaData => ’contentMetaData’)->value(’#NULL#’),
SOAP::Data->name(username => ’username’)->value(’username’),
SOAP::Data->name(password => ’password’)->value(’password’),
);
# send request and retrieve information (RPC like document style service)
my $body = SOAP::Data->name(’SendRequest’) ->
attr({xmlns => ’http://www.ipx.com/api/services/smsapi51/types’});
$result = $client->call($body => @parameters);
# print all results
if ($result->fault)
{
print "Error: ", $result->faultstring, "\n";
}
else
{
print "Result: correlationId: ", $result-
>valueof(’//SendResponse/correlationId’), "\n";
print "Result: messageId: ", $result->valueof(’//SendResponse/messageId’),
"\n";
print "Result: responseCode: ", $result-
>valueof(’//SendResponse/responseCode’), "\n";
print "Result: responseCode: ", $result->valueof(’//SendResponse/reasonCode’),
"\n";
print "Result: responseMessage: ", $result-
>valueof(’//SendResponse/responseMessage’), "\n";
}

.NET code example

This .NET example is written in C# using Microsoft .NET Framework 1.1. Add the
target web service WSDL as web reference and .NET will generate the necessary
stub code for the client side.

try
{
SmsApiService aService = new SmsApiService();
SendRequest aRequest = new SendRequest();
aRequest.correlationId = "corrId";
aRequest.originatingAddress = "72160";
aRequest.originatorTON = 0;
aRequest.destinationAddress = "msisdn";
aRequest.userData = "Test message";
aRequest.userDataHeader = "#NULL#";
aRequest.DCS = -1;
aRequest.PID = -1;
aRequest.relativeValidityTime = -1;
aRequest.deliveryTime = "#NULL#";
aRequest.statusReportFlags = -1;
aRequest.accountName = "#NULL#";
aRequest.tariffClass = "EUR0";
aRequest.VAT = -1;
aRequest.referenceId = "#NULL#";
aRequest.contentCategory = "#NULL#";
aRequest.contentMetaData = "#NULL#";
aRequest.username = "username";
aRequest.password = "password";
// If using proxy
// aService.Proxy = new System.Net.WebProxy("proxyhost", 8080);
// Change endpoint URL if other than service location specified in
WSDL
aService.Url = "http://host:port/path";
aService.Timeout = 60*10*1000; // Set read timeout to 10 minutes
SendResponse aResult = aService.send(aRequest);
Console.Out.WriteLine("Result: correlationId: " +
aResult.correlationId);
Console.Out.WriteLine("Result: messageId: " + aResult.messageId);
Console.Out.WriteLine("Result: responseCode: " +
aResult.responseCode);
Console.Out.WriteLine("Result: reasonCode: " + aResult.reasonCode);
Console.Out.WriteLine("Result: responseMessage: " +
aResult.responseMessage);
}
catch (Exception e)
{
Console.Out.WriteLine("Exception: " + e);
}