Ankur Ankur - 1 year ago 198
Android Question

How to use 'POST' Http Verb of Woocommerce REST API in JAVA/Android?

I am developing an Android app of my WooCommerce store and I'm getting store data like Products, Categories, Orders, Customers etc using GET http verb of WooCommerce REST Api. It's working fine and I'm able to generate oAuth 1.0 signature for api V2 and V3 properly. Now, I want to perform Write action. I learned from the same documentation that I need to use POST Http verb. I tried for the same and stuck.

When I'm performing any POST action with HttpGet or HttpPost request using URL, oAuth data and generated signature, I'm getting:

{"errors":[{"code":"woocommerce_api_authentication_error","message":"Invalid Signature - provided signature does not match"}]}

I'm following all the instructions given in document and found on Google as well, used "POST" string to generate oAuth signature, tried sending params using HttpGet and HttpPost but failed.

Can anyone please provide me some instruction or example to use POST Http verb for Android to perform write action using WooCommerce REST API. (like Create new Order, Create New Category etc)

Answer Source

I run into the same error and what I had to do was to create a different POST adapter class. I am using retrofit for network calls and here is my snippet code:


import android.util.Base64;
import android.util.Log;

import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import retrofit.GsonConverterFactory;
import retrofit.Retrofit;
import retrofit.RxJavaCallAdapterFactory;

 * Created by Aron on 10/31/2015.
public class PostRestAdapter {

    static String oauth_nonce = "";
    static String oauth_timestamp = "";
    static String oauth_signature_method = "HMAC-SHA1";

    static ArrayList<NameValuePair> params;

    public static API createAPI(final String endpoint) {


        // Define the interceptor, add authentication headers
        Interceptor interceptor = new Interceptor() {
            public Response intercept(Chain chain) throws IOException {

                HttpUrl.Builder builder = chain.request().httpUrl().newBuilder();
                for (NameValuePair entry : params) {
                    builder.addQueryParameter(entry.getName(), entry.getValue());

                Request newRequest = chain.request()

                return chain.proceed(newRequest);

        // Add the interceptor to OkHttpClient
        OkHttpClient client = new OkHttpClient();

        Retrofit retrofit = new Retrofit.Builder()
        return retrofit.create(API.class);

    public static ArrayList<NameValuePair> setParams(String endpoint) {

        final String uri = API.BASE_URL + endpoint;

        oauth_nonce = getOauth_nonce();
        oauth_timestamp = getOauth_timestamp();

        params = new ArrayList<>();
        params.add(new BasicNameValuePair("oauth_consumer_key", API.CONSUMER_KEY));
        params.add(new BasicNameValuePair("oauth_nonce", oauth_nonce));
        params.add(new BasicNameValuePair("oauth_timestamp", oauth_timestamp));
        params.add(new BasicNameValuePair("oauth_signature_method", oauth_signature_method));

        Collections.sort(params, new SortParams());

        String encodedParams = URLEncodedUtils.format(params, "utf-8");
        Log.d("encodedParamString", encodedParams);

        String string_to_sign = "";
        try {
            string_to_sign = (new StringBuilder("POST&")).append(URLEncoder.encode(uri, "utf-8")).append("&").append(URLEncoder.encode(encodedParams, "utf-8")).toString();
        } catch (UnsupportedEncodingException e) {

        Log.d("string to sign", string_to_sign);

        try {
            Mac mac = Mac.getInstance("HMAC-SHA1");
            String secret = API.CONSUMER_SECRET;
            if (API.WP_API_VERSION.equals("3")) {
                secret = API.CONSUMER_SECRET + "&";
            mac.init(new SecretKeySpec(secret.getBytes("utf-8"), "HMAC-SHA1"));
            String signature = Base64.encodeToString(mac.doFinal(string_to_sign.getBytes("utf-8")), 0).trim();
            Log.d("signature", signature);
            params.add(new BasicNameValuePair("oauth_signature", signature));
        } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {

        return params;

    public static String getOauth_nonce() {
        return (new StringBuilder(String.valueOf(Math.random() * 100000000D))).toString();

    public static String getOauth_timestamp() {
        long stamp = (long) (System.currentTimeMillis() / 1000D);
        Log.d("stamp", stamp + "");
        return (new StringBuilder(String.valueOf(stamp))).toString();

    static class SortParams implements Comparator<NameValuePair> {

        public int compare(NameValuePair nameValuePair1, NameValuePair nameValuePair2) {
            return nameValuePair1.getName().compareTo(nameValuePair2.getName());