# Beckn-ONIX Setup Guide This comprehensive guide walks you through setting up Beckn-ONIX from development to production deployment. ## Table of Contents 1. [Prerequisites](#prerequisites) 2. [Development Setup](#development-setup) 3. [Production Setup](#production-setup) 4. [Configuration Guide](#configuration-guide) 5. [External Services Setup](#external-services-setup) 6. [GUI Component Setup](#gui-component-setup) 7. [Docker Deployment](#docker-deployment) 8. [Kubernetes Deployment](#kubernetes-deployment) 9. [Testing Your Setup](#testing-your-setup) 10. [Troubleshooting](#troubleshooting) 11. [Sample Payloads](#sample-payloads) --- ## Prerequisites ### System Requirements - **Operating System**: Linux, macOS, or Windows (with WSL2) - **CPU**: 2+ cores recommended - **RAM**: 4GB minimum, 8GB recommended - **Disk Space**: 2GB free space ### Software Requirements #### Required - **Go 1.23+**: [Download Go](https://golang.org/dl/) - **Git**: [Download Git](https://git-scm.com/downloads) - **Redis 6.0+**: For caching functionality #### Optional (for production) - **Docker 20.10+**: For containerized deployment - **HashiCorp Vault 1.12+**: For secrets management - **RabbitMQ 3.10+**: For async messaging - **Kubernetes 1.25+**: For orchestrated deployment ### Verify Installation ```bash # Check Go version go version # Expected: go version go1.23.x # Check Git git --version # Check Docker (optional) docker --version # Check Redis redis-cli --version ``` --- ## Quick Start (Recommended) For a complete Beckn network setup with all services, use our automated setup: ```bash # Clone the repository git clone https://github.com/beckn/beckn-onix.git cd beckn-onix # Run the setup (includes only adapter services) cd install chmod +x setup.sh ./setup.sh # Start the Beckn-ONIX server source .env.vault && ./server --config=config/local-dev.yaml ``` This will automatically: - Run & Configure Redis and Vault - Build all plugins - Set up authentication - Create environment variables **Services Started:** - Vault: http://localhost:8200 - Redis: localhost:6379 - Beckn-ONIX: http://localhost:8081 **To stop all services:** `docker compose down` **To view logs:** `docker compose logs -f [service-name]` --- ## Development Setup (Manual) ### Step 1: Clone the Repository ```bash git clone https://github.com/beckn/beckn-onix.git cd beckn-onix ``` ### Step 2: Install Dependencies ```bash # Download Go dependencies go mod download # Verify dependencies go mod verify ``` ### Step 3: Build the Application ```bash # Build the main server binary go build -o server cmd/adapter/main.go # Make it executable chmod +x server ``` ### Step 4: Build Plugins The application uses a plugin architecture. Build all plugins: ```bash # Make the build script executable chmod +x install/build-plugins.sh # Build all plugins ./install/build-plugins.sh ``` This creates `.so` files in the `plugins/` directory: - `cache.so` - Redis caching - `router.so` - Request routing - `signer.so` - Message signing - `signvalidator.so` - Signature validation - `schemavalidator.so` - JSON schema validation - `keymanager.so` - Vault integration - `publisher.so` - RabbitMQ publishing - `encrypter.so` / `decrypter.so` - Encryption/decryption - `reqpreprocessor.so` - Request preprocessing ### Step 5: Setup Redis (Local) #### Option A: Using Docker ```bash docker run -d \ --name redis-onix \ -p 6379:6379 \ redis:alpine ``` #### Option B: Native Installation **macOS:** ```bash brew install redis brew services start redis ``` **Ubuntu/Debian:** ```bash sudo apt update sudo apt install redis-server sudo systemctl start redis-server sudo systemctl enable redis-server ``` **Verify Redis:** ```bash redis-cli ping # Expected: PONG ``` ### Step 6: Create Required Directories ```bash # Create schemas directory for validation mkdir -p schemas # Create logs directory (optional) mkdir -p logs ``` ### Step 7: Configure for Local Development Create or modify `config/local-dev.yaml`: ```yaml appName: "onix-local" log: level: debug destinations: - type: stdout contextKeys: - transaction_id - message_id - subscriber_id - module_id http: port: 8081 timeout: read: 30 write: 30 idle: 30 pluginManager: root: ./plugins modules: - name: bapTxnReceiver path: /bap/receiver/ handler: type: std role: bap registryUrl: http://localhost:8080/reg plugins: keyManager: id: keymanager config: projectID: beckn-onix-local vaultAddr: http://localhost:8200 kvVersion: v2 mountPath: beckn cache: id: cache config: addr: localhost:6379 schemaValidator: id: schemavalidator config: schemaDir: ./schemas signValidator: id: signvalidator config: publicKeyPath: beckn/keys router: id: router config: routingConfig: ./config/local-routing.yaml middleware: - id: reqpreprocessor config: uuidKeys: transaction_id,message_id role: bap steps: - validateSign - addRoute - validateSchema - name: bapTxnCaller path: /bap/caller/ handler: type: std role: bap registryUrl: http://localhost:8080/reg plugins: keyManager: id: keymanager config: projectID: beckn-onix-local vaultAddr: http://localhost:8200 kvVersion: v2 mountPath: beckn cache: id: cache config: addr: localhost:6379 router: id: router config: routingConfig: ./config/local-routing.yaml signer: id: signer middleware: - id: reqpreprocessor config: uuidKeys: transaction_id,message_id role: bap steps: - addRoute - sign - name: bppTxnReceiver path: /bpp/receiver/ handler: type: std role: bpp registryUrl: http://localhost:8080/reg plugins: keyManager: id: keymanager config: projectID: beckn-onix-local vaultAddr: http://localhost:8200 kvVersion: v2 mountPath: beckn cache: id: cache config: addr: localhost:6379 schemaValidator: id: schemavalidator config: schemaDir: ./schemas signValidator: id: signvalidator config: publicKeyPath: beckn/keys router: id: router config: routingConfig: ./config/local-routing.yaml steps: - validateSign - addRoute - validateSchema - name: bppTxnCaller path: /bpp/caller/ handler: type: std role: bpp registryUrl: http://localhost:8080/reg plugins: keyManager: id: keymanager config: projectID: beckn-onix-local vaultAddr: http://localhost:8200 kvVersion: v2 mountPath: beckn cache: id: cache config: addr: localhost:6379 router: id: router config: routingConfig: ./config/local-routing.yaml signer: id: signer steps: - addRoute - sign ``` ### Step 8: Create Routing Configuration Create `config/local-routing.yaml`: ```yaml routingRules: - domain: "nic2004:60221" # Mobility domain version: "0.9.4" targetType: "url" target: url: "http://localhost:9001/beckn" endpoints: - search - select - init - confirm - status - track - cancel - update - rating - support - domain: "nic2004:52110" # Retail domain version: "1.0.0" targetType: "url" target: url: "http://localhost:9002/beckn" endpoints: - search - select - init - confirm - status - track - cancel - update - rating - support ``` ### Step 9: Run the Application with HashiCorp Vault Since the configuration now includes the keyManager plugin for signing capabilities, you need to set up Vault: #### Quick Setup (Recommended) **Note:** Make sure Redis is already running from Step 5. ```bash # Make the script executable chmod +x start-vault.sh # Run the automated setup script ./start-vault.sh # This creates a .env.vault file with your credentials # Source it and run the server source .env.vault && ./server --config=config/local-dev.yaml ``` That's it! The script handles everything automatically. #### Manual Setup (Advanced) If you prefer to set up Vault manually or need custom configuration: ```bash # 1. Start Vault container docker run -d \ --name vault-dev \ --cap-add=IPC_LOCK \ -p 8200:8200 \ -e 'VAULT_DEV_ROOT_TOKEN_ID=root' \ hashicorp/vault:latest # 2. Configure Vault (run the setup script) chmod +x config/setup-vault.sh ./config/setup-vault.sh # 3. Export the displayed credentials export VAULT_ROLE_ID= export VAULT_SECRET_ID= # 4. Run the server ./server --config=config/local-dev.yaml ``` #### What the Setup Does - Starts Vault in development mode on port 8200 - Enables AppRole authentication - Creates necessary policies and roles - Sets up the KV secrets engine at path `beckn` - Stores sample keys for both BAP and BPP - Generates and saves credentials to `.env.vault` #### Accessing Vault UI - **URL:** http://localhost:8200 - **Token:** root #### Troubleshooting If you get "invalid role or secret ID" error, the SECRET_ID has expired. Simply run: ```bash ./start-vault.sh source .env.vault ``` **Alternative: Simple Docker Run Command** ```bash # Start Vault in dev mode with initial setup docker run -d \ --name vault-dev \ --cap-add=IPC_LOCK \ -p 8200:8200 \ -e 'VAULT_DEV_ROOT_TOKEN_ID=root' \ -e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \ hashicorp/vault:latest # Wait for Vault to be ready sleep 3 # Setup Vault using a single command docker exec vault-dev sh -c " export VAULT_ADDR='http://127.0.0.1:8200' && export VAULT_TOKEN='root' && vault secrets enable -path=beckn kv-v2 && vault kv put beckn/keys/bap private_key='sample_bap_private_key' public_key='sample_bap_public_key' && vault kv put beckn/keys/bpp private_key='sample_bpp_private_key' public_key='sample_bpp_public_key' " ``` **Step 9b: Set Environment Variables and Run** ```bash # Get the AppRole credentials from Vault container logs docker logs vault-dev | grep "VAULT_ROLE_ID\|VAULT_SECRET_ID" # Copy the displayed credentials and export them # They will look something like this: export VAULT_ROLE_ID='' export VAULT_SECRET_ID='' # Run the server ./server --config=config/local-dev.yaml # Or using go run go run cmd/adapter/main.go --config=config/local-dev.yaml ``` **Note:** The Vault address is already configured in `config/local-dev.yaml` as `http://localhost:8200`. The docker-compose automatically sets up AppRole authentication and displays the credentials in the logs. **Alternative: Create a startup script** Create `run-with-vault.sh`: ```bash #!/bin/bash # Set Vault environment variables export VAULT_ADDR=${VAULT_ADDR:-"http://localhost:8200"} export VAULT_TOKEN=${VAULT_TOKEN:-"root"} # For dev mode # Or use AppRole auth for production-like setup # export VAULT_ROLE_ID=${VAULT_ROLE_ID:-"beckn-role-id"} # export VAULT_SECRET_ID=${VAULT_SECRET_ID:-"beckn-secret-id"} echo "Starting Beckn-ONIX with Vault key management..." echo "Vault Address: $VAULT_ADDR" # Check if Vault is accessible if ! curl -s "$VAULT_ADDR/v1/sys/health" > /dev/null 2>&1; then echo "Error: Cannot reach Vault at $VAULT_ADDR" echo "Please start Vault first with: vault server -dev -dev-root-token-id='root'" exit 1 fi # Run the server ./server --config=config/local-dev.yaml ``` Make it executable and run: ```bash chmod +x run-with-vault.sh ./run-with-vault.sh ``` The server will start on `http://localhost:8081` ### Step 10: Verify Setup ```bash # Check health endpoint curl http://localhost:8081/health # Check if modules are loaded curl http://localhost:8081/bap/receiver/ # Expected: 404 with proper error (means module is loaded) ``` --- ## Production Setup ### Additional Requirements for Production 1. **HashiCorp Vault** for key management 2. **RabbitMQ** for message queuing 3. **TLS certificates** for secure communication 4. **Load balancer** for high availability ### Step 1: Setup HashiCorp Vault #### Install Vault ```bash # Download and install wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip unzip vault_1.15.0_linux_amd64.zip sudo mv vault /usr/local/bin/ ``` #### Configure Vault ```bash # Start Vault in dev mode (for testing only) vault server -dev -dev-root-token-id="root" # In production, use proper configuration cat > vault-config.hcl < # Or use different port in config ``` #### 6. Vault Authentication Issues **Error**: `vault: authentication failed` **Solution**: ```bash # Check Vault status vault status # Verify authentication vault login -method=approle \ role_id=${VAULT_ROLE_ID} \ secret_id=${VAULT_SECRET_ID} # Check policy permissions vault policy read beckn-policy ``` ### Debug Mode Enable debug logging: ```yaml log: level: debug destinations: - type: stdout config: pretty: true includeCalller: true ``` Or via environment variable: ```bash LOG_LEVEL=debug ./server --config=config/adapter.yaml ``` ### Performance Tuning #### System Limits ```bash # Increase file descriptors ulimit -n 65536 # Add to /etc/security/limits.conf beckn soft nofile 65536 beckn hard nofile 65536 ``` #### Go Runtime ```bash # Set GOMAXPROCS export GOMAXPROCS=8 # Enable profiling ./server --config=config/adapter.yaml --profile ``` #### Redis Optimization ```bash # Redis configuration redis-cli CONFIG SET maxclients 10000 redis-cli CONFIG SET tcp-keepalive 60 redis-cli CONFIG SET timeout 300 ``` --- ## Sample Payloads ### Search Request (Retail) ```json { "context": { "domain": "nic2004:52110", "country": "IND", "city": "std:080", "action": "search", "core_version": "1.0.0", "bap_id": "buyerapp.com", "bap_uri": "https://buyerapp.com/beckn", "transaction_id": "6d5f4c3b-2a1e-4b8c-9f7d-3e2a1b5c8d9f", "message_id": "a9f8e7d6-c5b4-3a2e-1f0d-9e8c7b6a5d4f", "timestamp": "2024-01-15T10:30:00.000Z", "ttl": "PT30S" }, "message": { "intent": { "item": { "descriptor": { "name": "Laptop" } }, "fulfillment": { "type": "Delivery", "end": { "location": { "gps": "12.9715987,77.5945627", "area_code": "560001" } } }, "payment": { "buyer_app_finder_fee_type": "percent", "buyer_app_finder_fee_amount": "3" } } } } ``` ### Select Request ```json { "context": { "domain": "nic2004:52110", "country": "IND", "city": "std:080", "action": "select", "core_version": "1.0.0", "bap_id": "buyerapp.com", "bap_uri": "https://buyerapp.com/beckn", "bpp_id": "sellerapp.com", "bpp_uri": "https://sellerapp.com/beckn", "transaction_id": "6d5f4c3b-2a1e-4b8c-9f7d-3e2a1b5c8d9f", "message_id": "b8e7f6d5-c4a3-2b1e-0f9d-8e7c6b5a4d3f", "timestamp": "2024-01-15T10:31:00.000Z", "ttl": "PT30S" }, "message": { "order": { "provider": { "id": "P1", "locations": [ { "id": "L1" } ] }, "items": [ { "id": "I1", "quantity": { "count": 2 } } ], "fulfillment": { "end": { "location": { "gps": "12.9715987,77.5945627", "address": { "door": "21A", "name": "ABC Apartments", "building": "Tower 1", "street": "100 Feet Road", "locality": "Indiranagar", "city": "Bengaluru", "state": "Karnataka", "country": "India", "area_code": "560001" } }, "contact": { "phone": "9876543210", "email": "customer@example.com" } } } } } } ``` ### Init Request ```json { "context": { "domain": "nic2004:52110", "country": "IND", "city": "std:080", "action": "init", "core_version": "1.0.0", "bap_id": "buyerapp.com", "bap_uri": "https://buyerapp.com/beckn", "bpp_id": "sellerapp.com", "bpp_uri": "https://sellerapp.com/beckn", "transaction_id": "6d5f4c3b-2a1e-4b8c-9f7d-3e2a1b5c8d9f", "message_id": "c7f6e5d4-b3a2-1e0f-9d8e-7c6b5a4d3e2f", "timestamp": "2024-01-15T10:32:00.000Z", "ttl": "PT30S" }, "message": { "order": { "provider": { "id": "P1", "locations": [ { "id": "L1" } ] }, "items": [ { "id": "I1", "quantity": { "count": 2 }, "fulfillment_id": "F1" } ], "billing": { "name": "John Doe", "address": { "door": "21A", "name": "ABC Apartments", "building": "Tower 1", "street": "100 Feet Road", "locality": "Indiranagar", "city": "Bengaluru", "state": "Karnataka", "country": "India", "area_code": "560001" }, "email": "john.doe@example.com", "phone": "9876543210", "created_at": "2024-01-15T10:32:00.000Z", "updated_at": "2024-01-15T10:32:00.000Z" }, "fulfillment": { "id": "F1", "type": "Delivery", "tracking": false, "end": { "location": { "gps": "12.9715987,77.5945627", "address": { "door": "21A", "name": "ABC Apartments", "building": "Tower 1", "street": "100 Feet Road", "locality": "Indiranagar", "city": "Bengaluru", "state": "Karnataka", "country": "India", "area_code": "560001" } }, "contact": { "phone": "9876543210", "email": "customer@example.com" } } }, "payment": { "type": "ON-ORDER", "collected_by": "BAP", "buyer_app_finder_fee_type": "percent", "buyer_app_finder_fee_amount": "3", "settlement_details": [ { "settlement_counterparty": "seller-app", "settlement_phase": "sale-amount", "settlement_type": "neft", "settlement_bank_account_no": "1234567890", "settlement_ifsc_code": "SBIN0001234", "beneficiary_name": "Seller Name", "bank_name": "State Bank of India", "branch_name": "Koramangala" } ] } } } } ``` ### Confirm Request ```json { "context": { "domain": "nic2004:52110", "country": "IND", "city": "std:080", "action": "confirm", "core_version": "1.0.0", "bap_id": "buyerapp.com", "bap_uri": "https://buyerapp.com/beckn", "bpp_id": "sellerapp.com", "bpp_uri": "https://sellerapp.com/beckn", "transaction_id": "6d5f4c3b-2a1e-4b8c-9f7d-3e2a1b5c8d9f", "message_id": "d8f7e6d5-c4b3-2a1e-0f9d-8e7c6b5a4d3f", "timestamp": "2024-01-15T10:33:00.000Z", "ttl": "PT30S" }, "message": { "order": { "id": "ORDER123", "state": "Created", "provider": { "id": "P1", "locations": [ { "id": "L1" } ] }, "items": [ { "id": "I1", "fulfillment_id": "F1", "quantity": { "count": 2 } } ], "quote": { "price": { "currency": "INR", "value": "4000" }, "breakup": [ { "item_id": "I1", "item_quantity": { "count": 2 }, "title_type": "item", "title": "Laptop", "price": { "currency": "INR", "value": "3800" } }, { "item_id": "F1", "title_type": "delivery", "title": "Delivery charges", "price": { "currency": "INR", "value": "100" } }, { "item_id": "F1", "title_type": "packing", "title": "Packing charges", "price": { "currency": "INR", "value": "50" } }, { "item_id": "I1", "title_type": "tax", "title": "Tax", "price": { "currency": "INR", "value": "50" } } ], "ttl": "P1D" }, "payment": { "uri": "https://ondc.transaction.com/payment", "tl_method": "http/get", "params": { "transaction_id": "TXN123456", "amount": "4000", "currency": "INR" }, "type": "ON-ORDER", "status": "PAID", "collected_by": "BAP", "buyer_app_finder_fee_type": "percent", "buyer_app_finder_fee_amount": "3", "settlement_details": [ { "settlement_counterparty": "seller-app", "settlement_phase": "sale-amount", "settlement_type": "neft", "settlement_bank_account_no": "1234567890", "settlement_ifsc_code": "SBIN0001234", "beneficiary_name": "Seller Name", "bank_name": "State Bank of India", "branch_name": "Koramangala" } ] }, "fulfillment": { "id": "F1", "type": "Delivery", "tracking": true, "start": { "location": { "id": "L1", "descriptor": { "name": "Seller Store" }, "gps": "12.9715987,77.5945627", "address": { "locality": "Koramangala", "city": "Bengaluru", "area_code": "560034", "state": "Karnataka" } }, "time": { "range": { "start": "2024-01-15T11:00:00.000Z", "end": "2024-01-15T12:00:00.000Z" } }, "contact": { "phone": "9988776655", "email": "seller@example.com" } }, "end": { "location": { "gps": "12.9715987,77.5945627", "address": { "door": "21A", "name": "ABC Apartments", "building": "Tower 1", "street": "100 Feet Road", "locality": "Indiranagar", "city": "Bengaluru", "state": "Karnataka", "country": "India", "area_code": "560001" } }, "time": { "range": { "start": "2024-01-15T14:00:00.000Z", "end": "2024-01-15T18:00:00.000Z" } }, "person": { "name": "John Doe" }, "contact": { "phone": "9876543210", "email": "customer@example.com" } } }, "created_at": "2024-01-15T10:33:00.000Z", "updated_at": "2024-01-15T10:33:00.000Z" } } } ``` ### Authorization Header Structure All requests must include proper authorization: ``` Authorization: Signature keyId="{subscriber_id}|{key_id}|{algorithm}",algorithm="{algorithm}",created="{created}",expires="{expires}",headers="(created) (expires) digest",signature="{base64_signature}" ``` Example generation in bash: ```bash #!/bin/bash # Variables SUBSCRIBER_ID="buyerapp.com" KEY_ID="key1" ALGORITHM="ed25519" CREATED=$(date +%s) EXPIRES=$((CREATED + 300)) PRIVATE_KEY="path/to/private_key.pem" # Create string to sign STRING_TO_SIGN="(created): ${CREATED} (expires): ${EXPIRES} digest: SHA-256=${DIGEST}" # Sign with Ed25519 SIGNATURE=$(echo -n "$STRING_TO_SIGN" | \ openssl pkeyutl -sign -inkey $PRIVATE_KEY -rawin | \ base64 -w 0) # Create header AUTH_HEADER="Signature keyId=\"${SUBSCRIBER_ID}|${KEY_ID}|${ALGORITHM}\",algorithm=\"${ALGORITHM}\",created=\"${CREATED}\",expires=\"${EXPIRES}\",headers=\"(created) (expires) digest\",signature=\"${SIGNATURE}\"" echo $AUTH_HEADER ``` --- ## Conclusion This setup guide covers all aspects of deploying Beckn-ONIX from local development to production. Key points: 1. **Start Simple**: Begin with local development setup 2. **Test Thoroughly**: Use provided test scripts and payloads 3. **Scale Gradually**: Move from single instance to clustered deployment 4. **Monitor Continuously**: Use logs and metrics for observability 5. **Secure Always**: Implement proper authentication and encryption For additional help: - Check [GitHub Issues](https://github.com/beckn/beckn-onix/issues) - Join [Community Discussions](https://github.com/beckn/beckn-onix/discussions) - Review [API Documentation](https://docs.beckn.org) Happy deploying! 🚀