Chuỗi bài: Go
go
100 dòng
· Cập nhật 2026-04-18
main.go
Go/payment-gateway-challenge/cmd/server/main.go
// Command server is the payment gateway process entrypoint.
//
// It loads configuration, connects to PostgreSQL, wires the bank HTTP client,
// and serves the Echo API until SIGINT/SIGTERM.
//
// @title Payment Gateway Challenge (Go)
// @version 1.0
// @description Checkout.com offline coding interview — Payment Gateway API (Echo + PostgreSQL). Use **Swagger UI** at `/swagger/index.html`. Behaviour and assumptions: see `DESIGN.md`.
// @termsOfService http://swagger.io/terms/
//
// @contact.name Checkout.com Recruitment
// @contact.url https://www.checkout.com/careers
// @contact.email careers@checkout.com
//
// @license.name MIT
// @license.url https://opensource.org/licenses/MIT
//
// @host localhost:8090
// @BasePath /
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
"payment-gateway-challenge/docs"
"payment-gateway-challenge/internal/bank"
"payment-gateway-challenge/internal/config"
"payment-gateway-challenge/internal/database"
"payment-gateway-challenge/internal/handlers"
"payment-gateway-challenge/internal/repository"
"payment-gateway-challenge/internal/router"
"github.com/joho/godotenv"
)
func main() {
if err := godotenv.Load(); err != nil {
log.Printf("no .env file loaded: %v", err)
}
cfg, err := config.Load()
if err != nil {
log.Fatalf("config: %v", err)
}
// Align Swagger "Try it out" host with the actual HTTP listen address
// (e.g. :8090 → localhost:8090, or 0.0.0.0:8090 unchanged).
docs.SwaggerInfo.Host = swaggerAPIHost(cfg.ServerAddr)
docs.SwaggerInfo.Version = "1.0"
db, err := database.Connect(cfg.DatabaseURL)
if err != nil {
log.Fatalf("database: %v", err)
}
// Dedicated HTTP client for outbound bank calls (separate timeout from Echo server).
bankHTTP := &http.Client{Timeout: cfg.HTTPClientTimeout}
bankClient := bank.NewClient(cfg.BankSimulatorURL, bankHTTP)
repo := repository.NewGormPaymentRepo(db)
api := handlers.NewPaymentAPI(cfg, repo, bankClient)
e := router.NewEcho(api)
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
go func() {
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := e.Shutdown(shutdownCtx); err != nil {
log.Printf("graceful shutdown: %v", err)
}
}()
log.Printf("payment gateway listening on %s (bank: %s)", cfg.ServerAddr, cfg.BankSimulatorURL)
log.Printf("Swagger UI: http://%s/swagger/index.html", docs.SwaggerInfo.Host)
if err := e.Start(cfg.ServerAddr); err != nil && err != http.ErrServerClosed {
log.Fatalf("server: %v", err)
}
}
// swaggerAPIHost converts a listen address like ":8090" into a host Swagger UI can call.
func swaggerAPIHost(listenAddr string) string {
listenAddr = strings.TrimSpace(listenAddr)
if listenAddr == "" {
return "localhost:8090"
}
if strings.HasPrefix(listenAddr, ":") {
return "localhost" + listenAddr
}
return listenAddr
}
Bài viết liên quan
Go
go
Cập nhật 2026-04-18
main.go
main.go — go source code from the Go learning materials (Go/Baasid/cmd/hashpw/main.go).
Đọc bài viết →
Go
go
Cập nhật 2026-04-18
main.go
main.go — go source code from the Go learning materials (Go/Baasid/cmd/server/main.go).
Đọc bài viết →
Go
go
Cập nhật 2026-04-18
docs.go
docs.go — go source code from the Go learning materials (Go/Baasid/docs/docs.go).
Đọc bài viết →
Go
go
Cập nhật 2026-04-18
jwt.go
jwt.go — go source code from the Go learning materials (Go/Baasid/internal/auth/jwt.go).
Đọc bài viết →
Go
go
Cập nhật 2026-04-18
password.go
password.go — go source code from the Go learning materials (Go/Baasid/internal/auth/password.go).
Đọc bài viết →
Go
go
Cập nhật 2026-04-18
password_test.go
password_test.go — go source code from the Go learning materials (Go/Baasid/internal/auth/password_test.go).
Đọc bài viết →