com.beanstream.api.PaymentsAPI.java Source code

Java tutorial

Introduction

Here is the source code for com.beanstream.api.PaymentsAPI.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 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.exceptions.BeanstreamApiException;
import com.beanstream.requests.CardPaymentRequest;
import com.beanstream.requests.CashPaymentRequest;
import com.beanstream.requests.ChequePaymentRequest;
import com.beanstream.requests.TokenPaymentRequest;
import com.beanstream.requests.ReturnRequest;
import com.beanstream.requests.UnreferencedCardReturnRequest;
import com.beanstream.requests.UnreferencedSwipeReturnRequest;
import com.beanstream.responses.BeanstreamResponse;
import com.beanstream.responses.PaymentResponse;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import org.apache.http.HttpStatus;

import static com.beanstream.connection.PaymentsUrls.*;
import com.beanstream.requests.PaymentRequest;
import com.beanstream.requests.ProfilePaymentRequest;

/**
 * The entry point for processing payments.
 *
 * @author bowens
 */
public class PaymentsAPI {

    private static final String AMOUNT_PARAM = "amount";
    private static final String MERCHANT_ID_PARAM = "merchant_id";
    private Configuration config;
    private HttpsConnector connector;
    private final Gson gson = new Gson();

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

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

    /**
     * Make a credit card payment. This payment must include credit card data.
     * An Approved request will return a PaymentResponse. If the request fails in
     * any way, even a card Decline, then an exception will be thrown.
     *
     * @author Chris Tihor
     * @param paymentRequest the payment request including a credit card data
     * @return PaymentResponse the result of the payment transaction
     * @throws BeanstreamApiException as a result of a business logic validation
     * or any other error @see
     */
    public PaymentResponse makePayment(CardPaymentRequest paymentRequest) throws BeanstreamApiException {
        paymentRequest.setMerchantId("" + config.getMerchantId());
        paymentRequest.getCard().setComplete(true); // false for pre-auth

        // build the URL
        String url = PaymentsUrls.getPaymentUrl(config.getPlatform(), config.getVersion());

        // process the transaction using the REST API
        String response = connector.ProcessTransaction(HttpMethod.post, url, paymentRequest);

        // parse the output and return a PaymentResponse
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * Make a tokenized payment. This payment must include a token that was previously
     * returned from the Legato tokenizing service, usually by the client application.
     *
     * @author Chris Tihor
     * @param paymentRequest the payment request including a token
     * @return PaymentResponse the result of the payment transaction
     * @throws BeanstreamApiException as a result of a business logic validation
     * or any other error
     */
    public PaymentResponse makePayment(TokenPaymentRequest paymentRequest) throws BeanstreamApiException {
        paymentRequest.setMerchantId("" + config.getMerchantId());
        paymentRequest.getToken().setComplete(true); // true to make the payment

        // build the URL
        String url = PaymentsUrls.getPaymentUrl(config.getPlatform(), config.getVersion());

        // process the transaction using the REST API
        String response = connector.ProcessTransaction(HttpMethod.post, url, paymentRequest);

        // parse the output and return a PaymentResponse
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * Make a tokenized payment with a Payment Profile. This payment must include a token that was previously
     * returned from the Payment Profile.
     *
     * @param paymentRequest the payment request including a token
     * @return PaymentResponse the result of the payment transaction
     * @throws BeanstreamApiException as a result of a business logic validation
     * or any other error
     */
    public PaymentResponse makePayment(ProfilePaymentRequest paymentRequest) throws BeanstreamApiException {
        paymentRequest.setMerchantId("" + config.getMerchantId());
        paymentRequest.getProfile().setComplete(true); // true to make the payment

        // build the URL
        String url = PaymentsUrls.getPaymentUrl(config.getPlatform(), config.getVersion());

        // process the transaction using the REST API
        String response = connector.ProcessTransaction(HttpMethod.post, url, paymentRequest);

        // parse the output and return a PaymentResponse
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * Make a cash payment.
     *
     * @author Chris Tihor
     * @param paymentRequest the cash payment request
     * @return PaymentResponse the result of the payment transaction
     * @throws BeanstreamApiException as a result of a business logic validation
     * or any other error @see
     */
    public PaymentResponse makePayment(CashPaymentRequest paymentRequest) throws BeanstreamApiException {

        // build the URL
        String url = PaymentsUrls.getPaymentUrl(config.getPlatform(), config.getVersion());

        // process the transaction using the REST API
        String response = connector.ProcessTransaction(HttpMethod.post, url, paymentRequest);

        // parse the output and return a PaymentResponse
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * Make a payment by cheque.
     *
     * @author Chris Tihor
     * @param paymentRequest the payment request including a cheque
     * @return PaymentResponse the result of the payment transaction
     * @throws BeanstreamApiException as a result of a business logic validation
     * or any other error @see
     */
    public PaymentResponse makePayment(ChequePaymentRequest paymentRequest) throws BeanstreamApiException {

        // build the URL
        String url = PaymentsUrls.getPaymentUrl(config.getPlatform(), config.getVersion());

        // process the transaction using the REST API
        String response = connector.ProcessTransaction(HttpMethod.post, url, paymentRequest);

        // parse the output and return a PaymentResponse
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * Void the specified paymentId. Voids generally need to occur before end of
     * business on the same day that the transaction was processed. Voids are
     * used to cancel a transaction before the item is registered against a
     * customer credit card account. Card holders will never see a voided
     * transaction on their credit card statement. As a result, voids can only
     * be attempted on the same day as the original transaction. After the end
     * of day (roughly 11:59 PM EST/EDT), void requests will be rejected from
     * the API if attempted.
     *
     * @author Pedro Garcia
     * @param paymentId payment transaction id to void
     * @param amount the amount to avoid in this transaction
     * @return PaymentResponse as result you will received a payment response
     * with the same payment transaction id but with the type 'VP'
     * @throws BeanstreamApiException as a result of a business logic validation
     * or any other error @see
     */
    public PaymentResponse voidPayment(String paymentId, double amount) throws BeanstreamApiException {

        Gateway.assertNotEmpty(paymentId, "invalid paymentId");
        String url = getVoidPaymentUrl(config.getPlatform(), config.getVersion(), paymentId);

        JsonObject voidRequest = new JsonObject();
        voidRequest.addProperty(MERCHANT_ID_PARAM, String.valueOf(config.getMerchantId()));
        voidRequest.addProperty(AMOUNT_PARAM, String.valueOf(amount));

        String response = connector.ProcessTransaction(HttpMethod.post, url, voidRequest);

        // parse the output and return a PaymentResponse
        return gson.fromJson(response, PaymentResponse.class);

    }

    /**
     * <p>
     * Pre-authorize a payment. Use this if you want to know if a customer has
     * sufficient funds before processing a payment. A real-world example of
     * this is pre-authorizing at the gas pump for $100 before you fill up, then
     * end up only using $60 of gas; the customer is only charged $60. The final
     * payment is used with preAuthCompletion() method.
     * </p>
     *
     * @param paymentRequest payment request to pre authorize with a valid
     * amount
     * @return a PaymentResponse pre-approved containing the paymentId you will
     * need to complete the transaction.
     * @throws BeanstreamApiException if any validation fail or error occur
     */
    public PaymentResponse preAuth(CardPaymentRequest paymentRequest) throws BeanstreamApiException {

        if (paymentRequest == null || paymentRequest.getCard() == null) {
            // TODO - do we need to supply category and code ids here?
            BeanstreamResponse response = BeanstreamResponse.fromMessage("invalid payment request");
            throw BeanstreamApiException.getMappedException(HttpStatus.SC_BAD_REQUEST, response);
        }

        paymentRequest.getCard().setComplete(false);

        String preAuthUrl = getPaymentUrl(config.getPlatform(), config.getVersion());

        String response = connector.ProcessTransaction(HttpMethod.post, preAuthUrl, paymentRequest);
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * <p>
     * Pre-authorize a payment. Use this if you want to know if a customer has
     * sufficient funds before processing a payment. A real-world example of
     * this is pre-authorizing at the gas pump for $100 before you fill up, then
     * end up only using $60 of gas; the customer is only charged $60. The final
     * payment is used with preAuthCompletion() method.
     * </p>
     *
     * @param paymentRequest payment request to pre authorize with a valid
     * amount
     * @return a PaymentResponse pre-approved containing the paymentId you will
     * need to complete the transaction.
     * @throws BeanstreamApiException if any validation fail or error occur
     */
    public PaymentResponse preAuth(ProfilePaymentRequest paymentRequest) throws BeanstreamApiException {

        if (paymentRequest == null || paymentRequest.getProfile() == null) {
            // TODO - do we need to supply category and code ids here?
            BeanstreamResponse response = BeanstreamResponse.fromMessage("invalid payment request");
            throw BeanstreamApiException.getMappedException(HttpStatus.SC_BAD_REQUEST, response);
        }

        paymentRequest.getProfile().setComplete(false);

        String preAuthUrl = getPaymentUrl(config.getPlatform(), config.getVersion());

        String response = connector.ProcessTransaction(HttpMethod.post, preAuthUrl, paymentRequest);
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * <p>
     * Pre-authorize a token payment. Use this if you want to know if a customer has
     * sufficient funds before processing a payment. A real-world example of
     * this is pre-authorizing at the gas pump for $100 before you fill up, then
     * end up only using $60 of gas; the customer is only charged $60. The final
     * payment is used with preAuthCompletion() method.
     * </p>
     *
     * @param paymentRequest payment request to pre authorize with a valid
     * amount
     * @return a PaymentResponse pre-approved containing the paymentId you will
     * need to complete the transaction.
     * @throws BeanstreamApiException if any validation fail or error occur
     */
    public PaymentResponse preAuth(TokenPaymentRequest paymentRequest) throws BeanstreamApiException {

        if (paymentRequest == null || paymentRequest.getToken() == null) {
            BeanstreamResponse response = BeanstreamResponse.fromMessage("invalid payment request");
            throw BeanstreamApiException.getMappedException(HttpStatus.SC_BAD_REQUEST, response);
        }

        paymentRequest.getToken().setComplete(false);

        String preAuthUrl = getPaymentUrl(config.getPlatform(), config.getVersion());

        String response = connector.ProcessTransaction(HttpMethod.post, preAuthUrl, paymentRequest);
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * Push the actual payment through after a pre-authorization.
     * Convenience method if you don't want to supply the whole PaymentRequest.
     * 
     * @param paymentId of the pre-authorized transaction
     * @param amount final amount to be charged
     * @return the PaymentResponse for the final transaction
     * @throws BeanstreamApiException when not successful
     */
    public PaymentResponse preAuthCompletion(String paymentId, double amount) throws BeanstreamApiException {

        Gateway.assertNotEmpty(paymentId, "Invalid Payment Id");

        String authorizePaymentUrl = getPreAuthCompletionsUrl(config.getPlatform(), config.getVersion(), paymentId);

        JsonObject authorizeRequest = new JsonObject();
        authorizeRequest.addProperty(MERCHANT_ID_PARAM, String.valueOf(config.getMerchantId()));
        authorizeRequest.addProperty(AMOUNT_PARAM, String.valueOf(amount));

        String response = connector.ProcessTransaction(HttpMethod.post, authorizePaymentUrl, authorizeRequest);

        return gson.fromJson(response, PaymentResponse.class);

    }

    /**
     * Push the actual payment through after a pre-authorization.
     * You can supply the PaymentRequest to set any fields you did not set in the pre-auth.
     * @param paymentId to complete
     * @param request that will be saved
     * @return PaymentResponse
     * @throws BeanstreamApiException if the transaction was declined 
     */
    public PaymentResponse preAuthCompletion(String paymentId, PaymentRequest request)
            throws BeanstreamApiException {

        Gateway.assertNotEmpty(paymentId, "Invalid Payment Id");
        String authorizePaymentUrl = getPreAuthCompletionsUrl(config.getPlatform(), config.getVersion(), paymentId);

        String response = connector.ProcessTransaction(HttpMethod.post, authorizePaymentUrl, request);
        return gson.fromJson(response, PaymentResponse.class);
    }

    /**
     * Return a previous payment made through Beanstream.
     *
     * @param paymentId payment transaction id to return
     * @param amount final amount to be returned
     * @return the PaymentResponse for the final transaction
     * @throws BeanstreamApiException when not successful
     */
    public PaymentResponse returnPayment(String paymentId, double amount) throws BeanstreamApiException {

        Gateway.assertNotEmpty(paymentId, "Invalid Payment Id");

        String returnPaymentUrl = getReturnUrl(config.getPlatform(), config.getVersion(), paymentId);

        ReturnRequest returnRequest = new ReturnRequest();
        returnRequest.setMerchantId(String.valueOf(config.getMerchantId()));
        returnRequest.setAmount(amount);

        String response = connector.ProcessTransaction(HttpMethod.post, returnPaymentUrl, returnRequest);

        return gson.fromJson(response, PaymentResponse.class);

    }

    /**
     * Return a previous card payment that was not made through Beanstream. Use
     * this if you would like to return a payment but that payment was performed
     * on another gateway.
     *
     * @param returnRequest of the UnreferencedCardReturnRequest
     * @return the PaymentResponse for the final transaction
     * @throws BeanstreamApiException when not successful
     */
    public PaymentResponse unreferencedReturn(UnreferencedCardReturnRequest returnRequest)
            throws BeanstreamApiException {

        String unreferencedReturnUrl = getUnreferencedReturnUrl(config.getPlatform(), config.getVersion());

        returnRequest.setMerchantId(String.valueOf(config.getMerchantId()));

        String response = connector.ProcessTransaction(HttpMethod.post, unreferencedReturnUrl, returnRequest);

        return gson.fromJson(response, PaymentResponse.class);

    }

    /**
     * Return a previous swipe payment that was not made through Beanstream. Use
     * this if you would like to return a payment but that payment was performed
     * on another payment service.
     *
     * @param returnRequest of the UnreferencedSwipeReturnRequest
     * @return the PaymentResponse for the final transaction
     * @throws BeanstreamApiException when not successful
     */
    public PaymentResponse unreferencedReturn(UnreferencedSwipeReturnRequest returnRequest)
            throws BeanstreamApiException {

        String unreferencedReturnUrl = getUnreferencedReturnUrl(config.getPlatform(), config.getVersion());

        returnRequest.setMerchantId(String.valueOf(config.getMerchantId()));

        String response = connector.ProcessTransaction(HttpMethod.post, unreferencedReturnUrl, returnRequest);

        return gson.fromJson(response, PaymentResponse.class);

    }

}