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);
}
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);
}
}
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);
}
}
}
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);
}
}
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);
}
Aggregations