SMS Status service allows end-users to track status of the SMS sent to them and resend the messages if message delivery fails.
It is recommended to use Script embedding methods with the SmsStatus.js library (jQuery version 1.7.1 or newer is required).
Send a GET-request to a URL matching the following template to get SMS data: /Sms/{locale}/{timezone}/{format}/{id}
Message data in XML and JSON formats contains the following fields:
Please note that the request results list can be extended in future releases.
Value | Result name | Description |
0 | Ok | The message report was successfully created. |
3 | NotFound | The message was not found. |
The instructions are formatted as an HTML document fragment. The instructions may contain the following elements:
Please note that the status list can be extended in future releases.
Value | Status name | Description |
1 | Buffered | The message is queued for sending. |
2 | Sending | The message is being sent. |
3 | Delivered | The message is delivered. |
4 | Sent | Them message is sent. |
5 | Undelivered | Message could not be delivered (e.g., subscriber is unavailable and message has expired). |
6 | Blacklist | Receiver phone number is blacklisted. |
7 | Suspended | Sending attempt failed, the message is waiting to be resent. |
8 | HlrPending | The message is waiting for SIM card identification to complete. |
9 | HlrMismatch | SIM card identity mismatch. If the client has changed the SIM card he can update the allowed SIM card identity on WebMoney Securty. |
Please note that the status list can be extended in future releases.
Value | Status name | Description |
0 | NotSent | The message was not sent. |
1 | Accepted | The message is accepted for sending. |
10 | SentOk | The message is sent (sending is confirmed). |
11 | SendingFailPaid | The message could not be sent, the attempt is tariffed. |
12 | SendingFailNotPaid | The message could not be sent, the attempt is not tariffed. |
20 | DeliveryOk | The message is delivered. |
21 | DeliveryFailPaid | The message could not be delivered, the attempt is tariffed. |
22 | DeliveryFailNotPaid | The message could not be delivered, the attempt is not tariffed. |
Please note that the transport list can be extended in future releases.
Value | Transport name | Description |
1 | Sms | The message was sent in a plain SMS. |
2 | VoiceCall | A call will be made to the receiver phone number and the message will be read aloud. |
3 | InternetMessenger | The message was sent to a messenger service (e.g. Telegram). |
4 | WmPush | The message was sent in a push-notification to WebMoney mobile application. |
5 | CallPassword | The receiver phone number will receive a call from a phone number ending with the code. |
Attempt tariffication affects whether further automatic attempts to resend the message are made.
Perform POST-request to a URL matching the following template to resend a message: /Resend/{locale}/{timezone}/{format}/{id}
Resending result in XML and JSON formats contains the following fields:
Please note that the resending outcomes list can be extended in future releases.
Value | Result name | Description |
0 | Ok | The message was successfully resent. |
1 | TryAgainLater | The message can not be resent now but it may be resent later. |
2 | Unresendable | The message can not be resent. |
3 | NotFound | The message was not found. |
4 | TooManyResends | Resend requests limit is exceeded. |
Embedding script allows you to define callback function called when loading a script and load the script using a script tag with the correct src. Create a script tag with resending URL in the src attribute and insert it in the DOM to resend a message.
var status_update_timeout = 10000; var sms_poll_id = undefined; function sms_status_on_load_callback(response) { /// <summary>The callback function called by the SmsStatus script when /// message report is requested as JavaScript. /// </summary> /// <param name="response" optional="false" mayBeNull="false"> /// The server response to the report request. /// </param> if (sms_poll_id !== undefined) { clearTimeout(sms_poll_id); } var report = response.Report; if (report !== null) { set_text('report-created', report.Created.toLocaleString()); set_text('report-retries', report.SendingRetries); set_text('report-validity', report.ValidityPeriodMinutes); set_text('report-status', report.Status); set_text('report-status-description', (report.StatusDetails || '') + ' '); var instruction = report.StatusInstruction || ''; var hide_instruction = (instruction === '' && !report.Resendable); set_hidden('report-show-instruction-button', hide_instruction); set_text('report-show-instruction', report.StatusInstruction); set_hidden('message-resend-button', !report.Resendable); if (!response.Report.IsFinalState) { sms_poll_id = setTimeout(reload_script, status_update_timeout); } } } function sms_status_on_resend_callback(response) { /// <summary>The callback function called by the SmsStatus script when /// message resend result is requested as JavaScript. /// </summary> /// <param name="response" optional="false" mayBeNull="false"> /// The server response to the resend request. /// </param> var resend_result = document.getElementById('resend-result'); set_hidden(resend_result, false); set_text(resend_result, response.Status); sms_poll_id = setTimeout(reload_script, 1); }
var status_url_base = 'http://sms.webmoney.ru/SmsStatus/Sms/ru-ru/Script/SecurID_1_12345678901234567890123456'; var resend_url_base = 'http://sms.webmoney.ru/SmsStatus/Resend/ru-ru/Script/SecurID_1_12345678901234567890123456'; function load_script(url) { /// <summary>Loads and executes JavaScript at the specified URL using GET. /// </summary> /// <param name="url" type="string" optional="false" mayBeNull="false"> /// The script URL. /// </param> var elems = document.getElementsByClassName('script-in-action'); var script_fired = false; for (var i = 0; i < elems.length && !script_fired; i++) { var node = elems[i]; var scripts = node.getElementsByTagName('script'); for (var j = 0; j < scripts.length && !script_fired; j++) { var old_script = scripts[j]; var new_script = document.createElement('script'); new_script.type = old_script.type; new_script.src = url; node.replaceChild(new_script, scripts[j]); script_fired = true; } } } function reload_script() { /// <summary>Reloads script contating the message report from the server.</summary> var now = new Date(); var url = status_url_base + '?date=' + now.getHours() + now.getMinutes(); load_script(url); } function resend_message() { /// <summary>Resends the message.</summary> var now = new Date(); var url = resend_url_base + '?date=' + now.getHours() + now.getMinutes(); load_script(url); }
Changing the 'date' query string parameter allows to reload the script (and update the message data) while controlling the time between updates. You should not update the data too often, it is creates an extra load on the server.
window.onload = function () { document.getElementById('reload').onclick = reload_script; document.getElementById('report-show-instruction-button').onclick = function () { set_hidden('resend-result', true); show_pop_up('pop-up') }; document.getElementById('pop-up-close-button').onclick = function () { hide_pop_up('pop-up') }; document.getElementById('message-resend-button').onclick = resend_message; sms_poll_id = setTimeout(reload_script, 1); }
<div class="script-in-action"> <p> <button id="reload">Refresh</button> </p> <div class="sms-status-report"> <div class="sms-status-report-field"> <span>Created: </span> <span id="report-created"></span> </div> <div class="sms-status-report-field"> <span>Sending attempts: </span> <span id="report-retries"></span> </div> <div class="sms-status-report-field"> <span>Timespan: </span> <span id="report-validity"></span> </div> <div class="sms-status-report-field"> <span>Status: </span> <span id="report-status"></span> </div> <div class="sms-status-report-field"> <span>Status description: </span> <span> <span id="report-status-description"></span> <span id="report-show-instruction-button" class="hidden">[Details]</span> </span> </div> </div> <div id="pop-up" class="hidden"> <div class="pop-up-close"><span id="pop-up-close-button">Close</span></div> <div class="pop-up-content"> <p id="report-show-instruction"></p> <p id="resend-result" class="hidden"></p> <button id="message-resend-button">Resend</button> </div> </div> <script type="text/javascript"></script> </div> <div id="blanket" class="hidden"></div>
.hidden { display: none; } .sms-status-report { width: 100%; } .sms-status-report-field { display: table; width: 100%; } .sms-status-report-field>span { display: table-cell; width: 75%; } .sms-status-report-field>span:first-child { width: 25%; } #report-show-instruction-button { cursor: pointer; text-decoration: underline; }
function set_text(node, text) { /// <summary>Sets the text of the specified node to the specified value. /// </summary> /// <param name="node" type="HTMLElement|string" optional="false" mayBeNull="false"> /// The node to receive the specified text or its id. /// </param> /// <param name="text" type="string" optional="false" mayBeNull="false"> /// The new node text value. /// </param> if (typeof (node) === 'string') { node = document.getElementById(node); } var childNodes = node.childNodes; var found = false; for (var i = 0; i < childNodes.length; i++) { var childNode = childNodes[i]; if (childNode.nodeType === 3 || childNode === 4) { if (found) { node.removeChild(childNode); } else { childNode.nodeValue = text; found = true; } } } if (!found) { var textNode = document.createTextNode(text); node.appendChild(textNode); } } function get_text(node) { /// <summary>Gets the text of the specified node. /// </summary> /// <param name="node" type="HTMLElement|string" optional="false" mayBeNull="false"> /// The node to receive the specified text or its id. /// </param> if (typeof (node) === 'string') { node = document.getElementById(node); } var result = ''; var childNodes = node.childNodes; for (var i = 0; i < childNodes.length; i++) { var childNode = childNodes[i]; if (childNode.nodeType === 3 || childNode.nodeType === 4) { result += childNode.nodeValue; } } return result; } function set_hidden(element, hide) { /// <summary>Sets the display mode of the specified element by /// adding or removing 'hidden' class to its CSS classes list. /// </summary> /// <param name="element" type="HTMLElement|string" optional="false" mayBeNull="false"> /// The node to receive the specified text or its id. /// </param> /// <param name="hide" type="boolean" optional="false" mayBeNull="false"> /// Set to <c>true</c> to hide the element; /// set to <c>false</c> to display it. /// </param> var hidden_class = 'hidden'; var hidden_re = new RegExp('\\b' + hidden_class + '\\b', 'gi'); if (typeof (element) === 'string') { element = document.getElementById(element); } if (hide) { var existing = element.className; if (existing !== undefined && existing !== null) { if (!hidden_re.test(existing)) { if (existing.length > 0 && existing.charAt(existing.length - 1) !== ' ') { element.className = existing.concat(' ', hidden_class); } else { element.className = existing.concat(hidden_class); } } } else { element.className = hidden_class; } } else { element.className = element.className.replace(hidden_re, ''); } } if (document.getElementsByClassName === undefined) { document.getElementsByClassName = function (class_name) { /// <summary>Gets array of elements with the specified class name. /// </summary> /// <param name="class_name" type="string" optional="false" mayBeNull="false"> /// The name of the class. /// </param> var result = []; var class_name_re = new RegExp('\\b' + class_name + '\\b', 'i'); var elements = this.getElementsByTagName('*'); for (var i = 0; i < elements.length; i++) { var element_class = elements[i].className; if (class_name_re.test(element_class)) { result.push(elem[i]); } } return result; }; }
function show_pop_up(element_id) { /// <summary>Displays the pop up element with the specified id. /// </summary> /// <param name="node" type="string" optional="false" mayBeNull="false"> /// The if of the pop up element. /// </param> var blanket = document.getElementById('blanket'); var pop_up = document.getElementById(element_id); set_hidden (blanket, false); set_hidden (pop_up, false); var doc_el = document.documentElement; var cl_w = doc_el.clientWidth; var cl_h = doc_el.clientHeight; var cl_l = doc_el.scrollLeft; var cl_t = doc_el.scrollTop; pop_up.style.left = Math.round(cl_l + (cl_w - pop_up.clientWidth) / 2) + 'px'; pop_up.style.top = Math.round(cl_t + (cl_h - pop_up.clientHeight) / 3) + 'px'; } function hide_pop_up(element_id) { /// <summary>Hides the pop up element with the specified id. /// </summary> /// <param name="node" type="string" optional="false" mayBeNull="false"> /// The if of the pop up element. /// </param> var blanket = document.getElementById('blanket'); var pop_up = document.getElementById(element_id); set_hidden (blanket, true); set_hidden (pop_up, true); }
/* Pop up window */ #blanket { background-color: #111; opacity: 0.65; /* Non-IE */ filter: Alpha(opacity=65); /* IE */ position: absolute; z-index: 9001; top: 0px; left: 0px; width: 100%; min-height: 100%; position: fixed; } #pop-up { position: absolute; opacity: 1.00; background-color: #ffffff; position: absolute; width: 450px; z-index: 9002; border: 2px solid #505050; } #pop-up>.pop-up-content { padding: 5px 15px 25px 15px; width: 420px; height: 100%; } .pop-up-close { padding: 5px 10px; position:relative; right: 20px; width: 100%; text-align: right; } .pop-up-close>span { text-decoration: underline; cursor: pointer; }