use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.
the class SubscriptionResource method changeEntitlementPlan.
@TimedResource
@PUT
@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
@Path("/{subscriptionId:" + UUID_PATTERN + "}")
@ApiOperation(value = "Change entitlement plan")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid subscription id supplied"), @ApiResponse(code = 404, message = "Entitlement not found") })
public Response changeEntitlementPlan(final SubscriptionJson entitlement, @PathParam("subscriptionId") final String subscriptionId, @QueryParam(QUERY_REQUESTED_DT) final String requestedDate, @QueryParam(QUERY_CALL_COMPLETION) @DefaultValue("false") final Boolean callCompletion, @QueryParam(QUERY_CALL_TIMEOUT) @DefaultValue("3") final long timeoutSec, @QueryParam(QUERY_BILLING_POLICY) final String policyString, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @HeaderParam(HDR_CREATED_BY) final String createdBy, @HeaderParam(HDR_REASON) final String reason, @HeaderParam(HDR_COMMENT) final String comment, @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException, AccountApiException, SubscriptionApiException {
verifyNonNullOrEmpty(entitlement, "SubscriptionJson body should be specified");
if (entitlement.getPlanName() == null) {
verifyNonNullOrEmpty(entitlement.getProductName(), "SubscriptionJson productName needs to be set", entitlement.getBillingPeriod(), "SubscriptionJson billingPeriod needs to be set", entitlement.getPriceList(), "SubscriptionJson priceList needs to be set");
}
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createContext(createdBy, reason, comment, request);
final EntitlementCallCompletionCallback<Response> callback = new EntitlementCallCompletionCallback<Response>() {
private boolean isImmediateOp = true;
@Override
public Response doOperation(final CallContext ctx) throws EntitlementApiException, InterruptedException, TimeoutException, AccountApiException {
final UUID uuid = UUID.fromString(subscriptionId);
final Entitlement current = entitlementApi.getEntitlementForId(uuid, callContext);
final LocalDate inputLocalDate = toLocalDate(requestedDate);
final Entitlement newEntitlement;
final Account account = accountUserApi.getAccountById(current.getAccountId(), callContext);
final PlanSpecifier planSpec = entitlement.getPlanName() != null ? new PlanSpecifier(entitlement.getPlanName()) : new PlanSpecifier(entitlement.getProductName(), BillingPeriod.valueOf(entitlement.getBillingPeriod()), entitlement.getPriceList());
final List<PlanPhasePriceOverride> overrides = PhasePriceOverrideJson.toPlanPhasePriceOverrides(entitlement.getPriceOverrides(), planSpec, account.getCurrency());
if (requestedDate == null && policyString == null) {
newEntitlement = current.changePlan(planSpec, overrides, pluginProperties, ctx);
} else if (policyString == null) {
newEntitlement = current.changePlanWithDate(planSpec, overrides, inputLocalDate, pluginProperties, ctx);
} else {
final BillingActionPolicy policy = BillingActionPolicy.valueOf(policyString.toUpperCase());
newEntitlement = current.changePlanOverrideBillingPolicy(planSpec, overrides, inputLocalDate, policy, pluginProperties, ctx);
}
isImmediateOp = newEntitlement.getLastActiveProduct().getName().equals(entitlement.getProductName()) && newEntitlement.getLastActivePlan().getRecurringBillingPeriod() == BillingPeriod.valueOf(entitlement.getBillingPeriod()) && newEntitlement.getLastActivePriceList().getName().equals(entitlement.getPriceList());
return Response.status(Status.OK).build();
}
@Override
public boolean isImmOperation() {
return isImmediateOp;
}
@Override
public Response doResponseOk(final Response operationResponse) throws SubscriptionApiException, AccountApiException, CatalogApiException {
if (operationResponse.getStatus() != Status.OK.getStatusCode()) {
return operationResponse;
}
return getEntitlement(subscriptionId, new AuditMode(AuditLevel.NONE.toString()), request);
}
};
final EntitlementCallCompletion<Response> callCompletionCreation = new EntitlementCallCompletion<Response>();
return callCompletionCreation.withSynchronization(callback, timeoutSec, callCompletion, callContext);
}
use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.
the class SubscriptionResource method uncancelEntitlementPlan.
@TimedResource
@PUT
@Path("/{subscriptionId:" + UUID_PATTERN + "}/uncancel")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Un-cancel an entitlement")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid subscription id supplied"), @ApiResponse(code = 404, message = "Entitlement not found") })
public Response uncancelEntitlementPlan(@PathParam("subscriptionId") final String subscriptionId, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @HeaderParam(HDR_CREATED_BY) final String createdBy, @HeaderParam(HDR_REASON) final String reason, @HeaderParam(HDR_COMMENT) final String comment, @javax.ws.rs.core.Context final HttpServletRequest request) throws EntitlementApiException {
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final UUID uuid = UUID.fromString(subscriptionId);
final Entitlement current = entitlementApi.getEntitlementForId(uuid, context.createContext(createdBy, reason, comment, request));
current.uncancelEntitlement(pluginProperties, context.createContext(createdBy, reason, comment, request));
return Response.status(Status.OK).build();
}
use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.
the class InvoiceResource method createExternalCharges.
@TimedResource
@POST
@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
@Path("/" + CHARGES + "/{accountId:" + UUID_PATTERN + "}")
@ApiOperation(value = "Create external charge(s)", response = InvoiceItemJson.class, responseContainer = "List")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Invalid account id supplied"), @ApiResponse(code = 404, message = "Account not found") })
public Response createExternalCharges(final Iterable<InvoiceItemJson> externalChargesJson, @PathParam("accountId") final String accountId, @QueryParam(QUERY_REQUESTED_DT) final String requestedDateTimeString, @QueryParam(QUERY_PAY_INVOICE) @DefaultValue("false") final Boolean payInvoice, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @QueryParam(QUERY_AUTO_COMMIT) @DefaultValue("false") final Boolean autoCommit, @QueryParam(QUERY_PAYMENT_EXTERNAL_KEY) final String paymentExternalKey, @QueryParam(QUERY_TRANSACTION_EXTERNAL_KEY) final String transactionExternalKey, @HeaderParam(HDR_CREATED_BY) final String createdBy, @HeaderParam(HDR_REASON) final String reason, @HeaderParam(HDR_COMMENT) final String comment, @javax.ws.rs.core.Context final UriInfo uriInfo, @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, InvoiceApiException, PaymentApiException {
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createContext(createdBy, reason, comment, request);
final Account account = accountUserApi.getAccountById(UUID.fromString(accountId), callContext);
final Iterable<InvoiceItem> sanitizedExternalChargesJson = validateSanitizeAndTranformInputItems(account.getCurrency(), externalChargesJson);
// Get the effective date of the external charge, in the account timezone
final LocalDate requestedDate = toLocalDateDefaultToday(account, requestedDateTimeString, callContext);
final List<InvoiceItem> createdExternalCharges = invoiceApi.insertExternalCharges(account.getId(), requestedDate, sanitizedExternalChargesJson, autoCommit, callContext);
// if all createdExternalCharges point to the same invoiceId, use the provided paymentExternalKey and / or transactionExternalKey
final boolean haveSameInvoiceId = Iterables.all(createdExternalCharges, new Predicate<InvoiceItem>() {
@Override
public boolean apply(final InvoiceItem input) {
return input.getInvoiceId().equals(createdExternalCharges.get(0).getInvoiceId());
}
});
if (payInvoice) {
final Collection<UUID> paidInvoices = new HashSet<UUID>();
for (final InvoiceItem externalCharge : createdExternalCharges) {
if (!paidInvoices.contains(externalCharge.getInvoiceId())) {
paidInvoices.add(externalCharge.getInvoiceId());
final Invoice invoice = invoiceApi.getInvoice(externalCharge.getInvoiceId(), callContext);
createPurchaseForInvoice(account, invoice.getId(), invoice.getBalance(), account.getPaymentMethodId(), false, (haveSameInvoiceId && paymentExternalKey != null) ? paymentExternalKey : null, (haveSameInvoiceId && transactionExternalKey != null) ? transactionExternalKey : null, pluginProperties, callContext);
}
}
}
final List<InvoiceItemJson> createdExternalChargesJson = Lists.<InvoiceItem, InvoiceItemJson>transform(createdExternalCharges, new Function<InvoiceItem, InvoiceItemJson>() {
@Override
public InvoiceItemJson apply(final InvoiceItem input) {
return new InvoiceItemJson(input);
}
});
return Response.status(Status.OK).entity(createdExternalChargesJson).build();
}
use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.
the class JaxRsResourceBase method extractPluginProperties.
protected Iterable<PluginProperty> extractPluginProperties(@Nullable final Iterable<String> pluginProperties, final PluginProperty... additionalProperties) {
final Collection<PluginProperty> properties = new LinkedList<PluginProperty>();
if (pluginProperties == null) {
return properties;
}
for (final String pluginProperty : pluginProperties) {
final List<String> property = ImmutableList.<String>copyOf(pluginProperty.split("="));
// Skip entries for which there is no value
if (property.size() == 1) {
continue;
}
final String key = property.get(0);
// Should we URL decode the value?
String value = Joiner.on("=").join(property.subList(1, property.size()));
if (pluginProperty.endsWith("=")) {
value += "=";
}
properties.add(new PluginProperty(key, value, false));
}
for (final PluginProperty cur : additionalProperties) {
properties.add(cur);
}
return properties;
}
use of org.killbill.billing.payment.api.PluginProperty in project killbill by killbill.
the class PaymentResource method searchPayments.
@TimedResource
@GET
@Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
@Produces(APPLICATION_JSON)
@ApiOperation(value = "Search payments", response = PaymentJson.class, responseContainer = "List")
@ApiResponses(value = {})
public Response searchPayments(@PathParam("searchKey") final String searchKey, @QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset, @QueryParam(QUERY_SEARCH_LIMIT) @DefaultValue("100") final Long limit, @QueryParam(QUERY_PAYMENT_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, @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts, @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final TenantContext tenantContext = context.createContext(request);
// Search the plugin(s)
final Pagination<Payment> payments;
if (Strings.isNullOrEmpty(pluginName)) {
payments = paymentApi.searchPayments(searchKey, offset, limit, withPluginInfo, withAttempts, pluginProperties, tenantContext);
} else {
payments = paymentApi.searchPayments(searchKey, offset, limit, pluginName, withPluginInfo, withAttempts, pluginProperties, tenantContext);
}
final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class, "searchPayments", payments.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey, 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>());
return buildStreamingPaginationResponse(payments, new Function<Payment, PaymentJson>() {
@Override
public PaymentJson apply(final Payment payment) {
// Cache audit logs per account
if (accountsAuditLogs.get().get(payment.getAccountId()) == null) {
accountsAuditLogs.get().put(payment.getAccountId(), auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext));
}
final AccountAuditLogs accountAuditLogs = accountsAuditLogs.get().get(payment.getAccountId());
return new PaymentJson(payment, accountAuditLogs);
}
}, nextPageUri);
}
Aggregations