You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2007/07/02 10:32:15 UTC

svn commit: r552432 - in /ofbiz/trunk/applications/accounting: servicedef/services_paymentmethod.xml src/org/ofbiz/accounting/payment/PaymentGatewayServices.java

Author: jacopoc
Date: Mon Jul  2 01:32:14 2007
New Revision: 552432

URL: http://svn.apache.org/viewvc?view=rev&rev=552432
Log:
Added new service to test a decline response for a cc capture request.
Fixed bu that was preventing the declined response for a capture request to be stored in the PaymentGatewayResponse entity.
Misc cleanups and improvements to the descriptions of the test cc processor services.

Modified:
    ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
    ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java

Modified: ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml?view=diff&rev=552432&r1=552431&r2=552432
==============================================================================
--- ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml (original)
+++ ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml Mon Jul  2 01:32:14 2007
@@ -535,82 +535,86 @@
     </service>
 
     <!-- Test Implementations -->
+    <!-- Test Credit Card (CC) Requests -->
     <service name="testCCProcessor" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: declines auth requests for all orders < 100.00; approves auth requests for all orders >= 100.00</description>
         <implements service="ccAuthInterface"/>
     </service>
-     <service name="testCCProcessorWithCapture" engine="java"
+    <service name="testCCProcessorWithCapture" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testProcessorWithCapture">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: declines auth requests for all orders < 100.00; approves auth requests for all orders >= 100.00</description>
         <implements service="ccAuthInterface"/>
     </service>
     <service name="testRandomAuthorize" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testRandomAuthorize">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: does random auth declines</description>
         <implements service="ccAuthInterface"/>
     </service>
-
     <service name="alwaysApproveCCProcessor" engine="java"
              location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysApproveProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: always approve the auth request</description>
         <implements service="ccAuthInterface"/>
     </service>
     <service name="alwaysApproveWithCaptureCCProcessor" engine="java"
              location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysApproveWithCapture">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: always approve with capture auth request</description>
         <implements service="ccAuthInterface"/>
     </service>
-
     <service name="alwaysDeclineCCProcessor" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysDeclineProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: always decline the auth request</description>
         <implements service="ccAuthInterface"/>
     </service>
     <service name="alwaysNsfCCProcessor" engine="java"
         location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysNsfProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: always decline for NSF (not sufficient funds) auth request</description>
         <implements service="ccAuthInterface"/>
     </service>
     <service name="alwaysBadExpireCCProcessor" engine="java"
         location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysBadExpireProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: always fail/bad expire date processor</description>
         <implements service="ccAuthInterface"/>
     </service>
     <service name="badExpireEvenCCProcessor" engine="java"
         location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="badExpireEvenProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: fail/bad expire date when year is even processor</description>
         <implements service="ccAuthInterface"/>
     </service>
     <service name="alwaysBadCardNumberCCProcessor" engine="java"
         location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysBadCardNumberProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: always decline the auth request for bad card number</description>
         <implements service="ccAuthInterface"/>
     </service>
     <service name="alwaysFailCCProcessor" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysFailProcessor">
-        <description>Credit Card Processing</description>
+        <description>Test Credit Card Auth Processing: always fail (error) the auth transaction request</description>
         <implements service="ccAuthInterface"/>
     </service>
 
     <service name="testCCCapture" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testCapture">
-        <description>Credit Card Test Capture</description>
+        <description>Test Credit Card Capture Processing: always approve the capture request</description>
         <implements service="ccCaptureInterface"/>
     </service>
     <service name="testCCCaptureWithReAuth" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testCaptureWithReAuth">
-        <description>Credit Card Test Capture</description>
+        <description>Test Credit Card Capture Processing: always approve with reauth the capture request</description>
+        <implements service="ccCaptureInterface"/>
+    </service>
+    <service name="testCCProcessorCaptureAlwaysDecline" engine="java"
+            location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testCCProcessorCaptureAlwaysDecline">
+        <description>Test Credit Card Capture Processing: always decline a cc capture request</description>
         <implements service="ccCaptureInterface"/>
     </service>
     <service name="testCCRelease" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testRelease">
-        <description>Credit Card Test Release</description>
+        <description>Test Credit Card Release Processing: always approve the release request</description>
         <implements service="paymentReleaseInterface"/>
     </service>
     <service name="testCCRefund" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testRefund">
-        <description>Credit Card Test Refund</description>
+        <description>Test Credit Card Refund Processing: always approve the refund request</description>
         <implements service="paymentRefundInterface"/>
     </service>
 

Modified: ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java?view=diff&rev=552432&r1=552431&r2=552432
==============================================================================
--- ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java (original)
+++ ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java Mon Jul  2 01:32:14 2007
@@ -1063,11 +1063,6 @@
                 // If we have an invoice, we find unapplied payments associated
                 // to the billing account and we apply them to the invoice
                 if (UtilValidate.isNotEmpty(invoiceId)) {
-                    // TODO: jacopo continue from here...
-                    // cercare le paymentapplication non applicate e associate al billing account e il cui
-                    // pagamento non abbia una orderPaymentPreferenceId
-                    // creare nuova payment application fino a raggiungere l'importo necessario o fino ad esaurimento
-                    // e associarle alla fattura; se la fattura non esiste, non fare nulla
                     Map captureResult = null;
                     try {
                         captureResult = dispatcher.runSync("captureBillingAccountPayments", UtilMisc.toMap("invoiceId", invoiceId,
@@ -1856,25 +1851,23 @@
         BigDecimal amtBd = new BigDecimal(amount.doubleValue());
         amtBd = amtBd.setScale(decimals, rounding);
 
-        if (captureResult.booleanValue()) {
-            // capture returned true (passed)
-            result.put("orderPaymentPreference", paymentPreference);
-            result.put("userLogin", userLogin);
-            result.put("serviceTypeEnum", authServiceType);
-
-            ModelService model = dctx.getModelService("processCaptureResult");
-            Map context = model.makeValid(result, ModelService.IN_PARAM);
-            Map capRes;
-            try {
-                capRes = dispatcher.runSync("processCaptureResult", context);
-            } catch (GenericServiceException e) {
-                Debug.logError(e, module);
-                throw e;
-            }
-            if (capRes != null && ServiceUtil.isError(capRes)) {
-                throw new GeneralException(ServiceUtil.getErrorMessage(capRes));
-            }
-        } else {
+        result.put("orderPaymentPreference", paymentPreference);
+        result.put("userLogin", userLogin);
+        result.put("serviceTypeEnum", authServiceType);
+
+        ModelService model = dctx.getModelService("processCaptureResult");
+        Map context = model.makeValid(result, ModelService.IN_PARAM);
+        Map capRes;
+        try {
+            capRes = dispatcher.runSync("processCaptureResult", context);
+        } catch (GenericServiceException e) {
+            Debug.logError(e, module);
+            throw e;
+        }
+        if (capRes != null && ServiceUtil.isError(capRes)) {
+            throw new GeneralException(ServiceUtil.getErrorMessage(capRes));
+        }
+        if (!captureResult.booleanValue()) {
             // capture returned false (error)
             try {
                 processReAuthFromCaptureFailure(dctx, result, amtBd, userLogin, paymentPreference);
@@ -2735,7 +2728,7 @@
 
 
     /**
-     * Simple test processor; declines all orders < 100.00; approves all orders > 100.00
+     * Simple test processor; declines all orders < 100.00; approves all orders >= 100.00
      */
     public static Map testProcessor(DispatchContext dctx, Map context) {
         Map result = new HashMap();
@@ -2988,6 +2981,25 @@
         result.put("captureAltRefNum", refNum);
         result.put("captureFlag", "C");
         result.put("captureMessage", "This is a test capture; no money was transferred");
+        return result;
+    }
+
+    /**
+     * Always decline processor
+     */
+    public static Map testCCProcessorCaptureAlwaysDecline(DispatchContext dctx, Map context) {
+        Map result = ServiceUtil.returnSuccess();
+        Double processAmount = (Double) context.get("captureAmount");
+        Debug.logInfo("Test Processor Declining Credit Card capture", module);
+
+        String refNum = UtilDateTime.nowAsString();
+
+        result.put("captureResult", Boolean.FALSE);
+        result.put("captureAmount", processAmount);
+        result.put("captureRefNum", refNum);
+        result.put("captureAltRefNum", refNum);
+        result.put("captureFlag", "D");
+        result.put("captureMessage", "This is a test processor; no payments were captured or authorized");
         return result;
     }
 



Re: svn commit: r552432 - in /ofbiz/trunk/applications/accounting: servicedef/services_paymentmethod.xml src/org/ofbiz/accounting/payment/PaymentGatewayServices.java

Posted by rohit2006 <ro...@yahoo.com>.
can you please check the code committed here, cause when i try to start ofbiz
with this version, i see a message in the log file stating that the XML for
'services_paymentmethod.xml' is not correctly formatted and the payment
services are not loaded.

Rohit



jacopoc wrote:
> 
> Author: jacopoc
> Date: Mon Jul  2 01:32:14 2007
> New Revision: 552432
> 
> URL: http://svn.apache.org/viewvc?view=rev&rev=552432
> Log:
> Added new service to test a decline response for a cc capture request.
> Fixed bu that was preventing the declined response for a capture request
> to be stored in the PaymentGatewayResponse entity.
> Misc cleanups and improvements to the descriptions of the test cc
> processor services.
> 
> Modified:
>    
> ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
>    
> ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
> 
> Modified:
> ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml?view=diff&rev=552432&r1=552431&r2=552432
> ==============================================================================
> ---
> ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
> (original)
> +++
> ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
> Mon Jul  2 01:32:14 2007
> @@ -535,82 +535,86 @@
>      </service>
>  
>      <!-- Test Implementations -->
> +    <!-- Test Credit Card (CC) Requests -->
>      <service name="testCCProcessor" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: declines auth
> requests for all orders < 100.00; approves auth requests for all orders >=
> 100.00</description>
>          <implements service="ccAuthInterface"/>
>      </service>
> -     <service name="testCCProcessorWithCapture" engine="java"
> +    <service name="testCCProcessorWithCapture" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testProcessorWithCapture">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: declines auth
> requests for all orders < 100.00; approves auth requests for all orders >=
> 100.00</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>      <service name="testRandomAuthorize" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testRandomAuthorize">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: does random auth
> declines</description>
>          <implements service="ccAuthInterface"/>
>      </service>
> -
>      <service name="alwaysApproveCCProcessor" engine="java"
>              
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="alwaysApproveProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: always approve the
> auth request</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>      <service name="alwaysApproveWithCaptureCCProcessor" engine="java"
>              
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="alwaysApproveWithCapture">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: always approve
> with capture auth request</description>
>          <implements service="ccAuthInterface"/>
>      </service>
> -
>      <service name="alwaysDeclineCCProcessor" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="alwaysDeclineProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: always decline the
> auth request</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>      <service name="alwaysNsfCCProcessor" engine="java"
>          location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="alwaysNsfProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: always decline for
> NSF (not sufficient funds) auth request</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>      <service name="alwaysBadExpireCCProcessor" engine="java"
>          location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="alwaysBadExpireProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: always fail/bad
> expire date processor</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>      <service name="badExpireEvenCCProcessor" engine="java"
>          location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="badExpireEvenProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: fail/bad expire
> date when year is even processor</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>      <service name="alwaysBadCardNumberCCProcessor" engine="java"
>          location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="alwaysBadCardNumberProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: always decline the
> auth request for bad card number</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>      <service name="alwaysFailCCProcessor" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="alwaysFailProcessor">
> -        <description>Credit Card Processing</description>
> +        <description>Test Credit Card Auth Processing: always fail
> (error) the auth transaction request</description>
>          <implements service="ccAuthInterface"/>
>      </service>
>  
>      <service name="testCCCapture" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testCapture">
> -        <description>Credit Card Test Capture</description>
> +        <description>Test Credit Card Capture Processing: always approve
> the capture request</description>
>          <implements service="ccCaptureInterface"/>
>      </service>
>      <service name="testCCCaptureWithReAuth" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testCaptureWithReAuth">
> -        <description>Credit Card Test Capture</description>
> +        <description>Test Credit Card Capture Processing: always approve
> with reauth the capture request</description>
> +        <implements service="ccCaptureInterface"/>
> +    </service>
> +    <service name="testCCProcessorCaptureAlwaysDecline" engine="java"
> +           
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testCCProcessorCaptureAlwaysDecline">
> +        <description>Test Credit Card Capture Processing: always decline
> a cc capture request</description>
>          <implements service="ccCaptureInterface"/>
>      </service>
>      <service name="testCCRelease" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testRelease">
> -        <description>Credit Card Test Release</description>
> +        <description>Test Credit Card Release Processing: always approve
> the release request</description>
>          <implements service="paymentReleaseInterface"/>
>      </service>
>      <service name="testCCRefund" engine="java"
>             
> location="org.ofbiz.accounting.payment.PaymentGatewayServices"
> invoke="testRefund">
> -        <description>Credit Card Test Refund</description>
> +        <description>Test Credit Card Refund Processing: always approve
> the refund request</description>
>          <implements service="paymentRefundInterface"/>
>      </service>
>  
> 
> Modified:
> ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
> URL:
> http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java?view=diff&rev=552432&r1=552431&r2=552432
> ==============================================================================
> ---
> ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
> (original)
> +++
> ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
> Mon Jul  2 01:32:14 2007
> @@ -1063,11 +1063,6 @@
>                  // If we have an invoice, we find unapplied payments
> associated
>                  // to the billing account and we apply them to the
> invoice
>                  if (UtilValidate.isNotEmpty(invoiceId)) {
> -                    // TODO: jacopo continue from here...
> -                    // cercare le paymentapplication non applicate e
> associate al billing account e il cui
> -                    // pagamento non abbia una orderPaymentPreferenceId
> -                    // creare nuova payment application fino a
> raggiungere l'importo necessario o fino ad esaurimento
> -                    // e associarle alla fattura; se la fattura non
> esiste, non fare nulla
>                      Map captureResult = null;
>                      try {
>                          captureResult =
> dispatcher.runSync("captureBillingAccountPayments",
> UtilMisc.toMap("invoiceId", invoiceId,
> @@ -1856,25 +1851,23 @@
>          BigDecimal amtBd = new BigDecimal(amount.doubleValue());
>          amtBd = amtBd.setScale(decimals, rounding);
>  
> -        if (captureResult.booleanValue()) {
> -            // capture returned true (passed)
> -            result.put("orderPaymentPreference", paymentPreference);
> -            result.put("userLogin", userLogin);
> -            result.put("serviceTypeEnum", authServiceType);
> -
> -            ModelService model =
> dctx.getModelService("processCaptureResult");
> -            Map context = model.makeValid(result, ModelService.IN_PARAM);
> -            Map capRes;
> -            try {
> -                capRes = dispatcher.runSync("processCaptureResult",
> context);
> -            } catch (GenericServiceException e) {
> -                Debug.logError(e, module);
> -                throw e;
> -            }
> -            if (capRes != null && ServiceUtil.isError(capRes)) {
> -                throw new
> GeneralException(ServiceUtil.getErrorMessage(capRes));
> -            }
> -        } else {
> +        result.put("orderPaymentPreference", paymentPreference);
> +        result.put("userLogin", userLogin);
> +        result.put("serviceTypeEnum", authServiceType);
> +
> +        ModelService model =
> dctx.getModelService("processCaptureResult");
> +        Map context = model.makeValid(result, ModelService.IN_PARAM);
> +        Map capRes;
> +        try {
> +            capRes = dispatcher.runSync("processCaptureResult", context);
> +        } catch (GenericServiceException e) {
> +            Debug.logError(e, module);
> +            throw e;
> +        }
> +        if (capRes != null && ServiceUtil.isError(capRes)) {
> +            throw new
> GeneralException(ServiceUtil.getErrorMessage(capRes));
> +        }
> +        if (!captureResult.booleanValue()) {
>              // capture returned false (error)
>              try {
>                  processReAuthFromCaptureFailure(dctx, result, amtBd,
> userLogin, paymentPreference);
> @@ -2735,7 +2728,7 @@
>  
>  
>      /**
> -     * Simple test processor; declines all orders < 100.00; approves all
> orders > 100.00
> +     * Simple test processor; declines all orders < 100.00; approves all
> orders >= 100.00
>       */
>      public static Map testProcessor(DispatchContext dctx, Map context) {
>          Map result = new HashMap();
> @@ -2988,6 +2981,25 @@
>          result.put("captureAltRefNum", refNum);
>          result.put("captureFlag", "C");
>          result.put("captureMessage", "This is a test capture; no money
> was transferred");
> +        return result;
> +    }
> +
> +    /**
> +     * Always decline processor
> +     */
> +    public static Map testCCProcessorCaptureAlwaysDecline(DispatchContext
> dctx, Map context) {
> +        Map result = ServiceUtil.returnSuccess();
> +        Double processAmount = (Double) context.get("captureAmount");
> +        Debug.logInfo("Test Processor Declining Credit Card capture",
> module);
> +
> +        String refNum = UtilDateTime.nowAsString();
> +
> +        result.put("captureResult", Boolean.FALSE);
> +        result.put("captureAmount", processAmount);
> +        result.put("captureRefNum", refNum);
> +        result.put("captureAltRefNum", refNum);
> +        result.put("captureFlag", "D");
> +        result.put("captureMessage", "This is a test processor; no
> payments were captured or authorized");
>          return result;
>      }
>  
> 
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/svn-commit%3A-r552432---in--ofbiz-trunk-applications-accounting%3A-servicedef-services_paymentmethod.xml-src-org-ofbiz-accounting-payment-PaymentGatewayServices.java-tf4010882.html#a11404416
Sent from the OFBiz - Commits mailing list archive at Nabble.com.