Search in sources :

Example 26 with AccountApiException

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

the class PaymentMethodResource method getPaymentMethods.

@TimedResource
@GET
@Path("/" + PAGINATION)
@Produces(APPLICATION_JSON)
@ApiOperation(value = "List payment methods", response = PaymentMethodJson.class, responseContainer = "List")
@ApiResponses(value = {})
public Response getPaymentMethods(@QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset, @QueryParam(QUERY_SEARCH_LIMIT) @DefaultValue("100") final Long limit, @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_NAME) final String pluginName, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo, @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
    final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
    final TenantContext tenantContext = context.createContext(request);
    final Pagination<PaymentMethod> paymentMethods;
    if (Strings.isNullOrEmpty(pluginName)) {
        paymentMethods = paymentApi.getPaymentMethods(offset, limit, withPluginInfo, pluginProperties, tenantContext);
    } else {
        paymentMethods = paymentApi.getPaymentMethods(offset, limit, pluginName, withPluginInfo, pluginProperties, tenantContext);
    }
    final URI nextPageUri = uriBuilder.nextPage(PaymentMethodResource.class, "getPaymentMethods", paymentMethods.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName), QUERY_AUDIT, auditMode.getLevel().toString()));
    final AtomicReference<Map<UUID, AccountAuditLogs>> accountsAuditLogs = new AtomicReference<Map<UUID, AccountAuditLogs>>(new HashMap<UUID, AccountAuditLogs>());
    final Map<UUID, Account> accounts = new HashMap<UUID, Account>();
    return buildStreamingPaginationResponse(paymentMethods, new Function<PaymentMethod, PaymentMethodJson>() {

        @Override
        public PaymentMethodJson apply(final PaymentMethod paymentMethod) {
            // Cache audit logs per account
            if (accountsAuditLogs.get().get(paymentMethod.getAccountId()) == null) {
                accountsAuditLogs.get().put(paymentMethod.getAccountId(), auditUserApi.getAccountAuditLogs(paymentMethod.getAccountId(), auditMode.getLevel(), tenantContext));
            }
            // Lookup the associated account(s)
            if (accounts.get(paymentMethod.getAccountId()) == null) {
                final Account account;
                try {
                    account = accountUserApi.getAccountById(paymentMethod.getAccountId(), tenantContext);
                    accounts.put(paymentMethod.getAccountId(), account);
                } catch (final AccountApiException e) {
                    log.warn("Error retrieving accountId='{}'", paymentMethod.getAccountId(), e);
                    return null;
                }
            }
            return PaymentMethodJson.toPaymentMethodJson(accounts.get(paymentMethod.getAccountId()), paymentMethod, accountsAuditLogs.get().get(paymentMethod.getAccountId()));
        }
    }, nextPageUri);
}
Also used : Account(org.killbill.billing.account.api.Account) HashMap(java.util.HashMap) TenantContext(org.killbill.billing.util.callcontext.TenantContext) AtomicReference(java.util.concurrent.atomic.AtomicReference) URI(java.net.URI) PluginProperty(org.killbill.billing.payment.api.PluginProperty) PaymentMethodJson(org.killbill.billing.jaxrs.json.PaymentMethodJson) AccountApiException(org.killbill.billing.account.api.AccountApiException) PaymentMethod(org.killbill.billing.payment.api.PaymentMethod) UUID(java.util.UUID) AccountAuditLogs(org.killbill.billing.util.audit.AccountAuditLogs) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) Path(javax.ws.rs.Path) TimedResource(org.killbill.commons.metrics.TimedResource) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 27 with AccountApiException

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

the class InvoiceListener method handleChildrenInvoiceCreationEvent.

@AllowConcurrentEvents
@Subscribe
public void handleChildrenInvoiceCreationEvent(final InvoiceCreationInternalEvent event) {
    try {
        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(event.getSearchKey2(), event.getSearchKey1(), "CreateParentInvoice", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken());
        final Account account = accountApi.getAccountById(event.getAccountId(), context);
        // catch children invoices and populate the parent summary invoice
        if (isChildrenAccountAndPaymentDelegated(account)) {
            dispatcher.processParentInvoiceForInvoiceGeneration(account, event.getInvoiceId(), context);
        }
    } catch (InvoiceApiException e) {
        log.error(e.getMessage());
    } catch (AccountApiException e) {
        log.error(e.getMessage());
    }
}
Also used : Account(org.killbill.billing.account.api.Account) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) AccountApiException(org.killbill.billing.account.api.AccountApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) AllowConcurrentEvents(com.google.common.eventbus.AllowConcurrentEvents) Subscribe(com.google.common.eventbus.Subscribe)

Example 28 with AccountApiException

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

the class InvoiceListener method handleBlockingStateTransition.

@AllowConcurrentEvents
@Subscribe
public void handleBlockingStateTransition(final BlockingTransitionInternalEvent event) {
    // We are only interested in blockBilling or unblockBilling transitions.
    if (!event.isTransitionedToUnblockedBilling() && !event.isTransitionedToBlockedBilling()) {
        return;
    }
    try {
        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(event.getSearchKey2(), event.getSearchKey1(), "SubscriptionBaseTransition", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken());
        final UUID accountId = accountApi.getByRecordId(event.getSearchKey1(), context);
        dispatcher.processAccountFromNotificationOrBusEvent(accountId, null, null, context);
    } catch (InvoiceApiException e) {
        log.warn("Unable to process event {}", event, e);
    } catch (AccountApiException e) {
        log.warn("Unable to process event {}", event, e);
    }
}
Also used : InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) AccountApiException(org.killbill.billing.account.api.AccountApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) UUID(java.util.UUID) AllowConcurrentEvents(com.google.common.eventbus.AllowConcurrentEvents) Subscribe(com.google.common.eventbus.Subscribe)

Example 29 with AccountApiException

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

the class InvoiceListener method handleChildrenInvoiceAdjustmentEvent.

@AllowConcurrentEvents
@Subscribe
public void handleChildrenInvoiceAdjustmentEvent(final DefaultInvoiceAdjustmentEvent event) {
    try {
        final InternalCallContext context = internalCallContextFactory.createInternalCallContext(event.getSearchKey2(), event.getSearchKey1(), "AdjustParentInvoice", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken());
        final Account account = accountApi.getAccountById(event.getAccountId(), context);
        // catch children invoices and populate the parent summary invoice
        if (isChildrenAccountAndPaymentDelegated(account)) {
            dispatcher.processParentInvoiceForAdjustments(account, event.getInvoiceId(), context);
        }
    } catch (InvoiceApiException e) {
        log.error(e.getMessage());
    } catch (AccountApiException e) {
        log.error(e.getMessage());
    }
}
Also used : Account(org.killbill.billing.account.api.Account) InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) AccountApiException(org.killbill.billing.account.api.AccountApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) AllowConcurrentEvents(com.google.common.eventbus.AllowConcurrentEvents) Subscribe(com.google.common.eventbus.Subscribe)

Example 30 with AccountApiException

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

the class InvoicePaymentControlPluginApi method getPluginPurchaseResult.

private PriorPaymentControlResult getPluginPurchaseResult(final PaymentControlContext paymentControlPluginContext, final Iterable<PluginProperty> pluginProperties, final InternalCallContext internalContext) throws PaymentControlApiException {
    try {
        final UUID invoiceId = getInvoiceId(pluginProperties);
        final Invoice invoice = getAndSanitizeInvoice(invoiceId, internalContext);
        if (!InvoiceStatus.COMMITTED.equals(invoice.getStatus())) {
            // abort payment if the invoice status is not COMMITTED
            return new DefaultPriorPaymentControlResult(true);
        }
        // Get account and check if it is child and payment is delegated to parent => abort
        final AccountData accountData = accountApi.getAccountById(invoice.getAccountId(), internalContext);
        if ((accountData != null) && (accountData.getParentAccountId() != null) && accountData.isPaymentDelegatedToParent()) {
            return new DefaultPriorPaymentControlResult(true);
        }
        final BigDecimal requestedAmount = validateAndComputePaymentAmount(invoice, paymentControlPluginContext.getAmount(), paymentControlPluginContext.isApiPayment());
        final boolean isAborted = requestedAmount.compareTo(BigDecimal.ZERO) == 0;
        if (!isAborted && paymentControlPluginContext.getPaymentMethodId() == null) {
            log.warn("Payment for invoiceId='{}' was not triggered, accountId='{}' doesn't have a default payment method", getInvoiceId(pluginProperties), paymentControlPluginContext.getAccountId());
            invoiceApi.recordPaymentAttemptCompletion(invoiceId, paymentControlPluginContext.getAmount(), paymentControlPluginContext.getCurrency(), paymentControlPluginContext.getProcessedCurrency(), paymentControlPluginContext.getPaymentId(), paymentControlPluginContext.getTransactionExternalKey(), paymentControlPluginContext.getCreatedDate(), false, internalContext);
            return new DefaultPriorPaymentControlResult(true);
        }
        if (!isAborted && insert_AUTO_PAY_OFF_ifRequired(paymentControlPluginContext, requestedAmount)) {
            return new DefaultPriorPaymentControlResult(true);
        }
        if (paymentControlPluginContext.isApiPayment() && isAborted) {
            throw new PaymentControlApiException("Abort purchase call: ", new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION, String.format("Aborted Payment for invoice %s : invoice balance is = %s, requested payment amount is = %s", invoice.getId(), invoice.getBalance(), paymentControlPluginContext.getAmount())));
        } else {
            //
            // Insert attempt row with a success = false status to implement a two-phase commit strategy and guard against scenario where payment would go through
            // but onSuccessCall callback never gets called (leaving the place for a double payment if user retries the operation)
            //
            invoiceApi.recordPaymentAttemptInit(invoice.getId(), MoreObjects.firstNonNull(paymentControlPluginContext.getAmount(), BigDecimal.ZERO), paymentControlPluginContext.getCurrency(), paymentControlPluginContext.getCurrency(), // to match the operation in the checkForIncompleteInvoicePaymentAndRepair logic below
            paymentControlPluginContext.getPaymentId(), paymentControlPluginContext.getTransactionExternalKey(), paymentControlPluginContext.getCreatedDate(), internalContext);
            return new DefaultPriorPaymentControlResult(isAborted, requestedAmount);
        }
    } catch (final InvoiceApiException e) {
        throw new PaymentControlApiException(e);
    } catch (final IllegalArgumentException e) {
        throw new PaymentControlApiException(e);
    } catch (AccountApiException e) {
        throw new PaymentControlApiException(e);
    }
}
Also used : InvoiceApiException(org.killbill.billing.invoice.api.InvoiceApiException) Invoice(org.killbill.billing.invoice.api.Invoice) AccountData(org.killbill.billing.account.api.AccountData) AccountApiException(org.killbill.billing.account.api.AccountApiException) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) UUID(java.util.UUID) DefaultPriorPaymentControlResult(org.killbill.billing.payment.retry.DefaultPriorPaymentControlResult) BigDecimal(java.math.BigDecimal) PaymentControlApiException(org.killbill.billing.control.plugin.api.PaymentControlApiException)

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