Announcement Announcement Module
Collapse
No announcement yet.
Spring MVC and paypal ipn handler Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring MVC and paypal ipn handler

    I'm wondering if anyone has ever created a POST method on a spring controller that is the listener for the payapl IPN(Instant Payment Notification) message they dispatch.

    All they give on their site is the following JSP as sample code: Jsp Code.

    I wanted the convenience of handling it in a mvc controller method so I could more effectively use it for its intended purpose, validating payments against various data hibernate will serve up. I thought it would be as simple as writing a method, annotating it as post, giving it the request and response object as parameters, and then firing up the server, apparently this isn't working out for me when I use paypals ipn simulator, any ideas or experience out there for this? thanks!

  • #2
    I have the same problem now.
    What was your solution ?

    Rita

    Comment


    • #3
      I came across this thread yesterday when I was searching for a solution to this problem. I have since gotten it working, so here's my code in case anyone else needs it. It's important to note that the PayPal IPN Simulator in the sandbox reports the url being invalid if it does not respond properly, even if the server does handle the POST request.

      The following code requires the Apache HttpClient package from the HttpComponents project (I used version 4.1.2)

      Code:
      @Controller
      @RequestMapping("/confirm")
      public class IPNController {
      		
              private final static String CONTENT_TYPE = "Content-Type";
              private final static String MIME_APP_URLENC = "application/x-www-form-urlencoded";	
      
      	private final static String PAY_PAL_DEBUG = "https://www.sandbox.paypal.com/cgi-bin/webscr";	
      	private final static String PAY_PAL_PROD = "https://www.paypal.com/cgi-bin/webscr";
      	
      	private final static String PARAM_NAME_CMD = "cmd";
      	private final static String PARAM_VAL_CMD = "_notify-validate";
      	
      	private final static String RESP_VERIFIED = "VERIFIED";
      	
              private final IPNProcessingService ipnService;	
       
              private final String paypalUrl;	
      	
      	@Autowired
      	public IPNController ( IPNProcessingService ipnService, @Value( "${paypal.debug:true}") boolean debug ) {
                      this.ipnService = ipnService;
      		paypalUrl = debug ? PAY_PAL_DEBUG : PAY_PAL_PROD;
      	}
      	
      	@RequestMapping( method=RequestMethod.POST )
      	public void processIPN( HttpServletRequest request ) {
      		
                  logger.debug( "POST Confirm" );		
      
                  //Create client for Http communication
          	    HttpClient httpClient = new DefaultHttpClient();  
      	    HttpParams clientParams = httpClient.getParams();
      	    HttpConnectionParams.setConnectionTimeout(clientParams ,40000 );
      	    HttpConnectionParams.setSoTimeout(clientParams ,40000 );
      	
      	    HttpPost httppost = new HttpPost( paypalUrl );
      	    httppost.setHeader( CONTENT_TYPE, MIME_APP_URLENC );
      	     
      	    try {
                      //Store Payment info for passing to processing service
                      Map<String, String> params = new HashMap<String, String>(); 
      
                      //Use name/value pair for building the encoded response string		
      		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
      
                      //Append the required command
      		nameValuePairs.add( new BasicNameValuePair( PARAM_NAME_CMD, PARAM_VAL_CMD  ) );
      		
                      //Process the parameters
      	    	Enumeration<String> names = request.getParameterNames();
      		while ( names.hasMoreElements() ) {
      			String param = names.nextElement();
      			String value = request.getParameter( param );
      			
      			nameValuePairs.add( new BasicNameValuePair( param, value ) );
      			params.put( param, value );
      			logger.debug( param + "=" + value );					
      		}
      		
      		httppost.setEntity( new UrlEncodedFormEntity( nameValuePairs ) ) );			
      			
      		if ( verifyResponse( httpClient.execute( httppost ) ) ) {
      			//Implement your processing logic here, I used an @Asyn annotation
                              //Remember to track completed transactions and don't process duplicates
                              ipnService.processPaymentNotification( params );
      		}
      
      	   } catch ( UnsupportedEncodingException e ) {			
      	        e.printStackTrace();
                 } catch ( ClientProtocolException e ) {
      	        e.printStackTrace();
      	   } catch ( IOException e ) {
      		e.printStackTrace();
                 }	 				
              }	
      		
      	private boolean verifyResponse( HttpResponse response ) throws IllegalStateException, IOException {
      		
      	       InputStream is = response.getEntity().getContent();
                     BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                     String responseText = reader.readLine();
                     is.close();
      
                    logger.debug( "RESPONSE : " + responseText );
              
                   return responseText.equals( RESP_VERIFIED );
              
      	}
      }
      The same pattern can be followed for using other Paypal back end services. I hope this helps others who may be struggling with this.
      Last edited by csalembier; Sep 7th, 2011, 05:06 PM.

      Comment

      Working...
      X