The OneAPI Payment interface allows you to charge mobile subscribers for use of your Web application or content. The API allows you to directly charge a user based on their consent (see ‘User consent and operator policies’ below). It also supports reserving funds from a user’s account for subsequent charging – this allows you to offer additional content within the same session to the user and then apply one charge for the total, whilst ensuring they have sufficient funds to pay. This can be especially important for pre-pay users with limited credits.
The API includes parameters to help you audit sales and provide sales information for the subscriber’s bill. Both ‘one-off’ and repeat charges are supported, as well as refunds. You can find some example use cases at www.gsmworld.com/oneapi
This is version 1 of the API. Please see below for document changelog.
The OneAPI homepage lists operators that support the interfaces. Click-through and you can sign-up to the terms of service for each. The OneAPI group are working on ways to make signing-up to multiple operators easier, to help speed up integration time.
You will also need the API documentation, described below. You will need to be familiar with a Web application programming language; we will host Client libraries as they become available – we welcome bindings in any languages, please send these to OneAPI [at] gsm.org
Note that to receive SMS sent to your Web application by end users, you will need to obtain a registrationId (e.g. short code or similar identifier) to identify your application to the network for correct routing. OneAPI implementations that support this are listed on the Implementations, and details for obtaining the code will be in the Terms & Conditions for those implementations.
Authentication depends on the OneAPI server you are using – we are working on agreeing a single authentication method for all implementing operators. Please see the Terms of Service agreement for the OneAPI service you are using for specific details.
In case there is a communication failure when attempting to charge a user, the OneAPI includes parameters to ensure you can try again without charging the user twice. clientCorrelator is a nonce that you can pass with any POST requests. If the OneAPI server sees the same clientCorrelator twice then it can recognize a duplicate request, and respond without having to apply the backend processing again.
When you are reserving funds to charge later, the referenceSequence allows the OneAPI server to keep track of additional reservations and a subsequent charge and release – please see examples below.
|
User consent and operator policies |
Since there are regulations governing how a user can give permission to be located, please see the Terms of Service agreement for the OneAPI service you are using for specific details. OneAPI includes policy exceptions to indicate any breaches, as described in the Examples and Exceptions section below.
OneAPI Payments may be accessed via a RESTful API (this document) or via a more complex SOAP API (see OneAPI SOAP at www.gsmworld.com/oneapi). A RESTful API utilises HTTP commands POST, GET, PUT, and DELETE in order to perform an operation on a resource at the server. This resource is addressed by a URI; and what is returned by the server is a representation of that resource depending on its current state.
OneAPI Payments uses GET, POST, PUT operations as described below. The URIs used in the Payment API are:
http://example.com/{apiVersion}/payment/{endUserId}/transactions/amount
- Charge a user
- Refund a user
http://example.com/{apiVersion}/payment/{endUserId}/transactions/amountReservation
- Reserve an amount to charge
http://example.com/{apiVersion}/payment/{endUserId}/transactions/amountReservation/{transactionId}
- Reserve an additional amount (i.e. extend an existing reservation)
- Charge against the reservation
- Release the reservation
example.com is replaced by the hostname of the OneAPI server you are accessing. apiVersion optionally indicates the version of OneAPI Payments you are accessing – the default is the latest version supported by that server. endUserId is the account to charge, either an MSISDN or operator-provided Anonymous Customer Reference (ACR).
See the examples section below.
|
Representation formats and content types supported |
The Payments API supports application/x-www-form-urlencoded and application/JSON content types for POST and PUT operations. The response content type is application/JSON.
Note the PUT and POST operations have been shown here as application/x-www-form-urlencoded . You can also use JSON in the request body, please see our Code examples pack at www.gsmworld.com/oneapi..
Example 1: charge an amount to the end user’s bill
|
POST http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amount HTTP/1.1
Accept: application/json
Host: example.com:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 12345
Date: Thu, 04 Jun 2009 02:51:59 GMT
endUserId= tel%3A%2B16309700001&
transactionStatus=charged&
description= Alien%20Invaders%20Game&
currency=USD&
amount=10&
referenceCode=REF-12345&
clientCorrelator=54321&
onBehalfOf=Example%20Games%20Inc&
purchaseCategoryCode=Game&
channel=WAP&
taxAmount=0 |
In the URI ‘/1/’ represents the API version.
Mandatory parameters:
endUserId is the URL-escaped end user ID; in this case their MSISDN including the ‘tel:’ protocol identifier and the country code preceded by ‘+’. i.e., tel:+16309700001. OneAPI also supports the Anonymous Customer Reference (ACR) if provided by the operator.
referenceCode (string, unique per charge event) is your reference for reconciliation purposes. The operator should include it in reports so that you can match their view of what has been sold with yours by matching the referenceCodes.
transactionStatus (enumeration). This indicates the desired resource state, in this case ‘charged’. See ‘resource states’ section below for further explantion.
description (string) is the human-readable text to appear on the bill, so the user can easily see what they bought.
currency (string) is the 3-figure code as per ISO 4217.
amount (decimal) can be a whole number or decimal.
Optional Parameters:
clientCorrelator (string) uniquely identifies this create charge request. If there is a communication failure during the charge request, using the same clientCorrelator when retrying the request allows the operator to avoid applying the same charge twice.
onBehalfOf (string) allows aggregators/partners to specify the actual payee.
channel (string) can be “Wap”, “Web”, “SMS”, depending on the source of user interaction
taxAmount (decimal) tax already charged by the merchant.
serviceID (string) The ID of the partner/merchant service
productID (string) combines with the serviceID to uniquely identify the product being purchased.
|
Response:
|
HTTP/1.1 201 Created Content-Type: application/json Content-Length: 12345 Date: Thu, 04 Jun 2009 02:51:59 GMT Location: http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amount/abc123
{"amountTransaction": {
"clientCorrelator": "54321",
"endUserId": "tel:+16309700001",
"paymentAmount": {
"chargingInformation": {
"amount": "10",
"currency": "USD",
"description": " Alien Invaders Game"
},
"totalAmountCharged": "10"
},
"referenceCode": "REF-12345",
"serverReferenceCode": "ABC-123",
"resourceURL": " http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amount/abc123
"transactionStatus": "Charged"
}} |
The 201 response indicates the reservation was created.
The Location HTTP header provides the URI of the created resource. The final part of this URI (‘abc123’) is the transactionId which uniquely identifies this charge transaction.
The JSON response confirms the information sent in the request.
transactionStatus=charged confirms that the resource state is ‘charged’ (see ‘Resource states’ below.)
serverReferenceCode is a reference to the charge or refund, provided by the server, and meaningful to the server’s backend system for the purpose of reconciliation. We strongly recommend that the server provide this. If they have provided it you will need to refer to it in any subsequent refund for this charge.
|
Example 2: reserve an amount for subsequent charging to an end user’s bill
|
POST http://example.com/payment/tel%3A%2B16309700001/transactions/amountReservation HTTP/1.1
Accept: application/json
Host: example.com:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 12345
Date: Thu, 04 Jun 2009 02:51:59 GMT
endUserId= tel%3A%2B16309700001&
transactionStatus=reserved&
description= Streaming%20video%20of%20the%Big%20Fight&
currency=USD&
amount=10&
referenceCode=Video-abc123&
clientCorrelator=54321&
referenceSequence=1&
onBehalfOf=Example%20Video%20Inc&
purchaseCategoryCode=Video&
channel=WAP&
taxAmount=0 |
Mandatory parameters:
transactionStatus=reserved is setting the initial state of the created resource (see ‘resource states’ section below), in this case to make a reservation.
referenceSequence (integer) – this allows the server to distinguish easily between new and repeated requests in the case of a communication failure. For each transaction within a reservation sequence, iterate the referenceSequence by 1.
e.g. initial reservation –> referenceSequence=1
reserve additional amount -> referenceSequence=2
charge reservation -> referenceSequence=3
release reservation -> referenceSequence=4
(if you do not need to reserve an additional amount, then charge reservation=3. release reservation=4)
Otherwise parameters are the same as for the charge section, see above.
Optional Parameters:
Same as for the charge section, see above.
|
Successful response:
|
HTTP/1.1 201 Created Content-Type: application/json Content-Length: 12345 Date: Thu, 04 Jun 2009 02:51:59 GMT Location: http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amountReservation/abc123
{"amountReservationTransaction": {
"clientCorrelator": "54321",
"endUserId": "tel:+16309700001",
"paymentAmount": {"chargingInformation": {
"amount": "10",
"currency": "USD",
"description": "Streaming video of the Big Fight"
}},
"referenceCode": "REF-12345",
"referenceSequence": "1",
"transactionStatus": "Reserved"
}} |
The 201 response indicates the reservation was created.
The Location HTTP header provides the URI of the created resource (‘abc123’ is the transactionId to uniquely identify this reservation). This is the URI you will use to charge or extend the reservation, as shown in the examples below.
The JSON response confirms the information sent in the request.
transactionStatus=reserved confirms that the resource state has changed to reserved (see ‘state changes’ below.) |
(Optional) Reserve an additional amount – NOTE THIS SECTION IS UNDER FINAL REVIEW
|
POST http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amountReservation/abc123 HTTP/1.1
Accept: application/json
Host: example.com:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 12345
Date: Thu, 04 Jun 2009 02:51:59 GMT
transactionStatus=reserved&
amount=5&
referenceCode=REF-12346&
referenceSequence=2&
|
Here we use POST, because although we are updating an existing resource, we are not updating all of it - so PUT would not be appropriate.
Mandatory parameters:
As above for the Create charging reservation example – except you only need to update changed parameter values, not all of them (see example)
transactionStatus=reserved indicates that we are not changing the resource state, just the value being reserved (see ‘resource states’ section below),
amount is the additional reserved amount (5) for this request– it is not the total amount reserved so far.
referenceSequence has been iterated to 2. Each time you reserve an additional amount against an existing reservation, make sure to iterate the referenceSequence each time. This ensures the OneAPI server can distinguish between new requests for additional amounts, and those that are being repeated due to a communication failure.
Optional Parameters:
As above for the Create charging reservation example.
clientCorrelator is not used as the resource has already been created. |
Response:
|
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 12345 Date: Thu, 04 Jun 2009 02:51:59 GMT
{"amountReservationTransaction": {
"endUserId": "tel:+16309700001",
"paymentAmount": {
"amountReserved": "15",
"chargingInformation": {
"amount": "10",
"currency": "USD",
"description": "Streaming Video of the Big Fight"
},
"totalAmountCharged": "0"
},
"referenceCode": "REF-12346",
"referenceSequence": "2",
"resourceURL": " http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amountReservation/abc123",
"transactionStatus": "Reserved"
}} |
The JSON now shows the total reservation amount so far in the “amountReserved” pair within the paymentAmount object.
It also confirms that nothing has been charged to the user’s bill yet:
totalAmountCharged is 0. |
Charge against the reservation - NOTE THIS SECTION IS UNDER FINAL REVIEW
|
POST http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amountReservation/abc123 HTTP/1.1
Accept: application/json
Host: example.com:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 12345
Date: Thu, 04 Jun 2009 02:51:59 GMT
transactionStatus=charged&
description= Three%20rounds%20of%20the%Big%20Fight&
amount=15&
referenceCode=REF-123457&
referenceSequence=3&
|
Again we use POST because we are partially updating the resource.
Mandatory parameters:
As above for the Create charging reservation example.
transactionStatus=charged is requesting a state change at the resource (see ‘resource states’ section below), in this case to apply the charge against the reservation.
The same applies to referenceSequence. Here it is ‘3’, but if you had not reserved an additional amount it would be ‘2’.
As we you are now charging, charge the total amount (15). This is the total of the orginal reservation plus any additional amounts reserved.
The description can be updated to show what was purchased by the user, in this case the first three rounds of a boxing video stream.
Other parameters
Optional Parameters:
As above for the Create charging reservation example.
|
Response
|
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 12345 Date: Thu, 04 Jun 2009 02:51:59 GMT
{"amountReservationTransaction": {
"endUserId": "tel:+16309700001",
"paymentAmount": {
"amountReserved": "0",
"chargingInformation": {
"amount": "15",
"currency": "USD",
"description": " Streaming Video of the Big Fight "
},
"totalAmountCharged": "15"
},
"referenceCode": "REF-123457",
"serverReferenceCode":"DEF-456",
"referenceSequence": "3",
"resourceURL": " http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amountReservation/abc123 ",
"transactionStatus": "Charged"
}} |
“amountReserved” is now 0 as the charge has been applied.
The “transactionStatus” and “totalAmountCharged” pairs confirm what has been charged to the user’s bill.
|
Release the reservation NOTE THIS SECTION IS UNDER FINAL REVIEW
|
PUT http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amountReservation/abc123 HTTP/1.1
Accept: application/json
Host: example.com:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 12345
Date: Thu, 04 Jun 2009 02:51:59 GMT
transactionStatus=released&
referenceSequence=4&
|
POST is used to update the existing reservation to ‘released’ as transactions have now completed. In case you reserve more than was eventually charged to the user, any outstanding funds will also be released back to the user’s account.
transactionStatus=released is used to request that the reservation be released.
referenceSequence is iterated to ‘4’. If you had not reserved an additional amount, it would instead be ‘3’
|
Response
|
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 12345 Date: Thu, 04 Jun 2009 02:51:59 GMT
{"amountReservationTransaction": {
"endUserId": "tel:+16309700001",
"paymentAmount": {
"amountReserved": "0",
"chargingInformation": {
"amount": "10",
"currency": "USD",
"description": "Streaming Video of the Big Fight"
},
"totalAmountCharged": "5"
},
"referenceCode": "REF-12346",
"referenceSequence": "4",
"resourceURL": " http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amountReservation/abc123 ",
"transactionStatus": "Released"
}} |
amountReserved is reduced to 0 to show the reservation has been released
amount is the remaining funds to release back to the user’s account (10)
totalAmountCharged confirms how much was charged to the user. |
Example 3: Refund the user
|
POST http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amount HTTP/1.1
Accept: application/json
Host: example.com:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 12345
Date: Thu, 04 Jun 2009 02:51:59 GMT
endUserId=tel%3A%2B16309700001&
transactionStatus=refunded&
description= Alien%20Invaders%20Game&
currency=USD&
amount=10&
referenceCode=REF-12345&
originalServerReferenceCode=ABC-123&
clientCorrelator=54321&
onBehalfOf=Example%20Games%20Inc&
purchaseCategoryCode=Game&
channel=WAP&
taxAmount=0 |
Use POST as you are creating a refund to an end user’s account.
Mandatory parameters
Same as for example 1, ‘Charge amount’.
amount here means the amount to refund, which can be a full or partial refund of the original charge.
Here the clientCorrelator protects against any communication failure as described previously.
If a serverReferenceCode was provided in the response to the orignal charge request, then you must include it in your refund request. Omitting it risks a policy exception being thrown.
Optional parameters
Same as for example 1, ‘Charge amount’
|
Response
|
HTTP/1.1 201 Created Content-Type: application/json Content-Length: 12345 Date: Thu, 04 Jun 2009 02:51:59 GMT Location: http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amount/efg789
{"amountTransaction": {
"clientCorrelator": "54321",
"endUserId": "tel:+16309700001",
"paymentAmount": {
"chargingInformation": {
"amount": "10",
"currency": "USD",
"description": "Alien Invaders"
},
"totalAmountRefunded": "10"
},
"referenceCode": "REF-12345",
"originalServerReferenceCode":"ABC-123",
"resourceURL": "http://example.com/1/payment/ tel%3A%2B16309700001/transactions/amount/efg789",
"transactionStatus": "Refunded"
}} |
The totalAmountRefunded to the user is confirmed in the response.
|
The client passes the transactionStatus in the request body so that the resource can be placed into a desired state. The server either confirms this desired state in the transactionStatus response field, or instead shows a failure state as listed below.
The resource http://example.com/{apiVersion}/payment/{endUserId}/transactions/amount which represents a basic charge or refund against an account may be in the following states:
- “Charged” - a successful charge was made
- “Refunded” – a successful refund was made.
- “Denied” – the policy exception in the response will explain the reason (insufficient balance, security issue etc.)
- “Refused” – the charge or refund was refused, or not explicitly accepted, by the end user.
The resource http://example.com/{apiVersion}/payment/{endUserId}/transactions/amountReservation which represents a reservation against an account may return the following transaction status:
- “Reserved” – success, the reservation was created
- “Denied” – the policy exception in the response will explain the reason
- “Refused” – the reservation was refused, or not explicitly accepted, by the end user.
- “Charged” – success, the reservation has been charged against
- “Released” – success, the reservation has ended.
Any additional reservation (with the transactionId appended to the request URI) will also use these states.
|
Response codes and exceptions |
HTTP response codes are used to indicate:
200 - Success!
400 - Bad request; check the error message for details.
401 - Authentication failure, check your OneAPI provider’s authentication requirements.
403 - Forbidden; please provide authentication credentials.
404 - Not found: mistake in the host or path of the service URI.
405 - Method not supported: for example you mistakenly used GET to create an SMS.
503 - Server busy and service unavailable. Please retry the request.
More details on these at http://www.ietf.org/rfc/rfc2616.txt .
Exceptions:
|
HTTP/1.1 400 Bad Request Content-Type: application/json Content-Length: 1234 Date: Thu, 04 Jun 2009 02:51:59 GMT
{"requestError": {
"serviceException": {
"messageId": "SVC0002",
"text": " Invalid input value for message part %1",
"variables": " tel:+016309700000"
}
}} |
HTTP 400 indicates either a service exception or a policy exception
The requestError object contains either a serviceException or a policyException object.
The serviceException describes the reason why the service cannot accept the request; in this example because the phone number was too long.
A policyException object means that the request syntax is valid, however an operator policy has been broken: for example you are requesting to charge an amount that exceeds a limit they have set.
serviceException and policyException share the same body: an identifier pair for the exception (messageId), a text pair to describe it consistently (text), and a variables pair to indicate any specific cause of the error (variables). The variables relate to the %1 placeholder(s) in the text.
|
In case of a POST operation to create a new transaction that results in a denial or refusal, the Server SHALL return an HTTP 400 Bad Request status and a RequestError data structure, with an indication of a ServiceException SVC0270 (Charge failed). The RequestError body MAY include a link to the previously created resource.
List of service exceptions for SMS:
|
ID |
Exception Text |
Variables |
|
SVC0270 |
Charging operation failed, the charge was not applied |
none |
...plus see the Common Service Exceptions for all OneAPI APIs
List of policy exceptions for SMS:
Nothing specific for messaging, but see the Common Policy Exceptions for all OneAPI APIs.
OneAPI has two Reference Implementations which provide free testing facilities. Please see the OneAPI homepage for details.
Please let us know any problems or suggestions for the location API. Contact details are: OneAPI [at] gsm.org
OneAPI is a profile (subset) of Parlay REST v1.0. The full specifications and guidelines may be found at: http://www.openmobilealliance.org/Technical/current_releases.aspx