{"id":20055051,"url":"https://github.com/pretix/pretixscan-proxy","last_synced_at":"2025-05-05T13:32:00.459Z","repository":{"id":37038316,"uuid":"198255323","full_name":"pretix/pretixscan-proxy","owner":"pretix","description":"pretixSCAN Proxy","archived":false,"fork":false,"pushed_at":"2025-01-10T18:33:42.000Z","size":566,"stargazers_count":3,"open_issues_count":3,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-08T23:41:52.726Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","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/pretix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2019-07-22T15:49:10.000Z","updated_at":"2024-11-07T09:51:52.000Z","dependencies_parsed_at":"2024-02-22T12:29:35.023Z","dependency_job_id":"c7ea06aa-fed8-4010-8d0f-8c1326ad4d66","html_url":"https://github.com/pretix/pretixscan-proxy","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pretix%2Fpretixscan-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pretix%2Fpretixscan-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pretix%2Fpretixscan-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pretix%2Fpretixscan-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pretix","download_url":"https://codeload.github.com/pretix/pretixscan-proxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252506482,"owners_count":21759055,"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","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":[],"created_at":"2024-11-13T12:45:42.912Z","updated_at":"2025-05-05T13:32:00.138Z","avatar_url":"https://github.com/pretix.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"pretixSCAN Proxy\n================\n\nOn-site server component for larger-scale pretixSCAN deployments.\n\nA word of caution\n-----------------\n\nThis is a tool for really advanced usage. The tool itself is made to be operated by people with comprehensive knowledge of the technical domain. Also, if you are in the situation of planning a rock-solid check-in process for thousands of participants, we **strongly advise you to get professional support** regardless of the tools in use. This is a **complex undertaking** and if you're not an expert with these things (or if you are an expert, but busy with other things during the event), **you are going to have a bad time**.\n\nIf you think you need this, please reach out at **support@pretix.eu** and let's talk about your use case. \nWe're happy to provide you with rental hardware as well as remote or on-site support, so you can focus on your event.\n\nMotivation\n----------\n\nBy default, our scanning apps [pretixSCAN](https://pretix.eu/about/en/scan) communicate directly with the pretix server on the internet. This way, they can make sure that no ticket is scanned twice and that they always have live data:\n\n![Online scanning](res/online.png?raw=true)\n\nObviously, this isn't practicable for lots of events. Many events, especially large ones, take place in environments with slow and unreliable internet connection and it's just not an option to rely on the internet to work. Therefore, pretixSCAN downloads all ticket data to the local device and supports an *Offline mode* in which it locally decides whether a ticket is valid and then syncs with the server periodically:\n\n![Offline scanning](res/offline.png?raw=true)\n\nThis is great for smaller events, because it just works without any infrastructure requirements, but if you try to scale it up to large events, there are a number of downsides to this approach:\n\n* Downloading all ticket data to the devices takes a long time if you have lots of ticket data.\n* Searching through the ticket data locally can also take quite some time if you have ten thousands of tickets since mobile devices often don't have fast storage and CPUs.\n* Having all this personal data on the devices is a problem when you loose a device.\n* *Offline mode* allows people to trick you by redeeming the same ticket twice in short sequence with different scanners.\n\n**pretixSCAN Proxy** is our solution to all of these problems. The idea is to set up a server in your local WiFi network that relays the communication between the devices and the pretix server and basically takes over the function of the local storage in *Offline mode*:\n\n![Proxy mode](res/proxy.png?raw=true)\n\nThis allows you to get the best of both worlds – as long as there is a reliable local network (of course there's a catch): No data is stored on the devices, you can use a fast server for the local caching, internet connection is still optional and every ticket can only be scanned once *per proxy* (you could use multiple, if you want).\n\nDevelopment status\n------------------\n\npretixSCAN Proxy has been used in production. However, it currently does not follow a defined release cycle\nand is currently mostly used in projects in close collaboration with our team.\n\nSystem requirements\n-------------------\n\n* Java 8 or newer\n\n* A PostgreSQL database\n\nThe API exposed by the proxy is currently supported by pretixSCAN on Android starting with version 1.0.2. and by pretixSCAN Desktop starting with version 1.1.0. Support for pretixSCAN on iOS is not planned.\n\nBuild and run\n-------------\n\nTo build the project, just use:\n\n    ./gradlew jar\n    \nThen you can run the built JAR file:\n\n    java \\\n        -Dpretixscan.database=\"jdbc:postgresql:scanproxy\" \\\n        -Dpretixscan.baseurl=\"https://local.baseurl.com\" \\\n        -Dpretixscan.adminauth=\"admin:admin\" \\\n        -Dpretixscan.autoOfflineMode=\"off\" \\\n        -jar server/build/libs/server-1.0-SNAPSHOT.jar\n\nFor initial configuration, visit the web interface at http://localhost:7000 (or the domain of your reverse proxy)\nand login with the admin credentials defined above.\n\nConfig options\n--------------\n\n| Property | Description |\n|----------| --- |\n| pretixscan.database | PostgreSQL connection URL |\n| pretixscan.baseurl | Base URL the proxy will be reachable at |\n| pretixscan.adminauth | user:pass for management interface |\n| pretixscan.autoOfflineMode | ``\"off\"`` for \"always offline\", ``\"on\"`` for \"default to online, but switch to offline after repeated errors\", or ``\"1s\"``, ``\"2s\"``, ``\"5s\"``, ``\"10s\"``, ``\"15s\"``, ``\"20s\"`` for \"default to online, but switch to offline after repeated errors or after average scans longer than X\". Other numbers are currently not allowed. |\n\nAPI\n---\n\nBeside the web interface and the endpoints powering it, the proxy server exposes two sets of API endpoints:\n\n- A set of API endpoints that \"mock\" endpoints from the pretix server API. For example, you can query\n  ``/api/v1/organizers/\u003corg\u003e/events/\u003cevent\u003e/orders/`` and will get a valid, but always empty response. For other\n  resources like items or check-in lists, you get a populated response. These API calls are not documented on\n  purpose as they only exist to ensure compatibility with our pretixSCAN apps.\n  \n- A set of API endpoints special to the proxy at ``/proxyapi/v1/``. The ones that are intended to be used by third\n  parties are documented below.\n  \n### Authentication\n\nAuthentication to the API closely follows the [Device authentication](https://docs.pretix.eu/en/latest/api/deviceauth.html#rest-deviceauth)\nprotocol pretix uses. The admin web interface allows to generate initialization tokens which can be converted into a device\ntoken with the ``/api/v1/device/initialize`` endpoint. You can then supply these tokens to all subsequent calls in a\n``Authorization: Device \u003ctoken\u003e`` header.\n\n### Check\n\nThe check endpoint allows you to check a ticket for validity.\n\nSample request:\n\n    POST /proxyapi/v1/rpc/\u003cevent\u003e/\u003ccheckinlist_id\u003e/check/ HTTP/1.1\n    Content-Type: application/json\n\n    {\n      \"ticketid\": \"barcode_content\",\n      \"answers\": [\n        {\n          \"question\": {\n            \"server_id\": 1234\n          },\n          \"value\": \"Foo\"\n        }\n      ],\n      \"with_badge_data\": false,\n      \"ignore_unpaid\": false\n    }\n\nSample response:\n\n    HTTP/1.1 200 OK\n    Content-Type: application/json\n\n    {\n      \"type\": \"VALID\",\n      \"ticket\": \"Entry pass\",\n      \"variation\": \"Regular\",\n      \"attendee_name\": \"John Doe\",\n      \"seat\": \"Row 3, Seat 5\",\n      \"message\": \"Additional message\",\n      \"reasonExplanation\": \"Additional reason for RULES error code\",\n      \"orderCode\": \"ABC123\",\n      \"firstScanned\": \"2021-05-12T12:00:00.000Z\",\n      \"addonText\": \"+ Workshop\",\n      \"isRequireAttention\": false,\n      \"isCheckinAllowed\": false,\n      \"requiredAnswers\": [\n        {\n          \"question\": {\n             ...\n          },\n          \"currentValue\": \"Foo\"\n        }\n      ],\n      \"position\": {\n        ...  // pretix API orderposition object\n      }\n    }\n\n``type`` can currently be any of ``VALID``, ``INVALID``, ``USED``, ``ERROR``, ``UNPAID``, ``CANCELED``, ``RULES``, ``REVOKED``, ``PRODUCT``, or ``ANSWERS_REQUIRED``.\nAll other fields are nullable.\n\n### Search\n\nThe search endpoint allows you to search for tickets.\n\nSample request:\n\n    POST /proxyapi/v1/rpc/\u003cevent\u003e/\u003ccheckinlist_id\u003e/search/ HTTP/1.1\n    Content-Type: application/json\n\n    {\n      \"query\": \"john\",\n      \"page\": 1\n    }\n\nSample response:\n\n    HTTP/1.1 200 OK\n    Content-Type: application/json\n\n    [\n      {\n        \"secret\": \"barcode_content\",\n        \"ticket\": \"Entry pass\",\n        \"variation\": \"Regular\",\n        \"attendee_name\": \"John Doe\",\n        \"seat\": \"Row 3, Seat 5\",\n        \"orderCode\": \"ABC123\",\n        \"addonText\": \"+ Workshop\",\n        \"status\": \"PAID\",\n        \"isRedeemed\": false,\n        \"isRequireAttention\": false,\n        \"position\": {\n          ...  // pretix API orderposition object\n        }\n      }\n    ]\n\n``status`` can currently be any of ``PAID``, ``CANCELED``, or ``PENDING``.\n\n### Status\n\nThe status endpoint allows you to access statistics.\n\nSample request:\n\n    GET /proxyapi/v1/rpc/\u003cevent\u003e/\u003ccheckinlist_id\u003e/status/ HTTP/1.1\n\nSample response:\n\n    HTTP/1.1 200 OK\n    Content-Type: application/json\n\n    {\n      \"event_name\": \"Museum\",\n      \"totalTickets\": 3,\n      \"alreadyScanned\": 2,\n      \"currentlyInside\": 2,\n      \"items\": [\n        {\n          \"id\": 1234,\n          \"name\": \"Entry Pass\",\n          \"total\": 3,\n          \"checkins\": 2,\n          \"admission\": true,\n          \"variations\": [\n            {\n              \"id\": 3214,\n              \"name\": \"Regular\",\n              \"total\": 3,\n              \"checkins\": 2\n            }\n          ]\n        }\n      ]\n    ]\n\n\nLicense\n-------\n\nCopyright 2019-2021 rami.io GmbH\n\nReleased under the terms of the GNU General Public License v3\n\nMaintained by the pretix team \u003csupport@pretix.eu\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpretix%2Fpretixscan-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpretix%2Fpretixscan-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpretix%2Fpretixscan-proxy/lists"}