• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
hails

hails

cosmoye

Public
Like
cosmoye
Home
Code
4
backend
5
shared
1
ANDROID_INTEGRATION.md
README.md
Branches
1
Pull requests
Remixes
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
ANDROID_INTEGRATION.md
Code
/
ANDROID_INTEGRATION.md
Search
5/17/2025
ANDROID_INTEGRATION.md

Android Integration Guide

This guide provides instructions for integrating your Android app with the E-Commerce API.

API Base URL

The base URL for the API is the URL of your Val Town HTTP endpoint. You'll need to replace {YOUR_VAL_TOWN_URL} with your actual Val Town URL in the examples below.

Authentication

User Registration

// Using Retrofit interface AuthService { @POST("api/auth/register") suspend fun register(@Body request: RegisterRequest): Response<ApiResponse<AuthResponse>> } data class RegisterRequest( val username: String, val email: String, val password: String ) data class AuthResponse( val token: String, val user: User ) data class User( val id: Int, val username: String, val email: String, val createdAt: String ) // Usage val authService = retrofit.create(AuthService::class.java) val response = authService.register(RegisterRequest("username", "email@example.com", "password")) if (response.isSuccessful) { val authResponse = response.body()?.data // Store token for future authenticated requests saveToken(authResponse?.token) }

User Login

// Using Retrofit interface AuthService { @POST("api/auth/login") suspend fun login(@Body request: LoginRequest): Response<ApiResponse<AuthResponse>> } data class LoginRequest( val email: String, val password: String ) // Usage val authService = retrofit.create(AuthService::class.java) val response = authService.login(LoginRequest("email@example.com", "password")) if (response.isSuccessful) { val authResponse = response.body()?.data // Store token for future authenticated requests saveToken(authResponse?.token) }

Product Browsing

Get All Products

interface ProductService { @GET("api/products") suspend fun getAllProducts(@Query("category") categoryId: Int? = null): Response<ApiResponse<List<Product>>> } data class Product( val id: Int, val name: String, val description: String, val price: Double, val imageUrl: String, val category: String, val stock: Int, val createdAt: String ) // Usage val productService = retrofit.create(ProductService::class.java) val response = productService.getAllProducts() if (response.isSuccessful) { val products = response.body()?.data // Display products in RecyclerView }

Get Product Details

interface ProductService { @GET("api/products/{id}") suspend fun getProductById(@Path("id") productId: Int): Response<ApiResponse<Product>> } // Usage val productService = retrofit.create(ProductService::class.java) val response = productService.getProductById(1) if (response.isSuccessful) { val product = response.body()?.data // Display product details }

Shopping Cart

Get Cart

interface CartService { @GET("api/cart") suspend fun getCart(): Response<ApiResponse<Cart>> } data class Cart( val items: List<CartItem>, val totalPrice: Double ) data class CartItem( val id: Int, val userId: Int, val productId: Int, val quantity: Int, val product: Product? ) // Usage val cartService = retrofit.create(CartService::class.java) val response = cartService.getCart() if (response.isSuccessful) { val cart = response.body()?.data // Display cart items }

Add to Cart

interface CartService { @POST("api/cart") suspend fun addToCart(@Body request: AddToCartRequest): Response<ApiResponse<Cart>> } data class AddToCartRequest( val productId: Int, val quantity: Int ) // Usage val cartService = retrofit.create(CartService::class.java) val response = cartService.addToCart(AddToCartRequest(1, 2)) if (response.isSuccessful) { val updatedCart = response.body()?.data // Update cart UI }

Update Cart Item

interface CartService { @PUT("api/cart/{itemId}") suspend fun updateCartItem( @Path("itemId") itemId: Int, @Body request: UpdateCartItemRequest ): Response<ApiResponse<Cart>> } data class UpdateCartItemRequest( val quantity: Int ) // Usage val cartService = retrofit.create(CartService::class.java) val response = cartService.updateCartItem(1, UpdateCartItemRequest(3)) if (response.isSuccessful) { val updatedCart = response.body()?.data // Update cart UI }

Remove Cart Item

interface CartService { @DELETE("api/cart/{itemId}") suspend fun removeCartItem(@Path("itemId") itemId: Int): Response<ApiResponse<Cart>> } // Usage val cartService = retrofit.create(CartService::class.java) val response = cartService.removeCartItem(1) if (response.isSuccessful) { val updatedCart = response.body()?.data // Update cart UI }

Order Management

Create Order

interface OrderService { @POST("api/orders") suspend fun createOrder(@Body request: CreateOrderRequest): Response<ApiResponse<Order>> } data class CreateOrderRequest( val shippingAddress: String ) data class Order( val id: Int, val userId: Int, val status: String, val totalAmount: Double, val createdAt: String, val items: List<OrderItem> ) data class OrderItem( val id: Int, val orderId: Int, val productId: Int, val quantity: Int, val price: Double, val product: Product? ) // Usage val orderService = retrofit.create(OrderService::class.java) val response = orderService.createOrder(CreateOrderRequest("123 Main St, City, Country")) if (response.isSuccessful) { val order = response.body()?.data // Proceed to payment }

Get Order History

interface OrderService { @GET("api/orders") suspend fun getOrders(): Response<ApiResponse<List<Order>>> } // Usage val orderService = retrofit.create(OrderService::class.java) val response = orderService.getOrders() if (response.isSuccessful) { val orders = response.body()?.data // Display order history }

Payment Processing

Get Payment Methods

interface PaymentService { @GET("api/payment/methods") suspend fun getPaymentMethods(): Response<ApiResponse<List<PaymentMethod>>> } data class PaymentMethod( val id: String, val name: String ) // Usage val paymentService = retrofit.create(PaymentService::class.java) val response = paymentService.getPaymentMethods() if (response.isSuccessful) { val paymentMethods = response.body()?.data // Display payment method options }

Process Payment

interface PaymentService { @POST("api/payment/process") suspend fun processPayment(@Body request: ProcessPaymentRequest): Response<ApiResponse<PaymentResponse>> } data class ProcessPaymentRequest( val orderId: Int, val paymentMethodId: String, val amount: Double ) data class PaymentResponse( val success: Boolean, val transactionId: String?, val message: String? ) // Usage val paymentService = retrofit.create(PaymentService::class.java) val response = paymentService.processPayment( ProcessPaymentRequest( orderId = 1, paymentMethodId = "credit_card", amount = 99.99 ) ) if (response.isSuccessful) { val paymentResult = response.body()?.data if (paymentResult?.success == true) { // Payment successful, show confirmation } else { // Payment failed, show error message } }

Setting Up Retrofit

Here's how to set up Retrofit with authentication interceptor:

class AuthInterceptor(private val tokenProvider: () -> String?) : Interceptor { override fun intercept(chain: Interceptor.Chain): okhttp3.Response { val token = tokenProvider() val request = if (token != null) { chain.request().newBuilder() .addHeader("Authorization", "Bearer $token") .build() } else { chain.request() } return chain.proceed(request) } } // Create OkHttpClient with interceptor val okHttpClient = OkHttpClient.Builder() .addInterceptor(AuthInterceptor { getStoredToken() }) .build() // Create Retrofit instance val retrofit = Retrofit.Builder() .baseUrl("https://{YOUR_VAL_TOWN_URL}/") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build()

API Response Wrapper

All API responses follow this structure:

data class ApiResponse<T>( val success: Boolean, val data: T?, val error: String? )

Error Handling

fun <T> handleApiResponse(response: Response<ApiResponse<T>>, onSuccess: (T) -> Unit) { if (response.isSuccessful) { val apiResponse = response.body() if (apiResponse?.success == true && apiResponse.data != null) { onSuccess(apiResponse.data) } else { // Handle API error showError(apiResponse?.error ?: "Unknown error") } } else { // Handle HTTP error showError("Network error: ${response.code()}") } }

Sample App Structure

Here's a recommended structure for your Android app:

com.example.ecommerce/
├── api/
│   ├── ApiClient.kt
│   ├── AuthInterceptor.kt
│   └── services/
│       ├── AuthService.kt
│       ├── ProductService.kt
│       ├── CartService.kt
│       ├── OrderService.kt
│       └── PaymentService.kt
├── models/
│   ├── User.kt
│   ├── Product.kt
│   ├── Cart.kt
│   ├── Order.kt
│   └── Payment.kt
├── ui/
│   ├── auth/
│   │   ├── LoginActivity.kt
│   │   └── RegisterActivity.kt
│   ├── products/
│   │   ├── ProductListActivity.kt
│   │   └── ProductDetailActivity.kt
│   ├── cart/
│   │   └── CartActivity.kt
│   ├── checkout/
│   │   ├── CheckoutActivity.kt
│   │   └── PaymentActivity.kt
│   └── orders/
│       └── OrderHistoryActivity.kt
└── utils/
    ├── TokenManager.kt
    └── ErrorHandler.kt

Next Steps

  1. Set up your Android project with the recommended structure
  2. Implement the API services using Retrofit
  3. Create the UI for each screen (product list, product details, cart, checkout, etc.)
  4. Implement authentication and token management
  5. Test the complete flow from browsing products to completing a purchase
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.