com.beanstream.api.ProfilesAPI.java Source code

Java tutorial

Introduction

Here is the source code for com.beanstream.api.ProfilesAPI.java

Source

/* The MIT License (MIT)
 *
 * Copyright (c) 2014 Beanstream Internet Commerce Corp, Digital River, Inc.
 *
 * 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.beanstream.api;

import java.util.List;

import com.beanstream.Configuration;
import com.beanstream.Gateway;
import com.beanstream.connection.PaymentsUrls;
import com.beanstream.connection.HttpMethod;
import com.beanstream.connection.HttpsConnector;
import com.beanstream.domain.Address;
import com.beanstream.domain.Card;
import com.beanstream.domain.CustomFields;
import com.beanstream.domain.PaymentProfile;
import com.beanstream.domain.Token;
import com.beanstream.exceptions.BeanstreamApiException;
import com.beanstream.requests.ProfileRequest;
import com.beanstream.responses.ProfileCardsResponse;
import com.beanstream.responses.ProfileResponse;
import com.beanstream.util.ProfilesUtils;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

/**
 * Payment Profiles allow you to store a customer's card number and other
 * information, such as billing address and shipping address. The card number
 * stored on the profile is a multi-use token and is called the ID.
 * 
 * Profiles can be created with a Credit Card or with a single-use Legato token.
 * If using a token then the card information needs to be entered each time the
 * user checks out. However the profile will always save the customer's billing
 * info.
 * 
 * @author Pedro Garcia
 *
 */
public class ProfilesAPI {

    private Configuration config;
    private HttpsConnector connector;
    private final Gson gson = new Gson();

    public ProfilesAPI(Configuration config) {
        this.config = config;
        connector = new HttpsConnector(config.getMerchantId(), config.getProfilesApiPasscode());
        connector.setCustomHttpClient(config.getCustomHttpClient());
    }

    public void setConfig(Configuration config) {
        this.config = config;
        connector = new HttpsConnector(config.getMerchantId(), config.getProfilesApiPasscode());
        connector.setCustomHttpClient(config.getCustomHttpClient());
    }

    /**
     * Create a PaymentProfile using a card and a billing address
     * 
     * @param card
     *            mandatory card, must be a valid card
     * @param billing
     *            address of the credit card
     * @return a ProfileResponse saying if the profile was created or not and the
     *         message
     * @throws BeanstreamApiException
     *             if any validation fails or error occur
     */
    public ProfileResponse createProfile(Card card, Address billing) throws BeanstreamApiException {
        return createProfile(card, null, billing, null, null, null);
    }

    /**
     * Create a PaymentProfile using a token, billing address
     * 
     * @param token
     *            mandatory token, must contain a valid name and code
     * @param billing
     *            address of the credit card
     * @return a ProfileResponse saying if the profile was created or not and the
     *         message
     * @throws BeanstreamApiException
     *             if any validation fails or error occur
     */
    public ProfileResponse createProfile(Token token, Address billing) throws BeanstreamApiException {
        return createProfile(null, token, billing, null, null, null);
    }

    /**
     * Create a PaymentProfile using a Card, billing address, custom fields,
     * language and comments
     * 
     * @param card
     *            mandatory parameter, must contain a valid card
     * @param billing
     *            address of the credit card
     * @param custom
     *            fields to add in the profile
     * @param language
     *            profile language
     * @param comments comments that a user would like to attach to the Payment Profile
     * @return a ProfileResponse saying if the profile was created or not and the
     *         message
     * @throws BeanstreamApiException
     *             if any validation fails or error occur
     */
    public ProfileResponse createProfile(Card card, Address billing, CustomFields custom, String language,
            String comments) throws BeanstreamApiException {
        return createProfile(card, null, billing, custom, language, comments);
    }

    /**
     * Create a PaymentProfile using a token, billing address, custom fields,
     * language and comments
     * 
     * @param token
     *            mandatory token, must contain a valid name and code
     * @param billing
     *            address of the credit card
     * @param custom
     *            fields to add in the profile
     * @param language
     *            profile language
     * @param comments comments that a user would like to attach to the Payment Profile
     * @return a ProfileResponse saying if the profile was created or not and the
     *         message
     * @throws BeanstreamApiException
     *             if any validation fails or error occur
     */
    public ProfileResponse createProfile(Token token, Address billing, CustomFields custom, String language,
            String comments) throws BeanstreamApiException {
        return createProfile(null, token, billing, custom, language, comments);
    }

    /**
     * Create a PaymentProfile using a token or token, billing address, custom
     * fields, language and comments you must send either one a token or a card
     * 
     * @param token
     *            mandatory parameter if card object is null, must contain a
     *            valid name and code
     * @param card
     *            mandatory parameter if token object is null, must contain a
     *            valid card
     * @param billing
     *            address of the credit card
     * @param custom
     *            fields to add in the profile
     * @param language
     *            profile language
     * @param comments comments that a user would like to attach to the Payment Profile
     * @return a ProfileResponse saying if the profile was created or not and the
     *         message
     * @throws BeanstreamApiException
     *             if any validation fails or error occur
     */
    private ProfileResponse createProfile(Card card, Token token, Address billing, CustomFields custom,
            String language, String comments) throws BeanstreamApiException {

        ProfileRequest req = new ProfileRequest(card, token, billing, custom, language, comments);
        ProfilesUtils.validateProfileReq(req);

        String url = PaymentsUrls.getProfilesUrl(config.getPlatform(), config.getVersion());

        String response = connector.ProcessTransaction(HttpMethod.post, url, req);
        return gson.fromJson(response, ProfileResponse.class);

    }

    /**
     * Retrieve a profile using the profile's ID. If you want to modify a
     * profile you must first retrieve it using this method
     * 
     * @param profileId
     *            to search
     * @return a PaymentProfile for the given profileId
     * @throws BeanstreamApiException
     *             if the profile does not exist or any validation or error
     *             occur
     */
    public PaymentProfile getProfileById(String profileId) throws BeanstreamApiException {
        ProfilesUtils.validateProfileId(profileId);
        String url = PaymentsUrls.getProfilesUrl(config.getPlatform(), config.getVersion(), profileId);

        String response = connector.ProcessTransaction(HttpMethod.get, url, null);
        return gson.fromJson(response, PaymentProfile.class);

    }

    /**
     * Delete the profile. You must send and valid profileId
     * 
     * @param profileId
     *            of the profile to delete
     * @return ProfileResponse if successful, an BeanstreamApiException if not.
     **/
    public ProfileResponse deleteProfileById(String profileId) throws BeanstreamApiException {

        ProfilesUtils.validateProfileId(profileId);
        String url = PaymentsUrls.getProfilesUrl(config.getPlatform(), config.getVersion(), profileId);

        String response = connector.ProcessTransaction(HttpMethod.delete, url, null);
        return gson.fromJson(response, ProfileResponse.class);

    }

    /**
     * Updates the profile. You must first retrieve the profile using
     * ProfilesAPI.getProfileById(id)
     * 
     * @param profile
     *            object to update
     * @return ProfileResponse if successful, an BeanstreamApiException if not.
     **/
    public ProfileResponse updateProfile(PaymentProfile profile) throws BeanstreamApiException {
        Gateway.assertNotNull(profile, "profile to update is null");
        ProfilesUtils.validateProfileId(profile.getId());

        ProfilesUtils.validateBillingAddr(profile.getBilling());

        String url = PaymentsUrls.getProfilesUrl(config.getPlatform(), config.getVersion(), profile.getId());

        JsonObject req = new JsonObject();
        req.add("billing", gson.toJsonTree(profile.getBilling(), Address.class));
        req.add("custom", gson.toJsonTree(profile.getCustom(), CustomFields.class));
        req.addProperty("language", profile.getLanguage());
        req.addProperty("comments", profile.getComments());
        String response = connector.ProcessTransaction(HttpMethod.put, url, req);
        return gson.fromJson(response, ProfileResponse.class);
    }

    /**
     * Gets the cards contained on this profile. It is possible for a profile
     * not to contain any cards if it was created using a Legato token
     * (single-use token)
     * 
     * @param profileId
     *            of the profile containing the cards
     * @return List with all the cards for that profile
     * @throws BeanstreamApiException
     *             if any validation fails or any error occur
     */
    public List<Card> getCards(String profileId) throws BeanstreamApiException {
        ProfilesUtils.validateProfileId(profileId);
        String url = PaymentsUrls.getProfileCardsUrl(config.getPlatform(), config.getVersion(), profileId);

        String response = connector.ProcessTransaction(HttpMethod.get, url, null);
        ProfileCardsResponse pcr = gson.fromJson(response, ProfileCardsResponse.class);
        return pcr.getCards();

    }

    /**
     * Get a particular card on a profile, Card IDs are their index in
     * getCards(), starting a 1 and going up: 1, 2, 3, 4...
     * 
     * @param profileId The profile id
     * @param cardId The card id
     * @return the Card you are looking for
     * @throws BeanstreamApiException when not successful
     */
    public Card getCard(String profileId, String cardId) throws BeanstreamApiException {

        ProfilesUtils.validateProfileId(profileId);
        Gateway.assertNotEmpty(cardId, "card id is empty");
        String url = PaymentsUrls.getProfileCardUrl(config.getPlatform(), config.getVersion(), profileId, cardId);

        String response = connector.ProcessTransaction(HttpMethod.get, url, null);
        ProfileCardsResponse pcr = gson.fromJson(response, ProfileCardsResponse.class);

        Card card = null;
        if (!pcr.getCards().isEmpty()) {
            int cid = new Integer(cardId) - 1;
            if (cid < 0 || cid > pcr.getCards().size())
                throw new IllegalArgumentException("Card ID was larger than the number of cards on the profile!");
            card = pcr.getCards().get(cid);
            card.setId(cardId);
        }
        return card;

    }

    /**
     * Updates the profile. You must first retrieve the profile using
     * ProfilesAPI.GetProfile(id)
     * 
     * @param profileId the profile id
     * @param card the card to update
     * @return ProfileResponse
     * @throws BeanstreamApiException when not successful
     */
    public ProfileResponse updateCard(String profileId, Card card) throws BeanstreamApiException {

        ProfilesUtils.validateProfileId(profileId);
        Gateway.assertNotNull(card, "card is is null");
        String cardId = card.getId();
        Gateway.assertNotEmpty(cardId, "card Id is empty");
        String url = PaymentsUrls.getProfileCardUrl(config.getPlatform(), config.getVersion(), profileId, cardId);

        if (card.getNumber().contains("X") || card.getNumber().contains("x"))
            card.setNumber(null);
        card.setType(null);
        card.setFunction(null);
        CardWrapper cw = new CardWrapper(card);

        // send the card json without id
        JsonElement _card = gson.toJsonTree(cw, CardWrapper.class);
        String response = connector.ProcessTransaction(HttpMethod.put, url, _card);
        return gson.fromJson(response, ProfileResponse.class);

    }

    /**
     * Add a new card to the profile. It gets appended to the end of the list of
     * cards. Make sure your Merchant account can support more cards. The
     * default amount is 1. You can change this limit in the online Members area
     * for Merchants located at: https://www.beanstream.com/admin/sDefault.asp
     * and heading to Configuration : Payment Profile Configuration
     * 
     * @param profileId The profile id.
     * @param card The card to add.
     * @return ProfileResponse
     * @throws BeanstreamApiException when not successful
     */
    public ProfileResponse addCard(String profileId, Card card) throws BeanstreamApiException {
        ProfilesUtils.validateProfileId(profileId);
        String url = PaymentsUrls.getProfileCardsUrl(config.getPlatform(), config.getVersion(), profileId);

        ProfilesUtils.validateCard(card);

        CardWrapper cw = new CardWrapper(card);
        String response = connector.ProcessTransaction(HttpMethod.post, url, cw);
        return gson.fromJson(response, ProfileResponse.class);

    }

    private class CardWrapper {
        private Card card;

        private CardWrapper(Card card) {
            this.card = card;
        }

        public Card getCard() {
            return card;
        }

        public void setCard(Card card) {
            this.card = card;
        }

    }

    /**
     * Removes the card from the profile. Card IDs are their index in
     * getCards(), starting a 1 and going up: 1, 2, 3, 4...
     * 
     * @param profileId the profile id
     * @param cardId the card id
     * @return ProfileResponse
     * @throws BeanstreamApiException when not successful
     */
    public ProfileResponse removeCard(String profileId, String cardId) throws BeanstreamApiException {
        ProfilesUtils.validateProfileId(profileId);
        Gateway.assertNotEmpty(cardId, "card it to remove is empty");
        String url = PaymentsUrls.getProfileCardUrl(config.getPlatform(), config.getVersion(), profileId, cardId);

        String response = connector.ProcessTransaction(HttpMethod.delete, url, null);
        return gson.fromJson(response, ProfileResponse.class);

    }

}