Giter Club home page Giter Club logo

woodroid's Introduction

Woocommerce Android SDK

This is an woocommerce api client for android

Built-based on the documentation: http://woocommerce.github.io/woocommerce-rest-api-docs/#introduction

Installation

Please note that files are still being moved around - the project should be stable before end Feb 2019

Maven dependency:

Step 1. Add the JitPack repository to your build file

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

Step 2. Add the dependency

<dependency>
	<groupId>com.github.gilokimu</groupId>
	<artifactId>woodroid</artifactId>
	<version>0.2.0</version>
</dependency>

Gradle dependency:

Step 1. Add the JitPack repository to your build file

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Step 2. Add the dependency

dependencies {
	implementation 'com.github.gilokimu:woodroid:0.2.0'
}

Getting started

Generate API credentials (Consumer Key & Consumer Secret) following this instructions http://docs.woocommerce.com/document/woocommerce-rest-api/ .

Check out the WooCommerce API endpoints and data that can be manipulated in https://woocommerce.github.io/woocommerce-rest-api-docs/.

Demo

I have left consumer key and secret within the app, for you to test the app without an installation of wordpress. To use my installation of wordpress, here are the credentials:

username: demo password: demo2019 https://gilo.me/store/wp-admin

PS/ Do no harm

Setup

Setup for the new WP REST API integration (WooCommerce 2.6 or later):

val woocommerce = Woocommerce.Builder()
	.setSiteUrl("http://example.com")
	.setApiVersion(Woocommerce.API_V2)
	.setConsumerKey("ck_XXXXX")
	.setConsumerSecret("cs_XXXX")
	.build()

Usage

Getting products example

woocommerce.ProductRepository().products().enqueue(object : Callback<List<Product>> {
        override fun onResponse(call: Call<List<Product>>, response: Response<List<Product>>) {
            val productsResponse = response.body()
            for (product in productsResponse!!) {
                products.add(product)
            }

            adapter.notifyDataSetChanged()
        }

        override fun onFailure(call: Call<List<Product>>, t: Throwable) {

        }
    })

Supported resources

The sdk currently supports :

  1. Order Notes
  2. Refunds
  3. Attributes
  4. Attribute Terms
  5. Product Category
  6. Shipping Class
  7. Product Tags
  8. Variations
  9. Coupons
  10. Customers
  11. Orders
  12. Products
  13. Reports

Coming soon

  1. Settings
  2. Payment gateway

API Methods

The general resource method calls are

  1. Create - Pass the object to create
  2. List - a list of all items
  3. View single method - retries a single item
  4. Delete - deletes the resource
  5. Filter - provides a list that meets a criteria

Create Method

Create an instance of the resource then pass onto a .create() function on the resource repository

val coupon = Coupon()
coupon.code = code
coupon.description = description
        
woocommerce.CouponRepository().create(coupon).enqueue(object : Callback<Coupon> {
    override fun onResponse(call: Call<Coupon>, response: Response<Coupon>) {
        val couponResponse = response.body()
        finish()
    }

    override fun onFailure(call: Call<Coupon>, t: Throwable) {
        
    }
})

List Method

 woocommerce.CouponRepository().coupons().enqueue(object : Callback<List<Coupon>> {
    override fun onResponse(call: Call<List<Coupon>>, response: Response<List<Coupon>>) {
        val couponResponse = response.body()
        for (coupon in couponResponse!!) {
            coupons.add(coupon)
        }

        adapter.notifyDataSetChanged()
    }

    override fun onFailure(call: Call<List<Coupon>>, t: Throwable) {

    }
})

View single item

val couponId = intent.getIntExtra("couponId", 0)

woocommerce.CouponRepository().coupon(couponId).enqueue(object : Callback<Coupon> {
    override fun onResponse(call: Call<Coupon>, response: Response<Coupon>) {
        val coupon = response.body()!!

        etCode.setText(coupon.code.toUpperCase())
        etDescription.setText(coupon.description)

    }

    override fun onFailure(call: Call<Coupon>, t: Throwable) {
        
    }
})

Delete item

woocommerce.CouponRepository().delete(couponId).enqueue(object : Callback<Coupon> {
    override fun onResponse(call: Call<Coupon>, response: Response<Coupon>) {
        if (response.isSuccessful) {
            val coupon = response.body()!!
            finish()
        }else{
            Toast.makeText(this@CouponActivity, "" + response.code() + " : " + response.message(), Toast.LENGTH_SHORT).show()
        }

    }

    override fun onFailure(call: Call<Coupon>, t: Throwable) {
        stopShowingLoading()
    }
})

Filter item

val filter = CouponFilter()
filter.search = "FEB"

woocommerce.CouponRepository().coupons(filter).enqueue(object : Callback<List<Coupon>> {
    override fun onResponse(call: Call<List<Coupon>>, response: Response<List<Coupon>>) {
        val couponResponse = response.body()
        for (coupon in couponResponse!!) {
            coupons.add(coupon)
        }

        adapter.notifyDataSetChanged()
    }

    override fun onFailure(call: Call<List<Coupon>>, t: Throwable) {

    }
})

Sample app

The sample app implements an MVVM approach which would look slightly different from the above. The methods are the same though

Contribution

Contributions are highly welcomed, just create a PR

Slack

You can also reach out through slack in case of any issues with installation or feature request

Love the Project?

You can donate to support the project futher. Donate with Crypto

woodroid's People

Contributors

aroniez avatar bitsnaps avatar gilokimu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

woodroid's Issues

Sign in through customer credentials

Is it possible to sign in through customer credentials, or restrict the android client to access data for only currently signed in customer user, not all of the data that is related to admins?

not working on another wooCommerce

after testing your application with your web site consumer key and password that work fine, now i change them on my own site and when i test application to get products list i get this message:

Response{protocol=http/1.1, code=401,
message=Unauthorized, url=http://www.aklin.ir/wp//wp-json/wc/v2/products?oauth_consumer_key=ck_c559b86adc5460395e3ae483b852201615d29712&oauth_nonce=9.55824708358162E7&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1555420204&oauth_signature=4R%2BipUXvIJBvO2OQjnvnMPLX6WU%3D

i installed and enabled wp-json plugin on this website

class Main : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val woocommerce = Woocommerce.Builder()
                .setSiteUrl("http://www.aklin.ir/wp")
                .setApiVersion(Woocommerce.API_V2)
                .setConsumerKey("ck_c559b86adc5460395e3ae483b852201615d29712")
                .setConsumerSecret("cs_5aaa22e54cd35fd42e490ab12c22afb4d99b6225")
                .build()

        woocommerce.products.enqueue(object : Callback<List<Product>> {
            override fun onResponse(call: Call<List<Product>>, response: Response<List<Product>>) {
                val productsResponse = response.body()
            }

            override fun onFailure(call: Call<List<Product>>, t: Throwable) {

            }
        })
    }
}

is any special settings on woocommerce?

Type me.gilo.woodroid.models.Download is defined multple times

I cloned the project and when I try to build it I get the following error:

:app:multiDexListDebug
Type me.gilo.woodroid.models.Download is defined multiple times: /home/omar/Documents/WooDroid/woodroid/build/intermediates/runtime_library_classes/debug/classes.jar:me/gilo/woodroid/models/Download.class, /home/omar/Documents/WooDroid/firebasecart/build/intermediates/runtime_library_classes/classes.jar:me/gilo/woodroid/models/Download.class

I think this is due to both classes with the same name, I will refactor firebasecart Download class and see what happens.

You're doing a great job with this project, thanks

What if we want to retrieve values one by one?

Instead of loading all the values (Products for example) together and then showing them in the list view or recycler ,what if I want to show each value after it's loaded ?
Currently I can accomplish this by running the enque function multiple times keeping the filter as per_page=1 and increasing the page number for each product and then showing it.
But this is not that much efficient as you can understand.
So please suggest how I can load values (Products for example) one by one and show them in the recycler view.
And currently this is what I am doing


  val allProducts : MutableLiveData<Product> by lazy {
        woocommerce = Woocommerce.Builder().setSiteUrl(baseURL)
            .setApiVersion(Woocommerce.API_V2)
            .setConsumerKey(consumerKey)
            .setConsumerSecret(consumerSecret)
            .build()
        preLoadProducts()
        MutableLiveData<Product>()
    }

    private fun preLoadProducts() {
        val productFilter = ProductFilter()
        productFilter.page = pageNum
        productFilter.per_page = 1
        loadProducts(productFilter)
    }

    private fun loadProducts(productFilter: ProductFilter){
        woocommerce.ProductRepository().products(productFilter).enqueue(object :
            Callback<List<Product>> {
            override fun onResponse(call: Call<List<Product>>, response: Response<List<Product>>) {
                try{
                    val productsResponse = response.body()
                    allProducts.value = productsResponse?.get(0)
                    pageNum ++
                    preLoadProducts()
                }catch (e : Exception){
                    e.printStackTrace()
                    allProducts.value = null
                }

            }
            override fun onFailure(call: Call<List<Product>>, t: Throwable) {
                t.printStackTrace()
                allProducts.value = null
            }
        })
    }

I'm not that much of an expert, but I hope you get the idea.
Thanks

After Product is updated, all associated attributes are removed

Great work!
But I have issues with product update. After the Update API returns successful, the product will have an empty attributes array.

For example, if I updated a product which have 2 attributes Colour and Size. By the time I called load product from the database, all the attributes are gone.

Please can you help?
Thank you

"Invalid signature - provided signature does not match."

First off, my apologies, I didn't want to open an issue for a support query but I couldn't find any alternative way to reach out (slack maybe?).

I'm a novice Android and WooCommerce developer and I'm trying to access a store using WooDroid but I'm getting the following response whenever I try to grab response from the onResponse method:

{"code":"woocommerce_rest_authentication_error","message":"Invalid signature - provided signature does not match.","data":{"status":401}}

I setup the new WP REST API integration using the store's credentials (URL, CK and CS) and double checked them. Everything is working fine in Postman.

Some type me.gilo.woodroid.xxx.xxx is defined multple times

hello, thanks for the project sir, you're doing great, however, im still getting the same error with this issue, is there any solution? i already renamed some class and the error is getting bigger

example :
WooDroid/woodroid/build/intermediates/runtime_library_classes/debug/classes.jar:me/gilo/woodroid/models/Download.class,

Cart Respositiory Issue

can anyone provide me code for using Cart Repository? I am having hard time to figure it out

"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}

This is error I am getting in response

Order webhook

Any idea how to configure the order completed webhook?
For example: As soon as an order is completed/payment is done, I should be notified via webhook in my android application.

How to apply filtering

Hello sir
I got a question
imagine I have a cloth shop and I have attributes color , made_in and special_off (I can already see the attributes when testing by Postman). I need "10 products" with following conditions:

  • color : red or blue
  • made_in : japan or US
  • special_off : true

how can I implement this request?
is it possible using (class ProductFilter)?
I have read the woocommerce_rest_api

Unable to create customer, without password

Hi there,
when I try to create customer with follwoing request:

 var customer = Customer()
                            customer.email = "[email protected]
                            customer.firstName = "test"
                            customer.lastName = "test"
                            customer.username = "test test"

It returns "code=400, message=Bad Request"

But when I use

 var customer = Customer()
                            customer.email = "[email protected]
                            customer.firstName = "test"
                            customer.lastName = "test"
                            customer.username = "test test"
                           customer.password = "Pass123"

above object, customer gets created succesfully.
However I want to create a customer without passing a password.
Please help.

Manifest merger failed : Attribute

Screenshot_2


Error spoiler `Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91 is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory). Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:8:3-141:17 to override. `
____________________________________________________________________

Pro-Guard

Can you post Pro-Guard fo this gradle

how to get user_meta_data and product_meta_data

hi. i collect some informations from user into the customer's metadata like membership state and some infos for products into the product's metadata that is important for app. but the wooDroid lib not return customer metadata and return product metadata without value. how i can resolve this?

Gradle sync failed: Tooling support for the platform 'JavaScript

Screenshot_1

Hello! can you help me?

4:01 AM Gradle sync started with IDEA sync 4:01 AM Project setup started 4:02 AM Gradle sync failed: Tooling support for the platform 'JavaScript' is missing. Implement 'IdePlatformKindTooling' for it. (56 s 155 ms) 4:02 AM NDK Resolution Outcome: Project settings: Gradle model version=5.3, NDK version is UNKNOWN

How to check coupon code valid or not?

I developed one e-commerce app using woocommerce rest-API. now I need to add coupons codes feature in-app. I know how to pass coupon code in creating order, but how to check this code is valid or not before creating an order?

Security Concern on saving secret in app

Hi I am new to mobile development, sorry if I asking dumb question.

From my understanding and some articles I found online (here, and here), isn't that saving consumer secret in app is a bad practice and potentially a security vulnerability for malicious user to exploit?

image

How should i use it?

I already manually add some implementations because of errors

    implementation 'com.github.gilokimu:woodroid:0.2.1'
    implementation 'com.squareup.retrofit2:retrofit:2.6.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation "com.google.code.gson:gson:2.8.2"
    implementation 'com.squareup.okhttp3:okhttp:4.1.0'
    implementation 'com.squareup.okio:okio:2.2.2'
    implementation "com.squareup.okhttp3:logging-interceptor:4.1.0"

Did I have to do that?

import me.gilo.woodroid.Woocommerce
import me.gilo.woodroid.models.Product
import retrofit2.*

fun main() {


    val siteUrl = "https://si.te/"
    val ConsumerKey = "ck_key"
    val ConsumerSecret = "cs_secret"
    WooComerceProvider(siteUrl, ConsumerKey, ConsumerSecret).loadProducts()
}

class WooComerceProvider(site: String, key: String, secretKey: String) {

    private val woocommerce = Woocommerce.Builder()
        .setSiteUrl(site)
        .setApiVersion(Woocommerce.API_V3)
        .setConsumerKey(key)
        .setConsumerSecret(secretKey)
        .build()


    fun loadProducts() {
        var products: MutableList<Product> = mutableListOf()

        woocommerce.ProductRepository().products().enqueue(object : Callback<List<Product>> {
            override fun onResponse(call: Call<List<Product>>, response: Response<List<Product>>) {
                val productsResponse = response.body()
                for (product in productsResponse!!) {
                    products.add(product)
                }
            }

            override fun onFailure(call: Call<List<Product>>, t: Throwable) {

            }
        })
    }
}

and there are more errors

Exception in thread "OkHttp Dispatcher" java.lang.RuntimeException: Stub!
at org.apache.http.message.BasicNameValuePair.(BasicNameValuePair.java:121)
at me.gilo.woodroid.data.auth.AuthIntercepter.getOauthParams(AuthIntercepter.java:90)
at me.gilo.woodroid.data.auth.AuthIntercepter.intercept(AuthIntercepter.java:43)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
at okhttp3.RealCall$AsyncCall.run(RealCall.kt:136)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

Woocommerce.Builder() worked, but the query did not. Sorry, it seems I don't really understand. Could you help me to install/use your package?

Please update model variables

Hey there..Please update the model variables to the current woocommerce responses...eg update "discount_tax" from "total_discount" in the orders class

401 Unauthorized

hi, i have this problem with wooDroid. what i must to do?
please help me

        Woocommerce woocommerce = Woocommerce.Builder()
                .setSiteUrl("http://parstuts.ir")
                .setApiVersion(Woocommerce.API_V3)
                .setConsumerKey(ConstantValues.WOOCOMMERCE_CONSUMER_KEY)
                .setConsumerSecret(ConstantValues.WOOCOMMERCE_CONSUMER_KEY)
                .build();

[size=327 text={"code":"woocommerce_rest_authentication_error","message":"\\u062โ€ฆ]

D/OkHttp: {"code":"woocommerce_rest_authentication_error","message":"\u0627\u0645\u0636\u0627\u0621 \u0646\u0627\u0645\u0639\u062a\u0628\u0631 \u0627\u0633\u062a - \u0627\u0645\u0636\u0627\u06cc \u0627\u0631\u0627\u0626\u0647 \u0634\u062f\u0647 \u0645\u0637\u0627\u0628\u0642\u062a \u0646\u062f\u0627\u0631\u062f.","data":{"status":401}}
    <-- END HTTP (327-byte body)
D/OkHttp: <-- 401 Unauthorized http://parstuts.ir/wp-json/wc/v3/products

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.