+2
-2
cmd/app/main.go
+2
-2
cmd/app/main.go
···
26
defer logger.Sync()
27
28
providers := providers.NewUseProviders([]providers.Provider{
29
-
providers.NewBraintreeProvider("http://" + getEnv("BRAINTREE_URL", "localhost:8001")),
30
-
providers.NewStripeProvider("http://" + getEnv("STRIPE_URL", "localhost:8002")),
31
}, logger)
32
paymentsService := service.NewPaymentService(providers)
33
···
26
defer logger.Sync()
27
28
providers := providers.NewUseProviders([]providers.Provider{
29
+
providers.NewBraintreeProvider("http://"+getEnv("BRAINTREE_URL", "localhost:8001"), logger),
30
+
providers.NewStripeProvider("http://"+getEnv("STRIPE_URL", "localhost:8002"), logger),
31
}, logger)
32
paymentsService := service.NewPaymentService(providers)
33
+10
-3
internal/providers/braintree.go
+10
-3
internal/providers/braintree.go
···
8
9
"github.com/Tulkdan/payment-gateway/internal/domain"
10
"github.com/google/uuid"
11
)
12
13
type BraintreeProvider struct {
14
-
Url string
15
}
16
17
-
func NewBraintreeProvider(url string) *BraintreeProvider {
18
-
return &BraintreeProvider{Url: url}
19
}
20
21
type BraintreeChargeCard struct {
···
39
}
40
41
func (b *BraintreeProvider) Charge(ctx context.Context, request *domain.Payment) (*domain.Provider, error) {
42
body := b.createChargeBody(request)
43
req, err := http.NewRequestWithContext(ctx, http.MethodPost, b.Url+"/charges", bytes.NewBuffer(body))
44
if err != nil {
···
8
9
"github.com/Tulkdan/payment-gateway/internal/domain"
10
"github.com/google/uuid"
11
+
"go.uber.org/zap"
12
)
13
14
type BraintreeProvider struct {
15
+
Url string
16
+
logger *zap.Logger
17
}
18
19
+
func NewBraintreeProvider(url string, logger *zap.Logger) *BraintreeProvider {
20
+
return &BraintreeProvider{Url: url, logger: logger.Named("BraintreeProvider")}
21
}
22
23
type BraintreeChargeCard struct {
···
41
}
42
43
func (b *BraintreeProvider) Charge(ctx context.Context, request *domain.Payment) (*domain.Provider, error) {
44
+
url := b.Url + "/transactions"
45
+
46
+
b.logger.Debug("Making request to charge",
47
+
zap.String("url", url))
48
+
49
body := b.createChargeBody(request)
50
req, err := http.NewRequestWithContext(ctx, http.MethodPost, b.Url+"/charges", bytes.NewBuffer(body))
51
if err != nil {
+5
-1
internal/providers/braintree_test.go
+5
-1
internal/providers/braintree_test.go
···
12
"github.com/Tulkdan/payment-gateway/internal/domain"
13
"github.com/Tulkdan/payment-gateway/internal/providers"
14
"github.com/google/uuid"
15
)
16
17
func TestBraintree(t *testing.T) {
18
t.Run("should make request to url", func(t *testing.T) {
19
id, _ := uuid.Parse("2ee70bcb-5cb9-4412-a35f-c2a15fb88ef1")
20
cardId, _ := uuid.Parse("ed6ecd4c-81d5-4e63-bb12-99439ae559e7")
21
ctx := context.WithValue(t.Context(), "request-id", uuid.New().String())
···
56
CardId: cardId,
57
}
58
59
-
provider := providers.NewBraintreeProvider(server.URL)
60
response, err := provider.Charge(ctx, charge)
61
62
if err != nil {
···
12
"github.com/Tulkdan/payment-gateway/internal/domain"
13
"github.com/Tulkdan/payment-gateway/internal/providers"
14
"github.com/google/uuid"
15
+
"go.uber.org/zap"
16
)
17
18
func TestBraintree(t *testing.T) {
19
t.Run("should make request to url", func(t *testing.T) {
20
+
logger, _ := zap.NewDevelopment()
21
+
defer logger.Sync()
22
+
23
id, _ := uuid.Parse("2ee70bcb-5cb9-4412-a35f-c2a15fb88ef1")
24
cardId, _ := uuid.Parse("ed6ecd4c-81d5-4e63-bb12-99439ae559e7")
25
ctx := context.WithValue(t.Context(), "request-id", uuid.New().String())
···
60
CardId: cardId,
61
}
62
63
+
provider := providers.NewBraintreeProvider(server.URL, logger)
64
response, err := provider.Charge(ctx, charge)
65
66
if err != nil {
+1
-1
internal/providers/provider.go
+1
-1
internal/providers/provider.go
+2
-2
internal/providers/provider_test.go
+2
-2
internal/providers/provider_test.go
···
53
})
54
55
t.Run("should make request for second provider when first provider timeouts", func(t *testing.T) {
56
-
logger, _ := zap.NewProduction()
57
defer logger.Sync()
58
59
spyFirst := &SpyProvider{Timeout: 20 * time.Millisecond, Response: &domain.Provider{Description: "First"}}
···
77
})
78
79
t.Run("should return error when all providers timeout", func(t *testing.T) {
80
-
logger, _ := zap.NewProduction()
81
defer logger.Sync()
82
83
spyFirst := &SpyProvider{Timeout: 20 * time.Millisecond, Response: &domain.Provider{Description: "First"}}
···
53
})
54
55
t.Run("should make request for second provider when first provider timeouts", func(t *testing.T) {
56
+
logger, _ := zap.NewDevelopment()
57
defer logger.Sync()
58
59
spyFirst := &SpyProvider{Timeout: 20 * time.Millisecond, Response: &domain.Provider{Description: "First"}}
···
77
})
78
79
t.Run("should return error when all providers timeout", func(t *testing.T) {
80
+
logger, _ := zap.NewDevelopment()
81
defer logger.Sync()
82
83
spyFirst := &SpyProvider{Timeout: 20 * time.Millisecond, Response: &domain.Provider{Description: "First"}}
+16
-9
internal/providers/stripe.go
+16
-9
internal/providers/stripe.go
···
8
9
"github.com/Tulkdan/payment-gateway/internal/domain"
10
"github.com/google/uuid"
11
)
12
13
type StripeProvider struct {
14
-
Url string
15
}
16
17
-
func NewStripeProvider(url string) *StripeProvider {
18
-
return &StripeProvider{Url: url}
19
}
20
21
type StripeChargeCard struct {
···
34
Card StripeChargeCard `json:"card"`
35
}
36
37
-
func (b *StripeProvider) Charge(ctx context.Context, request *domain.Payment) (*domain.Provider, error) {
38
-
body := b.createChargeBody(request)
39
-
req, err := http.NewRequestWithContext(ctx, http.MethodPost, b.Url+"/transactions", bytes.NewBuffer(body))
40
if err != nil {
41
return nil, err
42
}
···
50
}
51
defer response.Body.Close()
52
53
-
return b.responseCharge(response)
54
}
55
56
-
func (b *StripeProvider) createChargeBody(request *domain.Payment) []byte {
57
toSend := &StripeCharge{
58
Amount: request.Amount,
59
Currency: request.Currency,
···
83
CardId uuid.UUID `json:"cardId"`
84
}
85
86
-
func (b *StripeProvider) responseCharge(response *http.Response) (*domain.Provider, error) {
87
var data StripeChargeResponse
88
if err := json.NewDecoder(response.Body).Decode(&data); err != nil {
89
return nil, err
···
8
9
"github.com/Tulkdan/payment-gateway/internal/domain"
10
"github.com/google/uuid"
11
+
"go.uber.org/zap"
12
)
13
14
type StripeProvider struct {
15
+
Url string
16
+
logger *zap.Logger
17
}
18
19
+
func NewStripeProvider(url string, logger *zap.Logger) *StripeProvider {
20
+
return &StripeProvider{Url: url, logger: logger.Named("StripeProvider")}
21
}
22
23
type StripeChargeCard struct {
···
36
Card StripeChargeCard `json:"card"`
37
}
38
39
+
func (s *StripeProvider) Charge(ctx context.Context, request *domain.Payment) (*domain.Provider, error) {
40
+
url := s.Url + "/transactions"
41
+
42
+
s.logger.Debug("Making request to charge",
43
+
zap.String("url", url))
44
+
45
+
body := s.createChargeBody(request)
46
+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(body))
47
if err != nil {
48
return nil, err
49
}
···
57
}
58
defer response.Body.Close()
59
60
+
return s.responseCharge(response)
61
}
62
63
+
func (s *StripeProvider) createChargeBody(request *domain.Payment) []byte {
64
toSend := &StripeCharge{
65
Amount: request.Amount,
66
Currency: request.Currency,
···
90
CardId uuid.UUID `json:"cardId"`
91
}
92
93
+
func (s *StripeProvider) responseCharge(response *http.Response) (*domain.Provider, error) {
94
var data StripeChargeResponse
95
if err := json.NewDecoder(response.Body).Decode(&data); err != nil {
96
return nil, err
+5
-1
internal/providers/stripe_test.go
+5
-1
internal/providers/stripe_test.go
···
12
"github.com/Tulkdan/payment-gateway/internal/domain"
13
"github.com/Tulkdan/payment-gateway/internal/providers"
14
"github.com/google/uuid"
15
)
16
17
func TestStripe(t *testing.T) {
18
t.Run("should make request to url", func(t *testing.T) {
19
id, _ := uuid.Parse("2ee70bcb-5cb9-4412-a35f-c2a15fb88ef1")
20
cardId, _ := uuid.Parse("ed6ecd4c-81d5-4e63-bb12-99439ae559e7")
21
ctx := context.WithValue(t.Context(), "request-id", uuid.New().String())
···
56
CardId: cardId,
57
}
58
59
-
provider := providers.NewStripeProvider(server.URL)
60
response, err := provider.Charge(ctx, charge)
61
62
if err != nil {
···
12
"github.com/Tulkdan/payment-gateway/internal/domain"
13
"github.com/Tulkdan/payment-gateway/internal/providers"
14
"github.com/google/uuid"
15
+
"go.uber.org/zap"
16
)
17
18
func TestStripe(t *testing.T) {
19
t.Run("should make request to url", func(t *testing.T) {
20
+
logger, _ := zap.NewDevelopment()
21
+
defer logger.Sync()
22
+
23
id, _ := uuid.Parse("2ee70bcb-5cb9-4412-a35f-c2a15fb88ef1")
24
cardId, _ := uuid.Parse("ed6ecd4c-81d5-4e63-bb12-99439ae559e7")
25
ctx := context.WithValue(t.Context(), "request-id", uuid.New().String())
···
60
CardId: cardId,
61
}
62
63
+
provider := providers.NewStripeProvider(server.URL, logger)
64
response, err := provider.Charge(ctx, charge)
65
66
if err != nil {