Page 1 of 1

Ideal Payment module TemplateProcessingException / NullPoint

Posted: Fri Dec 14, 2012 7:37 am
by robvanbasten
I created a payment module based on the Paypal module. It makes use of the Ideal payment sites offered by all the Dutch (and some other European) banks. The banksite always returns to a single
URL address (whether the payment was successful or not). The success decision is made by a call to the bank API checking the status of the transaction. If the status is successful all works fine.
However if something went wrong Transaction-success will be set to false, followed by a null pointer exception processing the layout/checkoutLayout. Since there are no line numbers or other explanation
I am left in the dark with this exception.

    [TRACE] 12:32:07 HeadProcessor - [THYMELEAF][9][layout/checkoutLayout] Processing element "blc:head"
    [TRACE] 12:32:07 PriceTextDisplayProcessor - [THYMELEAF][9][layout/checkoutLayout] Processing attribute "blc:price" with value "${cart.subTotal}" in element "td"
    [TRACE] 12:32:07 PriceTextDisplayProcessor - [THYMELEAF][9][layout/checkoutLayout] Processing attribute "blc:price" with value "${cart.totalTax}" in element "td"
    [TRACE] 12:32:07 PriceTextDisplayProcessor - [THYMELEAF][9][layout/checkoutLayout] Processing attribute "blc:price" with value "${cart.totalShipping}" in element "td"
    [TRACE] 12:32:07 PriceTextDisplayProcessor - [THYMELEAF][9][layout/checkoutLayout] Processing attribute "blc:price" with value "${cart.total}" in element "div"
    [TRACE] 12:32:07 PriceTextDisplayProcessor - [THYMELEAF][9][layout/checkoutLayout] Processing attribute "blc:price" with value "*{price}" in element "td"
    [TRACE] 12:32:07 PriceTextDisplayProcessor - [THYMELEAF][9][layout/checkoutLayout] Processing attribute "blc:price" with value "*{price.multiply(quantity)}" in element "td"
    [ERROR] 12:32:07 TemplateEngine - [THYMELEAF][9] Exception processing template "layout/checkoutLayout": null
    [TRACE] 12:32:07 MergeXmlWebApplicationContext - Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/ideal/process]; client=[127.0.0.1]; method=[GET]; servlet=[bvb]; session=[1hmfkkl4ydhu51c7jk7icvnflt]; user=[null]; time=[858ms]; status=[failed: org.thymeleaf.exceptions.TemplateProcessingException: Exception processing template (layout/checkoutLayout)]
    2012-12-14 12:32:07.820:WARN:oejs.ServletHandler:/ideal/process
    org.thymeleaf.exceptions.TemplateProcessingException: Exception processing template (layout/checkoutLayout)
return URL:
http://localhost:8080/ideal/process?trx ... 84952D7B9A

setting TransactionSuccess to false:

Code: Select all

responseItem.setTransactionSuccess(response.getTransaction().getStatus().equals("Success"));

Re: Ideal Payment module TemplateProcessingException / NullPoint

Posted: Fri Dec 14, 2012 10:55 am
by phillipuniverse
What does your controller code look like that responds to the url /idea/process?

Re: Ideal Payment module TemplateProcessingException / NullPoint

Posted: Fri Dec 14, 2012 12:08 pm
by robvanbasten
It's almost a copy of the Paypal controller:
In the demo:

Code: Select all

@Controller
public class IdealController extends BroadleafIdealController {

    //This is the URL that will initiate the checkout process with Ideal.
    @RequestMapping("/ideal/checkout")
    public String idealCheckout(HttpServletRequest request, @RequestParam String selectedBank) throws PaymentException {
        return super.idealCheckout(request, selectedBank);
    }

    //This is the URL that Ideal will redirect back to on callback.
    //This should match ${ideal.return.url} in your properties file.
    //For example:  ${ideal.return.url}=http://localhost:8080/mycompany/ideal/process
    // http://localhost:8080/ideal/process?trxid=0000000000093072&ec=CEA490BF7518C25718921EEB9C30CAF671D13B10
    @RequestMapping("/ideal/process")
    public String idealProcess(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam("trxid") String transactionId, @RequestParam("ec") String entranceCode) throws CheckoutException, PricingException {
        return super.idealProcess(request, response, model, transactionId, entranceCode);
    }


and in the ideal payment module:

Code: Select all

public class BroadleafIdealController extends BroadleafCheckoutController {
    private static final Log LOG = LogFactory.getLog(BroadleafIdealController.class);

    @Resource(name="blIdealCheckoutService")
    protected IdealCheckoutService idealCheckoutService;

    /**
     * The default endpoint to initiate a Ideal Checkout.
     * To use: Create a controller in your application and extend this class.
     *
     * @param request - The Http request
     * @return ModelAndView
     */
    public String idealCheckout(HttpServletRequest request, String selectedBank) throws PaymentException {
        Order cart = CartState.getCart();
        if (!(cart instanceof NullOrderImpl)) {
            CompositePaymentResponse compositePaymentResponse = idealCheckoutService.initiateIdealCheckout(cart, selectedBank);

            for (PaymentInfo paymentInfo : compositePaymentResponse.getPaymentResponse().getResponseItems().keySet()) {
                if (IdealPaymentType.IDEAL.equals(paymentInfo.getType())) {
                    PaymentResponseItem responseItem = compositePaymentResponse.getPaymentResponse().getResponseItems().get(paymentInfo);
                    if (responseItem.getTransactionSuccess()) {
                        return "redirect:" + responseItem.getAdditionalFields().get(MessageConstants.REDIRECTURL);
                    }
                }
            }

            if (LOG.isDebugEnabled()) {
                if (compositePaymentResponse.getPaymentResponse().getResponseItems().size() == 0) {
                    LOG.debug("Payment Response is empty. Please see BLC_PAYMENT_LOG and BLC_PAYMENT_RESPONSE_ITEM for further details.");
                }
            }

        }

        return getCartPageRedirect();
    }
   
    public String idealNogeen(HttpServletRequest request, String selectedBank) throws PaymentException {
       return null;
    }

    /**
     * The default endpoint that Ideal redirects to on callback.
     * To use: Create a controller in your application and extend this class.
     *
     * Note: assumes there is already a Payment Info of Type IDEAL on the order.
     * This should have already been created before redirecting to Ideal (i.e. initiateIdealCheckout())
     *
     * @param request - The Http request
     * @param transactionId - An Ideal variable sent back as a request parameter
     * @param entrance code - An Ideal variable sent back as a request parameter
     * @return ModelAndView
     */
    public String idealProcess(HttpServletRequest request, HttpServletResponse response, Model model,
                            String transactionId, String entranceCode) throws CheckoutException, PricingException {
        Order cart = CartState.getCart();
        if (!(cart instanceof NullOrderImpl)) {
            //save the transaction id and entrance code on the payment info
            PaymentInfo idealPaymentInfo = null;
            for (PaymentInfo paymentInfo : cart.getPaymentInfos()) {
                if (IdealPaymentType.IDEAL.equals(paymentInfo.getType())) {
                    //There should only be one payment info of type ideal in the order
                    idealPaymentInfo = paymentInfo;
                    paymentInfo.getAdditionalFields().put(MessageConstants.TRANSACTIONID, transactionId);
                    paymentInfo.getAdditionalFields().put(MessageConstants.ENTRANCECODE, entranceCode);
                    break;
                }
            }

            if (idealPaymentInfo != null) {
                orderService.save(cart, false);

                initializeOrderForCheckout(cart);

                CheckoutResponse checkoutResponse = idealCheckoutService.completeIdealCheckout(transactionId, entranceCode, cart);
                if (checkoutResponse == null || !checkoutResponse.getPaymentResponse().getResponseItems().get(idealPaymentInfo).getTransactionSuccess()) {
                    processFailedOrderCheckout(cart);
                    populateModelWithShippingReferenceData(request, model);
                    model.addAttribute("paymentException", true);
                    return getCheckoutView();
                }

                return getConfirmationView(checkoutResponse.getOrder().getOrderNumber());

            }
        }

        return getCartPageRedirect();
    }
}
}

Re: Ideal Payment module TemplateProcessingException / NullPoint

Posted: Sun Dec 16, 2012 10:51 am
by robvanbasten
I did some further investigation and found out that the Paypal module has the same issue. Normally this does not show because a payment failure will be redirected to a different URL (cancelUrl). I forced the same behavior by setting the transactionSuccess to false in the PalPalPaymentModule on the PROCESS action.

Code: Select all

protected PaymentResponseItem commonAuthorizeOrSale(PaymentContext paymentContext, PayPalTransactionType transactionType) throws PaymentException {
.......

        PaymentResponseItem responseItem = buildBasicResponse(response);
        if(PayPalMethodType.PROCESS.equals(request.getMethodType())){
            setDecisionInformation(response, responseItem);
   ->         responseItem.setTransactionSuccess(false);
        } else if (PayPalMethodType.CHECKOUT.equals(request.getMethodType()) || PayPalMethodType.AUTHORIZATION.equals(request.getMethodType())) {
            responseItem.getAdditionalFields().put(MessageConstants.REDIRECTURL, response.getUserRedirectUrl());
        }
        responseItem.setAmountPaid(paymentContext.getPaymentInfo().getAmount());

        return responseItem;
 


Upon returning from the PayPal site, the same exception is thrown as in the Ideal payment module.

Re: Ideal Payment module TemplateProcessingException / NullPoint

Posted: Mon Dec 17, 2012 7:10 am
by robvanbasten
I pushed the Ideal Payment Module to github (0.0.1-SNAPSHOT) anyone who find this useful can get it here in the knowledge that there is still the above described exception. :?

https://github.com/robvanbasten/broadleaf-ideal.git

Re: Ideal Payment module TemplateProcessingException / NullPoint

Posted: Tue Dec 18, 2012 10:29 am
by phillipuniverse
Awesome, thanks so much for posting that!