Integrating Salesforce with External Billing Systems Using Platform Events

 Requirement:

  Whenever Opportunity becomes Closed Won, create an Invoice in Billing System.


Business Scenario:

  ABC Technologies purcheses an Internet Package worth $50,000.

1.Customer     : ABC Technologies

2.Product        : Internet Package

3.Amount        : $50,000

4.Opportunity  : Closed Won


Instead of directly calling Billing API from the Opportunity Trigger:

     Opportunity  => Platform Event => Billing Systen


External System setup:

Step 1: Create MockAPI Account

Website:      https://mockapi.io

Actions: open sign up & login.


Step 2: Create Project

-click New Project

        Name - Salesforce Billing System


Step 3: Create Invoice Resource

      Inside Project: 

         create Resource:

                  Resource Name - Invoices

Fields:

  1.  invoiceNumber
  2. customerName
  3. amount
  4. status
  5. opportunityid



Expected Structure:
 {
  "invoiceNumber":"IN001",
 "customerName": "ABC Technologies",
  "amount" : 5000,
  "status":"Generated",
   "opportunityId":"006XXXXXX"
}

Step 4: Verify API Endpoint
MockAPI generates URL:

Example:



Test in postman:
   

output:

  data get created by 1 and if you want to see the data click on endpoint


  Now Comes to Salesforce

Step 1: Create Named Credential in Salesforce
   
    

Step 2: Salesforce Platform Event

              Create Platform Event and Custom Fields

     


Step 3: Publish Event

Business Rule:

  Opportunity Stage= Closed Won

flow:    Opportunity =============> Closed Won ======> Publish Platform Event


Step 4: Platform Event Subscriber

Create Trigger:  Opportunity_Won__e

  trigger OpportunityTriggerIntegration on Opportunity (after update) {  
OpportunityTriggerHandler.publishWonEvent(Trigger.new,Trigger.oldMap);
}


Handler class:

public with sharing class OpportunityTriggerHandler {
    public static void publishWonEvent(List<Opportunity> newOpps,
Map<Id, Opportunity> oldMap){
        List<Opportunity_Won__e> eventsToPublish =  new List<Opportunity_Won__e>();

        for(Opportunity opp : newOpps){
            Opportunity oldOpp = oldMap.get(opp.Id);
            if(opp.StageName == 'Closed Won' && oldOpp.StageName != 'Closed Won'){

                eventsToPublish.add(
                    new Opportunity_Won__e(
                        OpportunityId__c = opp.Id,
                        OpportunityName__c = opp.Name,
                        AccountName__c = opp.Account.Name,
                        Amount__c = opp.Amount
                    )
                );
            }
        }

        if(!eventsToPublish.isEmpty()){
            EventBus.publish(eventsToPublish);
        }
    }
}


Trigger on OpportunityWonEventTrigger:

 trigger OpportunityWonEventTrigger on Opportunity_Won__e (after insert) { 
List<Opportunity_Won__e> events =  new List<Opportunity_Won__e>();
    events.addAll(Trigger.New);
    System.enqueueJob(new BillingIntegrationQueueable(events));
}        


public with sharing class BillingIntegrationQueueable
implements Queueable, Database.AllowsCallouts {

    private List<Opportunity_Won__e> events;

    public BillingIntegrationQueueable( List<Opportunity_Won__e> events    ){
        this.events = events;
    }

    public void execute(QueueableContext qc){

        for(Opportunity_Won__e evt : events){
            try{
                InvoiceRequest requestObj =  new InvoiceRequest();
                requestObj.invoiceNumber = 'INV-' + Datetime.now().getTime();
                requestObj.customerName =  evt.AccountName__c;
                requestObj.amount =  evt.Amount__c;
                requestObj.opportunityId = evt.OpportunityId__c;
                requestObj.status = 'Generated';

                HttpRequest req =  new HttpRequest();
                req.setEndpoint('callout:MockAPI');

                //req.setEndpoint('callout:MockAPI/api/v1/invoices');

                req.setMethod('POST');
                req.setHeader('Content-Type', 'application/json' );

                req.setBody(JSON.serialize(requestObj));

                Http http = new Http();
                HttpResponse res = http.send(req);

                BillingLogger.logSuccess(
                    evt.OpportunityId__c,
                    res.getStatusCode(),
                    res.getBody()
                );

            }catch(Exception ex){
                BillingLogger.logError( evt.OpportunityId__c, ex.getMessage() );
            }
        }
    }

    public class InvoiceRequest{
        public String invoiceNumber;
        public String customerName;
        public Decimal amount;
        public String opportunityId;
        public String status;
    }
}

flow:   platform Event ==========> subscribe Trigger =========> Queueable Job


Diagram:

      opp trigger --> EventBus.publish()-->Platform Event-->Subscriber Trigger


Step 8: Queueable Integration:

Queueable Performance

        Platform EventReceived=>Prepare JSON=>POST Request=>MockAPI


Payload:

 {
    "invoiceNumber":"IN001",
    "customerName": "ABC Technologies",
    "amount" : 5000,
    "status":"Generated",
    "opportunityId":"006XXXXXX"
 }


Step 5: Verify MockAPI

Open:   MockAPI Dashboard

Navigate : Invoices Resources

 

How it works:  

      create opportunity




Response:


External system:  Invoice got create below as 2 , click on endpoint.

                              

Once we click on endpoint below output will show:


Complete Flow Diagram:



Note: This article is optimized for desktop and tablet viewing. If you are reading on a mobile device, some code snippets may appear misaligned or overflow the screen. ๐Ÿ˜€

Comments

Popular posts from this blog

Oracle to Salesforce Integration: Handling Inbound REST API

๐ŸŒ Real-Time Salesforce to Oracle REST API Integration – Beginner Guide with JSON and Logging