diff --git a/pom.xml b/pom.xml index 153d4e6..2a96968 100644 --- a/pom.xml +++ b/pom.xml @@ -5,15 +5,15 @@ br.com.userede.erede erede - 1.2.1 + 1.3.0 org.apache.maven.plugins maven-compiler-plugin - 11 - 11 + 15 + 15 @@ -37,12 +37,12 @@ org.apache.httpcomponents httpclient - 4.5.13 + 4.5.14 com.google.code.gson gson - 2.9.0 + 2.12.1 diff --git a/src/main/java/br/com/userede/erede/AccessTokenResponse.java b/src/main/java/br/com/userede/erede/AccessTokenResponse.java new file mode 100644 index 0000000..a3489d8 --- /dev/null +++ b/src/main/java/br/com/userede/erede/AccessTokenResponse.java @@ -0,0 +1,41 @@ +package br.com.userede.erede; + +public class AccessTokenResponse { + + private String access_token; + private String token_type; + private Long expires_in; + private String scope; + + public String getAccessToken() { + return access_token; + } + + public String getTokenType() { + return token_type; + } + + public Long getExpiresIn() { + return expires_in; + } + + public String getScope() { + return scope; + } + + public void setAccessToken(String access_token) { + this.access_token = access_token; + } + + public void setTokenType(String token_type) { + this.token_type = token_type; + } + + public void setExpiresIn(Long expires_in) { + this.expires_in = expires_in; + } + + public void setScope(String scope) { + this.scope = scope; + } +} diff --git a/src/main/java/br/com/userede/erede/Environment.java b/src/main/java/br/com/userede/erede/Environment.java index 25f1f14..ae193a9 100755 --- a/src/main/java/br/com/userede/erede/Environment.java +++ b/src/main/java/br/com/userede/erede/Environment.java @@ -5,8 +5,8 @@ public class Environment { private static final String PRODUCTION = "https://api.userede.com.br/erede"; - private static final String SANDBOX = "https://api.userede.com.br/desenvolvedores"; - private static final String VERSION = "v1"; + private static final String SANDBOX = "https://sandbox-erede.useredecloud.com.br"; + private static final String VERSION = "v2"; @SerializedName("ip") private String ip; diff --git a/src/main/java/br/com/userede/erede/HttpUtils.java b/src/main/java/br/com/userede/erede/HttpUtils.java new file mode 100644 index 0000000..25c92c4 --- /dev/null +++ b/src/main/java/br/com/userede/erede/HttpUtils.java @@ -0,0 +1,36 @@ +package br.com.userede.erede; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.zip.GZIPInputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; + +public class HttpUtils { + + public static String parseResponse(HttpResponse response) throws IOException { + HttpEntity responseEntity = response.getEntity(); + InputStream responseEntityContent = responseEntity.getContent(); + + Header contentEncoding = response.getFirstHeader("Content-Encoding"); + + if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) { + responseEntityContent = new GZIPInputStream(responseEntityContent); + } + + BufferedReader responseReader = new BufferedReader( + new InputStreamReader(responseEntityContent)); + StringBuilder responseBuilder = new StringBuilder(); + String line; + + while ((line = responseReader.readLine()) != null) { + responseBuilder.append(line); + } + + return responseBuilder.toString(); + } +} diff --git a/src/main/java/br/com/userede/erede/OAuthEnvironment.java b/src/main/java/br/com/userede/erede/OAuthEnvironment.java new file mode 100644 index 0000000..92615da --- /dev/null +++ b/src/main/java/br/com/userede/erede/OAuthEnvironment.java @@ -0,0 +1,28 @@ +package br.com.userede.erede; + +import com.google.gson.annotations.SerializedName; + +public class OAuthEnvironment { + + private static final String PRODUCTION = "https://api.userede.com.br/redelabs/oauth2/token"; + private static final String SANDBOX = "https://rl7-sandbox-api.useredecloud.com.br/oauth2/token"; + + @SerializedName("endpoint") + private String endpoint; + + public OAuthEnvironment(String endpoint) { + this.endpoint = endpoint; + } + + public static OAuthEnvironment production() { + return new OAuthEnvironment(OAuthEnvironment.PRODUCTION); + } + + public static OAuthEnvironment sandbox() { + return new OAuthEnvironment(OAuthEnvironment.SANDBOX); + } + + public String getEndpoint() { + return endpoint; + } +} diff --git a/src/main/java/br/com/userede/erede/OAuthRede.java b/src/main/java/br/com/userede/erede/OAuthRede.java new file mode 100644 index 0000000..3515086 --- /dev/null +++ b/src/main/java/br/com/userede/erede/OAuthRede.java @@ -0,0 +1,17 @@ +package br.com.userede.erede; + +import br.com.userede.erede.service.OAuthService; + +public class OAuthRede { + + private OAuthService oAuthService; + + public OAuthRede(OAuthStore oAuthStore) { + this.oAuthService = new OAuthService(oAuthStore); + } + + /**Returns a new access_token*/ + public String generateAccessToken() { + return oAuthService.generateAccessToken(); + } +} diff --git a/src/main/java/br/com/userede/erede/OAuthStore.java b/src/main/java/br/com/userede/erede/OAuthStore.java new file mode 100644 index 0000000..1bc4601 --- /dev/null +++ b/src/main/java/br/com/userede/erede/OAuthStore.java @@ -0,0 +1,47 @@ +package br.com.userede.erede; + +public class OAuthStore { + + private OAuthEnvironment environment; + private String clientId; // OLD PV + private String clientSecret; // OLD CHAVE INTEGRACAO + + + public OAuthStore(String clientId, String clientSecret, OAuthEnvironment environment) { + this.clientId = clientId; + this.clientSecret = clientSecret; + this.environment = environment; + } + + /**Constructs production OAuthStore*/ + public OAuthStore(String clientId, String clientSecret) { + this(clientId, clientSecret, OAuthEnvironment.production()); + } + + public OAuthEnvironment getEnvironment() { + return environment; + } + + public OAuthStore setEnvironment(OAuthEnvironment environment) { + this.environment = environment; + return this; + } + + /**Old PV**/ + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + /**Old CHAVE INTEGRACAO**/ + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } +} diff --git a/src/main/java/br/com/userede/erede/Store.java b/src/main/java/br/com/userede/erede/Store.java index 2e92ed1..3577b8b 100755 --- a/src/main/java/br/com/userede/erede/Store.java +++ b/src/main/java/br/com/userede/erede/Store.java @@ -3,17 +3,17 @@ public class Store { private Environment environment; - private String filiation; - private String token; + private String filiation; // clientId + private String accessToken; // temporary access_token - public Store(String filiation, String token, Environment environment) { - this.environment = environment; - this.filiation = filiation; - this.token = token; + public Store(String filiation, String accessToken, Environment environment) { + this.filiation = filiation; + this.accessToken = accessToken; + this.environment = environment; } - public Store(String filiation, String token) { - this(filiation, token, Environment.production()); + public Store(String filiation, String accessToken) { + this(filiation, accessToken, Environment.production()); } public Environment getEnvironment() { @@ -33,13 +33,12 @@ public Store setFiliation(String filiation) { this.filiation = filiation; return this; } - - public String getToken() { - return token; - } - - public Store setToken(String token) { - this.token = token; - return this; - } + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } } diff --git a/src/main/java/br/com/userede/erede/eRede.java b/src/main/java/br/com/userede/erede/eRede.java index b5d08c0..2e2a8ac 100755 --- a/src/main/java/br/com/userede/erede/eRede.java +++ b/src/main/java/br/com/userede/erede/eRede.java @@ -1,15 +1,15 @@ package br.com.userede.erede; +import java.util.logging.Logger; + import br.com.userede.erede.service.CancelTransactionService; import br.com.userede.erede.service.CaptureTransactionService; import br.com.userede.erede.service.CreateTransactionService; import br.com.userede.erede.service.GetTransactionService; -import java.util.logging.Logger; - public class eRede { - public static final String VERSION = "1.2.0"; + public static final String VERSION = "1.3.0"; public static final String ARTIFACT_ID = "br.com.userede.erede"; public static final String USER_AGENT = "eRede/" + eRede.VERSION + " (Java; %s)"; @@ -27,7 +27,7 @@ public eRede(Store store, Logger logger) { public TransactionResponse authorize(Transaction transaction) { return create(transaction); - } + } public TransactionResponse create(Transaction transaction) { CreateTransactionService createTransactionService = new CreateTransactionService(store, diff --git a/src/main/java/br/com/userede/erede/service/AbstractTransactionService.java b/src/main/java/br/com/userede/erede/service/AbstractTransactionService.java index b18cad8..552cf94 100755 --- a/src/main/java/br/com/userede/erede/service/AbstractTransactionService.java +++ b/src/main/java/br/com/userede/erede/service/AbstractTransactionService.java @@ -1,14 +1,10 @@ package br.com.userede.erede.service; -import br.com.userede.erede.Store; -import br.com.userede.erede.Transaction; -import br.com.userede.erede.TransactionResponse; -import br.com.userede.erede.eRede; -import br.com.userede.erede.service.error.RedeError; -import br.com.userede.erede.service.error.RedeException; -import com.google.gson.Gson; -import org.apache.http.Header; -import org.apache.http.HttpEntity; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpUriRequest; @@ -16,16 +12,15 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.zip.GZIPInputStream; +import com.google.gson.Gson; + +import br.com.userede.erede.HttpUtils; +import br.com.userede.erede.Store; +import br.com.userede.erede.Transaction; +import br.com.userede.erede.TransactionResponse; +import br.com.userede.erede.eRede; +import br.com.userede.erede.service.error.RedeError; +import br.com.userede.erede.service.error.RedeException; abstract class AbstractTransactionService { @@ -44,18 +39,14 @@ abstract class AbstractTransactionService { URIBuilder getUri() throws URISyntaxException { return new URIBuilder(store.getEnvironment().getEndpoint("transactions")); - } + } TransactionResponse sendRequest(HttpUriRequest request) { - String credentials = Base64.getEncoder() - .encodeToString(String.format("%s:%s", store.getFiliation(), store.getToken()).getBytes( - StandardCharsets.US_ASCII)); - - request - .addHeader(HttpHeaders.USER_AGENT, String.format(eRede.USER_AGENT, store.getFiliation())); + + request.addHeader(HttpHeaders.USER_AGENT, String.format(eRede.USER_AGENT, store.getFiliation())); request.addHeader(HttpHeaders.ACCEPT, "application/json"); request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); - request.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + credentials); + request.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + store.getAccessToken()); request.addHeader("Transaction-Response", "brand-return-opened"); @@ -66,15 +57,15 @@ TransactionResponse sendRequest(HttpUriRequest request) { HttpResponse httpResponse = closeableHttpClient.execute(request); int status = httpResponse.getStatusLine().getStatusCode(); - String response = parseResponse(httpResponse); + String response = HttpUtils.parseResponse(httpResponse); TransactionResponse transactionResponse = new Gson() .fromJson(response, TransactionResponse.class); - + if (status < 200 || status >= 400) { RedeError redeError = new RedeError(transactionResponse.getReturnCode(), transactionResponse.getReturnMessage()); - throw new RedeException(httpResponse.getStatusLine().toString(), redeError, + throw new RedeException(response, redeError, transactionResponse); } @@ -87,25 +78,5 @@ TransactionResponse sendRequest(HttpUriRequest request) { return null; } - private String parseResponse(HttpResponse response) throws IOException { - HttpEntity responseEntity = response.getEntity(); - InputStream responseEntityContent = responseEntity.getContent(); - - Header contentEncoding = response.getFirstHeader("Content-Encoding"); - - if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) { - responseEntityContent = new GZIPInputStream(responseEntityContent); - } - - BufferedReader responseReader = new BufferedReader( - new InputStreamReader(responseEntityContent)); - StringBuilder responseBuilder = new StringBuilder(); - String line; - - while ((line = responseReader.readLine()) != null) { - responseBuilder.append(line); - } - - return responseBuilder.toString(); - } + } diff --git a/src/main/java/br/com/userede/erede/service/OAuthService.java b/src/main/java/br/com/userede/erede/service/OAuthService.java new file mode 100644 index 0000000..595250a --- /dev/null +++ b/src/main/java/br/com/userede/erede/service/OAuthService.java @@ -0,0 +1,71 @@ +package br.com.userede.erede.service; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Base64; + +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicNameValuePair; + +import com.google.gson.Gson; + +import br.com.userede.erede.AccessTokenResponse; +import br.com.userede.erede.HttpUtils; +import br.com.userede.erede.OAuthStore; +import br.com.userede.erede.eRede; + +public class OAuthService { + + private OAuthStore store; + + public OAuthService(OAuthStore store) { + this.store = store; + } + + public String generateAccessToken() { + + // Base64(clientId:clientSecret) + String clientId = store.getClientId(); + String clientSecret = store.getClientSecret(); + String basic = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8)); + + String tokenUrl = store.getEnvironment().getEndpoint(); + + HttpPost post = new HttpPost(tokenUrl); + + post.addHeader(HttpHeaders.USER_AGENT, String.format(eRede.USER_AGENT, store.getClientId())); + post.addHeader(HttpHeaders.ACCEPT, "application/json"); + post.addHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded"); + post.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + basic); + + // grant_type=client_credentials + post.setEntity(new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("grant_type", "client_credentials")), StandardCharsets.UTF_8)); + + try (CloseableHttpClient client = HttpClientBuilder.create().build()) { + HttpResponse httpResponse = client.execute(post); + int status = httpResponse.getStatusLine().getStatusCode(); + + String response = HttpUtils.parseResponse(httpResponse); + + if (status < 200 || status >= 400) { + throw new RuntimeException("Erro ao gerar access token. Status=" + status + " Body=" + response); + } + + AccessTokenResponse tokenResponse = new Gson().fromJson(response, AccessTokenResponse.class); + + if (tokenResponse == null || tokenResponse.getAccessToken() == null || tokenResponse.getAccessToken().isBlank()) { + throw new RuntimeException("Resposta inválida ao gerar access token: " + response); + } + + return tokenResponse.getAccessToken(); + } catch (IOException e) { + throw new RuntimeException("Falha ao gerar access token", e); + } + } +} diff --git a/src/test/java/br/com/userede/erede/eRedeTest.java b/src/test/java/br/com/userede/erede/eRedeTest.java index 5930113..6dfd67e 100755 --- a/src/test/java/br/com/userede/erede/eRedeTest.java +++ b/src/test/java/br/com/userede/erede/eRedeTest.java @@ -1,19 +1,26 @@ package br.com.userede.erede; -import junit.framework.TestCase; - import java.util.Date; -@SuppressWarnings("NewClassNamingConvention") +import junit.framework.TestCase; + public class eRedeTest extends TestCase { private Store store; + private OAuthStore oAuthStore; private int sequence; public void setUp() { - // Configuração da loja - store = new Store("36046288", "3cf40bfefad642d788c4a2721c0a0b11", Environment.sandbox()); - + + // novo: obtendo access token + oAuthStore = new OAuthStore("36046288", "3cf40bfefad642d788c4a2721c0a0b11", OAuthEnvironment.sandbox()); + + OAuthRede oAuthRede = new OAuthRede(oAuthStore); + + String accessToken = oAuthRede.generateAccessToken(); + + // Configuração da loja + store = new Store("36046288", accessToken, Environment.sandbox()); sequence = 0; } @@ -202,4 +209,10 @@ public void testShouldCreateADebitcardTransactionWithAuthentication() { transactionResponse.getThreeDSecure().getUrl() ); } + + public void testShouldGenerateAccessToken() { + OAuthRede oAuthRede = new OAuthRede(oAuthStore); + String accessToken = oAuthRede.generateAccessToken(); + assertNotNull(accessToken); + } }