{"action":"created","comment":{"url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/comments/41008646","id":41008646,"diff_hunk":"@@ -29,49 +35,156 @@\n import org.killbill.adyen.payment.PaymentResult;\n import org.killbill.adyen.payment.ServiceException;\n import org.killbill.billing.plugin.adyen.client.PaymentPortRegistry;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+import com.ctc.wstx.exc.WstxEOFException;\n+import com.google.common.base.Throwables;\n+\n+import static org.killbill.billing.plugin.adyen.client.payment.service.AdyenCallErrorStatus.REQUEST_NOT_SEND;\n+import static org.killbill.billing.plugin.adyen.client.payment.service.AdyenCallErrorStatus.RESPONSE_ABOUT_INVALID_REQUEST;\n+import static org.killbill.billing.plugin.adyen.client.payment.service.AdyenCallErrorStatus.RESPONSE_INVALID;\n+import static org.killbill.billing.plugin.adyen.client.payment.service.AdyenCallErrorStatus.RESPONSE_NOT_RECEIVED;\n+import static org.killbill.billing.plugin.adyen.client.payment.service.AdyenCallErrorStatus.UNKNOWN_FAILURE;\n \n public class AdyenPaymentRequestSender implements Closeable {\n \n+    private static final Logger logger = LoggerFactory.getLogger(\"adyen.sender\");\n+    private static final int SERVICE_UNAVAILABLE = 503;\n+\n     private final PaymentPortRegistry adyenPaymentPortRegistry;\n \n     public AdyenPaymentRequestSender(final PaymentPortRegistry adyenPaymentPortRegistry) {\n         this.adyenPaymentPortRegistry = adyenPaymentPortRegistry;\n     }\n \n-    public DirectDebitResponse directdebit(final String countryIsoCode, final DirectDebitRequest request) throws ServiceException {\n-        return adyenPaymentPortRegistry.getPaymentPort(countryIsoCode).directdebit(request);\n+    @SuppressWarnings(\"unused\")\n+    public AdyenCallResult<DirectDebitResponse> directdebit(final String countryIsoCode, final DirectDebitRequest request) {\n+        return callAdyen(countryIsoCode, new AdyenCall<PaymentPortType, DirectDebitResponse>() {\n+            @Override\n+            public DirectDebitResponse apply(final PaymentPortType paymentPort) throws ServiceException {\n+                return paymentPort.directdebit(request);\n+            }\n+        });\n+    }\n+\n+    public AdyenCallResult<PaymentResult> authorise(final String countryIsoCode, final PaymentRequest request) {\n+        return callAdyen(countryIsoCode, new AdyenCall<PaymentPortType, PaymentResult>() {\n+            @Override\n+            public PaymentResult apply(final PaymentPortType paymentPort) throws ServiceException {\n+                return paymentPort.authorise(request);\n+            }\n+        });\n     }\n \n-    public PaymentResult authorise(final String countryIsoCode, final PaymentRequest request) throws ServiceException {\n-        return adyenPaymentPortRegistry.getPaymentPort(countryIsoCode).authorise(request);\n+    public AdyenCallResult<PaymentResult> authorise3D(final String countryIsoCode, final PaymentRequest3D request) {\n+        return callAdyen(countryIsoCode, new AdyenCall<PaymentPortType, PaymentResult>() {\n+            @Override\n+            public PaymentResult apply(final PaymentPortType paymentPort) throws ServiceException {\n+                return paymentPort.authorise3D(request);\n+            }\n+        });\n     }\n \n-    public PaymentResult authorise3D(final String countryIsoCode, final PaymentRequest3D request) throws ServiceException {\n-        return adyenPaymentPortRegistry.getPaymentPort(countryIsoCode).authorise3D(request);\n+    public AdyenCallResult<ModificationResult> refund(final String countryIsoCode, final ModificationRequest modificationRequest) {\n+        return callAdyen(countryIsoCode, new AdyenCall<PaymentPortType, ModificationResult>() {\n+            @Override\n+            public ModificationResult apply(final PaymentPortType paymentPort) throws ServiceException {\n+                return paymentPort.refund(modificationRequest);\n+            }\n+        });\n     }\n \n-    public ModificationResult refund(final String countryIsoCode, final ModificationRequest modificationRequest) throws ServiceException {\n-        final PaymentPortType paymentPort = adyenPaymentPortRegistry.getPaymentPort(countryIsoCode);\n-        return paymentPort.refund(modificationRequest);\n+    public AdyenCallResult<ModificationResult> cancel(final String countryIsoCode, final ModificationRequest modificationRequest) {\n+        return callAdyen(countryIsoCode, new AdyenCall<PaymentPortType, ModificationResult>() {\n+            @Override\n+            public ModificationResult apply(final PaymentPortType paymentPort) throws ServiceException {\n+                return paymentPort.cancel(modificationRequest);\n+            }\n+        });\n     }\n \n-    public ModificationResult cancel(final String countryIsoCode, final ModificationRequest modificationRequest) throws ServiceException {\n-        final PaymentPortType paymentPort = adyenPaymentPortRegistry.getPaymentPort(countryIsoCode);\n-        return paymentPort.cancel(modificationRequest);\n+    public AdyenCallResult<ModificationResult> cancelOrRefund(final String countryIsoCode, final ModificationRequest modificationRequest) {\n+        return callAdyen(countryIsoCode, new AdyenCall<PaymentPortType, ModificationResult>() {\n+            @Override\n+            public ModificationResult apply(final PaymentPortType paymentPort) throws ServiceException {\n+                return paymentPort.cancelOrRefund(modificationRequest);\n+            }\n+        });\n     }\n \n-    public ModificationResult cancelOrRefund(final String countryIsoCode, final ModificationRequest modificationRequest) throws ServiceException {\n-        final PaymentPortType paymentPort = adyenPaymentPortRegistry.getPaymentPort(countryIsoCode);\n-        return paymentPort.cancelOrRefund(modificationRequest);\n+    public AdyenCallResult<ModificationResult> capture(final String countryIsoCode, final ModificationRequest modificationRequest) {\n+        return callAdyen(countryIsoCode, new AdyenCall<PaymentPortType, ModificationResult>() {\n+            @Override\n+            public ModificationResult apply(final PaymentPortType paymentPort) throws ServiceException {\n+                return paymentPort.capture(modificationRequest);\n+            }\n+        });\n     }\n \n-    public ModificationResult capture(final String countryIsoCode, final ModificationRequest modificationRequest) throws ServiceException {\n-        final PaymentPortType paymentPort = adyenPaymentPortRegistry.getPaymentPort(countryIsoCode);\n-        return paymentPort.capture(modificationRequest);\n+    private <T> AdyenCallResult<T> callAdyen(final String countryIsoCode, final AdyenCall<PaymentPortType, T> adyenCall) {\n+        try {\n+            final PaymentPortType paymentPort = adyenPaymentPortRegistry.getPaymentPort(countryIsoCode);\n+            final T result = adyenCall.apply(paymentPort);\n+            return new SuccessfulAdyenCall<T>(result);\n+        } catch (final Exception e) {\n+            logger.info(\"exception during adyen request\", e);\n+            return mapExceptionToCallResult(e);\n+        }\n+    }\n+\n+    /**\n+     * Educated guess approach to transform CXF exceptions into error status codes.\n+     * In the future if we encounter further different cases it makes sense to change this if/else structure to a map with lookup.\n+     */\n+    private <T> AdyenCallResult<T> mapExceptionToCallResult(final Exception e) {\n+        //noinspection ThrowableResultOfMethodCallIgnored\n+        final Throwable rootCause = Throwables.getRootCause(e);\n+        if (rootCause instanceof SocketTimeoutException) {\n+            // read timeout\n+            if (rootCause.getMessage().contains(\"Read timed out\")) {\n+                return new UnSuccessfulAdyenCall<T>(RESPONSE_NOT_RECEIVED, e.getMessage());\n+            } else if (rootCause.getMessage().contains(\"Unexpected end of file from server\")) {\n+                return new UnSuccessfulAdyenCall<T>(RESPONSE_INVALID, rootCause.getMessage());\n+            }\n+        } else if (rootCause instanceof SocketException) {\n+            if (rootCause.getMessage().contains(\"Unexpected end of file from server\")) {\n+                return new UnSuccessfulAdyenCall<T>(RESPONSE_INVALID, e.getMessage());\n+            }\n+        } else if (rootCause instanceof HTTPException) {\n+            // connection timeout\n+            if (((HTTPException) rootCause).getResponseCode() == SERVICE_UNAVAILABLE) {\n+                return new UnSuccessfulAdyenCall<T>(REQUEST_NOT_SEND, rootCause.getMessage());","path":"src/main/java/org/killbill/billing/plugin/adyen/client/payment/service/AdyenPaymentRequestSender.java","position":null,"original_position":155,"commit_id":"9cb2a0cb41b44ff52f902012921eef7febe04335","original_commit_id":"9537b041798a7aee71d4757b9c3906b19d2ad4b4","user":{"login":"arnelandwehr","id":2463887,"avatar_url":"https://avatars.githubusercontent.com/u/2463887?v=3","gravatar_id":"","url":"https://api.github.com/users/arnelandwehr","html_url":"https://github.com/arnelandwehr","followers_url":"https://api.github.com/users/arnelandwehr/followers","following_url":"https://api.github.com/users/arnelandwehr/following{/other_user}","gists_url":"https://api.github.com/users/arnelandwehr/gists{/gist_id}","starred_url":"https://api.github.com/users/arnelandwehr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arnelandwehr/subscriptions","organizations_url":"https://api.github.com/users/arnelandwehr/orgs","repos_url":"https://api.github.com/users/arnelandwehr/repos","events_url":"https://api.github.com/users/arnelandwehr/events{/privacy}","received_events_url":"https://api.github.com/users/arnelandwehr/received_events","type":"User","site_admin":false},"body":"fixed that","created_at":"2015-10-02T10:29:44Z","updated_at":"2015-10-02T10:29:44Z","html_url":"https://github.com/killbill/killbill-adyen-plugin/pull/12#discussion_r41008646","pull_request_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12","_links":{"self":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/comments/41008646"},"html":{"href":"https://github.com/killbill/killbill-adyen-plugin/pull/12#discussion_r41008646"},"pull_request":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12"}}},"pull_request":{"url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12","id":46548547,"html_url":"https://github.com/killbill/killbill-adyen-plugin/pull/12","diff_url":"https://github.com/killbill/killbill-adyen-plugin/pull/12.diff","patch_url":"https://github.com/killbill/killbill-adyen-plugin/pull/12.patch","issue_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/issues/12","number":12,"state":"open","locked":false,"title":"Handle communication errors nicely","user":{"login":"arnelandwehr","id":2463887,"avatar_url":"https://avatars.githubusercontent.com/u/2463887?v=3","gravatar_id":"","url":"https://api.github.com/users/arnelandwehr","html_url":"https://github.com/arnelandwehr","followers_url":"https://api.github.com/users/arnelandwehr/followers","following_url":"https://api.github.com/users/arnelandwehr/following{/other_user}","gists_url":"https://api.github.com/users/arnelandwehr/gists{/gist_id}","starred_url":"https://api.github.com/users/arnelandwehr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arnelandwehr/subscriptions","organizations_url":"https://api.github.com/users/arnelandwehr/orgs","repos_url":"https://api.github.com/users/arnelandwehr/repos","events_url":"https://api.github.com/users/arnelandwehr/events{/privacy}","received_events_url":"https://api.github.com/users/arnelandwehr/received_events","type":"User","site_admin":false},"body":"2end attempt. Sry for the confusion/struggle with the first one. The code style import didn't worked and i didn't realized it (not my day, missing sleep :( ). \r\n\r\nThe PR is still big but most of the changes are due to additional tests and changed signatures (it was really hard to find a common way how to pass the information through all layers).\r\n\r\nAlso split it up into 2 commits. The second one only contains removal of warnings.","created_at":"2015-10-01T16:50:38Z","updated_at":"2015-10-02T10:29:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d687df3c7a20d6d4930f967f90ea56a0724c7892","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12/commits","review_comments_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12/comments","review_comment_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/issues/12/comments","statuses_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/statuses/9cb2a0cb41b44ff52f902012921eef7febe04335","head":{"label":"arnelandwehr:gps_6025_handle_http_errors","ref":"gps_6025_handle_http_errors","sha":"9cb2a0cb41b44ff52f902012921eef7febe04335","user":{"login":"arnelandwehr","id":2463887,"avatar_url":"https://avatars.githubusercontent.com/u/2463887?v=3","gravatar_id":"","url":"https://api.github.com/users/arnelandwehr","html_url":"https://github.com/arnelandwehr","followers_url":"https://api.github.com/users/arnelandwehr/followers","following_url":"https://api.github.com/users/arnelandwehr/following{/other_user}","gists_url":"https://api.github.com/users/arnelandwehr/gists{/gist_id}","starred_url":"https://api.github.com/users/arnelandwehr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arnelandwehr/subscriptions","organizations_url":"https://api.github.com/users/arnelandwehr/orgs","repos_url":"https://api.github.com/users/arnelandwehr/repos","events_url":"https://api.github.com/users/arnelandwehr/events{/privacy}","received_events_url":"https://api.github.com/users/arnelandwehr/received_events","type":"User","site_admin":false},"repo":{"id":43144042,"name":"killbill-adyen-plugin","full_name":"arnelandwehr/killbill-adyen-plugin","owner":{"login":"arnelandwehr","id":2463887,"avatar_url":"https://avatars.githubusercontent.com/u/2463887?v=3","gravatar_id":"","url":"https://api.github.com/users/arnelandwehr","html_url":"https://github.com/arnelandwehr","followers_url":"https://api.github.com/users/arnelandwehr/followers","following_url":"https://api.github.com/users/arnelandwehr/following{/other_user}","gists_url":"https://api.github.com/users/arnelandwehr/gists{/gist_id}","starred_url":"https://api.github.com/users/arnelandwehr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arnelandwehr/subscriptions","organizations_url":"https://api.github.com/users/arnelandwehr/orgs","repos_url":"https://api.github.com/users/arnelandwehr/repos","events_url":"https://api.github.com/users/arnelandwehr/events{/privacy}","received_events_url":"https://api.github.com/users/arnelandwehr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/arnelandwehr/killbill-adyen-plugin","description":"Kill Bill Payment plugin to connect to Adyen","fork":true,"url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin","forks_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/forks","keys_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/teams","hooks_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/hooks","issue_events_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/issues/events{/number}","events_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/events","assignees_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/assignees{/user}","branches_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/branches{/branch}","tags_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/tags","blobs_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/statuses/{sha}","languages_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/languages","stargazers_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/stargazers","contributors_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/contributors","subscribers_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/subscribers","subscription_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/subscription","commits_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/contents/{+path}","compare_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/merges","archive_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/downloads","issues_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/issues{/number}","pulls_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/pulls{/number}","milestones_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/milestones{/number}","notifications_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/labels{/name}","releases_url":"https://api.github.com/repos/arnelandwehr/killbill-adyen-plugin/releases{/id}","created_at":"2015-09-25T13:29:55Z","updated_at":"2015-09-25T13:29:56Z","pushed_at":"2015-10-02T10:28:32Z","git_url":"git://github.com/arnelandwehr/killbill-adyen-plugin.git","ssh_url":"git@github.com:arnelandwehr/killbill-adyen-plugin.git","clone_url":"https://github.com/arnelandwehr/killbill-adyen-plugin.git","svn_url":"https://github.com/arnelandwehr/killbill-adyen-plugin","homepage":"http://killbill.io","size":330,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"killbill:master","ref":"master","sha":"af907022a5ddf74d77fe1766251edb5e91717322","user":{"login":"killbill","id":2446739,"avatar_url":"https://avatars.githubusercontent.com/u/2446739?v=3","gravatar_id":"","url":"https://api.github.com/users/killbill","html_url":"https://github.com/killbill","followers_url":"https://api.github.com/users/killbill/followers","following_url":"https://api.github.com/users/killbill/following{/other_user}","gists_url":"https://api.github.com/users/killbill/gists{/gist_id}","starred_url":"https://api.github.com/users/killbill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/killbill/subscriptions","organizations_url":"https://api.github.com/users/killbill/orgs","repos_url":"https://api.github.com/users/killbill/repos","events_url":"https://api.github.com/users/killbill/events{/privacy}","received_events_url":"https://api.github.com/users/killbill/received_events","type":"Organization","site_admin":false},"repo":{"id":26882862,"name":"killbill-adyen-plugin","full_name":"killbill/killbill-adyen-plugin","owner":{"login":"killbill","id":2446739,"avatar_url":"https://avatars.githubusercontent.com/u/2446739?v=3","gravatar_id":"","url":"https://api.github.com/users/killbill","html_url":"https://github.com/killbill","followers_url":"https://api.github.com/users/killbill/followers","following_url":"https://api.github.com/users/killbill/following{/other_user}","gists_url":"https://api.github.com/users/killbill/gists{/gist_id}","starred_url":"https://api.github.com/users/killbill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/killbill/subscriptions","organizations_url":"https://api.github.com/users/killbill/orgs","repos_url":"https://api.github.com/users/killbill/repos","events_url":"https://api.github.com/users/killbill/events{/privacy}","received_events_url":"https://api.github.com/users/killbill/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/killbill/killbill-adyen-plugin","description":"Kill Bill Payment plugin to connect to Adyen","fork":false,"url":"https://api.github.com/repos/killbill/killbill-adyen-plugin","forks_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/forks","keys_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/teams","hooks_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/hooks","issue_events_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/issues/events{/number}","events_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/events","assignees_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/assignees{/user}","branches_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/branches{/branch}","tags_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/tags","blobs_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/statuses/{sha}","languages_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/languages","stargazers_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/stargazers","contributors_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/contributors","subscribers_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/subscribers","subscription_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/subscription","commits_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/contents/{+path}","compare_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/merges","archive_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/downloads","issues_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/issues{/number}","pulls_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls{/number}","milestones_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/milestones{/number}","notifications_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/labels{/name}","releases_url":"https://api.github.com/repos/killbill/killbill-adyen-plugin/releases{/id}","created_at":"2014-11-19T21:38:26Z","updated_at":"2015-05-06T17:29:30Z","pushed_at":"2015-10-02T10:28:33Z","git_url":"git://github.com/killbill/killbill-adyen-plugin.git","ssh_url":"git@github.com:killbill/killbill-adyen-plugin.git","clone_url":"https://github.com/killbill/killbill-adyen-plugin.git","svn_url":"https://github.com/killbill/killbill-adyen-plugin","homepage":"http://killbill.io","size":586,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":6,"forks":4,"open_issues":6,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12"},"html":{"href":"https://github.com/killbill/killbill-adyen-plugin/pull/12"},"issue":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/issues/12"},"comments":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/issues/12/comments"},"review_comments":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12/comments"},"review_comment":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/pulls/12/commits"},"statuses":{"href":"https://api.github.com/repos/killbill/killbill-adyen-plugin/statuses/9cb2a0cb41b44ff52f902012921eef7febe04335"}}}}