{"id":30687697,"url":"https://github.com/rexlow/temporal-playground","last_synced_at":"2025-10-14T15:07:35.103Z","repository":{"id":312587185,"uuid":"1044848653","full_name":"rexlow/temporal-playground","owner":"rexlow","description":null,"archived":false,"fork":false,"pushed_at":"2025-08-31T17:00:27.000Z","size":571,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-31T19:05:25.245Z","etag":null,"topics":["architecture","go","payment-gateway","workflow-engine"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rexlow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-26T09:47:50.000Z","updated_at":"2025-08-31T17:00:31.000Z","dependencies_parsed_at":"2025-08-31T19:05:36.185Z","dependency_job_id":"e4ac3550-a3df-4452-85b6-c102e6c8c205","html_url":"https://github.com/rexlow/temporal-playground","commit_stats":null,"previous_names":["rexlow/temporal-playground"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rexlow/temporal-playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rexlow%2Ftemporal-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rexlow%2Ftemporal-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rexlow%2Ftemporal-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rexlow%2Ftemporal-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rexlow","download_url":"https://codeload.github.com/rexlow/temporal-playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rexlow%2Ftemporal-playground/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279019293,"owners_count":26086709,"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-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","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":["architecture","go","payment-gateway","workflow-engine"],"created_at":"2025-09-02T00:05:35.726Z","updated_at":"2025-10-14T15:07:35.091Z","avatar_url":"https://github.com/rexlow.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Temporal Playground 🛝 🎡\n\nThis project originated as an engineering solution to overcome a distributed bottleneck in a payment gateway company I currently work at. Previously, silent drop-off payment orders were handled with a simple cron job — an approach that quickly hit scalability limits due to external rate throttling or errors from upstream wallets and banks, and the risk of overwhelming internal databases.\n\nWe shifted from periodic batch jobs to continuous, event-driven distributed workflows. Temporal provides the orchestration layer that enables horizontal scalability, fault tolerance, and simplified state management — reducing complexity across payment microservices while ensuring the system can gracefully adapt to real-world constraints.\n\n## Architecture Diagram\n\n```mermaid\nsequenceDiagram\n    participant S as Payment Services\n    participant TQ as Workflow: Query-Order\n    participant R as Retry (N times)\n    participant TS as Workflow: Stale-Order\n    participant MQ as Workflow: Manual- Queue\n    participant Tech as Tech Support\n    participant C as Completed\n\n    S-\u003e\u003eTQ: Submit Job\n    TQ-\u003e\u003eR: Process Order\n    alt Success\n        R--\u003e\u003eC: Workflow Completed\n    else Fail after N retries\n        R--\u003e\u003eTS: Trigger Stale-Order\n        TS-\u003e\u003eTS: Wait 30 min \u0026 Retry\n        alt Success after retry\n            TS--\u003e\u003eC: Workflow Completed\n        else Fail again\n            TS--\u003e\u003eMQ: Send to Manual Queue\n            MQ--\u003e\u003eTech: Manual Processing\n            Tech--\u003e\u003eC: Signal Completion\n        end\n    end\n```\n\n## Usage\n\n### Build the application\n```bash\nmake all\n```\n\n### Register a namespace\nTo register a namespace. The official temporal cli has a fantastic support for this API but I wanted to try out the SDK, so here goes.\n```bash\n./temporal-playground namespace register --name=local-rex \n```\n\n### Start the Worker\nTo start the Temporal worker (assuming temporal server is installed locally and use default namespace)\n```bash\n./temporal-playground worker\n```\n\nTo start the Temporal worker in customer host port and namespace\n```bash\n./temporal-playground worker -n local-rex --hostport 192.168.100.123:7233\n```\n\n### Client Commands\n\n#### Simulate Payment (1 time)\nSimulate a single payment event\n```bash\n./temporal-playground client start -n local-rex\n```\n\nSimulate a single payment event, with a custom order ID\n```bash\n./temporal-playground client start -o test-123 -n local-rex\n```\n\n#### Simulate Payments\nTo simulate real-time payments flooding in for workers to handle:\n```bash\n./temporal-playground client simulate-payment -n local-rex\n```\n\n#### Recurring Payments with scheduled jobs\nIt takes a lot of load and architectural load moving from managing recurring workloads such as monthly gym membership payment from traditional scheduler approaches to asynchronous approaches such as a workflow engine. Remember to think about payment term lifecycles and ways to terminate. \n\nI have also included examples of how to manage a workflow version in here. Take a look at `RegisterRecurringPayment` workflow.\n\nTo create a recurring payment contract\n```bash\n./temporal-playground client create-recurring-payment\n```\n\nTo cancel a recurring payment contract\n```bash\n./temporal-playground client cancel-recurring-payment -o order-id\n```\n\n## Screenshot\n\nWith retries and state management in place, every order is deterministically processed at scale.\n\n![Alt text](/assets/screenshot.png \"Query order workflow\")\n\n## Requirements\n\n- Go 1.24+\n- Temporal server running locally (default: localhost:7233)\n\n## Disclaimer\n\nThis is an exploratory pet project that simulates a past issue we encountered. It contains no proprietary code.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frexlow%2Ftemporal-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frexlow%2Ftemporal-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frexlow%2Ftemporal-playground/lists"}