killbill / killbill-adyen-plugin

Kill Bill plugin for Adyen
https://killbill.io
Apache License 2.0
10 stars 31 forks source link

Check for technical exclusive-or business error needs reworking #25

Closed BLangendorf closed 8 years ago

BLangendorf commented 9 years ago

The xor check in AdyenPaymentTransactionInfoPlugin.java#L123

checkArgument(adyenCallErrorStatus.isPresent() ^ pspResult.isPresent());

… will always fail for the call at AdyenPaymentTransactionInfoPlugin.java#L95-L98

getPaymentPluginStatus(Optional.of(AdyenCallErrorStatus.UNKNOWN_FAILURE),
                       Optional.of(PaymentServiceProviderResult.getPaymentResultForId(record.getPspResult())))

… because Optional.of(...) never returns .absent() but rather throws a NullPointerException when called with null: Optional.java#L83-L88.

pierre commented 9 years ago

Note that AdyenPaymentTransactionInfoPlugin.java#L95-L98 breaks getPaymentInfo, as the PaymentTransactionInfoPlugin returned won't match the one returned by the payment API call.

The underlying problem is that we are not storing the information about the technical error, so we cannot re-build it.

Looking at how Ruby plugins do it, they actually store the exception and the computed plugin status in the response row, which is then re-used in the get path for both the status and the error message (associated unit tests and integration tests). We probably need to do something similar here (maybe we can re-use the generic additional_data column, which is already assumed to contain JSON?).

MariaDB [killbill]> select distinct message from cybersource_responses;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| message                                                                                                                                                             |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {"exception_class":"ActiveMerchant::ResponseError","exception_message":"Failed with 302 Found","payment_plugin_status":"UNDEFINED"}                                 |
| {"exception_class":"ActiveMerchant::ResponseError","exception_message":"Failed with 404 Not Found ","payment_plugin_status":"UNDEFINED"}                            |
| {"exception_class":"ActiveMerchant::ResponseError","exception_message":"Failed with 500 Internal Server Error","payment_plugin_status":"UNDEFINED"}                 |
| {"exception_class":"ActiveMerchant::RetriableConnectionError","exception_message":"The remote server refused the connection","payment_plugin_status":"UNDEFINED"}   |
| {"exception_class":"EOFError","exception_message":"End of file reached","payment_plugin_status":"UNDEFINED"}                                                        |
| {"exception_class":"Errno::ECONNREFUSED","exception_message":"Connection refused - Connection refused","payment_plugin_status":"CANCELED"}                          |
| {"exception_class":"Errno::ECONNRESET","exception_message":"Connection reset by peer - Connection reset by peer","payment_plugin_status":"UNDEFINED"}               |
| {"exception_class":"Errno::EPIPE","exception_message":"Broken pipe - Broken pipe","payment_plugin_status":"UNDEFINED"}                                              |
| {"exception_class":"IOError","exception_message":"Unsupported record version Unknown-79.84","payment_plugin_status":"UNDEFINED"}                                    |
| {"exception_class":"IOError","exception_message":"Unsupported record version Unknown-84.84","payment_plugin_status":"UNDEFINED"}                                    |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"Broken pipe","payment_plugin_status":"CANCELED"}                                                   |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"Connection reset by peer","payment_plugin_status":"CANCELED"}                                      |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"Socket closed","payment_plugin_status":"CANCELED"}                                                 |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"Unrecognized SSL message, plaintext connection?","payment_plugin_status":"CANCELED"}               |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"Unsupported record version Unknown-84.84","payment_plugin_status":"CANCELED"}                      |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"hostname does not match the server certificate","payment_plugin_status":"CANCELED"}                |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"signed overrun, bytes = 108","payment_plugin_status":"CANCELED"}                                   |
| {"exception_class":"OpenSSL::SSL::SSLError","exception_message":"writer side was already closed.","payment_plugin_status":"CANCELED"}                               |
| {"exception_class":"SocketError","exception_message":"initialize: name or service not known","payment_plugin_status":"CANCELED"}                                    |
| {"exception_class":"Timeout::Error","exception_message":"Timeout::Error","payment_plugin_status":"UNDEFINED"}                                                       |
| {"exception_class":"Timeout::Error","exception_message":"execution expired","payment_plugin_status":"UNDEFINED"}                                                    |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Related issue: https://github.com/killbill/killbill-adyen-plugin/issues/22.