bank-emul/cmd/server/main.go
2026-03-07 19:45:24 +03:00

176 lines
4.6 KiB
Go

package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"bank-emulator/internal/bank"
"bank-emulator/internal/storage"
)
var b *bank.Bank
func main() {
store := storage.New("bank_data.json")
b = bank.New(store)
http.HandleFunc("/validate", handleValidate)
http.HandleFunc("/bind", handleBind)
http.HandleFunc("/confirm-3ds", handleConfirm3DS)
http.HandleFunc("/charge", handleCharge)
http.HandleFunc("/complete-charge", handleCompleteCharge)
http.HandleFunc("/direct-charge", handleDirectCharge)
fmt.Println("Bank emulator running on :9090")
log.Fatal(http.ListenAndServe(":9090", nil))
}
type validateReq struct {
CardNumber string `json:"card_number"`
}
type bindReq struct {
CardNumber string `json:"card_number"`
CVV string `json:"cvv"`
Expiry string `json:"expiry"`
HolderName string `json:"holder_name"`
}
type confirm3dsReq struct {
SessionID string `json:"session_id"`
Code string `json:"code"`
}
type chargeReq struct {
CardNumber string `json:"card_number"`
Amount float64 `json:"amount"`
}
type completeChargeReq struct {
SessionID string `json:"session_id"`
Amount float64 `json:"amount"`
}
type directChargeReq struct {
CardNumber string `json:"card_number"`
Amount float64 `json:"amount"`
}
type resp struct {
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
SessionID string `json:"session_id,omitempty"`
}
func writeJSON(w http.ResponseWriter, status int, v any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(v)
}
func handleValidate(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeJSON(w, 405, resp{OK: false, Error: "method not allowed"})
return
}
var req validateReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSON(w, 400, resp{OK: false, Error: "invalid request body"})
return
}
if err := b.ValidateCard(req.CardNumber); err != nil {
writeJSON(w, 400, resp{OK: false, Error: err.Error()})
return
}
writeJSON(w, 200, resp{OK: true})
}
func handleBind(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeJSON(w, 405, resp{OK: false, Error: "method not allowed"})
return
}
var req bindReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSON(w, 400, resp{OK: false, Error: "invalid request body"})
return
}
session, err := b.InitiateBind(req.CardNumber, req.CVV, req.Expiry)
if err != nil {
writeJSON(w, 400, resp{OK: false, Error: err.Error()})
return
}
writeJSON(w, 200, resp{OK: true, SessionID: session.SessionID})
}
func handleConfirm3DS(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeJSON(w, 405, resp{OK: false, Error: "method not allowed"})
return
}
var req confirm3dsReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSON(w, 400, resp{OK: false, Error: "invalid request body"})
return
}
if err := b.Confirm3DS(req.SessionID, req.Code); err != nil {
writeJSON(w, 400, resp{OK: false, Error: err.Error()})
return
}
writeJSON(w, 200, resp{OK: true})
}
func handleCharge(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeJSON(w, 405, resp{OK: false, Error: "method not allowed"})
return
}
var req chargeReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSON(w, 400, resp{OK: false, Error: "invalid request body"})
return
}
session, err := b.Charge(req.CardNumber, req.Amount)
if err != nil {
writeJSON(w, 400, resp{OK: false, Error: err.Error()})
return
}
writeJSON(w, 200, resp{OK: true, SessionID: session.SessionID})
}
func handleCompleteCharge(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeJSON(w, 405, resp{OK: false, Error: "method not allowed"})
return
}
var req completeChargeReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSON(w, 400, resp{OK: false, Error: "invalid request body"})
return
}
if err := b.CompleteCharge(req.SessionID, req.Amount); err != nil {
writeJSON(w, 400, resp{OK: false, Error: err.Error()})
return
}
writeJSON(w, 200, resp{OK: true})
}
func handleDirectCharge(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeJSON(w, 405, resp{OK: false, Error: "method not allowed"})
return
}
var req directChargeReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSON(w, 400, resp{OK: false, Error: "invalid request body"})
return
}
if err := b.DirectCharge(req.CardNumber, req.Amount); err != nil {
writeJSON(w, 400, resp{OK: false, Error: err.Error()})
return
}
writeJSON(w, 200, resp{OK: true})
}