protected Payment getPaymentByIdOrKey(@Nullable final UUID paymentId, @Nullable final String externalKey, final Iterable<PluginProperty> pluginProperties, final TenantContext tenantContext) throws PaymentApiException { Preconditions.checkArgument(paymentId != null || externalKey != null, "Need to set either paymentId or payment externalKey"); if (paymentId != null) { return paymentApi.getPayment(paymentId, false, false, pluginProperties, tenantContext); } else { return paymentApi.getPaymentByExternalKey(externalKey, false, false, pluginProperties, tenantContext); } }
@TimedResource @GET @Path("/{paymentId:" + UUID_PATTERN + "}/" + TAGS) @Produces(APPLICATION_JSON) @ApiOperation(value = "Retrieve payment payment tags", response = TagJson.class, responseContainer = "List", nickname = "getPaymentTags") @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"), @ApiResponse(code = 404, message = "Invoice not found")}) public Response getTags(@PathParam(ID_PARAM_NAME) final UUID paymentId, @QueryParam(QUERY_TAGS_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, PaymentApiException { final TenantContext tenantContext = context.createTenantContextNoAccountId(request); final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), tenantContext); return super.getTags(payment.getAccountId(), paymentId, auditMode, includedDeleted, tenantContext); }
public List<String> getPaymentControlPluginNames(final UUID kbPaymentId, final TenantContext context) throws PaymentApiException { if (!withControl) { // Note that we could have decided to always call the control APIs with an empty list, since Kill Bill would have defaulted // to the non-control APIs. However, it might be better for the long term to not rely on that specific implementation behavior // (we have two APIs after all). return null; } final Payment payment = osgiKillbillAPI.getPaymentApi().getPayment(kbPaymentId, false, true, ImmutableList.<PluginProperty>of(), context); if (payment.getPaymentAttempts() != null && !payment.getPaymentAttempts().isEmpty()) { return ImmutableList.<String>copyOf(Splitter.on(",").split(payment.getPaymentAttempts().get(0).getPluginName())); } else { return ImmutableList.<String>of(); } }
@TimedResource @GET @Path("/{paymentId:" + UUID_PATTERN + "}/" + TAGS) @Produces(APPLICATION_JSON) @ApiOperation(value = "Retrieve payment tags", response = TagJson.class, responseContainer = "List", nickname = "getInvoicePaymentTags") @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid payment id supplied"), @ApiResponse(code = 404, message = "Payment not found")}) public Response getTags(@PathParam(ID_PARAM_NAME) final UUID paymentId, @QueryParam(QUERY_INCLUDED_DELETED) @DefaultValue("false") final Boolean includedDeleted, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, PaymentApiException { final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString); final TenantContext tenantContext = context.createTenantContextNoAccountId(request); final Payment payment = paymentApi.getPayment(paymentId, false, false, pluginProperties, tenantContext); return super.getTags(payment.getAccountId(), paymentId, auditMode, includedDeleted, tenantContext); }
@TimedResource(name = "getPayment") @GET @Path("/{paymentId:" + UUID_PATTERN + "}/") @Produces(APPLICATION_JSON) @ApiOperation(value = "Retrieve a payment by id", response = PaymentJson.class) @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentId supplied"), @ApiResponse(code = 404, message = "Payment not found")}) public Response getPayment(@PathParam("paymentId") final UUID paymentId, @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo, @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts, @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString, @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode, @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException { final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString); final TenantContext tenantContext = context.createTenantContextNoAccountId(request); final Payment payment = paymentApi.getPayment(paymentId, withPluginInfo, withAttempts, pluginProperties, tenantContext); final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext); final PaymentJson result = new PaymentJson(payment, accountAuditLogs); return Response.status(Response.Status.OK).entity(result).build(); }
@Override public Payment apply(@Nullable final Void input) { try { final InvoicePayment invoicePayment = invoicePaymentApi.createRefundForInvoicePayment(true, iias, account, payment.getId(), amount, currency, null, UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), PAYMENT_OPTIONS, callContext); return paymentApi.getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), callContext); } catch (final PaymentApiException e) { fail(e.toString()); return null; } } }, events);
protected PaymentTransaction getPaymentTransaction(final UUID kbPaymentId, final UUID kbTransactionId, final TenantContext context) throws OSGIServiceNotAvailable { final Payment payment; try { payment = getPaymentUserApi().getPayment(kbPaymentId, false, false, PLUGIN_PROPERTIES, context); } catch (final PaymentApiException e) { logService.log(LogService.LOG_INFO, "Error retrieving payment for paymentId " + kbPaymentId + ": " + e.getMessage()); throw new OSGIServiceNotAvailable(e); } return getPaymentTransaction(kbTransactionId, payment); }
@Override public Payment answer(final InvocationOnMock invocation) throws Throwable { final UUID kbPaymentId = (UUID) invocation.getArguments()[1]; final Payment payment = paymentApi.getPayment(kbPaymentId, false, false, ImmutableList.<PluginProperty>of(), (TenantContext) invocation.getArguments()[4]); Assert.assertNotNull(payment); final String kbPaymentTransactionExternalKey = (String) invocation.getArguments()[3]; PaymentTransaction paymentTransaction = null; for (final PaymentTransaction t : payment.getTransactions()) { if (kbPaymentTransactionExternalKey.equals(t.getExternalKey())) { paymentTransaction = t; break; } } Assert.assertNotNull(paymentTransaction); Assert.assertEquals(paymentTransaction.getTransactionStatus(), TransactionStatus.SUCCESS); Mockito.when(paymentTransaction.getTransactionStatus()).thenReturn(TransactionStatus.PAYMENT_FAILURE); return payment; } });
@Test(groups = "slow") public void testSimpleAuthCaptureWithInvalidPaymentId() throws Exception { final BigDecimal requestedAmount = new BigDecimal("80.0091"); final Payment initialPayment = paymentApi.createAuthorization(account, account.getPaymentMethodId(), null, requestedAmount, account.getCurrency(), null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), callContext); try { paymentApi.createCapture(account, UUID.randomUUID(), requestedAmount, account.getCurrency(), null, UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Expected capture to fail..."); } catch (final PaymentApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_NO_SUCH_PAYMENT.getCode()); final Payment latestPayment = paymentApi.getPayment(initialPayment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext); assertEquals(latestPayment, initialPayment); } }
@Override public Object execute() throws Throwable { assertEquals(DBRouterUntyped.getCurrentState(), THREAD_STATE.RO_ALLOWED); final Payment retrievedPayment2 = paymentApi.getPayment(payment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext); Assert.assertEquals(retrievedPayment2.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS); // No thread switch, RO as well assertEquals(mockPaymentProviderPlugin.getLastThreadState(), THREAD_STATE.RO_ALLOWED); assertEquals(DBRouterUntyped.getCurrentState(), THREAD_STATE.RO_ALLOWED); return null; } });
@Test(groups = "slow") public void testSimpleAuthCaptureWithInvalidCurrency() throws Exception { final BigDecimal requestedAmount = new BigDecimal("80.0091"); final Payment initialPayment = paymentApi.createAuthorization(account, account.getPaymentMethodId(), null, requestedAmount, account.getCurrency(), null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), callContext); try { paymentApi.createCapture(account, initialPayment.getId(), requestedAmount, Currency.AMD, null, UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Expected capture to fail..."); } catch (final PaymentApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode()); final Payment latestPayment = paymentApi.getPayment(initialPayment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext); assertEquals(latestPayment, initialPayment); } }
public static Payment buildPayment(final UUID accountId, final UUID paymentMethodId, final UUID paymentId, final Currency currency, final String paymentExternalKey, @Nullable final OSGIKillbill killbillApi) throws PaymentApiException { final Payment payment = Mockito.mock(Payment.class); Mockito.when(payment.getId()).thenReturn(paymentId); Mockito.when(payment.getExternalKey()).thenReturn(paymentExternalKey); Mockito.when(payment.getAccountId()).thenReturn(accountId); Mockito.when(payment.getPaymentMethodId()).thenReturn(paymentMethodId); Mockito.when(payment.getPaymentNumber()).thenReturn(1); Mockito.when(payment.getCapturedAmount()).thenReturn(new BigDecimal("199999")); Mockito.when(payment.getRefundedAmount()).thenReturn(new BigDecimal("199998")); Mockito.when(payment.getCurrency()).thenReturn(currency); Mockito.when(payment.getTransactions()).thenReturn(new LinkedList<PaymentTransaction>()); Mockito.when(payment.getCreatedDate()).thenReturn(new DateTime(2016, 1, 22, 10, 56, 56, DateTimeZone.UTC)); if (killbillApi != null) { Mockito.when(killbillApi.getPaymentApi().getPayment(Mockito.eq(payment.getId()), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.<Iterable<PluginProperty>>any(), Mockito.<TenantContext>any())).thenReturn(payment); final List<Payment> payments = MoreObjects.firstNonNull(killbillApi.getPaymentApi().getAccountPayments(accountId, false, false, ImmutableList.<PluginProperty>of(), Mockito.mock(TenantContext.class)), new LinkedList<Payment>()); payments.add(payment); Mockito.when(killbillApi.getPaymentApi().getAccountPayments(Mockito.eq(accountId), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.<Iterable<PluginProperty>>any(), Mockito.<TenantContext>any())).thenReturn(payments); } return payment; }
@Override public Payment apply(@Nullable final Void input) { try { final InvoicePayment invoicePayment = invoicePaymentApi.createPurchaseForInvoicePayment(account, invoice.getId(), account.getPaymentMethodId(), null, amount, currency, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), PAYMENT_OPTIONS, callContext); return paymentApi.getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), callContext); } catch (final PaymentApiException e) { fail(e.toString()); return null; } } }, events);
@Override public Payment apply(@Nullable final Void input) { try { final InvoicePayment invoicePayment = invoicePaymentApi.createPurchaseForInvoicePayment(account, invoice.getId(), account.getPaymentMethodId(), null, invoice.getBalance(), invoice.getCurrency(), null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), EXTERNAL_PAYMENT_OPTIONS, callContext); return paymentApi.getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), callContext); } catch (final PaymentApiException e) { fail(e.toString()); return null; } } }, events);
public PaymentTransaction checkRefund(final UUID paymentId, final CallContext context, ExpectedRefundCheck expected) throws PaymentApiException { final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), context); final PaymentTransaction refund = Iterables.tryFind(payment.getTransactions(), new Predicate<PaymentTransaction>() { @Override public boolean apply(final PaymentTransaction input) { return input.getTransactionType() == TransactionType.REFUND; } }).orNull(); Assert.assertNotNull(refund); final InvoicePayment refundInvoicePayment = getInvoicePaymentEntry(paymentId, InvoicePaymentType.REFUND, context); final InvoicePayment invoicePayment = getInvoicePaymentEntry(paymentId, InvoicePaymentType.ATTEMPT, context); Assert.assertEquals(refund.getPaymentId(), expected.getPaymentId()); Assert.assertEquals(refund.getCurrency(), expected.getCurrency()); Assert.assertEquals(refund.getAmount().compareTo(expected.getRefundAmount()), 0); Assert.assertEquals(refundInvoicePayment.getPaymentId(), paymentId); Assert.assertEquals(refundInvoicePayment.getLinkedInvoicePaymentId(), invoicePayment.getId()); Assert.assertEquals(refundInvoicePayment.getPaymentCookieId(), refund.getExternalKey()); Assert.assertEquals(refundInvoicePayment.getInvoiceId(), invoicePayment.getInvoiceId()); Assert.assertEquals(refundInvoicePayment.getAmount().compareTo(expected.getRefundAmount().negate()), 0); Assert.assertEquals(refundInvoicePayment.getCurrency(), expected.getCurrency()); return refund; }
@Test(groups = "slow") public void testAuthFailureWithPaymentControlNullPaymentMethodId() throws Exception { final AccountData accountData = getAccountData(1); final Account account = accountUserApi.createAccount(accountData, callContext); // Add non-default payment method final PaymentMethodPlugin info = createPaymentMethodPlugin(); final UUID paymentMethodId = paymentApi.addPaymentMethod(account, UUID.randomUUID().toString(), BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, false, info, PLUGIN_PROPERTIES, callContext); testPaymentControlWithControl.setAdjustedPaymentMethodId(paymentMethodId); paymentPlugin.makeNextPaymentFailWithError(); busHandler.pushExpectedEvents(NextEvent.PAYMENT_ERROR); final Payment payment = paymentApi.createAuthorizationWithPaymentControl(account, null, null, BigDecimal.ONE, account.getCurrency(), null, null, null, properties, paymentOptions, callContext); assertListenerStatus(); final Payment paymentWithAttempts = paymentApi.getPayment(payment.getId(), false, true, ImmutableList.<PluginProperty>of(), callContext); Assert.assertEquals(paymentWithAttempts.getPaymentMethodId(), paymentMethodId); Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().size(), 1); Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getPaymentMethodId(), paymentMethodId); Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getStateName(), "ABORTED"); }
@Test(groups = "slow") public void testAuthSuccessWithPaymentControlNullPaymentMethodId() throws Exception { final AccountData accountData = getAccountData(1); final Account account = accountUserApi.createAccount(accountData, callContext); // Add non-default payment method final PaymentMethodPlugin info = createPaymentMethodPlugin(); final UUID paymentMethodId = paymentApi.addPaymentMethod(account, UUID.randomUUID().toString(), BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, false, info, PLUGIN_PROPERTIES, callContext); testPaymentControlWithControl.setAdjustedPaymentMethodId(paymentMethodId); busHandler.pushExpectedEvents(NextEvent.PAYMENT); final Payment payment = paymentApi.createAuthorizationWithPaymentControl(account, null, null, BigDecimal.ONE, account.getCurrency(), null, null, null, properties, paymentOptions, callContext); assertListenerStatus(); final Payment paymentWithAttempts = paymentApi.getPayment(payment.getId(), false, true, ImmutableList.<PluginProperty>of(), callContext); Assert.assertEquals(paymentWithAttempts.getPaymentMethodId(), paymentMethodId); Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().size(), 1); Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getPaymentMethodId(), paymentMethodId); Assert.assertEquals(paymentWithAttempts.getPaymentAttempts().get(0).getStateName(), "SUCCESS"); }
private void verifyPaymentViaGetPath(final Payment payment) throws PaymentApiException { // We can't use Assert.assertEquals because the updateDate may have been updated by the Janitor final Payment refreshedPayment = paymentApi.getPayment(payment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext); Assert.assertEquals(refreshedPayment.getAccountId(), payment.getAccountId()); Assert.assertEquals(refreshedPayment.getTransactions().size(), payment.getTransactions().size()); Assert.assertEquals(refreshedPayment.getExternalKey(), payment.getExternalKey()); Assert.assertEquals(refreshedPayment.getPaymentMethodId(), payment.getPaymentMethodId()); Assert.assertEquals(refreshedPayment.getAccountId(), payment.getAccountId()); Assert.assertEquals(refreshedPayment.getAuthAmount().compareTo(payment.getAuthAmount()), 0); Assert.assertEquals(refreshedPayment.getCapturedAmount().compareTo(payment.getCapturedAmount()), 0); Assert.assertEquals(refreshedPayment.getPurchasedAmount().compareTo(payment.getPurchasedAmount()), 0); Assert.assertEquals(refreshedPayment.getRefundedAmount().compareTo(payment.getRefundedAmount()), 0); Assert.assertEquals(refreshedPayment.getCurrency(), payment.getCurrency()); for (int i = 0; i < refreshedPayment.getTransactions().size(); i++) { final PaymentTransaction refreshedPaymentTransaction = refreshedPayment.getTransactions().get(i); final PaymentTransaction paymentTransaction = payment.getTransactions().get(i); Assert.assertEquals(refreshedPaymentTransaction.getAmount().compareTo(paymentTransaction.getAmount()), 0); Assert.assertEquals(refreshedPaymentTransaction.getProcessedAmount().compareTo(paymentTransaction.getProcessedAmount()), 0); Assert.assertEquals(refreshedPaymentTransaction.getCurrency(), paymentTransaction.getCurrency()); Assert.assertEquals(refreshedPaymentTransaction.getExternalKey(), paymentTransaction.getExternalKey()); Assert.assertEquals(refreshedPaymentTransaction.getTransactionStatus(), paymentTransaction.getTransactionStatus()); } }
@Test(groups = "slow") public void testUnknownEntries() throws PaymentApiException, InvoiceApiException, EventBusException { final BigDecimal requestedAmount = BigDecimal.TEN; final String paymentExternalKey = "qwru"; final String transactionExternalKey = "lkjdsf"; testListener.pushExpectedEvent(NextEvent.PAYMENT); final Payment payment = paymentApi.createAuthorization(account, account.getPaymentMethodId(), null, requestedAmount, account.getCurrency(), null, paymentExternalKey, transactionExternalKey, ImmutableList.<PluginProperty>of(), callContext); testListener.assertListenerStatus(); // Artificially move the transaction status to UNKNOWN final String paymentStateName = paymentSMHelper.getErroredStateForTransaction(TransactionType.AUTHORIZE).toString(); testListener.pushExpectedEvent(NextEvent.PAYMENT_PLUGIN_ERROR); paymentDao.updatePaymentAndTransactionOnCompletion(account.getId(), null, payment.getId(), TransactionType.AUTHORIZE, paymentStateName, paymentStateName, payment.getTransactions().get(0).getId(), TransactionStatus.UNKNOWN, requestedAmount, account.getCurrency(), "foo", "bar", internalCallContext); testListener.assertListenerStatus(); // Move clock for notification to be processed testListener.pushExpectedEvent(NextEvent.PAYMENT); clock.addDeltaFromReality(5 * 60 * 1000); assertNotificationsCompleted(internalCallContext, 5); testListener.assertListenerStatus(); final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext); assertEquals(updatedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS); }
@Test(groups = "slow") public void testPendingEntries() throws PaymentApiException, EventBusException, NoSuchNotificationQueue { final BigDecimal requestedAmount = BigDecimal.TEN; final String paymentExternalKey = "jhj44"; final String transactionExternalKey = "4jhjj2"; testListener.pushExpectedEvent(NextEvent.PAYMENT); final Payment payment = paymentApi.createAuthorization(account, account.getPaymentMethodId(), null, requestedAmount, account.getCurrency(), null, paymentExternalKey, transactionExternalKey, ImmutableList.<PluginProperty>of(), callContext); testListener.assertListenerStatus(); // Artificially move the transaction status to PENDING final String paymentStateName = paymentSMHelper.getPendingStateForTransaction(TransactionType.AUTHORIZE).toString(); testListener.pushExpectedEvent(NextEvent.PAYMENT); paymentDao.updatePaymentAndTransactionOnCompletion(account.getId(), null, payment.getId(), TransactionType.AUTHORIZE, paymentStateName, paymentStateName, payment.getTransactions().get(0).getId(), TransactionStatus.PENDING, requestedAmount, account.getCurrency(), "loup", "chat", internalCallContext); testListener.assertListenerStatus(); // Move clock for notification to be processed ((default config is set for one hour) testListener.pushExpectedEvent(NextEvent.PAYMENT); clock.addDeltaFromReality(1000 * (3600 + 1)); assertNotificationsCompleted(internalCallContext, 5); testListener.assertListenerStatus(); final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext); Assert.assertEquals(updatedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS); }