5 Minute Java Client Tutorial

439 views
Skip to first unread message

alexwh...@gmail.com

unread,
Nov 24, 2014, 8:33:43 AM11/24/14
to killbill...@googlegroups.com
Hi,

I'm trying to believe in this project but I'm having a really tough time trying to figure out if the killbill java client works or not and if the system is for me.

Would it be possible for someone in the know to post the code to go from install to a monthly recurring payment of $20 USD by eg. creditcard / stripe. Or even a once off.

Besides my question I have other piece of feedback about the complexity of this system. It's too complex -> that was it.





Pierre-Alexandre Meyer

unread,
Nov 24, 2014, 8:42:58 AM11/24/14
to alexwh...@gmail.com, killbill...@googlegroups.com
Hello,

On Mon, Nov 24, 2014 at 8:33 AM, <alexwh...@gmail.com> wrote:
I'm trying to believe in this project but I'm having a really tough time trying to figure out if the killbill java client works or not and if the system is for me.

Regarding the Java client, it should work as it is used for most of our integration tests. You can see an example here:

 
Would it be possible for someone in the know to post the code to go from install to a monthly recurring payment of $20 USD by eg. creditcard / stripe. Or even a once off.

We recently posted a tutorial here which should cover both use cases (recurring and one-off): http://killbill.io/tutorial/

Let us know if it helps.

Besides my question I have other piece of feedback about the complexity of this system. It's too complex -> that was it.

Could you be a bit more specific? What are you trying to do? Do you have a hard time getting started? Or are the APIs too complex?

Hang in there! I'm sure we can unblock you.

Cheers,

--
Pierre

alexwh...@gmail.com

unread,
Nov 24, 2014, 4:18:57 PM11/24/14
to killbill...@googlegroups.com, alexwh...@gmail.com
Pierre, thanks for the response.
Here is a snippet of code I've been using to explore the API: http://pastie.org/9741145. I can't figure out why my create payment method is failing.

and here are some of my other issues with the API:
-Executing the commented bits of code in serial will cause a failure. Executing them one at a time seems to work a bit better...but why??
-the rpc style api is unusual. There seems to be no unambiguous feedback given whether a network operation has succeeded or failed. I'm working off the assumption that a null response is bad. This is potentially not the greatest because if your code throws a KillBillClientException in response to one of my calls, my (==null) check may never take place, which means I kind of need to wrap the killbill api in my own callKillBill (throws KBException) api.
-I've omitted the client.close(); and httpClient.close(); from after the end of the catch block in my example. Why? Because nothing seems to close the connection.
-killbill logging is extremely noisy which makes it harder to find bugs in the underlying project.



Pierre-Alexandre Meyer

unread,
Nov 25, 2014, 7:41:50 AM11/25/14
to alexwh...@gmail.com, killbill...@googlegroups.com
On Mon, Nov 24, 2014 at 4:18 PM, <alexwh...@gmail.com> wrote:
Here is a snippet of code I've been using to explore the API: http://pastie.org/9741145.

Thanks, that helps.

To get started, I suggest looking at the examples in our tests (https://github.com/killbill/killbill/tree/master/profiles/killbill/src/test/java/org/killbill/billing/jaxrs), which should give you some sample code. Also, the source class (https://github.com/killbill/killbill-client-java/blob/master/src/main/java/org/killbill/billing/client/KillBillClient.java) documents the required fields in the body.
 
I can't figure out why my create payment method is failing.

The issue is that the `isDefault' attribute isn't set, causing an NPE. We should probably have a default for it, I've opened https://github.com/killbill/killbill-client-java/issues/10 for tracking.

Adding `paymentMethod.setIsDefault(true);' solves it.

and here are some of my other issues with the API:
-Executing the commented bits of code in serial will cause a failure. Executing them one at a time seems to work a bit better...but why??

I'm not sure what is happening but here is a thought: the tenant and account creation will only work once because the external key is hardcoded. externalKey should be unique for any object, as it represents the id in an external system (in the case of accounts for example, it could represent the user_id in your web application).

When running such scripts, I usually set the external keys to UUID.randomUUID().toString(), so there is no duplication.


Regarding the createPayment call, there is a typo. The account id is set via `account.getAccountId()' but it should be `z.getAccountId()' (the re-hydrated object, the former yields null).


The creation of the payment is not correct. You need to specify the type of payment (PURCHASE, AUTHORIZATION, etc.) as well as the currency (when specifying an amount, we always require the currency, to avoid any ambiguity):

paymentTransaction.setTransactionType("PURCHASE");
paymentTransaction.setCurrency("USD");


Finally, the invoice creation call won't work. client.createInvoice will trigger a target invoice, i.e. generate an invoice according to subscriptions on the account at a future date. This will be a no-op as the account doesn't have any subscriptions (also, the first argument should be the account id, not the invoice id).

If I understand the code correctly, you'd like to create an invoice with some items (outside of subscriptions, i.e. what we call "external charges") and trigger a payment. This is how it looks like:

            final BigDecimal chargeAmount = BigDecimal.TEN;
            final InvoiceItem externalCharge = new InvoiceItem();
            externalCharge.setAccountId(z.getAccountId());
            externalCharge.setAmount(chargeAmount);
            externalCharge.setCurrency(Currency.valueOf(z.getCurrency()));
            externalCharge.setDescription(UUID.randomUUID().toString());
            // Note: auto-pay is true, no need to trigger a payment manually
            final InvoiceItem createdExternalCharge = client.createExternalCharge(externalCharge, new DateTime(System.currentTimeMillis()), true, "admin", "reason", "comment");
            final Invoice invoiceWithItems = client.getInvoice(createdExternalCharge.getInvoiceId(), true);


-the rpc style api is unusual. There seems to be no unambiguous feedback given whether a network operation has succeeded or failed. I'm working off the assumption that a null response is bad. This is potentially not the greatest because if your code throws a KillBillClientException in response to one of my calls, my (==null) check may never take place, which means I kind of need to wrap the killbill api in my own callKillBill (throws KBException) api.

Can you give us an example of ambiguous feedback?

If the server returns an error (400, 401, 409, 500, etc.), the code will throw KillBillClientException. If there is no response (204) or an object cannot be found (404), the code will return null (for single objects) or an empty list (for collections of objects). Otherwise, you should never get null.
 
-I've omitted the client.close(); and httpClient.close(); from after the end of the catch block in my example. Why? Because nothing seems to close the connection.

Why do think that? `close()' will close the underlying http client. This will shutdown the underlying Netty connections pool, open channels and executors.
 
-killbill logging is extremely noisy which makes it harder to find bugs in the underlying project.

With the default logback configuration file, when running your example, only the requests/responses were logged. Can you give us some log lines examples that are too chatty?

Hope that helps!

--
Pierre

alexwh...@gmail.com

unread,
Nov 25, 2014, 8:20:56 AM11/25/14
to killbill...@googlegroups.com, alexwh...@gmail.com
That is an excellent response, thank you. I'm going to go through it in detail and post back if I have other questions.
Reply all
Reply to author
Forward
0 new messages