@@ -2,7 +2,7 @@ package main
22
33import (
44 "context"
5- "log "
5+ "fmt "
66 "net/http"
77 "os"
88 "os/signal"
@@ -20,24 +20,84 @@ import (
2020 "github.com/malwarebo/gopay/services"
2121)
2222
23+ // ANSI color codes for debug console output
24+ const (
25+ colorReset = "\033 [0m"
26+ colorRed = "\033 [31m"
27+ colorGreen = "\033 [32m"
28+ colorYellow = "\033 [33m"
29+ colorBlue = "\033 [34m"
30+ colorPurple = "\033 [35m"
31+ colorCyan = "\033 [36m"
32+ colorWhite = "\033 [37m"
33+ colorBold = "\033 [1m"
34+ )
35+
36+ func printBanner () {
37+ fmt .Printf ("%s%s" , colorCyan , colorBold )
38+ fmt .Println ("╔══════════════════════════════════════════════════════════════╗" )
39+ fmt .Println ("║ ║" )
40+ fmt .Println ("║ 🚀 GoPay Payment Orchestration System ║" )
41+ fmt .Println ("║ ║" )
42+ fmt .Println ("║ Multi-provider payment processing made simple ║" )
43+ fmt .Println ("║ ║" )
44+ fmt .Println ("╚══════════════════════════════════════════════════════════════╝" )
45+ fmt .Printf ("%s" , colorReset )
46+ }
47+
48+ func printStep (step , message string ) {
49+ fmt .Printf ("%s[%s]%s %s%s%s\n " , colorBlue , step , colorReset , colorBold , message , colorReset )
50+ }
51+
52+ func printSuccess (message string ) {
53+ fmt .Printf ("%s✓%s %s\n " , colorGreen , colorReset , message )
54+ }
55+
56+ func printWarning (message string ) {
57+ fmt .Printf ("%s⚠%s %s\n " , colorYellow , colorReset , message )
58+ }
59+
60+ func printError (message string ) {
61+ fmt .Printf ("%s✗%s %s\n " , colorRed , colorReset , message )
62+ }
63+
64+ func printInfo (message string ) {
65+ fmt .Printf ("%sℹ%s %s\n " , colorCyan , colorReset , message )
66+ }
67+
2368func main () {
24- log .Println ("Starting gopay payment orchestration system..." )
69+ printBanner ()
70+ fmt .Println ()
2571
72+ // Configuration
73+ printStep ("1/8" , "Loading configuration..." )
2674 cfg , err := config .LoadConfig ()
2775 if err != nil {
28- log .Fatalf ("Failed to load configuration: %v" , err )
76+ printError (fmt .Sprintf ("Failed to load configuration: %v" , err ))
77+ os .Exit (1 )
2978 }
79+ printSuccess ("Configuration loaded successfully" )
3080
81+ // Validate configuration
82+ printStep ("2/8" , "Validating configuration..." )
3183 if err := cfg .Validate (); err != nil {
32- log .Fatalf ("Configuration validation failed: %v" , err )
84+ printError (fmt .Sprintf ("Configuration validation failed: %v" , err ))
85+ os .Exit (1 )
3386 }
87+ printSuccess ("Configuration validation passed" )
3488
89+ // Database connection
90+ printStep ("3/8" , "Connecting to database..." )
3591 db , err := db .NewDB (cfg .GetDatabaseURL ())
3692 if err != nil {
37- log .Fatalf ("Failed to connect to database: %v" , err )
93+ printError (fmt .Sprintf ("Failed to connect to database: %v" , err ))
94+ os .Exit (1 )
3895 }
3996 defer db .Close ()
97+ printSuccess (fmt .Sprintf ("Connected to PostgreSQL at %s:%d" , cfg .Database .Host , cfg .Database .Port ))
4098
99+ // Redis connection
100+ printStep ("4/8" , "Connecting to Redis..." )
41101 redisCache , err := cache .NewRedisCache (cache.RedisConfig {
42102 Host : cfg .Redis .Host ,
43103 Port : cfg .Redis .Port ,
@@ -46,37 +106,54 @@ func main() {
46106 TTL : time .Duration (cfg .Redis .TTL ) * time .Second ,
47107 })
48108 if err != nil {
49- log .Fatalf ("Failed to connect to Redis: %v" , err )
109+ printWarning (fmt .Sprintf ("Failed to connect to Redis: %v (continuing without cache)" , err ))
110+ } else {
111+ defer redisCache .Close ()
112+ printSuccess (fmt .Sprintf ("Connected to Redis at %s:%d" , cfg .Redis .Host , cfg .Redis .Port ))
50113 }
51- defer redisCache .Close ()
52114
115+ // Initialize payment providers
116+ printStep ("5/8" , "Initializing payment providers..." )
53117 stripeProvider := providers .NewStripeProvider (cfg .Stripe .Secret )
54118 xenditProvider := providers .NewXenditProvider (cfg .Xendit .Secret )
55119
56120 providerSelector := providers .NewMultiProviderSelector ([]providers.PaymentProvider {stripeProvider , xenditProvider })
121+ printSuccess ("Payment providers initialized" )
122+ printInfo (" • Stripe: Ready for USD, EUR, GBP" )
123+ printInfo (" • Xendit: Ready for IDR, SGD, MYR, PHP, THB, VND" )
57124
125+ // Initialize repositories
126+ printStep ("6/8" , "Initializing repositories..." )
58127 paymentRepo := repositories .NewPaymentRepository (db )
59128 planRepo := repositories .NewPlanRepository (db )
60129 subscriptionRepo := repositories .NewSubscriptionRepository (db )
61130 disputeRepo := repositories .NewDisputeRepository (db .DB )
131+ printSuccess ("Repositories initialized" )
62132
133+ // Initialize services
134+ printStep ("7/8" , "Initializing services..." )
63135 paymentService := services .NewPaymentService (paymentRepo , providerSelector )
64136 subscriptionService := services .NewSubscriptionService (planRepo , subscriptionRepo , providerSelector )
65137 disputeService := services .NewDisputeService (disputeRepo , providerSelector )
138+ printSuccess ("Services initialized" )
66139
140+ // Initialize handlers and router
141+ printStep ("8/8" , "Setting up HTTP server..." )
67142 paymentHandler := api .NewPaymentHandler (paymentService )
68143 subscriptionHandler := api .NewSubscriptionHandler (subscriptionService )
69144 disputeHandler := api .NewDisputeHandler (disputeService )
70145
71146 router := mux .NewRouter ()
72147
148+ // Apply middleware
73149 router .Use (middleware .LoggingMiddleware )
74150 router .Use (middleware .CORSMiddleware )
75151 router .Use (middleware .RecoveryMiddleware )
76152
77153 apiRouter := router .PathPrefix ("/api/v1" ).Subrouter ()
78154 apiRouter .Use (middleware .RateLimitMiddleware )
79155
156+ // Register routes
80157 apiRouter .HandleFunc ("/health" , api .HealthCheckHandler ).Methods ("GET" )
81158 apiRouter .HandleFunc ("/metrics" , api .MetricsHandler ).Methods ("GET" )
82159
@@ -104,25 +181,55 @@ func main() {
104181 IdleTimeout : 60 * time .Second ,
105182 }
106183
184+ printSuccess ("HTTP server configured" )
185+
186+ // Startup complete
187+ fmt .Println ()
188+ fmt .Printf ("%s%s🎉 GoPay is ready!%s\n " , colorGreen , colorBold , colorReset )
189+ fmt .Println ()
190+ fmt .Printf ("%s%sAPI Endpoints:%s\n " , colorPurple , colorBold , colorReset )
191+ fmt .Printf (" %s•%s Health Check: %shttp://localhost:%s/api/v1/health%s\n " , colorCyan , colorReset , colorYellow , cfg .Server .Port , colorReset )
192+ fmt .Printf (" %s•%s Metrics: %shttp://localhost:%s/api/v1/metrics%s\n " , colorCyan , colorReset , colorYellow , cfg .Server .Port , colorReset )
193+ fmt .Printf (" %s•%s Payments: %shttp://localhost:%s/api/v1/charges%s\n " , colorCyan , colorReset , colorYellow , cfg .Server .Port , colorReset )
194+ fmt .Printf (" %s•%s Subscriptions: %shttp://localhost:%s/api/v1/subscriptions%s\n " , colorCyan , colorReset , colorYellow , cfg .Server .Port , colorReset )
195+ fmt .Printf (" %s•%s Disputes: %shttp://localhost:%s/api/v1/disputes%s\n " , colorCyan , colorReset , colorYellow , cfg .Server .Port , colorReset )
196+ fmt .Println ()
197+ fmt .Printf ("%s%sEnvironment:%s %s%s%s\n " , colorPurple , colorBold , colorReset , colorYellow , "development" , colorReset )
198+ fmt .Printf ("%s%sServer Port:%s %s%s%s\n " , colorPurple , colorBold , colorReset , colorYellow , cfg .Server .Port , colorReset )
199+ fmt .Printf ("%s%sDatabase:%s %s%s:%d%s\n " , colorPurple , colorBold , colorReset , colorYellow , cfg .Database .Host , cfg .Database .Port , colorReset )
200+ if redisCache != nil {
201+ fmt .Printf ("%s%sRedis:%s %s%s:%d%s\n " , colorPurple , colorBold , colorReset , colorYellow , cfg .Redis .Host , cfg .Redis .Port , colorReset )
202+ }
203+ fmt .Println ()
204+ fmt .Printf ("%s%sPress Ctrl+C to stop the server%s\n " , colorYellow , colorReset )
205+ fmt .Println ()
206+
207+ // Start server
107208 go func () {
108- log . Printf ( "Server starting on port %s" , cfg .Server .Port )
209+ printInfo ( fmt . Sprintf ( "Starting HTTP server on port %s... " , cfg .Server .Port ) )
109210 if err := server .ListenAndServe (); err != nil && err != http .ErrServerClosed {
110- log .Fatalf ("Server failed to start: %v" , err )
211+ printError (fmt .Sprintf ("Server failed to start: %v" , err ))
212+ os .Exit (1 )
111213 }
112214 }()
113215
216+ // Wait for shutdown signal
114217 quit := make (chan os.Signal , 1 )
115218 signal .Notify (quit , syscall .SIGINT , syscall .SIGTERM )
116219 <- quit
117220
118- log .Println ("Shutting down server..." )
221+ fmt .Println ()
222+ printWarning ("Shutting down GoPay server..." )
119223
120224 ctx , cancel := context .WithTimeout (context .Background (), 30 * time .Second )
121225 defer cancel ()
122226
123227 if err := server .Shutdown (ctx ); err != nil {
124- log .Fatalf ("Server forced to shutdown: %v" , err )
228+ printError (fmt .Sprintf ("Server forced to shutdown: %v" , err ))
229+ os .Exit (1 )
125230 }
126231
127- log .Println ("Server exited" )
232+ printSuccess ("GoPay server stopped gracefully" )
233+ fmt .Println ()
234+ fmt .Printf ("%s%s👋 Thanks for using GoPay!%s\n " , colorCyan , colorBold , colorReset )
128235}
0 commit comments