Edit: Found a better way, see Solution 2 below
As mentioned in the comment, the SOAP API is the way to go.
Solution 1:
Suds worked for me with slight modification (Usage of Titanium.Network.HTTPClient
instead of XMLHttpRequest
), but it does not much more than creating a SOAP envelope for the call and returning the whole XML response.
Proof-of-Concept implementation, using jQuery Deferred for request chaining:
Service.MagentoClient = function()
{
var self = this;
var suds = new SudsClient({
endpoint : "http://the-magento-host/api/v2_soap/",
targetNamespace : "urn:Magento",
});
self.login = function() {
var deferred = new $.Deferred();
var args = {
username : 'the-username',
apiKey: 'the-api-key'
};
suds.invoke("login", args, function(xmlDoc) {
self.sessionId = $(xmlDoc).find("loginReturn").text();
deferred.resolve({});
//TODO reject if no sessionid returned
});
return deferred;
};
self.setStatus = function(orderId, status, comment, notify) {
var deferred = new $.Deferred();
if (!self.sessionId) {
deferred.reject({ error: 'Login not successful.' });
return;
}
var args = {
sessionId : self.sessionId,
orderIncrementId : orderId,
status : status,
comment : comment,
notify : notify
}
suds.invoke("salesOrderAddComment", args, function(xmlDoc) {
var success = $(xmlDoc).find("salesOrderAddCommentResponse").text();
if (success) {
deferred.resolve({});
} else {
deferred.reject({ error: 'Update not successful.' });
}
});
return deferred;
};
};
Usage example:
var magento = new Service.MagentoClient();
magento.login().then(function() {
magento.setStatus('100000029', 'complete', 'soap test');
}).then(function() {
alert('Update successful');
}, function(reject) {
alert('Update failed: ' + reject.error);
});
Solution 2:
Turned out that writing an own API adapter can be really easy. With the example of this core-hack (dead link) I was able to write a clean module for a JSON-RPC adapter based on Zend_Json_Server
. It uses the same Authentication and ACL as the SOAP and XML-RPC APIs.
To use the entry point /api/jsonrpc
, the new controller has to be added to the api
route:
<config>
<frontend>
<routers>
<api>
<args>
<modules>
<my_jsonrpc before="Mage_Api">My_JsonRpc_Api</my_jsonrpc>
</modules>
</args>
</api>
</routers>
</frontend>
</config>
Update 02/2015: The above link is dead now, so I open sourced my JSON-RPC adapter as a complete extension: https://github.com/sgh-it/jsonrpc
My JS client now looks like this (again with JQuery.Deferred, but no additional 3rd party libraries for the API):
/**
* Client for the Magento API
*/
Service.MagentoClient = function()
{
var self = this;
/**
* @param string method the remote procedure to call
* @param object params parameters for the RPC
* @param callback onSuccess callback for successful request. Expects one parameter (decoded response object)
* @param callback onError callback for failed request. Expects one parameter (error message)
*
* @return void
*/
self.jsonRpc = function(method, params, onSuccess, onError) {
var request = {
method : method,
params : params,
jsonrpc : "2.0",
id : 1
};
var options = {
entryPoint : config.magentoClient.entryPoint,
method: 'post',
timeout: config.magentoClient.timeout
};
var httpClient = Titanium.Network.createHTTPClient();
httpClient.onload = function(e) {
try {
var response = JSON.parse(this.responseText);
} catch (jsonError) {
return onError(jsonError);
}
if (response.error) {
if (response.error.code == 5) { // session expired
self.sessionId = null;
}
return onError(response.error.message);
}
onSuccess(response);
};
httpClient.onerror = function(e) {
onError(e.error + '; Response:' + this.responseText);
};
httpClient.setTimeout(options.timeout);
if (httpClient.open(options.method, options.entryPoint)) {
httpClient.setRequestHeader("Content-type", "application/json");
httpClient.send(JSON.stringify(request));
} else {
onError('cannot open connection');
}
}
/**
* Retrieve session id for API
*
* @return JQuery.Deferred deferred object for asynchronous chaining
*/
self.login = function() {
var deferred = new $.Deferred();
if (self.sessionId) {
deferred.resolve();
return deferred;
}
var loginParams = config.magentoClient.login;
try {
self.jsonRpc('login', loginParams, function(response) {
if (response && response.result) {
self.sessionId = response.result;
deferred.resolve();
} else {
deferred.reject('Login failed.');
}
}, function(error) {
deferred.reject(error);
});
} catch (rpcError) {
deferred.reject(rpcError);
}
return deferred;
};
/**
* Updates order states in Magento
*
* @param string method name of the remote method
* @param object args arguments for the remote method
*
* @return JQuery.Deferred deferred object for asynchronous chaining
*/
self.call = function(method, args) {
var deferred = new $.Deferred();
if (!self.sessionId) {
deferred.reject('No session.');
return;
}
var callParams = {
sessionId : self.sessionId,
apiPath : method,
args : args
};
try {
self.jsonRpc('call', callParams, function(response) {
deferred.resolve(response.result);
}, function(error) {
deferred.reject(error);
});
} catch (rpcError) {
deferred.reject(rpcError);
}
return deferred;
};
};
Note that all methods after login are routed through call
. The method
parameter is something like sales_order.list
, the args
parameter an array or object with the method arguments.
Usage example:
var filters = [];
var magento = new Service.MagentoClient();
magento.login().then(function() {
magento.call('sales_order.list', [filters]).then(
function(orders) {
// do something with the response
}, function(error) {
alert('Magento API error: ' + error);
}
);
});
So @user2636834 did you figure this one out already?
I remember when I was setting up a test scenario that I got the sames error(s). Seemed that I didn't have Oauth installed :O. So in short I did (running Ubuntu and following these instructions, also running into this error):
pecl install oauth
Then add extension=oauth.so
to php.ini
's "Dynamic Extensions" section.
Then restart Apache
I tried the examples from the Magento site and got an error from the API:
"Invalid auth/bad request"
I had to add a 'Accept' => '*/*'
header to the $oauthClient->fetch()
call. After that it worked all just fine.
Hope you can get things running if you hadn't already.
Best Answer
I will be trying to make an answer quite simple for you to see through Magento a bit more fluently. (background, there is a lot of documentation and a couple of sentences may guide you to understand what is what..)
Magento is an e-commerce framework (php code and connect to mysql).
In steps:
--> you can create as many API users as you want and each can have different privileges (access different API)
--> the data that you will receive from these API calls will be the data in your mysql database and therefore will be the data related to the sample data (2k products, 1 customer and 2 orders are the content pretty much of the sample data)
I hope this clarify your situation. I don't see what you call "your users' own Magento data" and therefore I hope you see now that the data in the Magento API are only reflecting the e-commerce data you have in your site.