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

com.global.api.gateways.PayPlanConnector Maven / Gradle / Ivy

There is a newer version: 14.2.3
Show newest version
package com.global.api.gateways;

import com.global.api.builders.RecurringBuilder;
import com.global.api.entities.*;
import com.global.api.entities.enums.*;
import com.global.api.entities.exceptions.ApiException;
import com.global.api.entities.exceptions.UnsupportedTransactionException;
import com.global.api.paymentMethods.*;
import com.global.api.utils.DateUtils;
import com.global.api.utils.JsonDoc;
import com.global.api.utils.StringUtils;
import com.global.api.utils.ValueConverter;
import org.apache.commons.codec.binary.Base64;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class PayPlanConnector extends RestGateway implements IRecurringGateway {
    private String secretApiKey;
    private ValueConverter dateConverter = new ValueConverter(){
        public Date call(String value) {
            if(value == null)
                return null;

            SimpleDateFormat parser = new SimpleDateFormat("MMddyyyy");
            try {
                return parser.parse(value);
            }
            catch(ParseException e) { return null; }
        }
    };
    private ValueConverter amountConverter = new ValueConverter() {
        public BigDecimal call(String value) {
            if(value != null)
                return StringUtils.toAmount(value);
            return null;
        }
    };
    private ValueConverter yesNoConverter = new ValueConverter() {
        public Boolean call(String value) {
            return (value != null) && !value.equals("No");
        }
    };

    public String getSecretApiKey() {
        return secretApiKey;
    }
    public void setSecretApiKey(String secretApiKey) {
        this.secretApiKey = secretApiKey;
        if(secretApiKey != null) {
            byte[] encoded = Base64.encodeBase64(secretApiKey.getBytes());
            String auth = String.format("Basic %s", new String(encoded));
            headers.put("Authorization", auth);
        }
    }
    public boolean supportsRetrieval() { return true; }
    public boolean supportsUpdatePaymentDetails() { return false; }

    public  T processRecurring(RecurringBuilder builder, Class clazz) throws ApiException {
        JsonDoc request = new JsonDoc();

        if(builder.getTransactionType() == TransactionType.Create || builder.getTransactionType() == TransactionType.Edit) {
            if(builder.getEntity() instanceof Customer) {
                buildCustomer(request, (Customer)builder.getEntity());
            }
            else if(builder.getEntity() instanceof RecurringPaymentMethod) {
                buildPaymentMethod(request, (RecurringPaymentMethod)builder.getEntity(), builder.getTransactionType());
            }
            else if(builder.getEntity() instanceof Schedule) {
                buildSchedule(request, (Schedule)builder.getEntity(), builder.getTransactionType());
            }
        }
        else if(builder.getTransactionType() == TransactionType.Search) {
            for(String key: builder.getSearchCriteria().keySet()) {
                request.set(key, builder.getSearchCriteria().get(key));
            }
        }
        else if(builder.getTransactionType() == TransactionType.Delete) {
            request.set("forceDelete", builder.isForceDelete());
        }

        String response = doTransaction(mapMethod(builder.getTransactionType()), mapUrl(builder, clazz), request.toString());
        return mapResponse(response, clazz);
    }

    private  T mapResponse(String rawResponse, Class clazz) throws ApiException {
        // DELETE returns nothing and that's OK
        if(StringUtils.isNullOrEmpty(rawResponse))
            return null;

        // Normal response elements
        JsonDoc response = JsonDoc.parse(rawResponse);
        try {
            T type = clazz.newInstance();
            if(type instanceof Customer)
                return hydrateCustomer(response, clazz);
            else if(type instanceof CustomerCollection) {
                for(JsonDoc customer: response.getEnumerator("results")) {
                    ((CustomerCollection)type).add(hydrateCustomer(customer, Customer.class));
                }
                return type;
            }
            else if(type instanceof RecurringPaymentMethod)
                return hydratePaymentMethod(response, clazz);
            else if(type instanceof RecurringPaymentMethodCollection) {
                for(JsonDoc payment: response.getEnumerator("results")) {
                    ((RecurringPaymentMethodCollection)type).add(hydratePaymentMethod(payment, RecurringPaymentMethod.class));
                }
                return type;
            }
            else if(type instanceof Schedule)
                return hydrateSchedule(response, clazz);
            else if(type instanceof ScheduleCollection) {
                for(JsonDoc schedule: response.getEnumerator("results")) {
                    ((ScheduleCollection)type).add(hydrateSchedule(schedule, Schedule.class));
                }
                return type;
            }
            return type;
        }
        catch(Exception e) {
            throw new ApiException(e.getMessage(), e);    
        }
    }

    private String mapMethod(TransactionType type) {
        switch(type) {
            case Create:
            case Search:
                return "POST";
            case Edit:
                return "PUT";
            case Delete:
                return "DELETE";
            default:
                return "GET";
        }
    }

    private String mapUrl(RecurringBuilder builder, Class clazz) throws ApiException {
        if(clazz == null)
            throw new ApiException("Cannot determine endpoint.");

        String suffix = "";
        if(builder.getTransactionType() == TransactionType.Fetch
                || builder.getTransactionType() == TransactionType.Delete
                || builder.getTransactionType() == TransactionType.Edit)
            suffix = "/" + builder.getKey();

        try {
            Object type = clazz.newInstance();
            if(type instanceof Customer || type instanceof CustomerCollection)
                return String.format("%s%s", (builder.getTransactionType() == TransactionType.Search) ? "searchCustomers" : "customers", suffix);
            else if(type instanceof RecurringPaymentMethod || type instanceof RecurringPaymentMethodCollection) {
                String paymentMethod = "";
                if(builder.getTransactionType() == TransactionType.Create)
                    paymentMethod = (((RecurringPaymentMethod)builder.getEntity()).getPaymentMethod() instanceof Credit) ? "CreditCard" : "ACH";
                else if(builder.getTransactionType() == TransactionType.Edit)
                    paymentMethod = ((RecurringPaymentMethod)builder.getEntity()).getPaymentType().replace(" ", "");
                return String.format("%s%s%s", (builder.getTransactionType() == TransactionType.Search) ? "searchPaymentMethods" : "paymentMethods", paymentMethod, suffix);
            }
            else if(type instanceof Schedule || type instanceof ScheduleCollection)
                return String.format("%s%s", (builder.getTransactionType() == TransactionType.Search) ? "searchSchedules" : "schedules", suffix);
            throw new UnsupportedTransactionException();
        }
        catch(Exception e) {
            throw new ApiException(e.getMessage(), e);
        }
    }

    private JsonDoc buildCustomer(JsonDoc request, Customer customer) {
        if (customer != null) {
            request.set("customerIdentifier", customer.getId());
            request.set("firstName", customer.getFirstName());
            request.set("lastName", customer.getLastName());
            request.set("company", customer.getCompany());
            request.set("customerStatus", customer.getStatus());
            request.set("primaryEmail", customer.getEmail());
            request.set("phoneDay", customer.getHomePhone());
            request.set("phoneEvening", customer.getWorkPhone());
            request.set("phoneMobile", customer.getMobilePhone());
            request.set("fax", customer.getFax());
            request.set("title", customer.getTitle());
            request.set("department", customer.getDepartment());
            buildAddress(request, customer.getAddress());
        }
        return request;
    }

    private JsonDoc buildPaymentMethod(JsonDoc request, RecurringPaymentMethod payment, TransactionType type) {
        if (payment != null) {
            request.set("preferredPayment", payment.isPreferredPayment());
            request.set("paymentMethodIdentifier", payment.getId());
            request.set("customerKey", payment.getCustomerKey());
            request.set("nameOnAccount", payment.getNameOnAccount());
            buildAddress(request, payment.getAddress());

            if (type == TransactionType.Create) {
                String tokenValue = getToken(payment.getPaymentMethod());
                boolean hasToken = tokenValue != null;
                JsonDoc paymentInfo = null;
                if (payment.getPaymentMethod() instanceof ICardData) {
                    ICardData method = (ICardData) payment.getPaymentMethod();
                    paymentInfo = request.subElement(hasToken ? "alternateIdentity" : "card")
                            .set("type", hasToken ? "SINGLEUSETOKEN" : null)
                            .set(hasToken ? "token" : "number", hasToken ? tokenValue : method.getNumber())
                            .set("expMon", method.getExpMonth())
                            .set("expYear", method.getExpYear());
                    request.set("cardVerificationValue", method.getCvn());
                }
                else if (payment.getPaymentMethod() instanceof ITrackData) {
                    ITrackData method = (ITrackData)payment.getPaymentMethod();
                    paymentInfo = request.subElement("track")
                            .set("data", method.getValue())
                            .set("dataEntryMode", method.getEntryMethod().getValue().toUpperCase());
                }
                else if (payment.getPaymentMethod() instanceof eCheck) {
                    eCheck check = (eCheck)payment.getPaymentMethod();
                    request.set("achType", StringUtils.toInitialCase(check.getAccountType().getValue()))
                            .set("accountType", StringUtils.toInitialCase(check.getCheckType()))
                            .set("telephoneIndicator", (check.getSecCode().equals(SecCode.Ccd) || check.getSecCode().equals(SecCode.Ppd)) ? false : true)
                            .set("routingNumber", check.getRoutingNumber())
                            .set("accountNumber", check.getAccountNumber())
                            .set("accountHolderYob", check.getBirthYear())
                            .set("driversLicenseState", check.getDriversLicenseState())
                            .set("driversLicenseNumber", check.getDriversLicenseNumber())
                            .set("socialSecurityNumberLast4", check.getSsnLast4());
                    request.remove("country");
                }

                if (payment.getPaymentMethod() instanceof IEncryptable) {
                    EncryptionData enc = ((IEncryptable)payment.getPaymentMethod()).getEncryptionData();
                    if (enc != null && paymentInfo != null) {
                            paymentInfo.set("trackNumber", enc.getTrackNumber());
                            paymentInfo.set("key", enc.getKtb());
                            paymentInfo.set("encryptionType", "E3");
                    }
                }
            }
            else { // EDIT FIELDS
                request.remove("customerKey");
                request.set("paymentStatus", payment.getStatus());
                request.set("cpcTaxType", payment.getTaxType());
                request.set("expirationDate", payment.getExpirationDate());
            }
        }
        return request;
    }

    private JsonDoc buildSchedule(JsonDoc request, Schedule schedule, TransactionType type) {
        if (schedule != null) {
            request.set("scheduleIdentifier", schedule.getId());
            request.set("scheduleName", schedule.getName());
            request.set("scheduleStatus", schedule.getStatus());
            request.set("paymentMethodKey", schedule.getPaymentKey());

            buildAmount(request, "subtotalAmount", schedule.getAmount(), schedule.getCurrency(), type);
            buildAmount(request, "taxAmount", schedule.getTaxAmount(), schedule.getCurrency(), type);

            request.set("deviceId", schedule.getDeviceId());
            request.set("processingDateInfo", mapProcessingDate(schedule));
            buildDate(request, "endDate", schedule.getEndDate(), (type == TransactionType.Edit));
            request.set("reprocessingCount", schedule.getReprocessingCount() == null ? 3 : schedule.getReprocessingCount());
            request.set("emailReceipt", schedule.getEmailReceipt());
            request.set("emailAdvanceNotice", schedule.isEmailNotification() ? "Yes" : "No");
            // debt repay ind
            request.set("invoiceNbr", schedule.getInvoiceNumber());
            request.set("poNumber", schedule.getPoNumber());
            request.set("description", schedule.getDescription());
            request.set("numberOfPayments", schedule.getNumberOfPayments());

            if (type == TransactionType.Create) {
                request.set("customerKey", schedule.getCustomerKey());
                buildDate(request, "startDate", schedule.getStartDate());
                request.set("frequency", schedule.getFrequency());
                request.set("duration", mapDuration(schedule));
            }
            else { // Edit Fields
                if (!schedule.isHasStarted()) {
                    buildDate(request, "startDate", schedule.getStartDate());
                    request.set("frequency", schedule.getFrequency());
                    request.set("duration", mapDuration(schedule));
                }
                else {
                    buildDate(request, "cancellationDate", schedule.getCancellationDate());
                    buildDate(request, "nextProcressingDate", schedule.getNextProcessingDate());
                }
            }
        }
        return request;
    }

    private String mapDuration(Schedule schedule) {
        if (schedule.getNumberOfPayments() != null)
            return "Limited Number";
        else if (schedule.getEndDate() != null)
            return "End Date";
        else return "Ongoing";
    }
    private String mapProcessingDate(Schedule schedule) {
        List frequencies = new ArrayList();
        frequencies.add(ScheduleFrequency.Monthly);
        frequencies.add(ScheduleFrequency.BiMonthly);
        frequencies.add(ScheduleFrequency.Quarterly);
        frequencies.add(ScheduleFrequency.SemiAnnually);

        if (frequencies.contains(schedule.getFrequency())) {
            switch (schedule.getPaymentSchedule()) {
                case FirstOfTheMonth:
                    return "First";
                case LastOfTheMonth:
                    return "Last";
                default: {
                    int day = schedule.getStartDate().getDay();
                    if (day > 28)
                        return "Last";
                    return day + "";
                }
            }
        }
        else if (schedule.getFrequency().equals(ScheduleFrequency.SemiMonthly)) {
            if (schedule.getPaymentSchedule().equals(PaymentSchedule.LastOfTheMonth))
                return "Last";
            return "First";
        }
        return null;
    }

    private JsonDoc buildDate(JsonDoc request, String name, Date date) {
        return buildDate(request, name, date, false);
    }
    private JsonDoc buildDate(JsonDoc request, String name, Date date, boolean force) {
        if (date != null || force) {
            String value = (date != null) ? DateUtils.toString(date, "MMddyyyy") : null;
            request.set(name, value, force);
        }
        return request;
    }

    private JsonDoc buildAmount(JsonDoc request, String name, BigDecimal amount, String currency, TransactionType type) {
        if (amount != null) {
            JsonDoc node = request.subElement(name);
            node.set("value", StringUtils.toNumeric(amount));
            if (type == TransactionType.Create)
                node.set("currency", currency);
        }
        return request;
    }

    private JsonDoc buildAddress(JsonDoc request, Address address) {
        if (address != null) {
            request.set("addressLine1", address.getStreetAddress1());
            request.set("addressLine2", address.getStreetAddress2());
            request.set("city", address.getCity());
            request.set("country", address.getCountry());
            request.set("stateProvince", address.getState());
            request.set("zipPostalCode", address.getPostalCode());
        }
        return request;
    }

    private  T hydrateCustomer(JsonDoc response, Class clazz) {
        try {
            T customer = clazz.newInstance();
            if(customer instanceof Customer) {
                Address address = new Address();
                address.setStreetAddress1(response.getString("addressLine1"));
                address.setStreetAddress2(response.getString("addressLine2"));
                address.setCity(response.getString("city"));
                address.setProvince(response.getString("stateProvince"));
                address.setPostalCode(response.getString("zipPostalCode"));
                address.setCountry(response.getString("country"));
                
                ((Customer)customer).setKey(response.getString("customerKey"));
                ((Customer)customer).setId(response.getString("customerIdentifier"));
                ((Customer)customer).setFirstName(response.getString("firstName"));
                ((Customer)customer).setLastName(response.getString("lastName"));
                ((Customer)customer).setCompany(response.getString("company"));
                ((Customer)customer).setStatus(response.getString("customerStatus"));
                ((Customer)customer).setTitle(response.getString("title"));
                ((Customer)customer).setDepartment(response.getString("department"));
                ((Customer)customer).setEmail(response.getString("primaryEmail"));
                ((Customer)customer).setHomePhone(response.getString("phoneDay"));
                ((Customer)customer).setWorkPhone(response.getString("phoneEvening"));
                ((Customer)customer).setMobilePhone(response.getString("phoneMobile"));
                ((Customer)customer).setFax(response.getString("fax"));
                ((Customer)customer).setAddress(address);

                if(response.has("paymentMethods")) {
                    List paymentMethods = new ArrayList();
                    for(JsonDoc paymentResponse : response.getEnumerator("paymentMethods")) {
                        RecurringPaymentMethod paymentMethod = hydratePaymentMethod(paymentResponse, RecurringPaymentMethod.class);
                        if(paymentMethod != null)
                            paymentMethods.add(paymentMethod);
                    }
                    ((Customer)customer).setPaymentMethods(paymentMethods);
                }
                return customer;
            }
            return null;
        }
        catch(Exception e) {
            return null;    
        }
    }

    private  T hydratePaymentMethod(JsonDoc response, Class clazz){
        try{
            T payment = clazz.newInstance();
            if(payment instanceof RecurringPaymentMethod) {
                Address address = new Address();
                address.setStreetAddress1(response.getString("addressLine1"));
                address.setStreetAddress2(response.getString("addressLine2"));
                address.setCity(response.getString("city"));
                address.setProvince(response.getString("stateProvince"));
                address.setPostalCode(response.getString("zipPostalCode"));
                address.setCountry(response.getString("country"));

                ((RecurringPaymentMethod)payment).setKey(response.getString("paymentMethodKey"));
                ((RecurringPaymentMethod)payment).setPaymentType(response.getString("paymentMethodType"));
                ((RecurringPaymentMethod)payment).setPreferredPayment(response.getBool("preferredPayment"));
                ((RecurringPaymentMethod)payment).setStatus(response.getString("paymentStatus"));
                ((RecurringPaymentMethod)payment).setId(response.getString("paymentMethodIdentifier"));
                ((RecurringPaymentMethod)payment).setCustomerKey(response.getString("customerKey"));
                ((RecurringPaymentMethod)payment).setNameOnAccount(response.getString("nameOnAccount"));
                ((RecurringPaymentMethod)payment).setCommercialIndicator(response.getString("cpcInd"));
                ((RecurringPaymentMethod)payment).setTaxType(response.getString("cpcTaxType"));
                ((RecurringPaymentMethod)payment).setExpirationDate(response.getString("expirationDate"));
                ((RecurringPaymentMethod)payment).setAccountNumberLast4(response.getString("accountNumberLast4"));
                ((RecurringPaymentMethod)payment).setAddress(address);
                return payment;
            }
            return null;
        }
        catch(Exception e) {
            return null;
        }
    }

    private  T hydrateSchedule(JsonDoc response, Class clazz) {
        try{
            T schedule = clazz.newInstance();
            if(schedule instanceof Schedule) {
                ((Schedule)schedule).setKey(response.getString("scheduleKey"));
                ((Schedule)schedule).setId(response.getString("scheduleIdentifier"));
                ((Schedule)schedule).setCustomerKey(response.getString("customerKey"));
                ((Schedule)schedule).setName(response.getString("scheduleName"));
                ((Schedule)schedule).setStatus(response.getString("scheduleStatus"));
                ((Schedule)schedule).setPaymentKey(response.getString("paymentMethodKey"));
                if (response.has("subtotalAmount")) {
                    JsonDoc subtotal = response.get("subtotalAmount");
                    ((Schedule)schedule).setAmount(subtotal.getValue("value", amountConverter));
                    ((Schedule)schedule).setCurrency(subtotal.getString("currency"));
                }
                if (response.has("taxAmount")) {
                    JsonDoc taxAmount = response.get("taxAmount");
                    ((Schedule)schedule).setTaxAmount(taxAmount.getValue("value", amountConverter));
                }
                ((Schedule)schedule).setDeviceId(response.getInt("DeviceId"));
                ((Schedule)schedule).setStartDate(response.getValue("startDate", dateConverter));
                ((Schedule)schedule).setPaymentSchedule(response.getValue("processingDateInfo", new ValueConverter() {
                    public PaymentSchedule call(String value) {
                        if (value == null) return PaymentSchedule.Dynamic;
                        if (value.equals("Last"))
                            return PaymentSchedule.LastOfTheMonth;
                        else if (value.equals("First"))
                            return PaymentSchedule.FirstOfTheMonth;
                        return PaymentSchedule.Dynamic;
                    }
                }));
                ((Schedule)schedule).setFrequency(response.getValue("frequency", new ValueConverter() {
                    public ScheduleFrequency call(String value) {
                        if(value != null)
                            return ScheduleFrequency.valueOf(value.replace("-", ""));
                        return ScheduleFrequency.Weekly;
                    }
                }));
                ((Schedule)schedule).setEndDate(response.getValue("endDate", dateConverter));
                ((Schedule)schedule).setReprocessingCount(response.getInt("reprocessingCount"));
                ((Schedule)schedule).setEmailReceipt(response.getValue("emailReceipt", new ValueConverter() {
                    public EmailReceipt call(String value) {
                        if(value != null)
                            return EmailReceipt.valueOf(value);
                        return EmailReceipt.Never;
                    }
                }));
                ((Schedule)schedule).setEmailNotification(response.getValue("emailAdvanceNotice", yesNoConverter));
                // dept repay indicator
                ((Schedule)schedule).setInvoiceNumber(response.getString("invoiceNbr"));
                ((Schedule)schedule).setPoNumber(response.getString("poNumber"));
                ((Schedule)schedule).setDescription(response.getString("description"));
                // statusSetDate
                ((Schedule)schedule).setNextProcessingDate(response.getValue("nextProcessingDate", dateConverter));
                // previousProcessingDate
                // approvedTransactionCount
                // failureCount
                // totalApprovedAmountToDate
                // numberOfPaymentsRemaining
                ((Schedule)schedule).setCancellationDate(response.getValue("cancellationDate", dateConverter));
                // creationDate
                // lastChangeDate
                ((Schedule)schedule).setHasStarted(response.getBool("scheduleStarted"));
                return schedule;
            }
            return null;
        }
        catch(Exception e) {
            return null;
        }
    }

    private String getToken(IPaymentMethod paymentMethod) {
        if(paymentMethod instanceof ITokenizable) {
            String tokenValue = ((ITokenizable)paymentMethod).getToken();
            if(tokenValue != null && !tokenValue.equals(""))
                return tokenValue;
            return null;
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy