All Downloads are FREE. Search and download functionalities are using the official Maven repository.

one.credify.sdk.CredifySdk Maven / Gradle / Ivy

package one.credify.sdk;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import one.credify.crypto.Encryption;
import one.credify.crypto.Signing;
import one.credify.sdk.impl.*;
import one.credify.sdk.restapi.CredifyRestV1;
import one.credify.sdk.restapi.CredifyRestV2;
import one.credify.sdk.restapi.OidcCoreRest;
import one.credify.sdk.utils.Constants;
import org.jetbrains.annotations.NotNull;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.function.Function;

/**
 * Currently, there are two Credify API version V1 and V2. In this class we define 2 function to generate Credify API Client for V1(*getCredifyClient*) and V2(*getCredifyClientV2*).
 * We can inject to a specific service with what credify client version we want to easy change the version of the api.
 */
public class CredifySdk {
    @Getter
    private final Encryption encryption;
    @Getter
    private final Signing signing;
    @Getter
    private final OidcService oidcService;

    @Getter
    private final AuthService authService;

    @Getter
    private final BnplService bnplService;

    @Getter
    private final OfferService offerService;

    @Getter
    private final FeedbackService feedbackService;

    @Getter
    private final ClaimsService claimsService;

    public String accessToken;

    private OkHttpClient credifyHttpClient;

    private OkHttpClient credifyHttpClientV2;

    private int authErrorCount = 0;

    private final int AUTH_ERROR_LIMIT = 5;

    @Builder
    public CredifySdk(String signingPrivateKey, String encryptionPrivateKey, String apiKey, CredifyConfig.Env env) throws IOException, InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException {
        signing = new Signing();
        signing.importPrivateKey(signingPrivateKey);
        encryption = new Encryption();
        encryption.importPrivateKey(encryptionPrivateKey);
        CredifyConfig config = new CredifyConfig(signing, encryption, apiKey, env);
        OidcCoreRest oidcCoreClient = getOidcCoreClient(config);
        CredifyRestV1 credifyClientV1 = getCredifyClient(config);
        CredifyRestV2 credifyClientV2 = getCredifyClientV2(config);
        this.authService = new AuthServiceImpl(credifyClientV1);
        this.oidcService = new OidcServiceImpl(config, oidcCoreClient);
        this.bnplService = new BnplServiceImpl(credifyClientV1);
        this.offerService = new OfferServiceImpl(credifyClientV1);
        this.feedbackService = new FeedbackServiceImpl(credifyClientV2);
        this.claimsService = new ClaimsServiceImpl(config, credifyClientV1);

        accessToken = this.authService.generateAccessToken(apiKey);
    }

    /**
     * generate oidc core client
     * @param config
     * @return
     */
    private static OidcCoreRest getOidcCoreClient(CredifyConfig config) {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(logging)
                .build();

        Retrofit oidcCoreRetrofit = new Retrofit.Builder()
                .baseUrl(config.getOidcCoreUrl())
                .client(client)
                .addConverterFactory(JacksonConverterFactory.create(Constants.MAPPER))
                .build();
        return oidcCoreRetrofit.create(OidcCoreRest.class);
    }

    /**
     * generate credify api client v1
     * @param config
     * @return
     */
    private CredifyRestV1 getCredifyClient(CredifyConfig config) {
        if (credifyHttpClient == null) {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            credifyHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(new AuthorizationInterceptor(config, this))
                    .addInterceptor(logging)
                    .build();
        }
        Retrofit credifyRetrofit = new Retrofit.Builder()
                .baseUrl(config.getApiUrlV1())
                .client(credifyHttpClient)
                .addConverterFactory(JacksonConverterFactory.create(Constants.MAPPER))
                .build();
        return credifyRetrofit.create(CredifyRestV1.class);
    }

    /**
     * generate credify client v2
     * @param config
     * @return
     */
    private CredifyRestV2 getCredifyClientV2(CredifyConfig config) {
        if (credifyHttpClientV2 == null) {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            credifyHttpClientV2 = new OkHttpClient.Builder()
                    .addInterceptor(new AuthorizationInterceptor(config, this))
                    .addInterceptor(logging)
                    .build();
        }
        Retrofit credifyRetrofit = new Retrofit.Builder()
                .baseUrl(config.getApiUrlV2())
                .client(credifyHttpClientV2)
                .addConverterFactory(JacksonConverterFactory.create(Constants.MAPPER))
                .build();
        return credifyRetrofit.create(CredifyRestV2.class);
    }

    @AllArgsConstructor
    @NoArgsConstructor
    public class AuthorizationInterceptor implements Interceptor {
        private CredifyConfig config;
        private CredifySdk credifySdk;

        @NotNull
        @Override
        public Response intercept(@NotNull Chain chain) throws IOException {
            Function checkRequestUrl = uriPath -> chain.request().url().uri().getPath().equals(uriPath);
            if (checkRequestUrl.apply(CredifyRestV1.GENERATE_ACCESS_TOKEN)) {
                return chain.proceed(chain.request());
            }
            Function addHeaderAccessTokenFn = chain1 ->
                    chain1.request().newBuilder().addHeader("Authorization", "Bearer " + accessToken).build();
            Response response = chain.proceed(addHeaderAccessTokenFn.apply(chain));
            if (response.code() == 401 && authErrorCount < AUTH_ERROR_LIMIT) {
                response.close();
                authErrorCount++;
                accessToken = credifySdk.getAuthService().generateAccessToken(config.getApiKey());
                response = chain.proceed(addHeaderAccessTokenFn.apply(chain));
                if (response.code() != 401) {
                    authErrorCount = 0;
                }
            } else {
                authErrorCount = 0;
            }
            return response;

        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy