/* * Copyright (C) 2014 SCVNGR, Inc. d/b/a LevelUp * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.scvngr.levelup.core.net.request.factory; import android.content.Context; import android.support.annotation.NonNull; import com.scvngr.levelup.core.R; import com.scvngr.levelup.core.annotation.AccessTokenRequired; import com.scvngr.levelup.core.annotation.LevelUpApi; import com.scvngr.levelup.core.annotation.LevelUpApi.Contract; import com.scvngr.levelup.core.annotation.RequiresPermission; import com.scvngr.levelup.core.model.CreditCard; import com.scvngr.levelup.core.net.AbstractRequest; import com.scvngr.levelup.core.net.AccessTokenRetriever; import com.scvngr.levelup.core.net.HttpMethod; import com.scvngr.levelup.core.net.JSONObjectRequestBody; import com.scvngr.levelup.core.net.LevelUpRequest; import com.scvngr.levelup.core.net.Permissions; import com.scvngr.levelup.core.util.LogManager; import com.scvngr.levelup.core.util.NullUtils; import com.scvngr.levelup.core.util.PreconditionUtil; import com.braintreegateway.encryption.Braintree; import net.jcip.annotations.Immutable; import org.json.JSONException; import org.json.JSONObject; /** * AbstractRequest builder for requests to the Credit Cards endpoint. */ @Immutable @LevelUpApi(contract = Contract.PUBLIC) public final class CreditCardRequestFactory extends AbstractRequestFactory { @NonNull private static final String CREDIT_CARDS_ENDPOINT = "credit_cards"; /** * The outer JSON object request parameter. */ @NonNull public static final String OUTER_PARAM_CARD = "credit_card"; /** * The encrypted CVV code. */ @NonNull public static final String PARAM_ENCRYPTED_CVV = "encrypted_cvv"; /** * The encrypted expiration date month. */ @NonNull public static final String PARAM_ENCRYPTED_EXPIRATION_MONTH = "encrypted_expiration_month"; /** * The encrypted expiration date year. */ @NonNull public static final String PARAM_ENCRYPTED_EXPIRATION_YEAR = "encrypted_expiration_year"; /** * The encrypted credit card number. */ @NonNull public static final String PARAM_ENCRYPTED_NUMBER = "encrypted_number"; /** * The postal/zip code. */ @NonNull public static final String PARAM_POSTAL_CODE = "postal_code"; /** * @param context the Application context. * @param retriever the implementation of {@link AccessTokenRetriever} to use to get the * {@link com.scvngr.levelup.core.model.User}'s * {@link com.scvngr.levelup.core.model.AccessToken}. */ public CreditCardRequestFactory(@NonNull final Context context, @NonNull final AccessTokenRetriever retriever) { super(context, retriever); } /** * Builds a request to the server which will add a credit card for the current user. * * @param cardNumber the card number for the card. * @param cvv the CVV (security code) of the card. * @param expirationMonth the month the card expires. * @param expirationYear the year the card expires. * @param postalCode the billing postal code of the card. * @return {@link AbstractRequest} to create a card on the server. */ @NonNull @LevelUpApi(contract = Contract.PUBLIC) @RequiresPermission(Permissions.PERMISSION_CREATE_FIRST_CREDIT_CARD) @AccessTokenRequired public AbstractRequest buildCreateCardRequest(@NonNull final String cardNumber, @NonNull final String cvv, @NonNull final String expirationMonth, @NonNull final String expirationYear, @NonNull final String postalCode) { PreconditionUtil.assertNotNull(cardNumber, "cardNumber"); PreconditionUtil.assertNotNull(cvv, "cvv"); PreconditionUtil.assertNotNull(expirationMonth, "expirationMonth"); PreconditionUtil.assertNotNull(expirationYear, "expirationYear"); PreconditionUtil.assertNotNull(postalCode, "postalCode"); final Braintree braintree = new Braintree(getContext().getString( R.string.levelup_braintree_clientside_encryption_key)); final JSONObject parameters = new JSONObject(); final JSONObject creditCard = new JSONObject(); try { creditCard.put(PARAM_ENCRYPTED_CVV, braintree.encrypt(cvv)); creditCard.put(PARAM_ENCRYPTED_EXPIRATION_MONTH, braintree.encrypt(expirationMonth)); creditCard.put(PARAM_ENCRYPTED_EXPIRATION_YEAR, braintree.encrypt(expirationYear)); creditCard.put(PARAM_ENCRYPTED_NUMBER, braintree.encrypt(cardNumber)); creditCard.put(PARAM_POSTAL_CODE, postalCode); parameters.put(OUTER_PARAM_CARD, creditCard); } catch (final JSONException e) { LogManager.e("Error building JSON.", e); } return new LevelUpRequest(getContext(), HttpMethod.POST, LevelUpRequest.API_VERSION_CODE_V15, CREDIT_CARDS_ENDPOINT, null, new JSONObjectRequestBody(parameters), getAccessTokenRetriever()); } /** * Builds a request to get the credit cards for a user. * * @return {@link AbstractRequest} to use to get the credit cards for the current user. */ @NonNull @LevelUpApi(contract = Contract.ENTERPRISE) @AccessTokenRequired public AbstractRequest buildGetCardsRequest() { return new LevelUpRequest(getContext(), HttpMethod.GET, LevelUpRequest.API_VERSION_CODE_V14, CREDIT_CARDS_ENDPOINT, null, null, getAccessTokenRetriever()); } /** * Builds a request to promote (set as default) a credit card. * * @param card the {@link CreditCard} to promote. * @return {@link AbstractRequest} to use to promote a credit card. */ @NonNull @LevelUpApi(contract = Contract.ENTERPRISE) @AccessTokenRequired public AbstractRequest buildPromoteCardRequest(@NonNull final CreditCard card) { return new LevelUpRequest(getContext(), HttpMethod.PUT, LevelUpRequest.API_VERSION_CODE_V14, NullUtils.format( "%s/%d", CREDIT_CARDS_ENDPOINT, card.getId()), null, null, getAccessTokenRetriever()); } /** * Builds a request to delete a credit card. * * @param card the {@link CreditCard} to delete. * @return {@link AbstractRequest} to use to delete a credit card. */ @NonNull @LevelUpApi(contract = Contract.ENTERPRISE) @AccessTokenRequired public AbstractRequest buildDeleteCardRequest(@NonNull final CreditCard card) { return new LevelUpRequest(getContext(), HttpMethod.DELETE, LevelUpRequest.API_VERSION_CODE_V14, NullUtils.format( "%s/%d", CREDIT_CARDS_ENDPOINT, card.getId()), null, null, getAccessTokenRetriever()); } }