Example #1
0
  @Test(groups = "slow")
  public void testUnknownEntriesWithExceptions() throws PaymentApiException, EventBusException {

    final BigDecimal requestedAmount = BigDecimal.TEN;
    final String paymentExternalKey = "minus";
    final String transactionExternalKey = "plus";

    // Make sure the state as seen by the plugin will be in PaymentPluginStatus.ERROR, which will be
    // returned later to Janitor
    mockPaymentProviderPlugin.makeNextPaymentFailWithException();
    try {
      paymentApi.createAuthorization(
          account,
          account.getPaymentMethodId(),
          null,
          requestedAmount,
          account.getCurrency(),
          paymentExternalKey,
          transactionExternalKey,
          ImmutableList.<PluginProperty>of(),
          callContext);
    } catch (PaymentApiException ignore) {
    }
    final Payment payment =
        paymentApi.getPaymentByExternalKey(
            paymentExternalKey, false, ImmutableList.<PluginProperty>of(), callContext);

    // Artificially move the transaction status to UNKNOWN
    final String paymentStateName =
        paymentSMHelper.getErroredStateForTransaction(TransactionType.AUTHORIZE).toString();
    paymentDao.updatePaymentAndTransactionOnCompletion(
        account.getId(),
        payment.getId(),
        TransactionType.AUTHORIZE,
        paymentStateName,
        paymentStateName,
        payment.getTransactions().get(0).getId(),
        TransactionStatus.UNKNOWN,
        requestedAmount,
        account.getCurrency(),
        "foo",
        "bar",
        internalCallContext);

    final List<PaymentTransactionModelDao> paymentTransactionHistoryBeforeJanitor =
        getPaymentTransactionHistory(transactionExternalKey);
    Assert.assertEquals(paymentTransactionHistoryBeforeJanitor.size(), 3);

    clock.addDays(1);
    try {
      Thread.sleep(1500);
    } catch (InterruptedException e) {
    }

    // Nothing new happened
    final List<PaymentTransactionModelDao> paymentTransactionHistoryAfterJanitor =
        getPaymentTransactionHistory(transactionExternalKey);
    Assert.assertEquals(paymentTransactionHistoryAfterJanitor.size(), 3);
  }
  @Test(groups = "slow")
  public void testFailedPaymentWithPerTenantRetryConfig() throws Exception {
    // Create the tenant
    final String apiKeyTenant1 = "tenantSuperTuned";
    final String apiSecretTenant1 = "2367$$ffr79";
    loginTenant(apiKeyTenant1, apiSecretTenant1);
    final Tenant tenant1 = new Tenant();
    tenant1.setApiKey(apiKeyTenant1);
    tenant1.setApiSecret(apiSecretTenant1);
    killBillClient.createTenant(tenant1, createdBy, reason, comment);

    // Configure our plugin to fail
    mockPaymentProviderPlugin.makeAllInvoicesFailWithError(true);

    // Upload the config
    final ObjectMapper mapper = new ObjectMapper();
    final HashMap<String, String> perTenantProperties = new HashMap<String, String>();
    perTenantProperties.put("org.killbill.payment.retry.days", "1,1,1");
    final String perTenantConfig = mapper.writeValueAsString(perTenantProperties);

    final TenantKey tenantKey =
        killBillClient.postConfigurationPropertiesForTenant(perTenantConfig, basicRequestOptions());

    final Account accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();

    final Payments payments = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments.size(), 1);
    Assert.assertEquals(payments.get(0).getTransactions().size(), 1);

    //
    // Because we have specified a retry interval of one day we should see the new attempt after
    // moving clock 1 day (and not 8 days which is default)
    //

    //
    // Now unregister special per tenant config and we the first retry occurs one day after (and
    // still fails), it now sets a retry date of 8 days
    //
    killBillClient.unregisterConfigurationForTenant(basicRequestOptions());
    // org.killbill.tenant.broadcast.rate has been set to 1s
    crappyWaitForLackOfProperSynchonization(2000);

    clock.addDays(1);

    Awaitility.await()
        .atMost(4, TimeUnit.SECONDS)
        .pollInterval(Duration.ONE_SECOND)
        .until(
            new Callable<Boolean>() {
              @Override
              public Boolean call() throws Exception {

                return killBillClient
                        .getPaymentsForAccount(accountJson.getAccountId())
                        .get(0)
                        .getTransactions()
                        .size()
                    == 2;
              }
            });
    final Payments payments2 = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments2.size(), 1);
    Assert.assertEquals(payments2.get(0).getTransactions().size(), 2);
    Assert.assertEquals(
        payments2.get(0).getTransactions().get(0).getStatus(),
        TransactionStatus.PAYMENT_FAILURE.name());
    Assert.assertEquals(
        payments2.get(0).getTransactions().get(1).getStatus(),
        TransactionStatus.PAYMENT_FAILURE.name());

    clock.addDays(1);
    crappyWaitForLackOfProperSynchonization(3000);

    // No retry with default config
    final Payments payments3 = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments3.size(), 1);
    Assert.assertEquals(payments3.get(0).getTransactions().size(), 2);

    mockPaymentProviderPlugin.makeAllInvoicesFailWithError(false);
    clock.addDays(7);

    Awaitility.await()
        .atMost(4, TimeUnit.SECONDS)
        .pollInterval(Duration.ONE_SECOND)
        .until(
            new Callable<Boolean>() {
              @Override
              public Boolean call() throws Exception {
                return killBillClient
                        .getPaymentsForAccount(accountJson.getAccountId())
                        .get(0)
                        .getTransactions()
                        .size()
                    == 3;
              }
            });
    final Payments payments4 = killBillClient.getPaymentsForAccount(accountJson.getAccountId());
    Assert.assertEquals(payments4.size(), 1);
    Assert.assertEquals(payments4.get(0).getTransactions().size(), 3);
    Assert.assertEquals(
        payments4.get(0).getTransactions().get(0).getStatus(),
        TransactionStatus.PAYMENT_FAILURE.name());
    Assert.assertEquals(
        payments4.get(0).getTransactions().get(1).getStatus(),
        TransactionStatus.PAYMENT_FAILURE.name());
    Assert.assertEquals(
        payments4.get(0).getTransactions().get(2).getStatus(), TransactionStatus.SUCCESS.name());
  }
 @AfterMethod(groups = "slow")
 public void tearDown() throws Exception {
   mockPaymentProviderPlugin.clear();
 }
Example #4
0
 @BeforeMethod(groups = "slow")
 public void beforeMethod() throws Exception {
   super.beforeMethod();
   mockPaymentProviderPlugin.clear();
   account = testHelper.createTestAccount("*****@*****.**", true);
 }