function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Daniel DennisDaniel Dennis 

Can someone give this code a quick check?

I'm trying to setup a simple bit of code that recieves a PayPal Instant Payment Notification (IPN) finds the created Opportunity and checks a box called "paid".

The key field in Salesforce is "FormAssemblyID" 
The IPN sends a block of text that includes this parameter: &custom=https://ncoa.tfaforms.net/responses/view/52932682&

My class is supposed to extract this and use it to lookup the right opportunity and a check a box. It's either not finding the right opportunity or its not checking the Paid box when it does and can't figure out which it is.

Here is the opportunity field that it should be finding:   User-added image

And here is my code:

public class IPNHandlerController {

    public PageReference myIPNupdate() {
     try{
        PageReference pageRef = ApexPages.currentPage();
        //Get the value of the 'custom' parameter from current page
        String paramCustom = pageRef.getParameters().get('custom');
        opportunity = [select Id,paid__c from Opportunity where FormAssemblyID__c = :paramCustom ];

        String content = '';
        for(String key : pageRef.getParameters().keySet()){
            //Note that there is no guarantee of order in the parameter key map.
            content += key + ' : ' + pageRef.getParameters().get(key) + '\n';
        }
        opportunity.PayPalInfo__c = content;
        opportunity.paid__c = True;
        update opportunity;

        PageReference newPage = new ApexPages.StandardController(opportunity).view();
        newPage.setRedirect(true);        

        return newPage;
     } catch (System.Exception e){
         //A failure occurred
         system.debug(e);
         return null;
     }
    }

    public Opportunity opportunity {get; set;}

    public IPNHandlerController() {
    }
}
GlynAGlynA
Have you been able to determine whether the catch block is executed (by looking at a debug log)?  It seems to me that the line

opportunity = [select Id,paid__c from Opportunity where FormAssemblyID__c = :paramCustom ];

will throw an exception if there are zero or more than one opportunities that have the desired FormAssemblyID value.  You seem to know that there is at least one opportunity with the desired value.  Could there be more than one?  This would cause the code to fail.

Instead, you could iterate over the query results and update the first opportunity found, or the last one found.  Or you could detect the error and handle it accordingly.  You could also make the field Unique, so that there would never be duplicate values.
James LoghryJames Loghry
In addition to GlynA's comments, throw a System.debug() statement around the following two lines to determine if the custom param is coming back as you would expect it to:
 
String paramCustom = pageRef.getParameters().get('custom');
opportunity = [select Id,paid__c from Opportunity where FormAssemblyID__c = :paramCustom ];

If paramCustom is wrong, then you obviously won't get an Opportunity back and like Glyn said, your code will throw and catch the exception.

Furthermore, instead of simply System.debugging the exception, you could create a custom object to log errors, and then insert any errors that occur. This way, you'll have a great idea of what is going on.  Here's a quick and dirty example of what I mean:
 
catch(Exception ex){
    //Assumes you have created a custom object called Error__c 
    //and given it custom text fields for classname, parameters, 
    //cause, error_description, line_number, and message
    insert new Error__c(
        ClassName__c = 'IPNHandlerController'
       ,Parameters__c = JSON.serialize(new Map{'custom'=>paramCustom}
       ,Cause__c = (ex.getCause() != null && ex.getCause().getMessage() != null ? ex.getCause().getMessage().abbreviate(255) : null)
       ,Error_Description__c = (ex.getStackTraceString() != null ? ex.getStackTraceString().abbreviate(128000) : null)
       ,Line_Number__c = ex.getLineNumber()
       ,Message__c = (ex.getMessage() != null ? ex.getMessage().abbreviate(255) : null)
    );
}

Note, for this example to work, you would have to move the "paramCustom" variable outside of the try/catch block.
SF UK ADMIN FINANCESF UK ADMIN FINANCE
Hello Daniel,

How did you resolve this issue? can you please share details

Ankur