diff --git a/Readme.md b/Readme.md index 10e79c209..f7596edac 100644 --- a/Readme.md +++ b/Readme.md @@ -87,6 +87,7 @@ import ( client := adyen.NewClient(&common.Config{ ApiKey: "your api key", Environment: common.TestEnv, + Log4XXError: true, }) service := client.Checkout() @@ -109,6 +110,7 @@ import ( client := adyen.NewClient(&common.Config{ ApiKey: "your api key", Environment: common.LiveEnv, + Log4XXError: true, LiveEndpointURLPrefix: "1797a841fbb37ca7-AdyenDemo", // Refer to https://docs.adyen.com/development-resources/live-endpoints#live-url-prefix }) service := client.Checkout() @@ -207,6 +209,20 @@ errorCode := err.(common.APIError).Code errorType := err.(common.APIError).Type ``` +Consider additional logging when an error occurs: +```go + +client := adyen.NewClient(&common.Config{ +ApiKey: "your api key", +Environment: common.TestEnv, +Log3XXError: true, +Log4XXError: true, +Log5XXError: true, +}) + +service := client.Checkout() +``` + ### Custom HTTP Client Configuration By default, Go [`http.DefaultClient`](https://golang.org/pkg/net/http/) will be used to submit requests to the API. But you can change that by injecting your own HttpClient on your client instance. diff --git a/go.sum b/go.sum index f1d9faaa6..f150930f4 100644 --- a/go.sum +++ b/go.sum @@ -755,10 +755,6 @@ github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkj github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= diff --git a/src/common/client.go b/src/common/client.go index f9a48e3d0..be862a112 100644 --- a/src/common/client.go +++ b/src/common/client.go @@ -161,6 +161,8 @@ func SendAPIRequest( return httpResponse, err } + c.logOnError(httpResponse) + if httpResponse.StatusCode >= 300 { newErr := NewAPIError(body, httpResponse.Status) return httpResponse, newErr @@ -227,6 +229,28 @@ func (c *Client) CallAPI(request *http.Request) (*http.Response, error) { return resp, err } +// LogOnError log response body when an error occurs +// the type of error being logged depends on the Configuration +func (c *Client) logOnError(httpResponse *http.Response) { + if c.Cfg.Log3XXError { + if httpResponse.StatusCode >= 300 && httpResponse.StatusCode < 400 { + fmt.Println(httpResponse.Body) + } + } + + if c.Cfg.Log4XXError { + if httpResponse.StatusCode >= 400 && httpResponse.StatusCode < 500 { + fmt.Println(httpResponse.Body) + } + } + + if c.Cfg.Log5XXError { + if httpResponse.StatusCode >= 500 { + fmt.Println(httpResponse.Body) + } + } +} + func maskApiKey(request *http.Request) { apiKey := request.Header.Get(apiKeyHeader) if apiKey == "" { @@ -860,3 +884,4 @@ func IdempotencyKey(ctx context.Context) (string, bool) { key, ok := ikey.(string) return key, ok } + diff --git a/src/common/configuration.go b/src/common/configuration.go index 5e54b2fec..e6275a67c 100644 --- a/src/common/configuration.go +++ b/src/common/configuration.go @@ -87,6 +87,12 @@ type Config struct { Debug bool `json:"debug,omitempty"` UserAgent string `json:"userAgent,omitempty"` HTTPClient *http.Client + // when true logs 3XX errors on stdout + Log3XXError bool `json:"debug,omitempty"` + // when true logs 4XX errors on stdout + Log4XXError bool `json:"debug,omitempty"` + // when true logs 5XX errors on stdout + Log5XXError bool `json:"debug,omitempty"` } func (c *Config) GetCheckoutEndpoint() (string, error) { diff --git a/src/common/model_invalid_field.go b/src/common/model_invalid_field.go index f2d0bd242..a006c70a3 100644 --- a/src/common/model_invalid_field.go +++ b/src/common/model_invalid_field.go @@ -1,11 +1,3 @@ -/* -Management API - -API version: 1 -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - package common import ( diff --git a/src/common/model_rest_service_error.go b/src/common/model_rest_service_error.go index ebc1e3e62..aa1d8e80d 100644 --- a/src/common/model_rest_service_error.go +++ b/src/common/model_rest_service_error.go @@ -1,11 +1,3 @@ -/* -Management API - -API version: 3 -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - package common import ( diff --git a/src/common/response.go b/src/common/response.go index 53a429304..a0b979561 100644 --- a/src/common/response.go +++ b/src/common/response.go @@ -1,9 +1,3 @@ -/* - * Adyen Checkout API - * - * Contact: support@adyen.com - */ - package common import ( diff --git a/tests/balanceplatform/integration_test.go b/tests/balanceplatform/integration_test.go new file mode 100644 index 000000000..b8336cabc --- /dev/null +++ b/tests/balanceplatform/integration_test.go @@ -0,0 +1,82 @@ +//go:build integration +// +build integration + +package balanceplatform + +import ( + "context" + "github.com/adyen/adyen-go-api-library/v16/src/adyen" + "github.com/adyen/adyen-go-api-library/v16/src/common" + "github.com/joho/godotenv" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "net/http" + "net/url" + "os" + "testing" +) + +func Test_BalancePlatform_Integration(t *testing.T) { + godotenv.Load("./../../.env") + + var apiKey, balancePlatformId, proxy string + + apiKey = os.Getenv("ADYEN_PLATFORM_API_KEY") + balancePlatformId = os.Getenv("BALANCE_PLATFORM_ID") + proxy = os.Getenv("HTTP_PROXY") + + if apiKey == "" || balancePlatformId == "" { + t.Skip("Integration tests require credentials") + } + + config := common.Config{ + Environment: common.TestEnv, + ApiKey: apiKey, + Debug: "true" == os.Getenv("DEBUG"), + } + + if proxy != "" { + proxyURL, _ := url.Parse(proxy) + config.HTTPClient = &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyURL(proxyURL), + }, + } + } + client := adyen.NewClient(&config) + service := client.BalancePlatform() + + t.Run("Get a Balance Platform", func(t *testing.T) { + req := service.PlatformApi.GetBalancePlatformInput(balancePlatformId) + res, httpRes, err := service.PlatformApi.GetBalancePlatform(context.Background(), req) + + require.NoError(t, err) + assert.Equal(t, 200, httpRes.StatusCode) + assert.Equal(t, balancePlatformId, res.GetId()) + }) + + t.Run("Get a Balance Platform that fails with 422", func(t *testing.T) { + req := service.PlatformApi.GetBalancePlatformInput("na") + _, httpRes, err := service.PlatformApi.GetBalancePlatform(context.Background(), req) + + require.Error(t, err) + assert.Equal(t, 422, httpRes.StatusCode) + + // cast to RestServiceError + restServiceError := err.(common.RestServiceError) + assert.Equal(t, "https://docs.adyen.com/errors/not-found", restServiceError.Type) + assert.Equal(t, "30_002", restServiceError.ErrorCode) + }) + + t.Run("Get a Balance Platform that fails with 400", func(t *testing.T) { + + // log 4xx error + service.PlatformApi.Client.Cfg.Log4XXError = true + + req := service.PlatformApi.GetBalancePlatformInput("with invalid char//") + _, httpRes, err := service.PlatformApi.GetBalancePlatform(context.Background(), req) + + require.Error(t, err) + assert.Equal(t, 400, httpRes.StatusCode) + }) +} diff --git a/tests/checkout/integration_test.go b/tests/checkout/integration_test.go index 182a202da..e96231a40 100644 --- a/tests/checkout/integration_test.go +++ b/tests/checkout/integration_test.go @@ -14,10 +14,10 @@ import ( "strings" "testing" - "github.com/joho/godotenv" + "github.com/joho/godotenv" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCheckoutIntegration(t *testing.T) { @@ -302,6 +302,15 @@ func TestCheckoutIntegration(t *testing.T) { require.NotNil(t, httpRes) assert.Equal(t, 422, httpRes.StatusCode) require.NotNil(t, res) - }) + + // cast to API Error + e := err.(common.APIError) + + require.NotNil(t, e.RawBody) + + assert.Equal(t, float64(422), e.Status) + assert.Equal(t, "validation", e.Type) + assert.Equal(t, "208", e.Code) + }) }) } diff --git a/tests/legalentity/integration_test.go b/tests/legalentity/integration_test.go index 4dd0b4cc7..6d4aed117 100644 --- a/tests/legalentity/integration_test.go +++ b/tests/legalentity/integration_test.go @@ -7,7 +7,8 @@ import ( "context" "github.com/adyen/adyen-go-api-library/v16/src/adyen" "github.com/adyen/adyen-go-api-library/v16/src/common" - "github.com/joho/godotenv" + "github.com/adyen/adyen-go-api-library/v16/src/legalentity" + "github.com/joho/godotenv" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net/http" @@ -23,7 +24,7 @@ func Test_LegalEntity_Integration(t *testing.T) { username = os.Getenv("ADYEN_LEM_USERNAME") password = os.Getenv("ADYEN_LEM_PASSWORD") - legalEntityId = os.Getenv("ADYEN_LEM_ID") + legalEntityId = os.Getenv("LEM_LEGAL_ENTITY_ID") proxy = os.Getenv("HTTP_PROXY") if username == "" || password == "" || legalEntityId == "" { @@ -54,7 +55,80 @@ func Test_LegalEntity_Integration(t *testing.T) { res, httpRes, err := service.LegalEntitiesApi.GetLegalEntity(context.Background(), req) require.NoError(t, err) - assert.Equal(t, 202, httpRes.StatusCode) + assert.Equal(t, 200, httpRes.StatusCode) assert.Equal(t, legalEntityId, res.GetId()) }) + + t.Run("Get a legal entity that should fail", func(t *testing.T) { + req := service.LegalEntitiesApi.GetLegalEntityInput("INVALID_ID") + + _, httpRes, err := service.LegalEntitiesApi.GetLegalEntity(context.Background(), req) + + require.NotNil(t, err) + assert.Equal(t, 422, httpRes.StatusCode) + + // cast to API Error + e := err.(common.APIError) + + require.NotNil(t, e.RawBody) + assert.Equal(t, float64(422), e.Status) + assert.Equal(t, "30_112", e.Code) + + }) + + t.Run("Create a legal entity", func(t *testing.T) { + + legalEntityInfoRequiredType := legalentity.LegalEntityInfoRequiredType{ + Type: "individual", + Individual: legalentity.NewIndividual(legalentity.Name{ + FirstName: "John", + LastName: "Smith", + }, + legalentity.Address{ + Country: "NL", + }), + } + + req := service.LegalEntitiesApi.CreateLegalEntityInput(). + LegalEntityInfoRequiredType(legalEntityInfoRequiredType) + + res, httpRes, err := service.LegalEntitiesApi.CreateLegalEntity(context.Background(), req) + + require.NoError(t, err) + assert.Equal(t, 200, httpRes.StatusCode) + assert.NotNil(t, res.GetId()) + + }) + + t.Run("Create a legal entity that fails", func(t *testing.T) { + + // log 4xx error + service.LegalEntitiesApi.Client.Cfg.Log4XXError = true + + legalEntityInfoRequiredType := legalentity.LegalEntityInfoRequiredType{ + Type: "individual", + Individual: legalentity.NewIndividual(legalentity.Name{ + FirstName: "John", + LastName: "Smith", + }, + legalentity.Address{ + Country: "The Netherlands", // invalid: must pass country code + }), + } + + req := service.LegalEntitiesApi.CreateLegalEntityInput(). + LegalEntityInfoRequiredType(legalEntityInfoRequiredType) + + _, httpRes, err := service.LegalEntitiesApi.CreateLegalEntity(context.Background(), req) + + assert.Equal(t, 422, httpRes.StatusCode) + + // cast to API Error + e := err.(common.APIError) + + require.NotNil(t, e.RawBody) + assert.Equal(t, float64(422), e.Status) + assert.Equal(t, "30_102", e.Code) + + }) }