Search in sources :

Example 16 with AccountApiException

use of org.killbill.billing.account.api.AccountApiException in project killbill by killbill.

the class PaymentMethodProcessor method addPaymentMethod.

public UUID addPaymentMethod(final String paymentMethodExternalKey, final String paymentPluginServiceName, final Account account, final boolean setDefault, final PaymentMethodPlugin paymentMethodProps, final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext context) throws PaymentApiException {
    return dispatchWithExceptionHandling(account, paymentPluginServiceName, new CallableWithAccountLock<UUID, PaymentApiException>(locker, account.getId(), paymentConfig, new DispatcherCallback<PluginDispatcherReturnType<UUID>, PaymentApiException>() {

        @Override
        public PluginDispatcherReturnType<UUID> doOperation() throws PaymentApiException {
            PaymentMethod pm = null;
            try {
                validateUniqueExternalPaymentMethod(account.getId(), paymentPluginServiceName);
                pm = new DefaultPaymentMethod(paymentMethodExternalKey, account.getId(), paymentPluginServiceName, paymentMethodProps);
                final PaymentPluginApi pluginApi = getPaymentPluginApi(paymentPluginServiceName);
                pluginApi.addPaymentMethod(account.getId(), pm.getId(), paymentMethodProps, setDefault, properties, callContext);
                final String actualPaymentMethodExternalKey = retrieveActualPaymentMethodExternalKey(account, pm, pluginApi, properties, callContext, context);
                final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), actualPaymentMethodExternalKey, pm.getCreatedDate(), pm.getUpdatedDate(), pm.getAccountId(), pm.getPluginName(), pm.isActive());
                paymentDao.insertPaymentMethod(pmModel, context);
                if (setDefault) {
                    accountInternalApi.updatePaymentMethod(account.getId(), pm.getId(), context);
                }
            } catch (final PaymentPluginApiException e) {
                throw new PaymentApiException(ErrorCode.PAYMENT_ADD_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
            } catch (final AccountApiException e) {
                throw new PaymentApiException(e);
            }
            return PluginDispatcher.createPluginDispatcherReturnType(pm.getId());
        }

        private void validateUniqueExternalPaymentMethod(final UUID accountId, final String pluginName) throws PaymentApiException {
            if (ExternalPaymentProviderPlugin.PLUGIN_NAME.equals(pluginName)) {
                final List<PaymentMethodModelDao> accountPaymentMethods = paymentDao.getPaymentMethods(context);
                if (Iterables.any(accountPaymentMethods, new Predicate<PaymentMethodModelDao>() {

                    @Override
                    public boolean apply(final PaymentMethodModelDao input) {
                        return ExternalPaymentProviderPlugin.PLUGIN_NAME.equals(input.getPluginName());
                    }
                })) {
                    throw new PaymentApiException(ErrorCode.PAYMENT_EXTERNAL_PAYMENT_METHOD_ALREADY_EXISTS, accountId);
                }
            }
        }
    }), uuidPluginNotificationDispatcher);
}
Also used : PaymentPluginApiException(org.killbill.billing.payment.plugin.api.PaymentPluginApiException) PaymentMethodModelDao(org.killbill.billing.payment.dao.PaymentMethodModelDao) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) DefaultPaymentMethod(org.killbill.billing.payment.api.DefaultPaymentMethod) PaymentPluginApi(org.killbill.billing.payment.plugin.api.PaymentPluginApi) AccountApiException(org.killbill.billing.account.api.AccountApiException) PaymentMethod(org.killbill.billing.payment.api.PaymentMethod) DefaultPaymentMethod(org.killbill.billing.payment.api.DefaultPaymentMethod) UUID(java.util.UUID)

Example 17 with AccountApiException

use of org.killbill.billing.account.api.AccountApiException in project killbill by killbill.

the class PaymentBusEventHandler method processInvoiceEvent.

@AllowConcurrentEvents
@Subscribe
public void processInvoiceEvent(final InvoiceCreationInternalEvent event) {
    log.info("Received invoice creation notification for accountId='{}', invoiceId='{}'", event.getAccountId(), event.getInvoiceId());
    final Collection<PluginProperty> properties = new ArrayList<PluginProperty>();
    final PluginProperty propertyInvoiceId = new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, event.getInvoiceId().toString(), false);
    properties.add(propertyInvoiceId);
    final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(event.getSearchKey2(), event.getSearchKey1(), "PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken());
    final CallContext callContext = internalCallContextFactory.createCallContext(internalContext);
    // We let the plugin compute how much should be paid
    final BigDecimal amountToBePaid = null;
    final List<String> paymentControlPluginNames = paymentConfig.getPaymentControlPluginNames(internalContext) != null ? new LinkedList<String>(paymentConfig.getPaymentControlPluginNames(internalContext)) : new LinkedList<String>();
    paymentControlPluginNames.add(InvoicePaymentControlPluginApi.PLUGIN_NAME);
    final String transactionType = TransactionType.PURCHASE.name();
    Account account = null;
    Payment payment = null;
    PaymentTransaction paymentTransaction = null;
    try {
        account = accountApi.getAccountById(event.getAccountId(), internalContext);
        logEnterAPICall(log, transactionType, account, account.getPaymentMethodId(), null, null, amountToBePaid, account.getCurrency(), null, null, null, paymentControlPluginNames);
        payment = pluginControlPaymentProcessor.createPurchase(false, account, account.getPaymentMethodId(), null, amountToBePaid, account.getCurrency(), null, null, properties, paymentControlPluginNames, callContext, internalContext);
        paymentTransaction = payment.getTransactions().get(payment.getTransactions().size() - 1);
    } catch (final AccountApiException e) {
        log.warn("Failed to process invoice payment", e);
    } catch (final PaymentApiException e) {
        // Log as warn unless nothing left to be paid
        if (e.getCode() != ErrorCode.PAYMENT_PLUGIN_API_ABORTED.getCode()) {
            log.warn("Failed to process invoice payment {}", e.toString());
        }
    } finally {
        logExitAPICall(log, transactionType, account, payment != null ? payment.getPaymentMethodId() : null, payment != null ? payment.getId() : null, paymentTransaction != null ? paymentTransaction.getId() : null, paymentTransaction != null ? paymentTransaction.getProcessedAmount() : null, paymentTransaction != null ? paymentTransaction.getProcessedCurrency() : null, payment != null ? payment.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getTransactionStatus() : null, paymentControlPluginNames, null);
    }
}
Also used : Account(org.killbill.billing.account.api.Account) ArrayList(java.util.ArrayList) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) BigDecimal(java.math.BigDecimal) PaymentTransaction(org.killbill.billing.payment.api.PaymentTransaction) PluginProperty(org.killbill.billing.payment.api.PluginProperty) Payment(org.killbill.billing.payment.api.Payment) AccountApiException(org.killbill.billing.account.api.AccountApiException) AllowConcurrentEvents(com.google.common.eventbus.AllowConcurrentEvents) Subscribe(com.google.common.eventbus.Subscribe)

Example 18 with AccountApiException

use of org.killbill.billing.account.api.AccountApiException in project killbill by killbill.

the class DefaultEntitlementInternalApi method cancel.

@Override
public void cancel(final Iterable<Entitlement> entitlements, @Nullable final LocalDate effectiveDate, final BillingActionPolicy billingPolicy, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext) throws EntitlementApiException {
    if (!entitlements.iterator().hasNext()) {
        return;
    }
    int bcd = 0;
    DateTimeZone accountTimeZone = null;
    try {
        bcd = accountApi.getBCD(entitlements.iterator().next().getAccountId(), internalCallContext);
        accountTimeZone = accountApi.getImmutableAccountDataByRecordId(internalCallContext.getAccountRecordId(), internalCallContext).getTimeZone();
    } catch (final AccountApiException e) {
        throw new EntitlementApiException(e);
    }
    Preconditions.checkState(bcd > 0 && accountTimeZone != null, "Unexpected condition where account info could not be retrieved");
    final CallContext callContext = internalCallContextFactory.createCallContext(internalCallContext);
    final ImmutableMap.Builder<BlockingState, Optional<UUID>> blockingStates = new ImmutableMap.Builder<BlockingState, Optional<UUID>>();
    final Map<DateTime, Collection<NotificationEvent>> notificationEvents = new HashMap<DateTime, Collection<NotificationEvent>>();
    final Collection<EntitlementContext> pluginContexts = new LinkedList<EntitlementContext>();
    final List<WithEntitlementPlugin> callbacks = new LinkedList<WithEntitlementPlugin>();
    final List<SubscriptionBase> subscriptions = new LinkedList<SubscriptionBase>();
    for (final Entitlement entitlement : entitlements) {
        if (entitlement.getState() == EntitlementState.CANCELLED) {
            // If subscription has already been cancelled, we ignore and carry on
            continue;
        }
        final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(entitlement.getBundleId(), entitlement.getExternalKey(), null, effectiveDate, null, false);
        final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
        baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
        final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.CANCEL_SUBSCRIPTION, entitlement.getAccountId(), null, baseEntitlementWithAddOnsSpecifierList, billingPolicy, properties, callContext);
        pluginContexts.add(pluginContext);
        final WithEntitlementPlugin<Entitlement> cancelEntitlementWithPlugin = new WithDateOverrideBillingPolicyEntitlementCanceler((DefaultEntitlement) entitlement, blockingStates, notificationEvents, callContext, internalCallContext);
        callbacks.add(cancelEntitlementWithPlugin);
        subscriptions.add(((DefaultEntitlement) entitlement).getSubscriptionBase());
    }
    final Callable<Void> preCallbacksCallback = new BulkSubscriptionBaseCancellation(subscriptions, billingPolicy, accountTimeZone, bcd, internalCallContext);
    pluginExecution.executeWithPlugin(preCallbacksCallback, callbacks, pluginContexts);
    // Record the new states first, then insert the notifications to avoid race conditions
    blockingStateDao.setBlockingStatesAndPostBlockingTransitionEvent(blockingStates.build(), internalCallContext);
    for (final DateTime effectiveDateForNotification : notificationEvents.keySet()) {
        for (final NotificationEvent notificationEvent : notificationEvents.get(effectiveDateForNotification)) {
            recordFutureNotification(effectiveDateForNotification, notificationEvent, internalCallContext);
        }
    }
}
Also used : HashMap(java.util.HashMap) WithEntitlementPlugin(org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin) EventsStreamBuilder(org.killbill.billing.entitlement.engine.core.EventsStreamBuilder) ArrayList(java.util.ArrayList) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) BlockingState(org.killbill.billing.entitlement.api.BlockingState) DateTime(org.joda.time.DateTime) SubscriptionBase(org.killbill.billing.subscription.api.SubscriptionBase) AccountApiException(org.killbill.billing.account.api.AccountApiException) BaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.BaseEntitlementWithAddOnsSpecifier) DefaultBaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier) UUID(java.util.UUID) DefaultEntitlementContext(org.killbill.billing.entitlement.api.DefaultEntitlementContext) EntitlementContext(org.killbill.billing.entitlement.plugin.api.EntitlementContext) DefaultBaseEntitlementWithAddOnsSpecifier(org.killbill.billing.entitlement.api.DefaultBaseEntitlementWithAddOnsSpecifier) Optional(com.google.common.base.Optional) EntitlementApiException(org.killbill.billing.entitlement.api.EntitlementApiException) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) CallContext(org.killbill.billing.util.callcontext.CallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) DateTimeZone(org.joda.time.DateTimeZone) ImmutableMap(com.google.common.collect.ImmutableMap) LinkedList(java.util.LinkedList) Collection(java.util.Collection) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Entitlement(org.killbill.billing.entitlement.api.Entitlement) DefaultEntitlementContext(org.killbill.billing.entitlement.api.DefaultEntitlementContext)

Example 19 with AccountApiException

use of org.killbill.billing.account.api.AccountApiException in project killbill by killbill.

the class DefaultSubscriptionApi method getBlockingStates.

@Override
public Iterable<BlockingState> getBlockingStates(final UUID accountId, @Nullable final List<BlockingStateType> typeFilter, @Nullable final List<String> svcsFilter, final OrderingType orderingType, final int timeFilter, final TenantContext tenantContext) throws EntitlementApiException {
    try {
        final InternalTenantContext internalTenantContextWithValidAccountRecordId = internalCallContextFactory.createInternalTenantContext(accountId, tenantContext);
        final List<BlockingState> allBlockingStates = blockingStateDao.getBlockingAllForAccountRecordId(internalTenantContextWithValidAccountRecordId);
        final ImmutableAccountData account = accountApi.getImmutableAccountDataById(accountId, internalTenantContextWithValidAccountRecordId);
        final Iterable<BlockingState> filteredByTypes = typeFilter != null && !typeFilter.isEmpty() ? Iterables.filter(allBlockingStates, new Predicate<BlockingState>() {

            @Override
            public boolean apply(final BlockingState input) {
                return typeFilter.contains(input.getType());
            }
        }) : allBlockingStates;
        final Iterable<BlockingState> filteredByTypesAndSvcs = svcsFilter != null && !svcsFilter.isEmpty() ? Iterables.filter(filteredByTypes, new Predicate<BlockingState>() {

            @Override
            public boolean apply(final BlockingState input) {
                return svcsFilter.contains(input.getService());
            }
        }) : filteredByTypes;
        final LocalDate localDateNowInAccountTimezone = new LocalDate(clock.getUTCNow(), account.getTimeZone());
        final List<BlockingState> result = new ArrayList<BlockingState>();
        for (final BlockingState cur : filteredByTypesAndSvcs) {
            final LocalDate eventDate = new LocalDate(cur.getEffectiveDate(), account.getTimeZone());
            final int comp = eventDate.compareTo(localDateNowInAccountTimezone);
            if ((comp <= 1 && ((timeFilter & SubscriptionApi.PAST_EVENTS) == SubscriptionApi.PAST_EVENTS)) || (comp == 0 && ((timeFilter & SubscriptionApi.PRESENT_EVENTS) == SubscriptionApi.PRESENT_EVENTS)) || (comp >= 1 && ((timeFilter & SubscriptionApi.FUTURE_EVENTS) == SubscriptionApi.FUTURE_EVENTS))) {
                result.add(cur);
            }
        }
        return orderingType == OrderingType.ASCENDING ? result : Lists.reverse(result);
    } catch (AccountApiException e) {
        throw new EntitlementApiException(e);
    }
}
Also used : ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) ArrayList(java.util.ArrayList) AccountApiException(org.killbill.billing.account.api.AccountApiException) DefaultBlockingState(org.killbill.billing.junction.DefaultBlockingState) EntitlementLoggingHelper.logAddBlockingState(org.killbill.billing.entitlement.logging.EntitlementLoggingHelper.logAddBlockingState) LocalDate(org.joda.time.LocalDate) Predicate(com.google.common.base.Predicate)

Example 20 with AccountApiException

use of org.killbill.billing.account.api.AccountApiException in project killbill by killbill.

the class DefaultSubscriptionApi method updateExternalKey.

@Override
public void updateExternalKey(final UUID bundleId, final String newExternalKey, final CallContext callContext) throws EntitlementApiException {
    logUpdateExternalKey(log, bundleId, newExternalKey);
    final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContextWithoutAccountRecordId(callContext);
    final SubscriptionBaseBundle bundle;
    final ImmutableAccountData account;
    try {
        bundle = subscriptionBaseInternalApi.getBundleFromId(bundleId, internalCallContext);
        account = accountApi.getImmutableAccountDataById(bundle.getAccountId(), internalCallContext);
    } catch (final SubscriptionBaseApiException e) {
        throw new EntitlementApiException(e);
    } catch (AccountApiException e) {
        throw new EntitlementApiException(e);
    }
    final LocalDate effectiveDate = new LocalDate(clock.getUTCNow(), account.getTimeZone());
    final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier = new DefaultBaseEntitlementWithAddOnsSpecifier(bundleId, newExternalKey, new ArrayList<EntitlementSpecifier>(), effectiveDate, effectiveDate, false);
    final List<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifierList = new ArrayList<BaseEntitlementWithAddOnsSpecifier>();
    baseEntitlementWithAddOnsSpecifierList.add(baseEntitlementWithAddOnsSpecifier);
    final EntitlementContext pluginContext = new DefaultEntitlementContext(OperationType.UPDATE_BUNDLE_EXTERNAL_KEY, bundle.getAccountId(), null, baseEntitlementWithAddOnsSpecifierList, null, ImmutableList.<PluginProperty>of(), callContext);
    final WithEntitlementPlugin<Void> updateExternalKeyWithPlugin = new WithEntitlementPlugin<Void>() {

        final InternalCallContext internalCallContextWithValidAccountId = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);

        @Override
        public Void doCall(final EntitlementApi entitlementApi, final EntitlementContext updatedPluginContext) throws EntitlementApiException {
            subscriptionBaseInternalApi.updateExternalKey(bundleId, newExternalKey, internalCallContextWithValidAccountId);
            return null;
        }
    };
    pluginExecution.executeWithPlugin(updateExternalKeyWithPlugin, pluginContext);
}
Also used : ImmutableAccountData(org.killbill.billing.account.api.ImmutableAccountData) WithEntitlementPlugin(org.killbill.billing.entitlement.api.EntitlementPluginExecution.WithEntitlementPlugin) ArrayList(java.util.ArrayList) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) LocalDate(org.joda.time.LocalDate) AccountApiException(org.killbill.billing.account.api.AccountApiException) SubscriptionBaseBundle(org.killbill.billing.subscription.api.user.SubscriptionBaseBundle) SubscriptionBaseApiException(org.killbill.billing.subscription.api.user.SubscriptionBaseApiException) EntitlementContext(org.killbill.billing.entitlement.plugin.api.EntitlementContext)

Aggregations

AccountApiException (org.killbill.billing.account.api.AccountApiException)36 UUID (java.util.UUID)17 Account (org.killbill.billing.account.api.Account)16 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)12 DefaultAccount (org.killbill.billing.account.api.DefaultAccount)10 ArrayList (java.util.ArrayList)7 ImmutableAccountData (org.killbill.billing.account.api.ImmutableAccountData)7 InvoiceApiException (org.killbill.billing.invoice.api.InvoiceApiException)7 PaymentApiException (org.killbill.billing.payment.api.PaymentApiException)6 SubscriptionBaseApiException (org.killbill.billing.subscription.api.user.SubscriptionBaseApiException)6 CallContext (org.killbill.billing.util.callcontext.CallContext)6 BigDecimal (java.math.BigDecimal)5 HashMap (java.util.HashMap)5 AccountModelDao (org.killbill.billing.account.dao.AccountModelDao)5 Invoice (org.killbill.billing.invoice.api.Invoice)5 AllowConcurrentEvents (com.google.common.eventbus.AllowConcurrentEvents)4 Subscribe (com.google.common.eventbus.Subscribe)4 LocalDate (org.joda.time.LocalDate)4 DefaultMutableAccountData (org.killbill.billing.account.api.DefaultMutableAccountData)4 PaymentMethod (org.killbill.billing.payment.api.PaymentMethod)4