I have a requirement with the following functionality:

  1. Before the Opp stage gets updated to Closed-Won on ever opp I should be able to push the opp info to an external REST webservice URL as JSON format.
  2. After successfully pushed I will get a JSON response with an account Id and status message with this I need to update the Opportunity.

I was not able to look my trigger in the debug lo is something in my trigger?I'm not able to make call to the URL? How to handle the request and response and map it to the opp?

Here is the Trigger:

trigger OppUpdate on Opportunity (before insert,before update) {
    for (Opportunity Opp : Trigger.new) {
        if (Opp.StageName=='ClosedWon') {

Here is my class:

public class opptycall {@future(callout = true)
    public static void post(id opptyid) {
        //Construct HTTP request and response
        HttpRequest req = new HttpRequest();

        //Http http = new Http();        

        //Construct Authorization and Content header
        //request.setHeader('Authorization', getBasicAuthHeader('test','test'));
        //req.setHeader('Authorization', authorizationHeader);
        req.setHeader('Content-Type', 'application/json');

        //Construct Endpoint
        String endpoint = 'https://test.com';

        //Set Method and Endpoint and Body
        //json string in body 
        system.debug('Opportunity ID' + opptyid);
        Opportunity Op = [select id, Name, Stagename, Account.Name from opportunity where stagename = 'Closed-Won'
        and id = : opptyid];
        System.debug('with pretty' + JSON.serializePretty(Op));
        system.debug('without pretty' + JSON.serialize(Op));
        String JsonString = JSON.serializePretty(Op);

        Http http = new Http();
        HTTPResponse res = http.send(req);
        if (response.getStatusCode() == 200) {
            JSONParser par = JSONParser.parse(response.getBody());
            System.debug('-par.message.Opportunity-' + par.message.Opportunity);
            for (JSONParser.Opportuntiy Opp: par.message.Opportuntiy) {
                Opp.add(new Opportunity(
                Id = par.message.Opportuntiy.Id,
                Status = par.message.Opportuntiy.status,
                Description = par.message.Opportuntiy.description));
                update opp Id;

  • Are you getting any exception in debug logs – Ashwani Aug 21 '15 at 18:25
  • Could you provide some more details, like what I understand of error do you get? – zokito Aug 21 '15 at 18:25
  • can you make sure that url in added in remote site settings – Ashwani Aug 21 '15 at 18:25
  • 2
    You should verify the string you are using for StageName. You've got both ClosedWon and Closed-Won in your code. Since this field is a picklist and can be changed by the user and more importantly multiple opportunity stage values can represent a closed opportunity, you might consider querying the OpportunityStage object for the StageName and check the values of isClosed and isWon and drive your logic from that data. – Mark Pond Aug 21 '15 at 18:41
  • 3
    One other problem is that you are passing a JSON string to opptycall.post when it is expecting an ID. – Keith C Aug 21 '15 at 18:41

If you care calling this trigger on a Before Insert, there is not ID for the object before insert. Before update is okay, but this won't work on before insert. You will want to do after insert.

As pointed out by someone else, you are passing in a JSON string when the opptycall.post is expecting an ID type. You can pass in Trigger.new.[0].Id. Be careful here, your code is not bulkified so this won't behave as expected when you bulkupdate.

trigger OppUpdate on Opportunity (before insert, before update) {
    for (Opportunity Opp : Trigger.new) {
        if (Opp.StageName == 'ClosedWon') {


The other thing you want to be aware of is that your code with the @future call means that the opportunity is getting updated and saved and then the callout is happening after that record is saved. Your callout is updating the opportunity after it gets a response. Small detail here, but it might help you with troubleshooting. In your log files, you'll see a FutureHandler log that looks like this. That is where you'll see the debug information:

futurehandler log file

I'm using the developerconsole to view the logs.


In opptycall.post, you have if (response.getStatusCode() == 200) { ... } but it should be if (res.getStatusCode() == 200) { ... }.

You have a few references to response and those all need to be changed to res.


You should also bulkify the trigger - it looks like your code will run a query for every changed Opportunity id, which may hit govenor limits. I believe it's best practice to build out a list of ids in the trigger:

trigger OppUpdate on Opportunity (before insert,before update) {
    List<String> opIds = new List<String>();
    for (Opportunity Opp : Trigger.new) {
      if (Opp.StageName=='ClosedWon') {

then pass that list of ids to your to pass to your method sending the callout:

opptycall.post(List<String> opids) {

and then loop through the ids there:

<List>Opportunity Ops = [select id, Name, Stagename, Account.Name from opportunity where id in :opIds];
for (Opportunity op : Ops) {
     // do call out

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.