com.paysafe.PaysafeApiClient.java Source code

Java tutorial

Introduction

Here is the source code for com.paysafe.PaysafeApiClient.java

Source

/*
 * Copyright (c) 2016 Paysafe
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.paysafe;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import javax.net.ssl.HttpsURLConnection;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.paysafe.cardpayments.CardPaymentsService;
import com.paysafe.common.ApiException;
import com.paysafe.common.EntityNotFoundException;
import com.paysafe.common.Id;
import com.paysafe.common.InvalidCredentialsException;
import com.paysafe.common.InvalidRequestException;
import com.paysafe.common.PaysafeException;
import com.paysafe.common.PermissionException;
import com.paysafe.common.RequestConflictException;
import com.paysafe.common.RequestDeclinedException;
import com.paysafe.common.impl.AddressContainer;
import com.paysafe.common.impl.AddressContainerAdapter;
import com.paysafe.common.impl.BaseDomainObject;
import com.paysafe.common.impl.BooleanAdapter;
import com.paysafe.common.impl.IdAdapter;
import com.paysafe.common.impl.Request;
import com.paysafe.customervault.CustomerVaultService;
import com.paysafe.directdebit.DirectDebitService;
import com.paysafe.threedsecure.ThreeDSecureService;

// TODO: Auto-generated Javadoc
/**
 * The Class PaysafeApiClient.
 */
public class PaysafeApiClient {

    /**
     * The api end point.
     */
    private final String apiEndPoint;

    /**
     * The environment.
     */
    private final Environment environment;

    /**
     * The key id.
     */
    private final String keyId;

    /**
     * The key password.
     */
    private final String keyPassword;

    /**
     * The account number.
     */
    private String accountNumber;

    /**
     * The CardPaymentsService.
     */
    private CardPaymentsService cardPaymentService;

    /**
     * The CustomerVaultService.
     */
    private CustomerVaultService customerVaultService;

    /**
     * The DirectDebitService.
     */
    private DirectDebitService directDebitService;

    /**
     * The ThreeDSecureService.
     */
    private ThreeDSecureService threeDSecureService;

    /**
     * The gson object used to deserialize the api response.
     */
    private final Gson gsonDeserializer;

    /**
     * Instantiates a new paysafe API client.
     *
     * @param keyId the key id
     * @param keyPassword the key password
     * @param environment the environment
     */
    public PaysafeApiClient(final String keyId, final String keyPassword, final Environment environment) {
        this.keyId = keyId;
        this.keyPassword = keyPassword;
        this.environment = environment;
        apiEndPoint = this.environment.getUrl();
        final GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeHierarchyAdapter(AddressContainer.class, new AddressContainerAdapter());
        gsonBuilder.registerTypeHierarchyAdapter(Boolean.class, new BooleanAdapter());
        gsonBuilder.registerTypeHierarchyAdapter(Id.class, new IdAdapter());
        gsonDeserializer = gsonBuilder.create();
    }

    /**
     * Instantiates a new paysafe API client.
     *
     * @param keyId the key id
     * @param keyPassword the key password
     * @param environment the environment
     * @param account the account number
     */
    public PaysafeApiClient(final String keyId, final String keyPassword, final Environment environment,
            final String account) {
        this(keyId, keyPassword, environment);
        this.setAccount(account);
    }

    /**
     * Card payment service.
     *
     * @return the card payment service
     */
    public final CardPaymentsService cardPaymentService() {
        if (null == cardPaymentService) {
            cardPaymentService = new CardPaymentsService(this);
        }
        return cardPaymentService;
    }

    /**
     * Customer vault service.
     *
     * @return the customer vault service
     */
    public final CustomerVaultService customerVaultService() {
        if (null == customerVaultService) {
            customerVaultService = new CustomerVaultService(this);
        }
        return customerVaultService;
    }

    /**
     * directDebitService.
     *
     * @return the directDebitService
    */

    public final DirectDebitService directDebitService() {
        if (null == directDebitService) {
            directDebitService = new DirectDebitService(this);
        }
        return directDebitService;
    }

    /**
     * ThreeD Secure Service.
     *
     * @return the ThreeD Secure Service
     */
    public final ThreeDSecureService threeDSecureService() {
        if (null == threeDSecureService) {
            threeDSecureService = new ThreeDSecureService(this);
        }
        return threeDSecureService;
    }

    /**
     * Process error.
     *
     * @param code the response code
     * @param obj the obj
     * @param cause the original exception
     * @return the exception
     */
    private PaysafeException getException(final int code, final BaseDomainObject obj, final IOException cause) {
        switch (code) {
        case 400:
            return new InvalidRequestException(obj, cause);
        case 401:
            return new InvalidCredentialsException(obj, cause);
        case 402:
            return new RequestDeclinedException(obj, cause);
        case 403:
            return new PermissionException(obj, cause);
        case 404:
            return new EntityNotFoundException(obj, cause);
        case 409:
            return new RequestConflictException(obj, cause);
        case 406:
        case 415:
        default:
            return new ApiException(obj, cause);
        }
    }

    /**
     * Create a connection from a request and return a specified type.
     *
     * @param <T> an extension of BaseDomainObject
     * @param request the Request object to be processed
     * @param returnType the class that will be returned
     * @return the t
     * @throws IOException Signals that an I/O exception has occurred.
     * @throws PaysafeException the paysafe exception
     */
    public final <T extends BaseDomainObject> T processRequest(final Request request, Class<T> returnType)
            throws IOException, PaysafeException {
        final URL url = new URL(request.buildUrl(apiEndPoint));

        final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        try {
            connection.setRequestProperty("Authorization", "Basic " + getAuthenticatedString());
            connection.setRequestMethod(request.getMethod().toString());
            connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            connection.setRequestProperty("SDK-Type", "Paysafe_Java_SDK");

            // Write to the stream if we can
            if (request.getMethod().equals(Request.RequestType.POST)
                    || (request.getMethod().equals(Request.RequestType.PUT))) {
                connection.setDoOutput(true);

                final OutputStream os = connection.getOutputStream();
                final DataOutputStream dos = new DataOutputStream(os);
                try {
                    dos.write(serializeObject(request, returnType).getBytes(StandardCharsets.UTF_8));
                    dos.flush();
                } finally {
                    dos.close();
                    os.close();
                }
            }

            return getReturnObject(connection, returnType);
        } finally {
            connection.disconnect();
        }
    }

    /**
     * Get the return object back from the connection.
     *
     * @param <T> an extension of BaseDomainObject
     * @param connection HttpsURLConnection
     * @param returnType the class that will be returned
     * @return the return object
     * @throws IOException Signals that an I/O exception has occurred.
     * @throws PaysafeException the paysafe exception
     */
    private <T extends BaseDomainObject> T getReturnObject(HttpsURLConnection connection, Class<T> returnType)
            throws IOException, PaysafeException {
        try {
            InputStream is = connection.getInputStream();

            try {
                return deserializeStream(is, returnType);
            } finally {
                is.close();
            }
        } catch (IOException cause) {
            // store the cause so we know to throw an exception after parsing
            // the response
            InputStream is = connection.getErrorStream();
            try {
                throw getException(connection.getResponseCode(), deserializeStream(is, returnType), cause);
            } finally {
                is.close();
            }
        }
    }

    /**
     * Take an input stream and return the gson deserialized version.
     *
     * @param <T> an extension of BaseDomainObject
     * @param is the input stream
     * @param returnType the class that will be returned
     * @return the t
     * @throws IOException Signals that an I/O exception has occurred.
     */
    private <T extends BaseDomainObject> T deserializeStream(InputStream is, Class<T> returnType)
            throws IOException {
        final InputStreamReader isr = new InputStreamReader(is, "UTF-8");
        try {
            return gsonDeserializer.fromJson(isr, returnType);
        } finally {
            isr.close();
        }
    }

    /**
     * Take a domain object, and json serialize it.
     *
     * @param request the request
     * @param returnType the return type
     * @return json encoding of the request object
     */
    private String serializeObject(Request request, Class<?> returnType) {
        final GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.excludeFieldsWithoutExposeAnnotation();
        gsonBuilder.registerTypeHierarchyAdapter(AddressContainer.class, new AddressContainerAdapter());
        gsonBuilder.registerTypeHierarchyAdapter(Id.class, new IdAdapter());
        if (null != request.getSerializer()) {
            gsonBuilder.registerTypeAdapter(returnType, request.getSerializer());
        }
        final Gson gson = gsonBuilder.create();
        return gson.toJson(request.getBody());
    }

    /**
     * Sets the account.
     *
     * @param accountNumber the new account
     */
    public final void setAccount(String accountNumber) {
        this.accountNumber = accountNumber;
    }

    /**
     * Gets the account.
     *
     * @return the account
     */
    public final String getAccount() {
        return accountNumber;
    }

    /**
     * Gets the base 64 encoded authenticated string.
     *
     * @return the authenticated string
     * @throws IOException Signals that an I/O exception has occurred.
     */
    private String getAuthenticatedString() throws IOException {
        return javax.xml.bind.DatatypeConverter.printBase64Binary((keyId + ':' + keyPassword).getBytes("UTF-8"));
    }
}