Ola Money Developer Hub

Welcome to the Ola Money developer hub. You'll find comprehensive guides and documentation to help you start working with Ola Money as quickly as possible, as well as support if you get stuck.

Guides

Introduction to offline Api's

 

What is offline api?

We have api's for retailers who would like to integrate with Olamoney. This requires deep integration with POS terminals of the merchant.

Offline flow - OTP

 

Merchant will have to implement a form on their end to accept the customers phone number and the bill amount and hit "Pay Now" button. Upon which another form has to accept the OTP

Then the merchant has to call the debit API with the following.

Step 1 : Call Debit API - Merchant Side

The JSON post of the debit call is attached below.
The phone number of the user has to sent in the call as a param.
https://sandbox.olamoney.in/olamoney/v1/debit?phone=<Mobile Number>

{
  "command": "debit",  // Always as debit
  "accessToken": "string", //Shared with you
  "uniqueId": "string",  // Unique transaction ID from your end
  "comments": "string",  // Any string Mandatory
  "udf": "string", //Mandatory
  "hash": "string", 
  "returnUrl": "string",
  "notificationUrl": "string",
  "amount": 100.00,  // Always in two decimal
  "currency": "string",
  "couponCode": "string"
}

Response of the transaction will be as follows.

{
  "type": "debit",
  "status": "string",
  "transactionId": "string",
  "merchantBillId": "string",
  "amount": "string",
  "hash": "string",
  "timestamp": 48146194691,
  "comments": "string",
  "udf": "string",
  "isCashbackSuccessful": "string",
  "isCashbackAttempted": "string"
}

However, the status of this response will remain in 'pending' stage.
The customer will get an OTP on the phone number.
Ask the OTP from the customer.

For these calls, the hash is calculated as given in the "Bill Generator" section.

Step 2: Customer Authentication

With the OTP from the customer and the bill params passed earlier make another POST call with the given JSON

https://sandbox.olamoney.in/olamoney/v1/capture

{
  "command": "capture",
  "accessToken": "string",
  "uniqueId": "string",
  "comments": "string",
  "udf": "string",
  "hash": "string",
  "returnUrl": "string",
  "notificationUrl": "string",
  "amount": 100.00,
  "currency":"INR",
  "otp": "string"
}

For this the hash is calculated with the string as given below.

<AccessToken>|command|comments|notificationUrl|otp|returnUrl|udf|uniqueId|<Salt>

This will give an updated response with a status "success"

{
  "type": "debit",
  "status": "string",
  "transactionId": "string",
  "merchantBillId": "string",
  "amount": "string",
  "hash": "string",
  "timestamp": 0,
  "comments": "string",
  "udf": "string",
  "isCashbackSuccessful": "string",
  "isCashbackAttempted": "string"
}

Also always verify the response hash as well :


data_string =  'type|status|merchantBillId|transactionId|amount|comments|udf|isCashbackAttempted|isCashbackSuccessful|timestamp|salt';
merchant_hash = sha512(data_string);

/resendTransactionOTP

 
posthttps://sandbox.olamoney.in/olamoney/v1/resendTransactionOTP
curl --request POST \
  --url https://sandbox.olamoney.in/olamoney/v1/resendTransactionOTP
var request = require("request");

var options = { method: 'POST',
  url: 'https://sandbox.olamoney.in/olamoney/v1/resendTransactionOTP' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v1/resendTransactionOTP")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/olamoney/v1/resendTransactionOTP");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v1/resendTransactionOTP"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "status": "success"
}
{"errorCode":"invalid_otp","message":"Not a valid
OTP","status":"error"}

Form Data

accessToken
string

merchant accessToken

command
string

resendOTP

timestamp
date-time

Current timestamp YYY-MM-DD HH:mm:SS e.g. 2015-08-13 13:17:12

uniqueBillId
string

uniqueBill Id to which OTP needs to be resend

hash
string

sha512(accessToken|resendOTP|<current timestamp>|<unique bill id>|<salt>)

 

In 1 minute you can hit the RE-SEND-OTP API, 4 times. From 5th time within that 1 minute,API will return 429 status code with no content. User can try again, from next minute.
Resend OTP will be valid only for 15 minutes from the commencement of transaction.
You can check the status code and if its 429, you can conclude OTP rate limiting error.

Offline flow - QR Code

 

Merchant has to enter the amount of transaction and generate the bill.

Step 1 : Call Debit API - Merchant Side

The JSON post of the debit call is attached below.
https://sandbox.olamoney.in/olamoney/v1/debit

{
  "command": "debit",
  "accessToken": "string",
  "uniqueId": "string",
  "comments": "string",
  "udf": "string",
  "hash": "string",
  "returnUrl": "string",
  "notificationUrl": "string",
  "amount": 1.00,
  "currency": "string",
  "couponCode": "string"
}

Response of the transaction will be as follows.

{
  "type": "debit",
  "status": "string",
  "transactionId": "string",
  "merchantBillId": "string",
  "amount": "string",
  "hash": "string",
  "timestamp": 1446655693970,
  "comments": "string",
  "udf": "string",
  "isCashbackSuccessful": "string",
  "isCashbackAttempted": "string"
}

However, the status of this response will remain in 'pending' stage.
The TransactionID in this response should be used to make a QR code.
QR codes can be generated with the help of the following link.

For these calls, the hash is calculated as given in the "Bill Generator" section.

Step 2: Customer authentication

When the Consumer side app scans the QR code, it should return the same TransactionID. This is for user authentication which upon which you'll get this response with a "success" status.

{
  "type": "debit",
  "status": "success",
  "transactionId": "string",
  "merchantBillId": "string",
  "amount": "1.00",
  "hash": "bb3e508655c7511f1980af88a64e962d4cf70a5fca8668a01a721dfda41f21d1a7e767523ecc001f294e96df54dddcd5e20fa737c95bec9afecdb4f114fe7e19",
  "timestamp": 1446655693970,
  "comments": "string",
  "udf": "string"
}

Offline flow - PayCode & Teller

 

Merchant will have sign-up into OM Merchant Console and create "Tellers" ( These tellers are to represent the POS terminal of the merchant )
Teller will be provided with Username & Password.
Bulk Teller Creation is supported.
These "Tellers" can consume Offline PayCodes provided by Customers

Step 1 : Login for teller ( Returns Access_Token used to call further APIs )

POST 'http://stark-teller-qa-002.app.qa.olamoney.net/teller/v1/login'
Host: stark-teller-qa-002.app.qa.olamoney.net
Content-Type: application/json
Authorization: Basic <Basic Auth Token>
Body : Null

Response contains AccessToken & RefreshToken
AccessToken --> Expires in a while ( Configurable by OlaMoney )
RefreshToken --> Always remains constant for a given Login ( no expiry )

Step 2. Teller Initiated Debit

POST 'http://stark-teller-qa-002.app.qa.olamoney.net/teller/v1/payment/teller/initiateDebit'
Host: stark-teller-qa-002.app.qa.olamoney.net
Content-Type: application/json
Authorization: Bearer <Access_token>
Body :

{
  "payCode": "2522737",
  "amount": 10,
  "transactionId": "112112",
  "content": {}
}

Incase response is of type 401 ( UnAuthorized , please call the below API to refresh the Access Token )
Once Refresh is complete , use the new AccessToken with the above transaction.

Step 3. Teller Refresh Token ( Refresh the Access_Token sent in Login )

POST 'http://stark-teller-qa-002.app.qa.olamoney.net/teller/v1/refreshToken'
Host: stark-teller-qa-002.app.qa.olamoney.net
Content-Type: application/json
Authorization: Bearer <Access_token>
Body :

{
    "access_token": "6db19673-f64f-409d-9aa9-d412ebbd9e99",
    "refresh_token": "3a70f6aa3f644be4a22c13a3ee1b1fec"
}

Introduction to Merchant Reward Points

 

What is merchant reward points?

Merchant gives loyalty points to its customers.Merchant can convert these loyalty points into Ola money but to use that they need to put prepaid money with Ola.While they redeem the loyalty point respective amount will be deducted from that available balance.
Using this reward point feature they can convert their reward points into Ola Money, get their available prepaid balance and even check their redeem transaction details. With the redeem API you can add money to a user’s Ola Money wallet with their mobile number.

Step 1: Buy reward points

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in
curl --request POST \
  --url https://sandbox.olamoney.in/
var request = require("request");

var options = { method: 'POST', url: 'https://sandbox.olamoney.in/' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

Try the API to see results
 

Merchant has to pay the amount to the finance team to buy the reward points.
Once we receive the amount, we will credit the amount to your merchant account.
You can check the available credit balance at any point of time using the API in step 2.

Step 2: Check your Available prepaid balance

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/rewardpoints/balance
{
  "command": "reward_point_query",
  "accessToken": "merchant_access_token",
  "hash": "8ee7189ee2ee02867705098aee4b8a94c47f56e69b2668cf71bd98bdb30cb0dc35d4e9dd91658731bbecc8f39d8197a2a099b1c54522ca904a48e85ac1d70fbc"
}
A binary file was returned

You couldn't be authenticated

{
  "type": "reward_point",
  "status": "success",
  "externalMerchantId": "RUM863",
  "amount": "2000.00",
  "hash": "423c733d80f80c04d54f6a5a6e5fde7c4ebb9af23cbff93781072eb67965f3baa75e2d1029581449c83c410fd85afc8e63f30c59262e266c5864409156ad7fb3",
  "timestamp": 1470207751431
}
{
  "errorCode": "hash_mismatch",
  "message": "Hash verification failed",
  "status": "error"
}
 

Merchant can check their available balance in their prepaid account that they can use for redeeming the user's reward point.
Send http POST request with the JSON body .

{
  "command": "reward_point_query",
  "accessToken": "merchant_access_token",
  "hash": "8ee7189ee2ee02867705098aee4b8a94c47f56e69b2668cf71bd98bdb30cb0dc35d4e9dd91658731bbecc8f39d8197a2a099b1c54522ca904a48e85ac1d70fbc"
}
hash=sha512('merchant_access_token|reward_point_query|<SALT>');

Step 3: Validate Before Redeeming Amount

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/rewardpoints/validatecredit
{
 "command": "reward_point",
 "accessToken": "ola_access_token",
 "amount": "10.01",
 "currency": "INR",
 "mobile": "9999999999",
 "hash": "d2616084511420a576b777fa0d3eeba4781c65f2150d73844d9ad30e5d681bd6761c4b11daeb530a0881d76ba8436f4d5d74951fb354ac3856e535982955c706"
}
A binary file was returned

You couldn't be authenticated


{
  "status": "success"
}
{
  "status": "FAILED"
}
{
  "errorCode": "invalid_command",
  "message": "Hash Mismatch",
  "status": "error"
}
 

Merchants may end up debiting amount from user's bank but redeem transaction may fail. Before proceeding to actually redeeming or crediting amount let us figure out whether the transaction may get succeeded or failed. This is achieved through Validate API. This API helps Merchants to debit user's amount only in case of success response.

Validate API , helps the merchant to know in advance whether the redeem transaction fulfils all constraints to get succeeded from our end. It can be either success or failure.
Failure cases may be due to monthly limit breach, invalid user, blocked user or rate limiting factors.
Redeem instructions are given in next step.

Validate POST request needs Basic Authentication and Application/JSON headers.

{
 "command": "reward_point",
 "accessToken": "ola_access_token",
 "amount": "10.01",// Always in 2 decimals
 "currency": "INR",
 "mobile": "9999999999",
 "hash": "d2616084511420a576b777fa0d3eeba4781c65f2150d73844d9ad30e5d681bd6761c4b11daeb530a0881d76ba8436f4d5d74951fb354ac3856e535982955c706"
}

Hash for the validate API is calculated as follows.

hash=sha512('<Merchant access token>|reward_point|INR|9999999999|10.01|<salt>');

Step 4: Redeem Reward Points

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/rewardpoints/redeem
{
  "command": "reward_point",
  "accessToken": "merchant_access_token",
  "uniqueId": "ttab988977",
  "comments": "string",
  "udf": "string",
  "hash": "string",
  "returnUrl": "string",
  "notificationUrl": "string",
  "amount": "50.00",
  "balanceType": "cash",
  "balanceName": "string",
  "currency": "INR",
  "mobile": "9999999999",
  "agentId": "string"// Anything but not null
}
A binary file was returned

You couldn't be authenticated


{
  "type": "credit",
  "status": "success",
  "transactionId": "c7t8-9pqv-5rgj",
  "merchantBillId": "ttab988977",
  "amount": "50.00",
  "hash": "459c9a3e65e3d6589f483f3663f1c7fb26845623500c80ac8eea42ee342ab4f1aa9ece6d5028ce9f0383ca813ae3675dda1999c25b75e34dec1cce4f976ec5c5",
  "timestamp": 1470153253189,
  "comments": "string",
  "udf": "udf"
}
{
  "errorCode": "hash_mismatch",
  "message": "Hash verification failed",
  "status": "error"
}
 

Allow your users to convert their reward points into Ola Money with this redeem API. With the redeem API you can add money to a user’s Ola Money wallet with their mobile number.

In order to use this API you must prepay a certain amount to Ola Money. Every time you credit Ola Money to a user, the amount is deducted from your prepaid balance.

As you get closer to exhausting your prepaid balance, you will receive an email with instructions to recharge your prepaid balance.
Send http POST request with the JSON body .

Basic Authentication key is required for this API.
POST call to Redeem API with headers "Authorization": "Basic Auth" and "Content-Type": "application/json"

{
  "command": "reward_point",
  "accessToken": "merchant_access_token",
  "uniqueId": "uniqueId",
  "comments": "redeem 50 reward points",
  "udf": "udf",
  "hash": "f85798463bd0b7a32aa6ce9952b3db87a0e82ca19ef13b6696df758a0071389c130b4937e086656404d3edc4a39090b5c7fe86dc3857ec4afa5fcd4fa09821c3",
  "returnUrl": "returnUrl",
  "notificationUrl": "notificationUrl",
  "amount": "50.00",
  "balanceType": "cash",
  "balanceName": "cash",
  "currency": "INR",
  "mobile": "9999999999",
  "agentId": "123"
}
hash=sha512('merchant_access_token|uniqueId|redeem 50 reward points|udf|returnUrl|notificationUrl|INR|50.00|cash|cash|9999999999|<SALT>');

Step 5: Check redeem transaction details

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/rewardpoints/query
{
  "command": "reward_point_query",
  "accessToken": "merchan_access_token",
  "uniqueId": "UniqueBillId",
  "hash": "4382fec90203cff78d18a627a1512a84dc718a493cb2c9555ad777197d2a029c14ba555a0dafad1c617b45f504029e31c2883fb0058ba252bc9226f58a2b6926"
}
A binary file was returned

You couldn't be authenticated


{
  "type": "reward_point",
  "status": "completed",
  "uniqueBillId": "UniqueBillId",
  "externalMerchantId": "RUM863",
  "amount": "13.30",
  "udf": "udf",
  "hash": "fba2648df13f38df743f5a05a3d69c8a809af8d3730c404294d0e04033ad1c7492e6c780b8d47409f780b97090b900d889f69d147cc1465f9ee88439661fb143",
  "timestamp": 1470161314078
}
{
  "errorCode": "hash_mismatch",
  "message": "Hash verification failed",
  "status": "error"
}
 

This API allow merchant to view their redeem transaction so that they can check the status and other details of the transaction.
Send http POST request with the JSON body .

{
  "command": "reward_point_query",
  "accessToken": "merchan_access_token",
  "uniqueId": "UniqueBillId",
  "hash": "4382fec90203cff78d18a627a1512a84dc718a493cb2c9555ad777197d2a029c14ba555a0dafad1c617b45f504029e31c2883fb0058ba252bc9226f58a2b6926"
}
hash=sha512('merchant_access_token|UniqueBillId|reward_point_query|<SALT>');

Introduction

This page outlines the deep integration of Ola Money wallet with your checkout

 

What is Auto Debit?

Auto debit feature allows your customers to deep link his Ola Money wallet to his account. Once the customer link the wallet to your account, it will allow you to debit your customer account for the services you provided without customer authenticating the payment. This feature helps your business grow by providing a great payment experience to your customers.

Auto debit

Its recommended that Auto debit flow should be used only after user has completed merchant authentication i.e only once the user has logged in on the merchant platform.

Agreement

The usage of this flow should be mutually agreed between the merchant and OLA money teams since this flows would require certain technical approach agreements.

Integration guide - Auto Debit

This page outlines the deep integration of Ola Money wallet with your checkout

 

To link a user wallet with his account , merchant need to call addUserWallet API with phone number and emailId. Note that in case the user does not exists with Olamoney, a new user account is signed up with Ola money account. On below API call user will receive a OTP

Merchant needs to render OTP page for the user to enter this OTP.
Followed by linkUserWallet API call Step 2.

Step 1: Call addUserWallet API

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/userWallet/addUserWallet
{
	"phoneNumber":"9999999999",
	"email":"test@mail.com"
}
A binary file was returned

You couldn't be authenticated

{ 
"status": "success", 
"message": "" 
}
{
 "status": "FAILED",
 "message": "User wallet already added"
}

Query Params

phone
string

User's Phone number

email
string

user's Email

Body Params

phoneNumber
string
email
string
 

To link a user wallet with his account , merchant need to call addUserWallet API with phone number and emailId.

Note that in case the user does not exists with Olamoney, a new user account is signed up with Ola money account. On below API call user will receive a OTP

Merchant needs to render OTP page for the user to enter this OTP.
Followed by linkUserWallet API call Step 2.

POST CALL to addUserWallet API with headers set as "Authorization":Basic Auth and "Content-Type":application/json

AddUserWallet option

  1. You should not allow guest users to add ola money wallet
  2. Render the email id and phone number using which user has been signed in on merchant app.

Step 2 : Call linkUserWallet API

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/userWallet/linkUserWallet?phone=phone&otp=:otp
curl --request POST \
  --url 'https://sandbox.olamoney.in/olamoney/v1/userWallet/linkUserWallet?otp=%3Aotp&phone=phone'
var request = require("request");

var options = { method: 'POST',
  url: 'https://sandbox.olamoney.in/olamoney/v1/userWallet/linkUserWallet',
  qs: { otp: ':otp', phone: 'phone' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v1/userWallet/linkUserWallet?otp=%3Aotp&phone=phone")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/olamoney/v1/userWallet/linkUserWallet?otp=%3Aotp&phone=phone");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v1/userWallet/linkUserWallet"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

{ 
"status": "success", 
"message": "", 
"accessToken": "1938ee1a-df6c-4562-b378-c713434b9f1a", 
"refreshToken": "619186e816a14c65912d7d7126b2fc66” 
}
{
 "status": "FAILED",
 "message": "Invalid OTP",
 "accessToken": "",
 "refreshToken": ""
}

Query Params

phone
string

User Phone Number

OTP
string

user OTP

 

With OTP from the customer and his phone number make another POST call

Above two steps are mandatory for the new customer.After that Merchant needs to store accessToken and refreshToken generated at their end for every user.

NOTE : accessToken expiry time is 8 hour,refresh token expiry time is 6 month.

If the token is expired you need to call the refresh API explained in next step.

Note : Merchant need to persist access token and refresh token on their side and send then to Ola as and when required by the other API - autoDebit, delinkUserWallet, userBalance etc.

What if you lose user access token ?

In case merchant fails to persist access token and refresh token user, then step 1 and step 2 has to be repeated for that particular user.

Step 3. Call refresh API (If any token is expired)

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/userWallet/refresh
curl --request POST \
  --url https://sandbox.olamoney.in/olamoney/v1/userWallet/refresh
var request = require("request");

var options = { method: 'POST',
  url: 'https://sandbox.olamoney.in/olamoney/v1/userWallet/refresh' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v1/userWallet/refresh")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/olamoney/v1/userWallet/refresh");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v1/userWallet/refresh"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "status": "success",
  "refreshSessionResponse": {
    "access_token": "8e6e3f70-b6a9-4984-9372-b51326895f04",
    "access_token_expiry": 9223372036854775807,
    "access_token_expiry_from_now": 9223372036854775807
  },
  "message": ""
}
{
  "errorCode": "unknown_error",
  "message": "Something went wrong!!",
  "status": "error"
}

Query Params

accessToken
string

user access token

refreshToken
string

user refresh token

 

When access token for the user is expired, call POST with the given JSON

with headers set as "Authorization" and "Content-Type" as Basic Auth and application/json respectively.

{
 "accessToken":"8e6e3f70-b6a9-4984-9372-v51326895f04",
 "refreshToken":"ae831906-d3ca-4c33-8dba-7bc8ae9aafe6"
}

Step 4: Call userBalance API

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/userBalance
curl --request POST \
  --url https://sandbox.olamoney.in/olamoney/v1/userBalance
var request = require("request");

var options = { method: 'POST',
  url: 'https://sandbox.olamoney.in/olamoney/v1/userBalance' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v1/userBalance")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/olamoney/v1/userBalance");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v1/userBalance"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "status": "success",
  "comments": "string",
  "amount": 0,
  "balanceType": "string”
}
{
  "status": "error",
  "comments": "Invalid user access token",
  "amount": 0,
  "balanceType": null
}

Query Params

userAccessToken
string

user' access token for the one, you want to check the balance

 

Once the tokens are generated , call the balance API to check the user has the sufficient balance or not.

Headers :
Authorization : Basic Auth
Content-Type: application/json

Request Payload specified below

{"userAccessToken":"8e6e3f70-b6a9-4984-9372-b51326895f04"}

Step 5. Call autoDebit API

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/autoDebit
{
  "command": "debit",
  "accessToken": "string",
  "uniqueId": "string",
  "comments": "string",
  "udf": "string",
  "hash": "string",
  "returnUrl": "string",
  "notificationUrl": "string",
  "amount": 10.00,
  "currency": "string",
  "couponCode": "NA",
  "userAccessToken": "string"
}
A binary file was returned

You couldn't be authenticated

{
  "type": "debit",
  "status": "string",
  "transactionId": "string",
  "merchantBillId": "string",
  "amount": "string",
  "hash": "string",
  "timestamp": 1472024600672,
  "comments": "string",
  "udf": "string",
  "isCashbackSuccessful": "string",
  "isCashbackAttempted": "string”
}

Body Params

command
string

It will be "debit"

accessToken
string

Merchant access token.

comments
string

Comments for the transaction - Mandatory

udf
string

To be provided by you - Mandatory

hash
string

SHA 512 of given string explained below

returnUrl
string
notificationUrl
string
amount
string

It should be in two decimal

currency
string

INR

couponCode
string

For any running offers other wise you have to pass it as "NA"

userAccessToken
string

Token of the user for whom you want to make the debit

 

command - This will be ‘debit’ for a charge transaction.

accessToken - An unique key using which Ola identifies the merchant.

uniqueId - A unique transaction ID provided by merchant. The generation of uniqueId completely lies with you.

amount - Amount for which you wish to charge the customer.Upto two decimal and same value has to be passed in hash as well.

udf - user defined fields significant to merchants.

currency - currency of the payment made.

notificationurl - this is a url hosted on merchant server where we post the details of the transaction after the transaction is complete. This is a server to server call.

return_url - this is a url hosted on merchant server where we redirect the user after the transaction is complete. This redirect happens in your web-view. (In case of in-app payments, there is no redirect and return_url is ignored.)

CouponCode - This is a coupon code that Ola Money team can generate for running cashback offers. If you pass this, then the user will get the appropriate cashback, if you don't it you can just pass any param such as "NA".

userAccessToken - Generated at Step 2. If the token is expired repeat step 3 and pass the newly generated accessToken.

{
  "command": "debit",
  "accessToken": "string",
  "uniqueId": "string",
  "comments": "string",
  "udf": "string",
  "hash": "string",
  "returnUrl": "string",
  "notificationUrl": "string",
  "amount": 10.00,
  "currency": "string",
  "couponCode": "NA",
  "userAccessToken": "string"
}

HASH GENERATION

You need to generate a hash, in the following format, using SHA-512:
hash = sha512('access_token|uniqueId|comments|udf|returnUrl|notificationUrl|currency|amount|useracessToken|couponCode|salt')

Step 6 . Call delinkUserWallet

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/userWallet/delinkUserWallet
curl --request POST \
  --url https://sandbox.olamoney.in/olamoney/v1/userWallet/delinkUserWallet
var request = require("request");

var options = { method: 'POST',
  url: 'https://sandbox.olamoney.in/olamoney/v1/userWallet/delinkUserWallet' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v1/userWallet/delinkUserWallet")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/olamoney/v1/userWallet/delinkUserWallet");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v1/userWallet/delinkUserWallet"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated


{
  "status": "string",
  "message": "string"
}

{
 "status": "FAILED",
 "message": "Invalid phone number"
}

Body Params

phoneNumber
string

user phone number

refreshToken
string

refresh token of the user

 

Finally when user want to delink from the merchant, call the delinkUserWallet with given JSON post

Headers :
Authorization : Basic Auth
Content-Type: application/json

{
  "phoneNumber": "8989898989",
  "refreshToken": "23c16592-7d1c-4178-9b51-b443fea8010d"
}

In Case of Insufficient Balance- Web

 

You can user userBalance API to check the user balance beforehand before proceeding to payment.
In case user does not have sufficient balance , webview will be rendered for the user , from there user can recharge its ola money wallet

Step 1. WebView - Wallet Recharge (Credit) Payload

Merchant first need to generate a JSON credit payload for the required amount, as shown below.

{
"command":"credit",
"accessToken":"MerchantAccessToken",
" merchantReferenceId ":"XCd54def32",
"comments":"tX9EY",
"udf":"Ip63u",
"hash":"85f4fe6f19bef13135936565c0a32787a3f6b0acf81167a0a8ef639c256a94caab96725ef040155b5be121f130284cbfdee2f91d44d771d12dc6fe084360989b",
"returnUrl":"http://localhost:8080/olamoney/dummy_return",
"notificationUrl":"http://localhost:8080/olamoney/dummy_return",
"amount":"1.00",// amount should be upto two decimal same has to be pass in hash
"userAccessToken":"e9c6956d-efcd-4cc6-a6d5-38888fc4e50a",
"currency":"INR",
"balanceType":"cash",
"balanceName":"cash"
}

DETAILS:

command - This will be ‘credit’ for a load money transaction.

accessToken - An unique key using which Ola identifies the merchant.

merchantReferenceId - A unique transaction ID provided by merchant. The generation of uniqueId completely lies with you.

amount - Required amount to be loaded for the payment of transaction.

udf - user defined fields significant to merchants.

currency - currency of the payment made.

notificationUrl - this is a url hosted on merchant server where we post the details of the transaction after the transaction is complete. This is a server to server call.

return_url - this is a url hosted on merchant server where we redirect the user after the transaction is complete. This redirect happens in your web-view. (In case of in-app payments, there is no redirect and return_url is ignored.)

userAcessToken – which you have stored at your end, generated from the linkUserWallet API

HASH GENERATION

hash= sha512('access_token|merchantReferenceId|comments|udf|returnUrl|notificationUrl|currency|amount|userAccessToken|salt'); // All the params are mandatory

Step 2. Base64 Encode the Credit Payload

Merchant need to Base65 encode the JSON created at Step 1.

After Base64 encoding the it will look like =>

eyJjb21tYW5kIjoiY3JlZGl0IiwNCiJhY2Nlc3NUb2tlbiI6Ik1lcmNoYW50QWNjZXNzVG9rZW4iLA0KIiBtZXJjaGFudFJlZmVyZW5jZUlkICI6IlhDZDU0ZGVmMzIiLA0KImNvbW1lbnRzIjoidFg5RVkiLA0KInVkZiI6IklwNjN1IiwNCiJoYXNoIjoiODVmNGZlNmYxOWJlZjEzMTM1OTM2NTY1YzBhMzI3ODdhM2Y2YjBhY2Y4MTE2N2EwYThlZjYzOWMyNTZhOTRjYWFiOTY3MjVlZjA0MDE1NWI1YmUxMjFmMTMwMjg0Y2JmZGVlMmY5MWQ0NGQ3NzFkMTJkYzZmZTA4NDM2MDk4OWIiLA0KInJldHVyblVybCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9vbGFtb25leS9kdW1teV9yZXR1cm4iLA0KIm5vdGlmaWNhdGlvblVybCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9vbGFtb25leS9kdW1teV9yZXR1cm4iLA0KImFtb3VudCI6IjEuMDAiLA0KInVzZXJBY2Nlc3NUb2tlbiI6ImU5YzY5NTZkLWVmY2QtNGNjNi1hNmQ1LTM4ODg4ZmM0ZTUwYSIsDQoiY3VycmVuY3kiOiJJTlIifQ0K

STEP 3. OPEN THE FOLLOWING URL ALONG WITH BILL

https://sandbox.olamoney.in/olamoney/webview/index.html?bill=<Base64bill>

Once the user redirects after the above webview flow to the returnURL you have provided. Use the below API (Verify Load Money) to check the status of the transaction and accordingly you can display the status to the user.

In Case of Insufficient Balance - Android

 

Step 1 Wallet Recharge(Credit) in Android app

To launch the webview following is the code snippet =>

The payload that you have generated in STEP 1 "Wallet Recharge (Credit) Payload" has to be passed below.

StringBuffer buffer=new StringBuffer("https://sandbox.olamoney.in/olamoney/webview/index.html");
String base64_bill = Base64.encodeToString(bill.getBytes(), Base64.DEFAULT); 
buffer.append("?bill="+base64_bill); 
webview.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl(buffer.toString());

Step 2. TO GET BACK TO YOUR APP

STEP 1: DECLARE A JAVASCRIPT INTERFACE FOR YOUR WEB-VIEW

interface OlaMoneyInteface {
 @android.webkit.JavascriptInterface
 void onPaymentDone(String jsonResponse); }

STEP 2: ADD THIS JAVASCRIPT INTERFACE TO THE WEBVIEW:

webView.addJavascriptInterface(new OlaMoneyInteface() { @Override 
@android.webkit.JavascriptInterface 
public void onPaymentDone(String jsonResponse) 
{ /*Control is returned to the native code   You can get the data in jsonResponse */ } }, "OlaMoney");

STEP 3: MODIFY PROGUARD CONFIGURATION (OPTIONAL)

If you are using proguard, then you need to add the following line to your proguard configuration file:

-keepclassmembers class * {  @android.webkit.JavascriptInterface <methods>; }

STEP 4: HANDLE RETURN_URL

We will send data to the return_url specified in your bill, and you should invoke the function send_user_native in your javascript once you get the data received from Ola Money, as below:

<script type="text/javascript">     function send_user_native(data) {         OlaMoney.onPaymentDone(data);      } </script>

Verify Load Money

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/verifyloadmoney?merchantReferenceId=id
curl --request POST \
  --url 'https://sandbox.olamoney.in/olamoney/v1/verifyloadmoney?merchantReferenceId=id'
var request = require("request");

var options = { method: 'POST',
  url: 'https://sandbox.olamoney.in/olamoney/v1/verifyloadmoney',
  qs: { merchantReferenceId: 'id' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v1/verifyloadmoney?merchantReferenceId=id")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/olamoney/v1/verifyloadmoney?merchantReferenceId=id");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v1/verifyloadmoney"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated


{
 "status": "completed",
 "amount": 100,
 "created_at": 1464879700000,
 "merchantTransactionId": "kDbTc",
 "transaction": "c79j-anu0-5iua"
}

Query Params

id
string

merchantReferenceId is the unique id provided during recharge (credit) payload.

 

Merchant can verify the status of wallet recharge done by the user from merchant app in order to display proper message to the end user.

Below is the Verify API =>

POST CALL
Headers :
Authorization : Basic Auth
Content Type : application/json

v2/refund

 
posthttps://sandbox.olamoney.in/olamoney/v2/refund
curl --request POST \
  --url https://sandbox.olamoney.in/olamoney/v2/refund
var request = require("request");

var options = { method: 'POST',
  url: 'https://sandbox.olamoney.in/olamoney/v2/refund' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v2/refund")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://sandbox.olamoney.in/olamoney/v2/refund");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v2/refund"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
 "type":"refund",
 "status":"success",
 "transactionId":"bgho-5bot-ne16",
 "merchantBillId":"cd1501ce-a88e-4654-898d-8b2a266bc467",
 "amount":"20.00",
 "hash":"d1880d064c17db0121645f7c4492176dafa24a25c168d1a045bc46ee2521156c845ebeba2005a487d76d23e47178b7aedd238db2130aab1fb9cca00dbd9294e9",
 "timestamp":1439473847354,
 "comments":"test",
 "udf":"test"
}
{
  "message": "Invalid parameters",
  "status": "error"
}
 

You need to post a JSON in the body to make this work. A sample JSON is below:

{
   "command": "refund",
   "accessToken": "ola_access_token",
   "uniqueId": "7c9f7b95-0f43-4028-9e01-3126b58b61d4", (new one merchant has to generate for the refund txn)
   "comments": "test",
   "udf": "test",
   "hash": "10b4ba7039136ecb5246c4107b4eb124f0462c1dbb9a5fdaaa160d9a143385ecdc17c88047f8d23bc4e5544a719822949a685b1d37132da0ba510f9aa35cb178",
   "returnUrl": "test",
   "notificationUrl": "test",
   "amount": "20.00",//Always in 2 decimals
   "balanceType": "cash",
   "balanceName": "cash",
   "saleId": "4cd39a6a-afda-4b45-9a66-653325aad744", (original parent txn id)
   "currency": "INR"
}

where the hash is computed as follows:

hash_string = 'accessToken|uniqueId|comments|udf|returnUrl|notificationUrl|currency|amount|balanceType|balanceName|saleId|salt';

hash = sha512(hash_string);

/enquiry

 
gethttps://sandbox.olamoney.in/olamoney/v2/query?uniqueBillId=uniqueBillId&accessToken=accessToken&timestamp=timestamp&hash=hash
curl --request GET \
  --url 'https://sandbox.olamoney.in/olamoney/v2/query?hash=hash&timestamp=timestamp&accessToken=accessToken&uniqueBillId=uniqueBillId'
var request = require("request");

var options = { method: 'GET',
  url: 'https://sandbox.olamoney.in/olamoney/v2/query',
  qs: 
   { hash: 'hash',
     timestamp: 'timestamp',
     accessToken: 'accessToken',
     uniqueBillId: 'uniqueBillId' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://sandbox.olamoney.in/olamoney/v2/query?hash=hash&timestamp=timestamp&accessToken=accessToken&uniqueBillId=uniqueBillId")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://sandbox.olamoney.in/olamoney/v2/query?hash=hash&timestamp=timestamp&accessToken=accessToken&uniqueBillId=uniqueBillId");

xhr.send(data);
import requests

url = "https://sandbox.olamoney.in/olamoney/v2/query"

response = requests.request("GET", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
  "status": "completed",
  "uniqueBillId": "xyz",
  "merchantDetails": "ola money cashback",
  "amount": "10.00",
  "createdAt": 1454583091000,
  "type": "debit",
  "comments": "ola money cashback for coupon MIN10CR",
  "udf": "ola money cashback for coupon MIN10CR",
  "globalMerchantId": "c66c-cwoc-or8p"
}
{
    "errorCode": "stale_query",
    "message": "Invalid timestamp",
    "status": "error"
}

Path Params

uniqueBillId
string
required

saleId (uniqueBillId of the transaction already happened/initiated)

accessToken
string
required

accessToken of the merchant

timestamp
string
required

current timestamp of your system in the form of YYYY-MM-DD HH MM SS e.g. 2015-08-13 13:17:12

hash
string
required

sha512('access_token|uniqueBillId||timestamp|||merchant_salt')

 

Introduction

 

This page refers to all the Api's used in Offline Flow as explained here

MPIN FLOW

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/payment/initiateDebit
{
    "command": "debit",
    "accessToken": "ola_access_token",
    "uniqueId": "7820d4d0-bb16-434e-9f95-0e21c76d11d6",
    "comments": "Test Comment",
    "udf": "Test User",
    "hash": "a8ead1805535143a743381339063cbe6d73ba47f51092e282aacff3a924ada8371e5f9b5d00b32a6a3465ca4df7929bd8bc5de4b01ef4b10feb9f15ed562280f",
    "returnUrl": "http://localhost:1251/return",
    "notificationUrl": "http://localhost:1251/notify",
    "amount": "10.00",
    "currency": "INR",
    "payCode": "0116042",
    "couponCode": "ABC"
}
A binary file was returned

You couldn't be authenticated

{
    "type": "debit",
    "status": "success",
    "transactionId": "c725-713m-fu9i",
    "merchantBillId": "7820d4d0-bb16-434e-9f95-0e21c76d11d6",
    "amount": "10.00",
    "hash": "dc1c30a259eb0cc6deebf0eb217487830140a36ba9a171579fb87beff88d2da75609346ec4164af0c1f79ddfc0ec07f23f550f49028d63cf8662c44732bb4d2a",
    "timestamp": "1464336120023",
    "comments": "Test Comment",
    "udf": "Test User",
    "isCashbackSuccessful": "false",
    "isCashbackAttempted": "true",
    "sdf": "{\"phone\":\"7204477564\"}"
}
{
  "status": "string",
  "message": "string",
  "errorCode": "string"
}

Headers

Authorization
string

Basic Auth : We will be providing this to you

 

You need to post a JSON in the body to make this work. A sample JSON is below:

{
  "command": "debit",
  "accessToken": "string",
  "uniqueId": "string",
  "comments": "string",
  "udf": "string",
  "hash": "string",
  "returnUrl": "string",
  "notificationUrl": "string",
  "amount": "100.00",
  "currency": "string",
  "payCode": "string",
  "couponCode": "string"
}

where the hash is computed as follows:

hash_string = 'accessToken|uniqueId|comments|udf|returnUrl|notificationUrl|currency|amount|payCode|couponCode|salt'
hash = sha512(hash_string);

Hash Validation for received Response

You need to calculate hash using the received parameters from the response. Only then you need to check the status of response whether success or failed. If hash you generated and received don't match, straight away reject the response.

data_string =  'type|status|merchantBillId|transactionId|amount|comments|udf|isCashbackAttempted|isCashbackSuccessful|timestamp|sdf|salt'; 
merchant_hash = sha512(data_string);

Introduction to Ola-Money Postpaid Autodebit

One click experience of Ola Money(Postpaid + Wallet)

 

What is Postpaid Auto Debit?

Auto-debit flow enable you to debit user , on one click concept.
Only for the first time user has to go through OTP validation. Thats handled completely from our end. From next time onwards, since he is linked to your merchant_id, you can directly debit from user account on one click.

Caution

Its recommended to allow only your registered logged in users to use ola money payment. Guest users are not recommended for this flow.

Agreement

The usage of this flow should be mutually agreed between the merchant and OLA money teams since this flows would require certain technical approach agreements.

Implementation Model:

Recommended to store user access details against your customer Id.

 

How should you store User Access Details?

Its advised to map user details sent by us along with mobile number to your internal customer ID.
First refer your customer id if you have already stored user access tokens. If you have access access token and mobile-number against your customer id, it implies user is linked to your merchant_id. You can use them to debit. (Refresh before using)

If you don't find user access details against your customer id, (i.e User not linked to your merchant id) you can send empty userAccessToken.
We will give you call back response with his user access details, mobile number, unique transaction id. The unique id will help you in getting the user to whom the transaction belongs. Once you identify user (customer Id) , you can store the access details , mobile-number against customer id.

Ex: Let your customer id be 1234222 and his mobile number be 9999999999 and transaction id be txn1234. We would send you user access token and refresh token, mobile, transaction id on successful linking. You can get customer Id based on your transaction id txn1234 (i.e 1234222).
Then you can map these user details to customer Id.
1234222 , 9999999999, UserAccessToken, refreshToken.

Note:

Always fetch userAccessToken based on your customer id not based on Mobile Number. You can get your customer Id , based on your unique transaction id sent by us to your publicly accessible linkNotifUrl.

Eligibility API

This API should be used by merchant for understanding whether user can complete this transaction in one click. API returns true when Ola Money Wallet + Postpaid balance is >= transaction amount. When the API returns false, user can still complete his payment by loading money in his Ola Money Wallet or by clearing postpaid dues (This feature is coming soon). You can post debit request even in if eligibility is false.

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/postpaid/eligibility
{  "user_info":{"mobile_number":"string","email":"string","first_name":"string","last_name":"string"},
    
   "transaction_details":{"amount":10.00,"denomination":"rupee","currency":"INR"},
  
   "source":"string",
  
   "hash":"string",
  
   "unique_eligibility_id":"string"
}
A binary file was returned

You couldn't be authenticated

{
    "eligibility" : {
        "eligible" : true/false,
        "status_code" : "XXX",
        "message" : "string"
    },
    "transaction_split" : [
        {
            "source" : "postpaid",
            "display_name" : "Ola Postpaid",
            "amount" : 100.0,        //in rupee
            "display" : true/false,        //Boolean, whether to display or not
        },
        {
            "source" : "wallet",
            "display_name" : "Wallet",
            "amount" : 100.0,        //in rupee
            "display" : true/false,        //Boolean, whether to display or not
        }
    ],
    "hash" : "string",  //SHA512(eligible|status_code|message|unique_response_id|salt)
    "request_id" : "string"
}
{
    "eligibility": {
        "eligible": false,
        "status_code": "OC_011",
        "message": "User not found for mobile number"
    },
    "hash": "86b0259ae8c668b67d636157f023f47cb5908616b4675118d0b4bd924a412ceed8f7a47ef8824669b2892550298f20f0be97b74793bb7e5c3188a08a21b2ef64",
    "unique_response_id": "7caefede-ba83-43e2-b94f-bda982260117"
}

Headers

Authorization
string
 

Request body details

Mandatory params -

mobile_number (String) : Mobile number of the user for which eligibility is being requested.

first_name (String) : Name of the user for which eligibility is being requested.

amount (Double) : Transaction Amount(Always in 2 decimals).

source (String) : Merchant name.

hash (String) : Unique string.

unique_eligibility_id( String) : Unique value for each request

Non mandatory params -

email (String) : Email of the user for which eligibility is being requested.

denomination (String): Default value "rupee". Currently only "rupee" denomination is supported.

currency (String) : Default value "INR". Currently only "INR" currency is supported.

last_name (String) : Last name of the user for which eligibility is being requested.

Authorization Header: Basic Auth key of merchant which will be provided

In case of successful eligibility of the user for the amount requested, transaction split will provide the split of amount used from Ola Money wallet and Ola Postpaid for the requested amount.

Hash Generation Logic:

Request Hash Generation:

SHA512('mobile|email|first_name|last_name|amount|source|unique_eligibility_id|salt')
  
Response Hash Generation:
Validate the hash before checking response:
SHA512('eligible|status_code|message|unique_response_id|salt')

Response Status codes :

Code
Status
Eligible
Error Details

OC_000

Success

true

OC_010

Success

false

insufficient funds

OC_011

Success

false

user not found

OC_012

Success

false

postpaid not available

OC_020

Failure

false

bad request, missing parameter

OC_021

Failure

false

hash mismatch

OC_022

Failure

false

server error

OC_030

Failure

false

merchant not enabled

Debit

On the merchant payment page, when user clicks on Ola Money (Postpaid + Wallet) icon, merchant should pass the below parameters while opening a browser as post params in body.

 

Post following form data to URL https://sandbox.olamoney.in/credit-app/postpaid

signature=<Digitally Signed uniqueId with Merchant private key>
command="debit"
accessToken=<"sandbox merchant token credential">
uniqueId=<unique_request_id>
comments=<string>
udf=<string>
hash=<hash value>
returnUrl=<redirect webpage url>
notificationUrl=<s2s debit notification url>
linkNotifUrl=<s2s user-merchant link url>
amount=<transaction amount in 2 decimals>
currency="INR"
userAccessToken=<user_access_token>
mobile=<user_phone_number>
email=<user_mail>
balancePreference="preferConfig"
couponCode="NA"

Note:

For the first time user, you have to send empty userAccessToken. Once user is linked we will debit amount and also we will send his userAccessToken and refreshToken to linkNotifUrl.

For his next debit you have to refresh userAccessToken and send it in below request. Else debit will be failed as we don't have userAccessToken or we have expired userAccessToken.

Web form Request details

signature : This is the digitally signed text using RSA ("SHA1WithRSA") and 2048 length key. The merchant will generate the key pair and sign the uniqueId with the private key. We in turn verify the same with public key for verification.

command : It must be "debit"

accessToken : This is the access token of the merchant.

uniqueId : generated by the merchant for the transaction.

comments : Comment to be sent for the transaction.

udf : Optional Message

amount: Transaction amount in 2 decimals (Rs)

hash : The hash generated in the same way as previous debits.

returnUrl : {the redirect page once transaction is done} mandatory field

linkNotifUrl= Provide s2s callback URL, so that we can post user access details to this URL

notificationUrl : {the link where s2s call will be made for the debit response} mandatory filed

currency : currency denomination (INR).

userAccessToken : The merchant user linking access token.

balancePreference : Value to be sent is "preferConfig". Accepted Values={walletOnly, olaCreditOnly, preferWallet, preferOlaCredit, cardOnly,custom, preferConfig}

mobile : It should contain the phone number of the user.

email=<user_mail> (Optional - Send Empty String)

couponCode: "NA" (Note: If we are running offers with you, we will let you know coupon code to be passed in request. Else you have to send "NA" as couponCode)

Request Hash Generation is as below:

sha512('accessToken|uniqueId|comments|udf|returnUrl|notificationUrl|currency|amount|couponCode|<balancePreference>|salt')

Amount should be in 2 decimals

NOTE: If you are integrating Sub-merchant flow, then use below hash-string

sha512('AccessToken|uniqueId|comments|udf|returnUrl|notificationUrl|currency|amount|couponCode|subEntityName|subEntityId|balancePreference|salt')

When we send User linking callback and debit callback?

Once the parameters are passed, we check whether user is linked to your merchant or not. If it is the first transaction (i.e. merchant & user are not linked) OTP flow is triggered. OTP sent on the mobile number passed & user is supposed to enter the OTP. Once 'Activate & Pay' is clicked by user (post entering the OTP) - OTP is verified.
1st time user :

  1. merchant & user are linked in our system
  2. Accesstoken & refresh token are sent to linkNotifUrl as callback response
  3. Our system will internally call debit api and debit callback response is sent to notificationUrl.

Linked User:
After first transaction of a user,user is linked to your merchant_id. From next time when parameters are posted in the webform we use the phone number to verify if the user is linked to the merchant. If the user is linked then debit api is automatically called. Merchant is supposed to pass correct user accesstoken in the webform. If user accesstoken is incorrect then debit api will fail and you get failed callback response. We won't send you user access details as you already have it in first transaction. You will get only debit response.

  1. Debit callback response is sent to notificationUrl

Debit Response:

In case of 200 status , you need to decrypt body , in case of Non-200 status , we send plain json response

Debit callback response at notificationUrl:
{ 
	"xtenant" : "Ola",
	"xtenantkey" : "<Encrypted-value>",
	"xauthkey" : "<Signature of xTenantKey>",
	"body" : "<Encrypted body>" // Decrypted response is explained below.
}

1. succes
Decrypted body of above response: http status 200 
{
"type":"debit",
"status":"success",
"transactionId":"dqtf-j717-qlfb",
"merchantBillId":"t2s5",
"amount":"15.00",
"hash":"b8edb58d9c3d299359f360e78c53ddf9d5bca6c3495c4276ba323840b84059d96847be4f6c40220c9f566d8aa2d920e8b55a269eca3acb58a7eff0e328bcf8e4",
"timestamp":1536825541954,"comments":"NA",
"udf":"NA",
"isCashbackSuccessful":"true",
"isCashbackAttempted":"true",
"debits":[{"name":"wallet","amount":15.0},{"name":"olaCredit","amount":0.0}]
}


2. failed

Decrypted body of above response: http status 200 
{
"type":"debit",
"status":"failed",
"transactionId":"",
"merchantBillId":"t2s5",
"amount":"15.00",
"hash":"5ee111bf40e6e0713d5fb15526657e09ecca52680ccddb969435ea63d609c23ec221d98a4afd866f13798f34b1d694209c290ca3d10c6d9be007df4f5148e3e9",
"timestamp":1536825541954,"comments":"NA",
"udf":"NA",
"isCashbackSuccessful":"false",
"isCashbackAttempted":"false",
"debits":[{"name":"wallet","amount":15.0},{"name":"olaCredit","amount":0.0}]
}

Failure Debit Response:

In case status is not 200(4xx or 5xx), you can read response directly and validate hash.

Http statuscode will be not be 200 in failure case. 
We are sending plain text respnse unlike in case of failure.
Most of the times it would be 400 or 401.

Debit callback response at notificationUrl:

{"errorCode":"invalid_request","message":"Invalid user access token.","request_id":"260855","hash":"5ee111bf40e6e0713d5fb15526657e09ecca52680ccddb969435ea63d609c23ec221d98a4afd866f13798f34b1d694209c290ca3d10c6d9be007df4f5148e3e9","status":"error","supportMessage":"Invalid user"}


Hash validatioon of failure response:
Validate the hash before failing the transacion.
If validation fails donot fail the transaction and keep in pending.

sha512('errorCode|message|supportMessage|request_id|salt')
 
following can the errorcodes:
 
1. hash_mismatch
2. insufficient_funds
3. duplicate_command
4. instrument_not_available
5. user_merchant_limit_breached
6. user_blocked  
7. invalid_parameter
8. outstanding_limit_breached
9. invalid_request

Steps to get Decrypted Body:

1). Signature verification:

First verify the x-auth-key using Ola Public key to check if it matches with the xtenantkey.
xauthkey is signature of xtenantkey.
So you can verify the signature by matching the signature with xauthkey . Refer sample code to understand the same.

byte[] xAuthKeyBytes = Base64.decodeBase64(xauthkey);
Signature e = Signature.getInstance("SHA1WithRSA");
e.initVerify(getOlaPublicKeyFromConfig);
e.update(Base64.decodeBase64(xtenantkey));
flag = e.verify(xAuthKeyBytes);
if(flag == true)
    go ahead
else
    reject response

2) Decrypt the xtenantkey:

If flag is true in first step, decrypt the xtenantkey using your private key. ( You will get decrypted string like => <uuid>:<timestamp>)

byte[]  xTenantKeyBytes = Base64.decodeBase64(xtenantkey);
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(2, getMerchantPrivateKeyFromConfig);
    plainText = cipher.doFinal(xTenantKeyBytes);
} catch (Exception var7) {
    log.error("Failed to decrypt the text", var7);
    throw new EncryptionException("Failed to decrypt the text");
}
return new String(plainText); // it would be like <uuid>:<timestamp>

3) Check if the timestamp is not expired. If expired fail transaction.

if(timestamp>System.currentTimeInMillis()){
   // success it
   } else {
// fail (Expired)
}

4) If not expired, get the uuid and decrypt the body using uuid as the key

try {
 getIvParamFromConfig="use sandbox IVParam credential"; // We Will Share the production IV vector once you are done with Testing
        IvParameterSpec iv = new IvParameterSpec(getIvParamFromConfig.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(uuid.getBytes("UTF-8"), "AES"); //Get UUID from 3rd step
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] plainText = cipher.doFinal(Base64.decodeBase64(body)); // Get it from direct debit response at NotificationUrl
            return new String(plainText);
        }
catch (Exception ex) {
            log.error("Error decrypting", ex);
            throw new Exception(ErrorCode.unknown_error, "Something went wrong");
        }

5) Validate Hash to confirm the contents of response body:

Validate the debit response hash and if validation fails reject transaction.
If hash is valid , check the transaction status and proceed accordingly.

Hash Validation of Response: 
Wallet and olaCredit amount should be passed as received in response while generating hash.

response hash= SHA512('type|status|merchantBillId|transactionId|amount|comments|udf|isCashBackAttempted|isCashBackSuccesfull|timestamp|salt')

Refresh API

Refresh API

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v1/userWallet/refresh
{
"accessToken" : "string",
"refreshToken" : "string"
}
A binary file was returned

You couldn't be authenticated

{
    "status": "success",
    "refreshSessionResponse": {
        "access_token": "7681d8b2-b3d9-4d3a-8ff6-c922950fee8f",
        "access_token_expiry": 1536833168073,
        "access_token_expiry_from_now": 172799986
    },
    "message": ""
}
{
    "status": "error",
    "refreshSessionResponse": null,
    "message": "Error refreshing token"
}

Headers

Authorization
string
 

Refresh API :

It's s2s call. Since user Access token is valid only for 8 hours it gets expired after 8 hours.
Merchant has to refresh the userAccessToken by using refresh API.
The refreshToken is used to generate new accessToken for user.
Call this API just before every debit request and pass updated userAccessToken in debit request.

Update on your end:

Update the user Access Token stored against customer Id, once you refresh it. Keep the refresh Access Token as it is.

enquiry

You can check status of transaction after 10-15 mins of initiating the transaction.
User may take upto 15 mins for validating his OTP (Worst case). You can call query API , only after 15 minutes of intiating transaction. Even then if you get transaction not found, you can fail transaction at your end (After 15 mins).

 
gethttps://sandbox.olamoney.in/olamoney/v2/query?uniqueBillId=uniqueBillId&accessToken=accessToken&timestamp=timestamp&hash=hash
curl -X GET 'https://sandbox.olamoney.in/olamoney/v1/query?uniqueBillId=6495015220180821095354&accessToken=MERCHANT_SANDBOX_access_token&timestamp=2018-08-23%2012%3A10%3A27&hash=865551c45a9aabbc8b0a91e7735833b32dfaa1050dd9fa116ffe9c39d3bbffadabfc76b860aa084cdc2aef0365c67bcdd96d4be0a2411f0d51c40662fedc65c2' -H 'cache-control: no-cache' -H 'content-type: application/json'
A binary file was returned

You couldn't be authenticated

{
    "id": 320812273,
    "status": "completed",
    "transactionLink": {
        "id": 474935344,
        "description": null,
        "createdAt": 1534845235000
    },
    "uniqueBillId": "6495015220180821095354",
    "merchantDetails": "IN-PAID30-RECUR-OTT-OLA-PROMO90D",// UDF sent in debit request
    "amount": 2,
    "createdAt": 1534845235000,
    "type": "debit",
    "comments": "olaMoney payment",
    "udf": "IN-PAID30-RECUR-OTT-OLA-PROMO90D",
    "userId": "9603054591",
    "globalMerchantId": "dqkd-hm8l-09uw",
    "subMerchant": null,
    "merchantTeller": null,
    "merchantTransactionDetails": {
        "id": 263132034,
        "saleId": "6495015220180821095354",
        "balanceType": {
            "type": "cash",
            "active": true,
            "name": "cash",
            "handler": {},
            "hibernateLazyInitializer": {}
        },
        "transactionSubType": {
            "id": 1,
            "subType": "debit",
            "handler": {},
            "hibernateLazyInitializer": {}
        }
    },
    "handler": {},
    "merchantId": 1,
    "hibernateLazyInitializer": {}
}
Ex 1 : 
{
    "errorCode": "stale_query",
    "message": "Invalid timestamp",
    "status": "error"
}


Ex 2 :

{
 "errorCode":"transaction_not_found",
 "message":"No such merchant Transaction",
 "status":"error"
}

Path Params

uniqueBillId
string
required

saleId (uniqueBillId of the transaction already happened/initiated)

accessToken
string
required

accessToken of the merchant

timestamp
string
required

current timestamp of your system in the form of YYYY-MM-DD HH MM SS e.g. 2015-08-13 13:17:12

hash
string
required

sha512('access_token|uniqueBillId||timestamp|||merchant_salt')

 

Note:

URL Encode the timestamp while hitting query api (not while generating hash).

v3/refund

 

Header Auth

 Authentication is required for this endpoint.
posthttps://sandbox.olamoney.in/olamoney/v3/refund
{
   "command": "refund",
   "accessToken": "sandbox merchant token credential",
   "uniqueId": "7c9f7b95-0f43-4028-9e01-3126b58b61d4", //(new one merchant has to generate for the refund txn)
   "comments": "test",
   "udf": "test",
   "hash": "10b4ba7039136ecb5246c4107b4eb124f0462c1dbb9a5fdaaa160d9a143385ecdc17c88047f8d23bc4e5544a719822949a685b1d37132da0ba510f9aa35cb178",
   "returnUrl": "public returnUrl",
   "notificationUrl": "public notificationUrl",
   "amount": "20.00",
   "balanceType": "cash",
   "balanceName": "cash",
   "olaTransactionId": "bhfo-5bot-bgh6", //(original parent txn id provided by Ola Money)
   "currency": "INR"
}
A binary file was returned

You couldn't be authenticated

{
 "type":"refund",
 "status":"success",
 "transactionId":"bgho-5bot-ne16",
 "merchantBillId":"7c9f7b95-0f43-4028-9e01-3126b58b61d4",
 "amount":20.0,
 "hash":"d1880d064c17db0121645f7c4492176dafa24a25c168d1a045bc46ee2521156c845ebeba2005a487d76d23e47178b7aedd238db2130aab1fb9cca00dbd9294e9",
 "timestamp":1439473847354,
 "comments":"test",
 "udf":"test"
}
{
    "errorCode": "cannot_refund_amount",
    "message": "The refund limit has exceeded",
    "status": "error"
}
 

Hash Generation of refund request:

hash_string = 'accessToken|uniqueId|comments|udf|returnUrl|notificationUrl|currency|amount|balanceType|balanceName|olaTransactionId|salt';
// Amount should be in 2 decimals
hash = sha512(hash_string);