{"id":13987802,"url":"https://github.com/l4rm4nd/VoucherVault","last_synced_at":"2025-07-22T07:31:29.318Z","repository":{"id":247315311,"uuid":"825422733","full_name":"l4rm4nd/VoucherVault","owner":"l4rm4nd","description":"Django web application to store and manage vouchers, coupons, loyalty and gift cards digitally. Supports expiry notifications, transaction histories, file uploads and OIDC SSO.","archived":false,"fork":false,"pushed_at":"2025-07-05T10:53:31.000Z","size":16189,"stargazers_count":346,"open_issues_count":1,"forks_count":11,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-07-17T14:18:18.588Z","etag":null,"topics":["apprise","asset-manager","conventional-commits","coupon","coupon-management","coupon-management-system","coupons","django5","expiry-checker","giftcard","giftcards","loyalty-cards","loyaltycard","oidc","python3","selfhosting","stocard","voucher","vouchers","vouchers-management"],"latest_commit_sha":null,"homepage":"https://github.com/l4rm4nd/VoucherVault/wiki","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/l4rm4nd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-07T18:16:23.000Z","updated_at":"2025-07-10T16:45:03.000Z","dependencies_parsed_at":"2024-08-04T17:04:52.980Z","dependency_job_id":"90846db6-b975-4e2b-9f34-84bb40dc761e","html_url":"https://github.com/l4rm4nd/VoucherVault","commit_stats":null,"previous_names":["l4rm4nd/vouchervault"],"tags_count":104,"template":false,"template_full_name":null,"purl":"pkg:github/l4rm4nd/VoucherVault","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l4rm4nd%2FVoucherVault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l4rm4nd%2FVoucherVault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l4rm4nd%2FVoucherVault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l4rm4nd%2FVoucherVault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/l4rm4nd","download_url":"https://codeload.github.com/l4rm4nd/VoucherVault/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l4rm4nd%2FVoucherVault/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266447610,"owners_count":23929988,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apprise","asset-manager","conventional-commits","coupon","coupon-management","coupon-management-system","coupons","django5","expiry-checker","giftcard","giftcards","loyalty-cards","loyaltycard","oidc","python3","selfhosting","stocard","voucher","vouchers","vouchers-management"],"created_at":"2024-08-09T12:01:07.038Z","updated_at":"2025-07-22T07:31:24.299Z","avatar_url":"https://github.com/l4rm4nd.png","language":"HTML","funding_links":["https://www.buymeacoffee.com/LRVT"],"categories":["Software","HTML"],"sub_categories":["Money, Budgeting \u0026 Management"],"readme":"\u003cdiv align=\"center\" width=\"100%\"\u003e\n    \u003ch1\u003eVoucherVault\u003c/h1\u003e\n    \u003cimg width=\"150px\" src=\"myapp/static/assets/img/logo.png\"\u003e\n    \u003cp\u003eDjango web application to store and manage vouchers, coupons, loyalty and gift cards digitally\u003c/p\u003e\u003cp\u003e\n    \u003ca target=\"_blank\" href=\"https://github.com/l4rm4nd\"\u003e\u003cimg src=\"https://img.shields.io/badge/maintainer-LRVT-orange\" /\u003e\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://GitHub.com/l4rm4nd/VoucherVault/graphs/contributors/\"\u003e\u003cimg src=\"https://img.shields.io/github/contributors/l4rm4nd/VoucherVault.svg\" /\u003e\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://github.com/PyCQA/bandit\"\u003e\u003cimg src=\"https://img.shields.io/badge/security-bandit-yellow.svg\"/\u003e\u003c/a\u003e\u003cbr\u003e\n    \u003ca target=\"_blank\" href=\"https://GitHub.com/l4rm4nd/VoucherVault/commits/\"\u003e\u003cimg src=\"https://img.shields.io/github/last-commit/l4rm4nd/VoucherVault.svg\" /\u003e\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://GitHub.com/l4rm4nd/VoucherVault/issues/\"\u003e\u003cimg src=\"https://img.shields.io/github/issues/l4rm4nd/VoucherVault.svg\" /\u003e\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://github.com/l4rm4nd/VoucherVault/issues?q=is%3Aissue+is%3Aclosed\"\u003e\u003cimg src=\"https://img.shields.io/github/issues-closed/l4rm4nd/VoucherVault.svg\" /\u003e\u003c/a\u003e\u003cbr\u003e\n        \u003ca target=\"_blank\" href=\"https://github.com/l4rm4nd/VoucherVault/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/l4rm4nd/VoucherVault.svg?style=social\u0026label=Star\" /\u003e\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://github.com/l4rm4nd/VoucherVault/network/members\"\u003e\u003cimg src=\"https://img.shields.io/github/forks/l4rm4nd/VoucherVault.svg?style=social\u0026label=Fork\" /\u003e\u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://github.com/l4rm4nd/VoucherVault/watchers\"\u003e\u003cimg src=\"https://img.shields.io/github/watchers/l4rm4nd/VoucherVault.svg?style=social\u0026label=Watch\" /\u003e\u003c/a\u003e\u003cbr\u003e\n    \u003ca target=\"_blank\" href=\"https://hub.docker.com/r/l4rm4nd/vouchervault\"\u003e\u003cimg src=\"https://badgen.net/badge/icon/l4rm4nd%2Fvouchervault:latest?icon=docker\u0026label\" /\u003e\u003c/a\u003e\u003cbr\u003e\u003cp\u003e\n    \u003ca href=\"https://www.buymeacoffee.com/LRVT\" target=\"_blank\"\u003e\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me A Coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\" \u003e\u003c/a\u003e\n\u003c/div\u003e\n\n## ⭐ Features\n\n- User-friendly, mobile-optimized web portal\n- Light and dark theme support\n- Integration of vouchers, coupons, gift cards and loyalty cards\n- Transaction history tracking (gift cards only)\n- Item-specific file uploads (images and PDFs)\n- Item sharing between users\n- Display of redeem codes as QR codes or EAN13 barcodes\n- Client-side redeem code scanning (1D/2D) during item creation\n- Expiry notifications via Apprise\n- Multi-user support\n- Multi-language support (English, German, French, Italian)\n- Single Sign-On (SSO) via OIDC\n- Database compatibility with SQLite3 and PostgreSQL\n- REST API endpoint with stats for Home Assisstant (HA) and other dashboards\n\n## 📷 Screenshots\n\n\u003cdetails\u003e\n\u003cimg src=\"screenshots/dashboard.png\"\u003e\n\u003cimg src=\"screenshots/items.png\"\u003e\n\u003cimg src=\"screenshots/item-details.png\"\u003e\n\u003c/details\u003e\n\n## 🐳 Usage\n\n[READ THE WIKI](https://github.com/l4rm4nd/VoucherVault/wiki/01-%E2%80%90-Installation)\n\n````\n# create volume dir for persistence\nmkdir -p ./volume-data/database\n\n# adjust permissions\nsudo chown -R www-data:www-data volume-data/*\n\n# spawn the container stack\ndocker compose -f docker/docker-compose-sqlite.yml up\n````\n\nOnce the container is up and running, you can access the web portal at http://127.0.0.1:8000. \n\nThe default username is `admin`. The default password is auto-generated.\n\nYou can obtain the auto-generated password via the Docker container logs:\n\n````\ndocker compose -f docker/docker-compose-sqlite.yml logs -f\n````\n\n\u003e [!WARNING]\n\u003e The container runs as low-privileged `www-data` user. So you have to adjust the permissions for the persistent database bind mount volume. A command like `sudo chown -R www-data:www-data \u003cpath-to-volume-data-dir\u003e` should work. Afterwards, please restart the container.\n\n\u003e [!TIP]\n\u003e This repository follows the Conventional Commits standard. Therefore, you will find `patch`, `minor` and `major` release version tags on DockerHub.\n\u003e No one stops you from using the `latest` image tag but I recommend pinning a minor version series tag such as `1.7.x`.\n\u003e\n\u003e This is safer for automatic upgrades and you still get recent patches as well as bug fixes.\n\n## 🌍 Environment Variables\n\nThe docker container takes various environment variables:\n\n| Variable                         | Description                                                                                                     | Default                    | Optional/Mandatory  |\n|----------------------------------|-----------------------------------------------------------------------------------------------------------------|----------------------------|---------------------|\n| `DOMAIN`                         | Your Fully Qualified Domain Name (FQDN) or IP address. Used to define `ALLOWED_HOSTS` and `CSRF_TRUSTED_ORIGINS` for the Django framework. | `localhost` | Mandatory           |\n| `SECURE_COOKIES`                 | Set to `True` if you use a reverse proxy with TLS. Enables the `secure` cookie flag and `HSTS` HTTP response header, which will only work for SSL/TLS encrypted communication channels (HTTPS). | `False`                    | Optional            |\n| `EXPIRY_THRESHOLD_DAYS`          | Defines the days prior item expiry when an Apprise expiry notification should be sent out.                      | `30`                       | Optional            |\n| `TZ`                             | Defines the `TIME_ZONE` variable in Django's settings.py.                                                       | `Europe/Berlin`            | Optional            |\n| `SECRET_KEY`                     | Defines a fixed secret key for the Django framework. If missing, a secure secret is auto-generated on the server-side each time the container starts. | `\u003cauto-generated\u003e`         | Optional            |\n| `PORT`                           | Defines a custom port. Used to set `CSRF_TRUSTED_ORIGINS` in conjunction with the `DOMAIN` environment variable for the Django framework. Only necessary, if VoucherVault is operated on a different port than `8000`, `80` or `443`. | `8000`                     | Optional            |\n| `REDIS_URL`                      | Defines the Redis URL to use for Django-Celery-Beat task processing.                                            | `redis://redis:6379/0`     | Optional            |\n| `OIDC_ENABLED`                   | Set to `True` to enable OIDC authentication.                                                                    | `False`                    | Optional            |\n| `OIDC_CREATE_USER`               | Set to `True` to allow the creation of new users through OIDC.                                                  | `True`                     | Optional            |\n| `OIDC_RP_SIGN_ALGO`              | The signing algorithm used by the OIDC provider (e.g., RS256, HS256).                                           | `HS256`                    | Optional            |\n| `OIDC_OP_JWKS_ENDPOINT`          | URL of the JWKS endpoint for the OIDC provider. Mandatory if `RS256` signing algo is used.                      | `None`                     | Optional            |\n| `OIDC_RP_CLIENT_ID`              | Client ID for your OIDC RP.                                                                                     | `None`                     | Optional            |\n| `OIDC_RP_CLIENT_SECRET`          | Client secret for your OIDC RP.                                                                                 | `None`                     | Optional            |\n| `OIDC_OP_AUTHORIZATION_ENDPOINT` | Authorization endpoint URL of the OIDC provider.                                                                | `None`                     | Optional            |\n| `OIDC_OP_TOKEN_ENDPOINT`         | Token endpoint URL of the OIDC provider.                                                                        | `None`                     | Optional            |\n| `OIDC_OP_USER_ENDPOINT`          | User info endpoint URL of the OIDC provider.                                                                    | `None`                     | Optional            |\n| `DB_ENGINE`                      | Database engine to use (e.g., `postgres` for PostgreSQL or `sqlite3` for SQLite3).                              | `sqlite3`                  | Optional            |\n| `POSTGRES_HOST`                  | Hostname for the PostgreSQL database.                                                                           | `db`                       | Optional            |\n| `POSTGRES_PORT`                  | Port number for the PostgreSQL database.                                                                        | `5432`                     | Optional            |\n| `POSTGRES_USER`                  | PostgreSQL database user.                                                                                       | `vouchervault`             | Optional            |\n| `POSTGRES_PASSWORD`              | PostgreSQL database password.                                                                                   | `vouchervault`             | Optional            |\n| `POSTGRES_DB`                    | PostgreSQL database name.                                                                                       | `vouchervault`             | Optional            |\n\nYou can find detailed instructions on how to setup OIDC SSO in the [wiki](https://github.com/l4rm4nd/VoucherVault/wiki/02-%E2%80%90-Authentication#oidc-authentication).\n\n## 🔔 Notifications\n\nNotifications are handled by [Apprise](https://github.com/caronc/apprise). May read the [wiki](https://github.com/l4rm4nd/VoucherVault/wiki/03-%E2%80%90-Notifications).\n\nYou can define custom Apprise URLs in the user profile settings. The input form takes a single or a comma-separated list of multiple Apprise URLs.\n\nThe interval, how often items are checked against a potential expiry, is pre-defined (every Monday at 9AM) in the Django admin area. Here, we are utilizing Django-Celery-Beat + a Redis instance for periodic task execution. If you want to adjust the crontab interval, please head over to the admin area at `Periodic Tasks` \u003e `Periodic Expiry Check` \u003e `Crontab Schedule` \u003e `Edit` and adjust to your liking.\n\nAn item will trigger an expiry notification if the expiry date is within the number of days defined by the environment variable `EXPIRY_THRESHOLD_DAYS`. By default, this threshold is set to 30 days.\n\n## 🔐 Multi-User Setup\n\nVoucherVault is initialized with a default superuser account named `admin` and a secure auto-generated password. \n\nThis administrative account has full privileges to the Django admin panel, located at `/admin`. \n\nTherefore, all database model entries can be read and modified by this user. Additionally, new user accounts and groups can be freely created too. \n\nFinally, Single-Sign-On (SSO) via OIDC is supported. Check out the environment variables above as well as the [wiki](https://github.com/l4rm4nd/VoucherVault/wiki/02-%E2%80%90-Authentication#oidc-authentication).\n\n## 💾 Backups\n\nAll application data is stored within a Docker bind mount volume. \n\nThis volume is defined in the example Docker Compose files given. The default location is defined as `./volume-data/database`.\n\nTherefore, by backing up this bind mount volume, all your application data is saved.\n\n\u003e [!WARNING]\n\u003e Read the official [SQLite3 documentation](https://sqlite.org/backup.html) or [PostgreSQL documentation](https://www.postgresql.org/docs/current/backup.html) regarding backups.\n\n## 🤖 Repo Statistics\n![Alt](https://repobeats.axiom.co/api/embed/a8e369506f50bb08a3295b495639d42f7e20d1ba.svg \"Repobeats analytics image\")\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl4rm4nd%2FVoucherVault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fl4rm4nd%2FVoucherVault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl4rm4nd%2FVoucherVault/lists"}