<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sabir Sheikh</title>
    <description>The latest articles on DEV Community by Sabir Sheikh (@sabir_sheikh_cd49d4c419e3).</description>
    <link>https://dev.to/sabir_sheikh_cd49d4c419e3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3121461%2Fda727979-6f71-4d4e-9acc-5b6f3bd6ad38.jpg</url>
      <title>DEV Community: Sabir Sheikh</title>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sabir_sheikh_cd49d4c419e3"/>
    <language>en</language>
    <item>
      <title>Accept Payments in Salesforce: A Complete Guide to Stripe Integration</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Sat, 07 Mar 2026 16:44:49 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/accept-payments-in-salesforce-a-complete-guide-to-stripe-integration-1a2k</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/accept-payments-in-salesforce-a-complete-guide-to-stripe-integration-1a2k</guid>
      <description>&lt;h2&gt;
  
  
  Accept Payments in Salesforce: A Complete Guide to Stripe Integration
&lt;/h2&gt;

&lt;p&gt;Tired of switching between your Salesforce CRM and a separate payment processor? What if you could accept credit card payments directly inside Salesforce and have every transaction automatically logged?&lt;/p&gt;

&lt;p&gt;This guide will walk you through building a complete, secure payment gateway using Stripe and a Lightning Web Component (LWC). We'll cover everything: backend logic, frontend UI, security best practices, and deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before you start, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A Salesforce Developer Org or Scratch Org.&lt;/li&gt;
&lt;li&gt;  A free &lt;a href="https://stripe.com/" rel="noopener noreferrer"&gt;Stripe Account&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Visual Studio Code with the Salesforce Extension Pack installed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 1: Get Your Stripe API Keys
&lt;/h3&gt;

&lt;p&gt;First, we need to get the credentials from Stripe to allow Salesforce to communicate with it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Log in to your &lt;a href="https://dashboard.stripe.com/login" rel="noopener noreferrer"&gt;Stripe Dashboard&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt; Toggle the &lt;strong&gt;Test Mode&lt;/strong&gt; switch in the top-left corner. This lets you make fake payments without charging real cards.&lt;/li&gt;
&lt;li&gt; In the left-hand menu, go to &lt;strong&gt;Developers &amp;gt; API keys&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; You will see two keys we need:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Publishable key:&lt;/strong&gt; Starts with &lt;code&gt;pk_test_...&lt;/code&gt;. This is safe to use in your frontend code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Secret key:&lt;/strong&gt; Starts with &lt;code&gt;sk_test_...&lt;/code&gt;. &lt;strong&gt;Treat this like a password!&lt;/strong&gt; Never expose it in frontend code. We will secure this in Salesforce.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Copy both keys and keep them handy.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Create the Salesforce Data Model
&lt;/h3&gt;

&lt;p&gt;We need a place to store the record of each successful payment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In Salesforce Setup, go to &lt;strong&gt;Object Manager &amp;gt; Create &amp;gt; Custom Object&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Fill in the details:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Label:&lt;/strong&gt; &lt;code&gt;Payment Transaction&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Plural Label:&lt;/strong&gt; &lt;code&gt;Payment Transactions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Object Name:&lt;/strong&gt; &lt;code&gt;Payment_Transaction__c&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Go to the &lt;strong&gt;Fields&lt;/strong&gt; section for your new object and click &lt;strong&gt;New&lt;/strong&gt;. Create the following three fields:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Field 1:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Data Type: &lt;code&gt;Text&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Field Label: &lt;code&gt;Payment ID&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Field Name: &lt;code&gt;Payment_ID__c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Length: &lt;code&gt;255&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Field 2:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Data Type: &lt;code&gt;Text&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Field Label: &lt;code&gt;Status&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Field Name: &lt;code&gt;Status__c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Length: &lt;code&gt;50&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Field 3:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Data Type: &lt;code&gt;Currency&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Field Label: &lt;code&gt;Amount&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Field Name: &lt;code&gt;Amount__c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Decimal Places: &lt;code&gt;2&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Step 3: Secure the Connection with Named Credentials
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This is the most important security step.&lt;/strong&gt; We will store the Secret Key in a Named Credential so it's encrypted and never visible in your code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In Salesforce Setup, go to &lt;strong&gt;Security &amp;gt; Named Credentials&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;New Named Credential&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Fill in the form as follows:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Label:&lt;/strong&gt; &lt;code&gt;Stripe_Named_Credential&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;Stripe_Named_Credential&lt;/code&gt; (this will auto-fill)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;URL:&lt;/strong&gt; &lt;code&gt;https://api.stripe.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Identity Type:&lt;/strong&gt; &lt;code&gt;Named Principal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Authentication Protocol:&lt;/strong&gt; &lt;code&gt;Password Authentication&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Username:&lt;/strong&gt; Leave this blank.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Password:&lt;/strong&gt; Paste your Stripe &lt;strong&gt;Secret Key&lt;/strong&gt; (&lt;code&gt;sk_test_...&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Check the box for &lt;strong&gt;Allow Merge Fields in HTTP Header&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Step 4: The Apex Controller (Backend Logic)
&lt;/h3&gt;

&lt;p&gt;This Apex class will receive the payment information from our LWC, communicate with Stripe using the Named Credential, and create a &lt;code&gt;Payment_Transaction__c&lt;/code&gt; record on success.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In VS Code, create a new Apex class named &lt;code&gt;PaymentController.cls&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Paste the following code:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apex"&gt;&lt;code&gt;&lt;span class="c1"&gt;// File: force-app/main/default/classes/PaymentController.cls&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="kd"&gt;sharing&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@AuraEnabled(&lt;/span&gt;&lt;span class="n"&gt;cacheable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Decimal&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;stripeToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// The 'callout:' prefix tells Salesforce to use the Named Credential for authentication.&lt;/span&gt;
        &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;callout:Stripe_Named_Credential/v1/charges'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Http&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Http&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;POST'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Stripe requires the amount in cents (e.g., $50.00 -&amp;gt; 5000)&lt;/span&gt;
        &lt;span class="n"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;amountInCents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Set the request body with the amount, currency, and the token from the frontend&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;amount='&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amountInCents&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;currency=usd&amp;amp;source='&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;stripeToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;HttpResponse&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Deserialize the JSON response from Stripe&lt;/span&gt;
            &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;responseMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deserializeUntyped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBody&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;responseMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;status'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;succeeded'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Payment was successful, create a record in Salesforce&lt;/span&gt;
                &lt;span class="n"&gt;Payment_Transaction__c&lt;/span&gt; &lt;span class="n"&gt;txn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Payment_Transaction__c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;Payment_ID__c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;responseMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;Status__c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;responseMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;status'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;Amount__c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="n"&gt;txn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="c1"&gt;// Return a success message with the Salesforce Record ID&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;SUCCESS: Payment recorded with ID '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;txn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Payment failed, return the error message from Stripe&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;ERROR: '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;responseMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;error_message'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Handle any other exceptions (e.g., network issues)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s2"&gt;ERROR: An unexpected error occurred - '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 5: Configure CSP Trusted Sites
&lt;/h3&gt;

&lt;p&gt;For security, Salesforce blocks external scripts. We must whitelist Stripe's JavaScript library.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In Salesforce Setup, go to &lt;strong&gt;Security &amp;gt; CSP Trusted Sites&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;New Trusted Site&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Fill in the details:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Trusted Site Name:&lt;/strong&gt; &lt;code&gt;Stripe_JS_CDN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Trusted Site URL:&lt;/strong&gt; &lt;code&gt;https://js.stripe.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Active:&lt;/strong&gt; Check this box.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CSP Directives:&lt;/strong&gt; Check the box for &lt;strong&gt;Allow JavaScript Connectors&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Step 6: The Lightning Web Component (Frontend)
&lt;/h3&gt;

&lt;p&gt;This is the user-facing part. We will create a single LWC that securely displays the payment form.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Part A: Create the Static Resource for Stripe.js&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt; Go to &lt;a href="https://js.stripe.com/v3/" rel="noopener noreferrer"&gt;https://js.stripe.com/v3/&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt; Save the page as &lt;code&gt;stripe.js&lt;/code&gt; to your computer.&lt;/li&gt;
&lt;li&gt; In VS Code, right-click the &lt;code&gt;force-app/main/default/staticresources&lt;/code&gt; folder and select &lt;strong&gt;SFDX: Create Static Resource&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;stripe&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Cache Control:&lt;/strong&gt; &lt;code&gt;Public&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Browse and select the &lt;code&gt;stripe.js&lt;/code&gt; file you just saved.&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Part B: Create the LWC&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt; In VS Code, right-click the &lt;code&gt;lwc&lt;/code&gt; folder and select &lt;strong&gt;SFDX: Create Lightning Web Component&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Name it &lt;code&gt;stripePaymentForm&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Part C: Write the Code&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Now, replace the contents of the three generated files with the code below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;stripePaymentForm.html&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;lightning-card&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Make a Payment"&lt;/span&gt; &lt;span class="na"&gt;icon-name=&lt;/span&gt;&lt;span class="s"&gt;"standard:payment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"slds-m-around_medium"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"payment-form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"card-element"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"slds-p-around_small slds-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="c"&gt;&amp;lt;!-- A Stripe Element will be securely inserted here. --&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"submit-button"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"slds-button slds-button_brand slds-m-top_small"&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;{handlePayClick}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    Pay $50.00
                &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"card-errors"&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"slds-m-top_small slds-text-color_error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/lightning-card&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;stripePaymentForm.js&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// File: force-app/main/default/lwc/stripePaymentForm/stripePaymentForm.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LightningElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lwc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ShowToastEvent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lightning/platformShowToastEvent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;processPayment&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@salesforce/apex/PaymentController.processPayment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loadScript&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lightning/platformResourceLoader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;STRIPE_JS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@salesforce/resourceUrl/stripe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StripePaymentForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;LightningElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;cardElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Replace with your Stripe TEST Publishable Key&lt;/span&gt;
    &lt;span class="nx"&gt;stripePublishableKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pk_test_...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- PASTE YOUR KEY HERE&lt;/span&gt;
    &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;50.00&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

    &lt;span class="nf"&gt;renderedCallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Prevents script from being loaded multiple times&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;loadScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STRIPE_JS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initializeStripe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error loading Stripe.js:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Could not load payment form.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;initializeStripe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Stripe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripePublishableKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;16px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#424770&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#card-element&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#card-errors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;displayError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;displayError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;handlePayClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submitButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#submit-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;submitButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#card-errors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;errorElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;submitButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;stripeToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SUCCESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Payment was successful.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Clear the form&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Payment Failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apexError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Apex Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apexError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;submitButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;showToast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ShowToastEvent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;stripePaymentForm.js-meta.xml&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;LightningComponentBundle&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://soap.sforce.com/2006/04/metadata"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;apiVersion&amp;gt;&lt;/span&gt;58.0&lt;span class="nt"&gt;&amp;lt;/apiVersion&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;isExposed&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/isExposed&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;lightning__AppPage&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;lightning__RecordPage&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;lightning__HomePage&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/LightningComponentBundle&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 7: Deploy and Add to Your Home Page
&lt;/h3&gt;

&lt;p&gt;You're ready to see it in action!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Deploy:&lt;/strong&gt; In VS Code, open the Command Palette (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;) and run &lt;code&gt;SFDX: Deploy Source to Org&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Create a Home Page:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  In Salesforce Setup, go to &lt;strong&gt;Lightning App Builder&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Click &lt;strong&gt;New&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Select &lt;strong&gt;Home Page&lt;/strong&gt; and click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Give it a name like "Payment Home" and click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Click &lt;strong&gt;Finish&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Add Your Component:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  On the left side, under "Standard Components," find your &lt;strong&gt;stripePaymentForm&lt;/strong&gt; component.&lt;/li&gt;
&lt;li&gt;  Drag it onto the page canvas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Save and Activate:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  You will be taken to the activation screen. Select &lt;strong&gt;"App Default"&lt;/strong&gt; and choose an app (e.g., "Sales").&lt;/li&gt;
&lt;li&gt;  Click &lt;strong&gt;Save&lt;/strong&gt;, then &lt;strong&gt;Activate&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, navigate to the Home tab in the app you selected. You will see your fully functional Stripe payment form! You can test it with the Stripe test card number: &lt;code&gt;4242 4242 4242 4242&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>How to Connect Stripe Payments to Salesforce (Step-by-Step Guide)</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Sat, 07 Mar 2026 15:15:08 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/how-to-connect-stripe-payments-to-salesforce-step-by-step-guide-54bh</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/how-to-connect-stripe-payments-to-salesforce-step-by-step-guide-54bh</guid>
      <description>&lt;p&gt;Integrating Stripe with Salesforce allows you to accept payments and save transaction data directly into your CRM. No more switching between tabs—your payment status and transaction IDs will live right inside your Salesforce records.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create Your Stripe Account &amp;amp; Get API Keys&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://stripe.com/in" rel="noopener noreferrer"&gt;Stripe.com&lt;/a&gt; and sign up for a free account.&lt;/li&gt;
&lt;li&gt;Once logged in, switch to Test Mode (toggle on the left side).&lt;/li&gt;
&lt;li&gt;Go to Developers &amp;gt; API Keys.&lt;/li&gt;
&lt;li&gt;Copy your Publishable Key (starts with pk_test_...) and Secret Key (starts with sk_test_...).&lt;/li&gt;
&lt;li&gt;Note: Keep your Secret Key safe. Never share it publicly!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Prepare Salesforce&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a Custom Object:&lt;/strong&gt; Go to &lt;code&gt;Setup &amp;gt; Object Manager &amp;gt; Create &amp;gt; Custom&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Object&lt;/strong&gt;. Name it&lt;code&gt;Payment_Transaction__c&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add Fields:&lt;/strong&gt; Create these fields:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Payment_ID__c&lt;/code&gt; (Text, length 255)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Status__c&lt;/code&gt; (Text, length 50)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Amount__c&lt;/code&gt; (Currency)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.Add Remote Site:&lt;/strong&gt;&lt;br&gt;
 Go to &lt;code&gt;Setup &amp;gt; Quick Find &amp;gt; "Remote Site Settings"&lt;/code&gt;. Add a new site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt;&lt;code&gt;Stripe_API&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;code&gt;https://api.stripe.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Secure the Connection&lt;/strong&gt;&lt;br&gt;
Don’t hardcode your API keys in the code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Setup &amp;gt; Named Credentials.&lt;/li&gt;
&lt;li&gt;Create a new Named Credential.&lt;/li&gt;
&lt;li&gt;Name: Stripe_Named_Credential.&lt;/li&gt;
&lt;li&gt;URL: &lt;a href="https://api.stripe.com" rel="noopener noreferrer"&gt;https://api.stripe.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Select "Password Authentication" and enter your Secret Key as the Password.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 4: The Apex Controller (Backend)&lt;/strong&gt;&lt;br&gt;
This Apex code sends the payment request to Stripe and saves the response into your &lt;code&gt;Payment_Transaction__c&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public with sharing class PaymentController {

    @AuraEnabled
    public static String processAndSavePayment(Decimal amount, String stripeToken) {
        try {
            Http http = new Http();
            HttpRequest req = new HttpRequest();
            // Use your Named Credential here
            req.setEndpoint('callout:Stripe_Named_Credential/v1/charges');
            req.setMethod('POST');
            req.setBody('amount=' + (Integer)(amount * 100) + '&amp;amp;currency=usd&amp;amp;source=' + stripeToken);

            HttpResponse res = http.send(req);
            Map&amp;lt;String, Object&amp;gt; responseMap = (Map&amp;lt;String, Object&amp;gt;) JSON.deserializeUntyped(res.getBody());

            if (res.getStatusCode() == 200) {
                Payment_Transaction__c txn = new Payment_Transaction__c(
                    Payment_ID__c = (String)responseMap.get('id'),
                    Status__c = (String)responseMap.get('status'),
                    Amount__c = amount
                );
                insert txn;
                return 'SUCCESS:' + txn.Payment_ID__c;
            }
            return 'ERROR: Payment Failed';
        } catch (Exception e) {
            return 'ERROR: ' + e.getMessage();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Add a CSP Trusted Site&lt;/strong&gt;&lt;br&gt;
Salesforce has a strict security system called Content Security Policy (CSP). To allow your Lightning Web Component (LWC) to communicate with Stripe’s external servers, you must whitelist the Stripe URL.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your Salesforce Admin account.&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Gear Icon&lt;/strong&gt; at the top right corner and select Setup.&lt;/li&gt;
&lt;li&gt;In the Quick Find box on the left, type &lt;code&gt;"CSP Trusted Sites"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click on &lt;code&gt;CSP&lt;/code&gt;Trusted Sites from the search results.&lt;/li&gt;
&lt;li&gt;Click the New Trusted Site button.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Configure Trusted Site Details&lt;/strong&gt;&lt;br&gt;
Fill in the form with the following information to permit communication:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Trusted Site Name:&lt;/strong&gt; &lt;code&gt;Stripe_JS_CDN&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;2. Trusted Site URL:&lt;/strong&gt; &lt;code&gt;https://js.stripe.com&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;3. Active:&lt;/strong&gt; Check the &lt;code&gt;Active&lt;/code&gt;checkbox to enable the site.&lt;br&gt;
**4. CSP Directives: **Under the CSP Directives section, ensure both "Allow JavaScript Connectors" and "Allow Font Connectors" are checked.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 6: The Lightning Web Component (Frontend)&lt;/strong&gt;&lt;br&gt;
Create an LWC with a button. When clicked, it generates a token via Stripe and sends it to the Apex class above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { LightningElement } from 'lwc';
import processAndSavePayment from '@salesforce/apex/PaymentController.processAndSavePayment';

export default class PaymentComponent extends LightningElement {

    async handlePayClick() {
        // Use Stripe JS to tokenize card data
        const stripe = window.Stripe('pk_test_YOUR_KEY');
        const cardElement = this.template.querySelector('c-card-element');
        const { token } = await stripe.createToken(cardElement);

        processAndSavePayment({ amount: 50.00, stripeToken: token.id })
            .then(result =&amp;gt; {
                alert(result.startsWith('SUCCESS') ? 'Payment Saved!' : 'Error Occurred');
            });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Summary Checklist for Your Blog&lt;/strong&gt;&lt;br&gt;
Safety First: We used Named Credentials, so your Secret Key is never exposed in the code.&lt;/p&gt;

&lt;p&gt;Data Integrity: We use insert in the same transaction as the API call, ensuring that no payment succeeds without a record being saved.&lt;/p&gt;

&lt;p&gt;User Experience: The user gets an instant confirmation once the button is clicked.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>salesforce</category>
    </item>
    <item>
      <title>🔗 Salesforce Integration with JavaScript: Get Access Token &amp; Perform CRUD</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Wed, 10 Sep 2025 10:02:17 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/salesforce-integration-with-javascript-get-access-token-perform-crud-m5b</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/salesforce-integration-with-javascript-get-access-token-perform-crud-m5b</guid>
      <description>&lt;p&gt;Salesforce provides powerful REST APIs that allow developers to interact with Salesforce data from external applications. In this blog, we’ll learn how to:&lt;/p&gt;

&lt;p&gt;✅ Get an Access Token from Salesforce using JavaScript&lt;br&gt;
✅ Perform CRUD operations (Create, Read, Update, Delete) on Salesforce records&lt;br&gt;
✅ Test everything in a simple HTML + JS file without extra tools&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we start, you’ll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Salesforce Developer Org (free: signup here)&lt;/li&gt;
&lt;li&gt;A Connected App created in Salesforce with OAuth enabled&lt;/li&gt;
&lt;li&gt;Your Client ID, Client Secret, Username, Password, and Security Token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🔑 Step 1: Create a Connected App in Salesforce&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;code&gt;Setup → App Manager → New Connected App&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enter the following:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;JS Integration&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Enable OAuth Settings ✅&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Callback URL:&lt;/strong&gt; 
&lt;a href="https://www.postman.com/oauth2/callback" rel="noopener noreferrer"&gt;https://www.postman.com/oauth2/callback&lt;/a&gt; (or your app URL)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;OAuth Scopes:&lt;/strong&gt;&lt;br&gt;
          -Full access (full)&lt;br&gt;
          -Access and manage your data (api)&lt;br&gt;
          -Perform requests on your behalf &lt;br&gt;
            (refresh_token,     offline_access)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Save → Copy the Client ID and Client Secret&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;🔑 Step 2: Get Access Token via JavaScript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Salesforce uses OAuth 2.0 for authentication. In testing, we can use the Password Grant Flow.&lt;/p&gt;

&lt;p&gt;Here’s how we request an access token with plain JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getAccessToken() {
  const body = new URLSearchParams({
    grant_type: "password",
    client_id: "YOUR_CLIENT_ID",
    client_secret: "YOUR_CLIENT_SECRET",
    username: "YOUR_SALESFORCE_USERNAME",
    password: "YOUR_PASSWORD_WITH_SECURITY_TOKEN"
  });

  return fetch("https://login.salesforce.com/services/oauth2/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: body
  })
  .then(res =&amp;gt; res.json())
  .then(data =&amp;gt; {
    console.log("Access Token:", data.access_token);
    return data;
  });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔨 Step 3: Perform CRUD Operations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you have the access_token and instance_url, you can interact with Salesforce objects.&lt;/p&gt;

&lt;p&gt;Here’s a full HTML + JavaScript example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Salesforce CRUD Example&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;h2&amp;gt;Salesforce CRUD via JavaScript&amp;lt;/h2&amp;gt;
  &amp;lt;script&amp;gt;
    const clientId = "YOUR_CLIENT_ID";
    const clientSecret = "YOUR_CLIENT_SECRET";
    const username = "YOUR_SALESFORCE_USERNAME";
    const password = "YOUR_PASSWORD_WITH_SECURITY_TOKEN";
    const loginUrl = "https://login.salesforce.com"; 
    const apiVersion = "v59.0";

    let accessToken = "";
    let instanceUrl = "";

    // 1️⃣ Get Access Token
    function getAccessToken() {
      const body = new URLSearchParams({
        grant_type: "password",
        client_id: clientId,
        client_secret: clientSecret,
        username: username,
        password: password
      });

      return fetch(`${loginUrl}/services/oauth2/token`, {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: body
      })
      .then(res =&amp;gt; res.json())
      .then(data =&amp;gt; {
        console.log("🔑 Access Token:", data);
        accessToken = data.access_token;
        instanceUrl = data.instance_url;
        return data;
      });
    }

    // 2️⃣ CREATE
    function createAccount() {
      fetch(`${instanceUrl}/services/data/${apiVersion}/sobjects/Account/`, {
        method: "POST",
        headers: {
          "Authorization": "Bearer " + accessToken,
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          Name: "JS Test Account",
          Phone: "1234567890"
        })
      })
      .then(res =&amp;gt; res.json())
      .then(data =&amp;gt; {
        console.log("✅ Account Created:", data);
        getAccount(data.id);
      });
    }

    // 3️⃣ READ
    function getAccount(accountId) {
      fetch(`${instanceUrl}/services/data/${apiVersion}/sobjects/Account/${accountId}`, {
        method: "GET",
        headers: { "Authorization": "Bearer " + accessToken }
      })
      .then(res =&amp;gt; res.json())
      .then(data =&amp;gt; {
        console.log("📖 Account Data:", data);
        updateAccount(accountId);
      });
    }

    // 4️⃣ UPDATE
    function updateAccount(accountId) {
      fetch(`${instanceUrl}/services/data/${apiVersion}/sobjects/Account/${accountId}`, {
        method: "PATCH",
        headers: {
          "Authorization": "Bearer " + accessToken,
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ Phone: "9876543210" })
      })
      .then(res =&amp;gt; {
        if (res.status === 204) {
          console.log("✏️ Account Updated!");
          deleteAccount(accountId);
        } else {
          console.log("❌ Update Failed");
        }
      });
    }

    // 5️⃣ DELETE
    function deleteAccount(accountId) {
      fetch(`${instanceUrl}/services/data/${apiVersion}/sobjects/Account/${accountId}`, {
        method: "DELETE",
        headers: { "Authorization": "Bearer " + accessToken }
      })
      .then(res =&amp;gt; {
        if (res.status === 204) {
          console.log("🗑️ Account Deleted!");
        } else {
          console.log("❌ Delete Failed");
        }
      });
    }

    // 🚀 Run: Login then CRUD
    getAccessToken().then(() =&amp;gt; createAccount());
  &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔒 Security Considerations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Password Grant Flow exposes your Salesforce password → only use for testing.&lt;/li&gt;
&lt;li&gt;For production apps, always use the OAuth Web Server Flow (authorization code).&lt;/li&gt;
&lt;li&gt;Never commit your Client Secret or Access Token to GitHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;🎯 Conclusion&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With just a few lines of JavaScript, you can:&lt;/li&gt;
&lt;li&gt;Authenticate with Salesforce&lt;/li&gt;
&lt;li&gt;Create, Read, Update, and Delete records&lt;/li&gt;
&lt;li&gt;Test your API integration in the browser&lt;/li&gt;
&lt;li&gt;This approach is perfect for learning, prototyping, or small automation tasks.&lt;/li&gt;
&lt;li&gt;For production, switch to secure OAuth flows and use server-side code (Node.js, Java, .NET, etc.).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>salesforce</category>
      <category>integration</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building a QR Code Generator in Salesforce Using LWC</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Sun, 17 Aug 2025 14:51:18 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/building-a-qr-code-generator-in-salesforce-using-lwc-2dab</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/building-a-qr-code-generator-in-salesforce-using-lwc-2dab</guid>
      <description>&lt;p&gt;QR codes are a convenient way to share information such as URLs, IDs, or text strings in a compact scannable format. With Salesforce Lightning Web Components (LWC), you can build a QR Code Generator that works directly inside Salesforce pages such as Home, Record, or App Pages. In this blog, we'll walk through how to implement this step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you start, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Salesforce org (Developer Edition or Sandbox is fine)&lt;/li&gt;
&lt;li&gt;Familiarity with LWC basics&lt;/li&gt;
&lt;li&gt;Access to upload static resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Download and Upload the QR Code Library
&lt;/h2&gt;

&lt;p&gt;We will use the popular &lt;a href="https://github.com/sabirsheikh007/QRCode-JS-Lib" rel="noopener noreferrer"&gt;QRCode.js&lt;/a&gt; library to generate QR codes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the &lt;code&gt;qrcode.min.js&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;In Salesforce Setup, search for Static Resources.&lt;/li&gt;
&lt;li&gt;Upload the file as a static resource with the name: &lt;strong&gt;qrcode&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Create a New Lightning Web Component
&lt;/h2&gt;

&lt;p&gt;Run the following command (if using Salesforce CLI):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sfdx force:lightning:component:create --type lwc --componentname qrcodeGenrate --outputdir force-app/main/default/lwc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create the component folder with .js, .html, and .js-meta.xml files.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Implement the Component Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;qrcodeGenrate.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { LightningElement, track } from 'lwc';
import qrcodeLib from '@salesforce/resourceUrl/qrcode';
import { loadScript } from 'lightning/platformResourceLoader';

export default class QrcodeGenrate extends LightningElement {
    @track inputText = '';
    qrcodeInitialized = false;
    qrLibLoaded = false;

    renderedCallback() {
        if (this.qrcodeInitialized) return;
        this.qrcodeInitialized = true;

        loadScript(this, qrcodeLib)
            .then(() =&amp;gt; {
                this.qrLibLoaded = true;
                console.log('✅ QRCode library loaded');
            })
            .catch(error =&amp;gt; {
                console.error('❌ Error loading QRCode library', error);
            });
    }

    handleChange(event) {
        this.inputText = event.target.value;
    }

    generateQRCode() {
        if (!this.qrLibLoaded) {
            alert('QR Code library not loaded yet');
            return;
        }

        if (!this.inputText) {
            alert('Please enter some text or URL');
            return;
        }

        const container = this.template.querySelector('.qrcode');
        container.innerHTML = ""; // clear old QR

        // ✅ Use window.QRCode
        new window.QRCode(container, {
            text: this.inputText,
            width: 200,
            height: 200
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;qrcodeGenrate.html&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;lightning-card title="QR Code Generator"&amp;gt;
        &amp;lt;div class="slds-p-around_medium"&amp;gt;
            &amp;lt;lightning-input
                label="Enter Text or URL"
                value={inputText}
                onchange={handleChange}&amp;gt;
            &amp;lt;/lightning-input&amp;gt;

            &amp;lt;lightning-button
                label="Generate QR Code"
                onclick={generateQRCode}
                class="slds-m-top_small"&amp;gt;
            &amp;lt;/lightning-button&amp;gt;

            &amp;lt;!-- QR Code will appear here --&amp;gt;
            &amp;lt;div class="qrcode" style="margin-top:20px;"&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/lightning-card&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;qrcodeGenrate.js-meta.xml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"&amp;gt;
    &amp;lt;apiVersion&amp;gt;59.0&amp;lt;/apiVersion&amp;gt;
    &amp;lt;isExposed&amp;gt;true&amp;lt;/isExposed&amp;gt;
    &amp;lt;targets&amp;gt;
        &amp;lt;target&amp;gt;lightning__RecordPage&amp;lt;/target&amp;gt;
        &amp;lt;target&amp;gt;lightning__AppPage&amp;lt;/target&amp;gt;
        &amp;lt;target&amp;gt;lightning__HomePage&amp;lt;/target&amp;gt;
    &amp;lt;/targets&amp;gt;
&amp;lt;/LightningComponentBundle&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Deploy and Test the Component
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Deploy the component to your org.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;App Builder&lt;/strong&gt; (e.g., Home Page → Edit Page).&lt;/li&gt;
&lt;li&gt;Drag and drop the &lt;strong&gt;QR Code Generator&lt;/strong&gt; component onto the page.&lt;/li&gt;
&lt;li&gt;Enter text or a URL and click Generate &lt;strong&gt;QR Code&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  6. Possible Enhancements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Auto-generate QR code as you type (no button click needed).&lt;/li&gt;
&lt;li&gt;Add a download button to save the QR code as an image.&lt;/li&gt;
&lt;li&gt;Store QR code data in Salesforce records.&lt;/li&gt;
&lt;li&gt;Support dynamic QR codes that can redirect to Salesforce pages.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>lwc</category>
      <category>salesforce</category>
    </item>
    <item>
      <title>🔐 Building JWT Authentication in ASP.NET Core (Step-by-Step)</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Sun, 20 Jul 2025 05:04:03 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/building-jwt-authentication-in-aspnet-core-step-by-step-4ihe</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/building-jwt-authentication-in-aspnet-core-step-by-step-4ihe</guid>
      <description>&lt;p&gt;In modern web applications, JWT (JSON Web Token) is a powerful and widely used technique for securing APIs. This guide will walk you through how to implement JWT authentication in an ASP.NET Core MVC project using a practical controller and configuration example.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;.NET Core SDK installed&lt;/li&gt;
&lt;li&gt;Visual Studio or VS Code&lt;/li&gt;
&lt;li&gt;Basic understanding of ASP.NET Core&lt;/li&gt;
&lt;li&gt;NuGet packages:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microsoft.AspNetCore.Authentication.JwtBearer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.IdentityModel.Tokens.Jwt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎯 Project Overview
&lt;/h2&gt;

&lt;p&gt;We are building a simple API that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accepts login credentials&lt;/li&gt;
&lt;li&gt;Generates a JWT token if the credentials are correct&lt;/li&gt;
&lt;li&gt;Provides a protected endpoint (TestApi2) accessible only with a valid token&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠 Step 1: Configure JWT in &lt;code&gt;Startup.cs&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🔐 &lt;code&gt;ConfigureServices&lt;/code&gt;– JWT Setup&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services)
{
    string securityKey = "Your256BitSecretKeyWhichNeedsToBe32BytesLong!"; // Must be 32 bytes
    var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =&amp;gt;
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = "myshop.com.in",
                ValidAudience = "user",
                IssuerSigningKey = symmetricSecurityKey
            };
        });

    services.Configure&amp;lt;CookiePolicyOptions&amp;gt;(options =&amp;gt;
    {
        options.CheckConsentNeeded = context =&amp;gt; true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;✅ Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The securityKey must be 32 bytes when using HMAC SHA-256.&lt;/li&gt;
&lt;li&gt;The token is validated based on Issuer, Audience, and SigningKey.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🔁 &lt;code&gt;Configure&lt;/code&gt;– Middleware&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseAuthentication(); // 🔐 Add JWT Authentication middleware
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc(routes =&amp;gt;
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Important: &lt;code&gt;app.UseAuthentication()&lt;/code&gt; must be called before &lt;code&gt;UseMvc()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Step 2: Create JWT Controller
&lt;/h2&gt;

&lt;p&gt;Here’s a breakdown of your &lt;code&gt;TestJWTController&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpPost]
public IActionResult GetToken()
{
    string securityKey = "Your256BitSecretKeyWhichNeedsToBe32BytesLong!";
    var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
    var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: "myshop.com.in",
        audience: "user",
        expires: DateTime.Now.AddHours(1),
        signingCredentials: signingCredentials
    );

    return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔐 &lt;code&gt;/GetToken&lt;/code&gt; Endpoint&lt;/strong&gt;&lt;br&gt;
This endpoint generates a JWT token signed with your &lt;code&gt;securityKey&lt;/code&gt;.&lt;br&gt;
The token is valid for 1 hour.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;🧪 &lt;code&gt;/Login&lt;/code&gt; Endpoint (Dummy Authentication)&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpPost]
public string Login([FromBody] LoginModel login)
{
    if (login.Username == "sabir" &amp;amp;&amp;amp; login.Password == "sabir")
    {
        return "Success";
    }
    return "Unauthorized";
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Simple login check with hardcoded credentials.&lt;/li&gt;
&lt;li&gt;In a real-world app, validate against a database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;🔓 &lt;code&gt;/TestApi&lt;/code&gt; – Public Endpoint&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpPost]
public string TestApi()
{
    byte[] key = new byte[16];
    using (var rng = new RNGCryptoServiceProvider())
    {
        rng.GetBytes(key);
    }

    return Convert.ToBase64String(key);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Generates a 128-bit random key.&lt;/li&gt;
&lt;li&gt;This API is accessible without authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;🔐 &lt;code&gt;/TestApi2&lt;/code&gt; – Protected with &lt;code&gt;[Authorize]&lt;/code&gt;&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpPost]
[Authorize]
public string TestApi2()
{
    byte[] key = new byte[16];
    using (var rng = new RNGCryptoServiceProvider())
    {
        rng.GetBytes(key);
    }

    return "Auth" + Convert.ToBase64String(key);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You must send a valid JWT token in the Authorization header to access this.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization: Bearer &amp;lt;your_token_here&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📦 LoginModel Class
&lt;/h2&gt;

&lt;p&gt;Used to bind JSON payload during login:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class LoginModel
{
    public string Username { get; set; }
    public string Password { get; set; }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Testing the Flow
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Get Token&lt;/strong&gt;&lt;br&gt;
POST /TestJWT/GetToken&lt;br&gt;
→ Returns JWT token&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Access Unprotected API&lt;/strong&gt;&lt;br&gt;
POST /TestJWT/TestApi&lt;br&gt;
→ Always works&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Access Protected API&lt;/strong&gt;&lt;br&gt;
POST /TestJWT/TestApi2 with Header:&lt;br&gt;
Authorization: Bearer &lt;br&gt;
→ Returns response only if token is valid&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Final Thoughts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔒 JWT is great for securing APIs in stateless applications.&lt;/li&gt;
&lt;li&gt;🚫 Do not hardcode credentials or secrets in production.&lt;/li&gt;
&lt;li&gt;🛡 Always store JWT secret keys in a secure config like Azure Key Vault or AWS Secrets Manager.&lt;/li&gt;
&lt;li&gt;👨‍💻 Use middleware and services to centralize token handling and validation.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Complete Guide: Building a Google Forms to Salesforce Webhook Integration</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Mon, 07 Jul 2025 18:32:08 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/complete-guide-building-a-google-forms-to-salesforce-webhook-integration-55he</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/complete-guide-building-a-google-forms-to-salesforce-webhook-integration-55he</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
Integrating Google Forms with Salesforce via webhooks enables real-time data transfer without third-party tools. This guide covers the end-to-end implementation, troubleshooting common errors, and best practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 1: Architecture Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8guud1yikqsurr9fwp2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8guud1yikqsurr9fwp2j.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Google Form:&lt;/strong&gt; Collects user data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Apps Script:&lt;/strong&gt; Processes form submissions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salesforce REST Endpoint:&lt;/strong&gt; Receives and stores data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth 2.0:&lt;/strong&gt; Secures the connection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Section 2: Step-by-Step Implementation&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Prepare Salesforce&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a REST Endpoint
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestResource(urlMapping='/form-submissions/*')
global class FormWebhook {

    @HttpPost
    global static String processFormData() {
        try {
            // Parse incoming JSON
            RestRequest req = RestContext.request;
            Map&amp;lt;String, Object&amp;gt; payload = (Map&amp;lt;String, Object&amp;gt;)JSON.deserializeUntyped(req.requestbody.toString());

            // Create Lead record
            Lead newLead = new Lead(
                FirstName = String.valueOf(payload.get('firstName')),
                LastName = String.valueOf(payload.get('lastName')),
                Email = String.valueOf(payload.get('email')),
                Company = String.valueOf(payload.get('company'))
            );
            insert newLead;

            return '{"status": "success", "recordId": "' + newLead.Id + '"}';

        } catch(Exception e) {
            return '{"error": "' + e.getMessage() + '"}';
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Enable Remote Site Settings&lt;/strong&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to Setup → Security → Remote Site Settings&lt;/li&gt;
&lt;li&gt;Add &lt;a href="https://script.google.com" rel="noopener noreferrer"&gt;https://script.google.com&lt;/a&gt; as a trusted domain`&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Set Up Google Apps Script&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the Webhook Handler
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function onFormSubmit(e) {
  const sfEndpoint = 'https://yourdomain.salesforce.com/services/apexrest/form-submissions';
  const accessToken = getSalesforceToken(); // See Step 3 for OAuth setup

  const payload = {
    firstName: e.namedValues['First Name'][0],
    lastName: e.namedValues['Last Name'][0],
    email: e.namedValues['Email'][0],
    company: e.namedValues['Company'][0]
  };

  const options = {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + accessToken,
      'Content-Type': 'application/json'
    },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };

  try {
    const response = UrlFetchApp.fetch(sfEndpoint, options);
    const result = JSON.parse(response.getContentText());

    if (result.error) {
      Logger.log('Error: ' + result.error);
      sendErrorEmail(result.error); // Implement error handling
    } else {
      Logger.log('Success: Record ID ' + result.recordId);
    }
  } catch (error) {
    Logger.log('Connection Error: ' + error.toString());
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Configure the Trigger&lt;/strong&gt;&lt;br&gt;
Open script editor in Google Forms&lt;br&gt;
&lt;code&gt;Go to Edit → Current project's triggers&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Set:&lt;/strong&gt;&lt;br&gt;
    &lt;strong&gt;Function:&lt;/strong&gt; &lt;code&gt;onFormSubmit&lt;/code&gt;&lt;br&gt;
    &lt;strong&gt;Event:&lt;/strong&gt; On form submit&lt;br&gt;
    &lt;strong&gt;Failure notification:&lt;/strong&gt; Daily&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 3: Authentication Methods&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Option A:&lt;/strong&gt; Password-Based OAuth&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getSalesforceToken() {
  const loginUrl = 'https://login.salesforce.com/services/oauth2/token';

  const params = {
    method: 'POST',
    payload: {
      grant_type: 'password',
      client_id: 'YOUR_CONSUMER_KEY',
      client_secret: 'YOUR_CONSUMER_SECRET',
      username: 'salesforce@email.com',
      password: 'PASSWORD+SECURITY_TOKEN'
    }
  };

  const response = UrlFetchApp.fetch(loginUrl, params);
  return JSON.parse(response).access_token;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Option B: JWT Bearer Flow (Recommended for Production)&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a self-signed certificate:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout private.key -out cert.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Upload cert.pem to Salesforce:
&lt;code&gt;Setup → Certificate and Key Management&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use this Apps Script function:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getJWTAccessToken() {
  const jwtHeader = Utilities.base64Encode(JSON.stringify({
    "alg": "RS256",
    "typ": "JWT"
  }));

  const jwtClaim = Utilities.base64Encode(JSON.stringify({
    "iss": "YOUR_CONSUMER_KEY",
    "sub": "user@domain.com",
    "aud": "https://login.salesforce.com",
    "exp": Math.floor(Date.now()/1000) + 300
  }));

  const signature = Utilities.computeRsaSha256Signature(
    jwtHeader + "." + jwtClaim,
    "-----BEGIN PRIVATE KEY-----\n" + 
    "YOUR_PRIVATE_KEY\n" +
    "-----END PRIVATE KEY-----"
  );

  const jwt = jwtHeader + "." + jwtClaim + "." + Utilities.base64Encode(signature);

  const response = UrlFetchApp.fetch('https://login.salesforce.com/services/oauth2/token', {
    method: 'POST',
    payload: {
      grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
      assertion: jwt
    }
  });

  return JSON.parse(response).access_token;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Section 4: Testing &amp;amp; Debugging&lt;br&gt;
Test Cases&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Complete Guide: Sending Google Form Data to Salesforce Using Webhooks</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Mon, 07 Jul 2025 15:28:03 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/complete-guide-sending-google-form-data-to-salesforce-using-webhooks-1lp5</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/complete-guide-sending-google-form-data-to-salesforce-using-webhooks-1lp5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
Webhooks provide a powerful way to connect Google Forms with Salesforce in real-time. This guide walks through the entire process from setup to implementation, including troubleshooting tips.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Section 1: Prerequisites&lt;/strong&gt;&lt;br&gt;
Before beginning, ensure you have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Google Workspace account&lt;/strong&gt; (for Google Forms and Apps Script)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salesforce account&lt;/strong&gt; with API access enabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic understanding&lt;/strong&gt; of:&lt;/li&gt;
&lt;li&gt;Google Apps Script (JavaScript-based)&lt;/li&gt;
&lt;li&gt;Salesforce REST API&lt;/li&gt;
&lt;li&gt;Webhook concepts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Section 2: Implementation Steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create Your Salesforce Webhook Endpoint&lt;/strong&gt;&lt;br&gt;
In Salesforce Setup, navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Setup → Develop → Apex Classes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new Apex REST class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RestResource(urlMapping='/form-submissions/*')
global class GoogleFormWebhook {
    @HttpPost
    global static void handleFormSubmission() {
        RestRequest req = RestContext.request;
        Map&amp;lt;String, Object&amp;gt; formData = (Map&amp;lt;String, Object&amp;gt;)JSON.deserializeUntyped(req.requestBody.toString());

        // Process data and create Salesforce records
        Lead newLead = new Lead(
            FirstName = (String)formData.get('firstName'),
            LastName = (String)formData.get('lastName'),
            Email = (String)formData.get('email'),
            Company = (String)formData.get('company')
        );
        insert newLead;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy the class and note your endpoint URL:&lt;br&gt;
&lt;a href="https://yourdomain.my.salesforce.com/services/apexrest/form-submissions" rel="noopener noreferrer"&gt;https://yourdomain.my.salesforce.com/services/apexrest/form-submissions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Configure the Google Form Webhook&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open your Google Form → Click "⋮" → Script Editor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste this script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function onFormSubmit(e) {
  const webhookUrl = 'YOUR_SALESFORCE_ENDPOINT_URL';
  const authToken = 'YOUR_SALESFORCE_SECURITY_TOKEN';

  const headers = {
    "Authorization": "Bearer " + authToken,
    "Content-Type": "application/json"
  };

  const payload = {
    "firstName": e.namedValues['First Name'][0],
    "lastName": e.namedValues['Last Name'][0],
    "email": e.namedValues['Email'][0],
    "company": e.namedValues['Company'][0]
    // Add other form fields as needed
  };

  const options = {
    "method": "POST",
    "headers": headers,
    "payload": JSON.stringify(payload),
    "muteHttpExceptions": true
  };

  try {
    const response = UrlFetchApp.fetch(webhookUrl, options);
    Logger.log("Submission success: " + response.getContentText());
  } catch (error) {
    Logger.log("Error: " + error.toString());
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Set Up the Trigger&lt;/strong&gt;&lt;br&gt;
In the Apps Script editor:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
Go to Edit → Current project's triggers&lt;br&gt;
Click + Add Trigger&lt;br&gt;
Configure:&lt;br&gt;
Function to run: onFormSubmit&lt;br&gt;
Event: "On form submit"&lt;br&gt;
Failure notifications: Daily&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Test the Integration&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Submit a test form&lt;br&gt;
Check:&lt;br&gt;
Apps Script logs (View → Logs)&lt;br&gt;
Salesforce debug logs (Setup → Debug → Logs)&lt;br&gt;
Verify the new Lead record appears in Salesforce&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Send Email Using JSP and JavaMail API</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Sun, 06 Jul 2025 18:40:39 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/how-to-send-email-using-jsp-and-javamail-api-pam</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/how-to-send-email-using-jsp-and-javamail-api-pam</guid>
      <description>&lt;p&gt;Sending emails from a JSP page is very useful for contact forms, notifications, and automation in Java web applications. In this guide, you’ll learn how to send a simple text email using JSP + JavaMail API, step by step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Requirements&lt;/strong&gt;&lt;br&gt;
Before you begin, you need the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;JavaMail API Library
Download from the official GitHub:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;JavaMail (javax.mail.jar):&lt;br&gt;
[&lt;a href="https://repo1.maven.org/maven2/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2.jar" rel="noopener noreferrer"&gt;https://repo1.maven.org/maven2/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2.jar&lt;/a&gt;]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;JavaBeans Activation Framework (activation.jar)
Download:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;activation.jar:&lt;br&gt;
[&lt;a href="https://repo1.maven.org/maven2/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2.jar" rel="noopener noreferrer"&gt;https://repo1.maven.org/maven2/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2.jar&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;📁 Place both JARs in your project’s WEB-INF/lib folder.&lt;/p&gt;

&lt;p&gt;📝 Instructions to Use:&lt;br&gt;
Download both .jar files.&lt;/p&gt;

&lt;p&gt;Place them in your project’s WEB-INF/lib folder if using a Java web app.&lt;/p&gt;

&lt;p&gt;Make sure your server (e.g., Apache Tomcat) loads them at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📄 Step-by-Step Implementation in JSP&lt;/strong&gt;&lt;br&gt;
Here’s a complete working example of sending an email from a sendmail.jsp file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%@ page import="java.util.*, javax.mail.*, javax.mail.internet.*" %&amp;gt;
&amp;lt;%
    final String senderEmail = "your_email@gmail.com";
    final String senderPassword = "your_app_password"; // App Password, not Gmail password
    String recipient = "recipient@example.com";
    String subject = "Test Mail from JSP";
    String messageText = "This is a test email sent from JSP page.";

    Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.port", "587");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");

    Session session = Session.getInstance(props,
        new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(senderEmail, senderPassword);
            }
        });

    try {
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(senderEmail));
        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
        message.setSubject(subject);
        message.setText(messageText);
        Transport.send(message);

        out.println("&amp;lt;h3&amp;gt;Email sent successfully!&amp;lt;/h3&amp;gt;");
    } catch (MessagingException e) {
        out.println("&amp;lt;h3&amp;gt;Error: " + e.getMessage() + "&amp;lt;/h3&amp;gt;");
        e.printStackTrace(out);
    }
%&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔐 Gmail App Password Setup&lt;br&gt;
Since Google doesn't allow you to use your Gmail password directly, follow these steps:&lt;/p&gt;

&lt;p&gt;Turn on 2-Step Verification for your Google account.&lt;/p&gt;

&lt;p&gt;Go to: [&lt;a href="https://myaccount.google.com/apppasswords" rel="noopener noreferrer"&gt;https://myaccount.google.com/apppasswords&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Generate a new App Password.&lt;/p&gt;

&lt;p&gt;Use this password in place of your Gmail password in the JSP code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📌 Tips&lt;/strong&gt;&lt;br&gt;
Never use real credentials in public code.&lt;/p&gt;

&lt;p&gt;Always handle exceptions gracefully.&lt;/p&gt;

&lt;p&gt;For real-world projects, separate business logic (email sending) into a Servlet or Java Bean instead of putting it directly in JSP.&lt;br&gt;
&lt;strong&gt;🧾 Summary&lt;/strong&gt;&lt;br&gt;
| Component      | Description                       |&lt;br&gt;
| -------------- | --------------------------------- |&lt;br&gt;
| JSP Page       | Sends email using JavaMail API    |&lt;br&gt;
| JavaMail Jar   | &lt;code&gt;javax.mail-1.6.2.jar&lt;/code&gt;            |&lt;br&gt;
| Activation Jar | &lt;code&gt;activation-1.1.1.jar&lt;/code&gt;            |&lt;br&gt;
| SMTP Server    | Gmail SMTP (&lt;code&gt;smtp.gmail.com:587&lt;/code&gt;) |&lt;br&gt;
| Authentication | Gmail App Password                |&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Node JS Upload Multiple Files</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Thu, 12 Jun 2025 09:15:52 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/node-js-upload-multiple-files-22kc</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/node-js-upload-multiple-files-22kc</guid>
      <description>&lt;p&gt;You can upload multiple files using multer in Node.js and return their filenames. Here's how:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Setup Express &amp;amp; Multer&lt;/strong&gt;&lt;br&gt;
Install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express multer cors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Configure the Server&lt;/strong&gt;&lt;br&gt;
Set up an Express server with multer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const multer = require('multer');
const cors = require('cors');

const app = express();
app.use(cors());

const storage = multer.diskStorage({
    destination: './uploads/',
    filename: (req, file, cb) =&amp;gt; {
        cb(null, Date.now() + '-' + file.originalname);
    }
});

const upload = multer({ storage: storage });

app.post('/upload', upload.array('files', 10), (req, res) =&amp;gt; {
    const filenames = req.files.map(file =&amp;gt; file.filename);
    res.json({ message: 'Files uploaded successfully', filenames });
});

app.listen(3000, () =&amp;gt; console.log('Server running on port 3000'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Frontend Fetch Request&lt;/strong&gt;&lt;br&gt;
Send multiple files using fetch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="file" id="fileInput" multiple&amp;gt;
&amp;lt;button onclick="uploadFiles()"&amp;gt;Upload&amp;lt;/button&amp;gt;

&amp;lt;script&amp;gt;
function uploadFiles() {
    const fileInput = document.getElementById('fileInput');
    const files = fileInput.files;
    const formData = new FormData();

    for (let file of files) {
        formData.append('files', file);
    }

    fetch('http://localhost:3000/upload', {
        method: 'POST',
        body: formData
    })
    .then(response =&amp;gt; response.json())
    .then(data =&amp;gt; console.log('Uploaded Files:', data.filenames))
    .catch(error =&amp;gt; console.error('Error:', error));
}
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Running the Project&lt;/strong&gt;&lt;br&gt;
Start your server (node server.js).&lt;/p&gt;

&lt;p&gt;Open the HTML file in your browser.&lt;/p&gt;

&lt;p&gt;Select multiple files and click "Upload."&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Upload File Using Fetch Method</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Thu, 12 Jun 2025 09:08:10 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/upload-file-using-fetch-method-5nk</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/upload-file-using-fetch-method-5nk</guid>
      <description>&lt;p&gt;Using the fetch method, you can send files from the frontend to your Node.js backend for processing. Here's a simple example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Backend (Node.js with Express &amp;amp; Multer)&lt;/strong&gt;&lt;br&gt;
Set up an Express server to handle file uploads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const multer = require('multer');
const cors = require('cors');

const app = express();
app.use(cors());

const storage = multer.diskStorage({
    destination: './uploads/',
    filename: (req, file, cb) =&amp;gt; {
        cb(null, file.originalname);
    }
});

const upload = multer({ storage: storage });

app.post('/upload', upload.single('file'), (req, res) =&amp;gt; {
    res.json({ message: 'File uploaded successfully', filename: req.file.filename });
});

app.listen(3000, () =&amp;gt; console.log('Server running on port 3000'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Frontend (Using fetch to Upload File)&lt;/strong&gt;&lt;br&gt;
Use JavaScript's fetch API to send a file to your backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="file" id="fileInput"&amp;gt;
&amp;lt;button onclick="uploadFile()"&amp;gt;Upload&amp;lt;/button&amp;gt;

&amp;lt;script&amp;gt;
function uploadFile() {
    const fileInput = document.getElementById('fileInput');
    const file = fileInput.files[0];

    const formData = new FormData();
    formData.append('file', file);

    fetch('http://localhost:3000/upload', {
        method: 'POST',
        body: formData
    })
    .then(response =&amp;gt; response.json())
    .then(data =&amp;gt; console.log(data))
    .catch(error =&amp;gt; console.error('Error:', error));
}
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Running the Project&lt;/strong&gt;&lt;br&gt;
Start the Node.js server (node server.js)&lt;/p&gt;

&lt;p&gt;Open the HTML file in your browser, select a file, and click "Upload."&lt;/p&gt;

&lt;p&gt;This will send the file to the backend using the fetch method and store it in the uploads directory.&lt;/p&gt;

&lt;p&gt;Would you like to extend this to store blog content dynamically in a database?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Upload file Node JS</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Thu, 12 Jun 2025 09:05:47 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/upload-file-node-js-423e</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/upload-file-node-js-423e</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. Initialize Your Project&lt;/strong&gt;&lt;br&gt;
Create a new Node.js project and install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir my-blog
cd my-blog
npm init -y
npm install express multer body-parser ejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Configure Express Server&lt;/strong&gt;&lt;br&gt;
Set up an Express server with multer for file uploads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const multer = require('multer');
const path = require('path');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('uploads'));
app.set('view engine', 'ejs');

const storage = multer.diskStorage({
    destination: './uploads/',
    filename: (req, file, cb) =&amp;gt; {
        cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
    }
});

const upload = multer({ storage: storage });

app.post('/upload', upload.single('image'), (req, res) =&amp;gt; {
    res.render('blog', { image: req.file.filename });
});

app.get('/', (req, res) =&amp;gt; {
    res.render('index');
});

app.listen(3000, () =&amp;gt; console.log('Server running on port 3000'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Create Blog Templates&lt;/strong&gt;&lt;br&gt;
Create an index.ejs file for the upload form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form action="/upload" method="POST" enctype="multipart/form-data"&amp;gt;
    &amp;lt;input type="file" name="image"&amp;gt;
    &amp;lt;button type="submit"&amp;gt;Upload&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a blog.ejs file to display the uploaded file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h2&amp;gt;Uploaded Blog Image&amp;lt;/h2&amp;gt;
&amp;lt;img src="/&amp;lt;%= image %&amp;gt;" alt="Blog Image"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Run Your Blog&lt;/strong&gt;&lt;br&gt;
Start the server and access the blog at &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Would you like to integrate a database to store blog content dynamically? I can help with that too&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🔧 Add, Edit, and Delete Questions Dynamically in Salesforce Using LWC</title>
      <dc:creator>Sabir Sheikh</dc:creator>
      <pubDate>Wed, 21 May 2025 14:42:53 +0000</pubDate>
      <link>https://dev.to/sabir_sheikh_cd49d4c419e3/add-edit-and-delete-questions-dynamically-in-salesforce-using-lwc-1jah</link>
      <guid>https://dev.to/sabir_sheikh_cd49d4c419e3/add-edit-and-delete-questions-dynamically-in-salesforce-using-lwc-1jah</guid>
      <description>&lt;p&gt;In many audit-related Salesforce applications, users often need to maintain a dynamic list of questions — especially in sectors like manufacturing where compliance and quality assurance require periodic updates. In this blog post, we’ll walk through building a Lightning Web Component (LWC) that allows users to add, edit, and delete questions and store them in a custom field as JSON.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧩 Use Case&lt;/strong&gt;&lt;br&gt;
We want to allow auditors to manage a list of questions (add, edit, delete) directly from a record page, and save them in a field (QuestionSet_&lt;em&gt;c) of a custom object (Auditor_Question&lt;/em&gt;_c).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📦 Salesforce Schema Setup&lt;/strong&gt;&lt;br&gt;
Object: Auditor_Question__c&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fields Used:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Name&lt;/strong&gt;  (Standard)&lt;br&gt;
&lt;strong&gt;QuestionSet__c&lt;/strong&gt;  (Long Text Area / Rich Text – stores JSON array of questions)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧠 Key Functionalities&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch record data using &lt;code&gt;@wire(getRecord)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Display a list of questions (parsed from JSON)&lt;/li&gt;
&lt;li&gt;Add new questions&lt;/li&gt;
&lt;li&gt;Edit existing questions&lt;/li&gt;
&lt;li&gt;Delete unwanted questions&lt;/li&gt;
&lt;li&gt;Update &lt;code&gt;QuestionSet__c&lt;/code&gt; field with modified JSON using &lt;code&gt;updateRecord&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ AuditorQuestionController.cls&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public with sharing class AuditorQuestionController {

    @AuraEnabled(cacheable=true)
    public static Auditor_Question__c findRecordByName(String name) {
        // Validate input
        if (String.isBlank(name)) {
            return null;
        }

        // Query the record by Name
        List&amp;lt;Auditor_Question__c&amp;gt; results = [
            SELECT Id, Name, QuestionSet__c
            FROM Auditor_Question__c
            WHERE Name = :name
            LIMIT 1
        ];

        // Return the first result or null if not found
        return results.isEmpty() ? null : results[0];
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔍 Notes:&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;@AuraEnabled(cacheable=true)&lt;/code&gt; annotation makes it usable in LWC wire adapters for better performance (read-only).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;with sharing&lt;/code&gt; ensures field-level security and record-level access are respected.&lt;/p&gt;

&lt;p&gt;You can add fields like &lt;code&gt;QuestionSet__c&lt;/code&gt; as required for your use case.&lt;/p&gt;

&lt;p&gt;You can also expand this controller with additional methods like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;updateQuestions(String recordId, String questionsJson)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;createNewAuditorQuestion(...)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;💻 LWC Template (HTML)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;lightning-card title="Add New Question New"&amp;gt;
        &amp;lt;div class="slds-p-around_medium"&amp;gt;
            &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Record Name:&amp;lt;/strong&amp;gt; {recordName}&amp;lt;/p&amp;gt;

            &amp;lt;lightning-input
                label="Add New Question"
                value={inputValue}
                onchange={handleInputChange}&amp;gt;
            &amp;lt;/lightning-input&amp;gt;

            &amp;lt;lightning-button
                label="Add Question"
                class="slds-m-top_medium"
                onclick={handleAdd}&amp;gt;
            &amp;lt;/lightning-button&amp;gt;

            &amp;lt;template if:true={questionArray}&amp;gt;
                &amp;lt;template for:each={questionArray} for:item="q"&amp;gt;
                    &amp;lt;div key={q.id} class="slds-box slds-m-top_small"&amp;gt;
                        &amp;lt;template if:false={isEdit}&amp;gt;
                            &amp;lt;p&amp;gt;{q.Question}&amp;lt;/p&amp;gt;
                        &amp;lt;/template&amp;gt;
                        &amp;lt;template if:true={isEdit}&amp;gt;
                            &amp;lt;lightning-input
                                value={q.Question}
                                data-id={q.id}
                                onchange={handleChangeUpdateQuestion}
                                label="Edit Question"&amp;gt;
                            &amp;lt;/lightning-input&amp;gt;
                        &amp;lt;/template&amp;gt;

                        &amp;lt;template if:false={isEdit}&amp;gt;
                            &amp;lt;lightning-button label="Edit" onclick={handleEdit}&amp;gt;&amp;lt;/lightning-button&amp;gt;
                        &amp;lt;/template&amp;gt;
                        &amp;lt;template if:true={isEdit}&amp;gt;
                            &amp;lt;lightning-button label="Update" onclick={handleUpdate}&amp;gt;&amp;lt;/lightning-button&amp;gt;
                            &amp;lt;lightning-button label="Cancel" onclick={handleEdit}&amp;gt;&amp;lt;/lightning-button&amp;gt;
                        &amp;lt;/template&amp;gt;

                        &amp;lt;template if:false={isEdit}&amp;gt;
                            &amp;lt;lightning-button
                                variant="destructive"
                                label="Delete"
                                data-id={q.id}
                                onclick={handleDelete}&amp;gt;
                            &amp;lt;/lightning-button&amp;gt;
                        &amp;lt;/template&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/template&amp;gt;
            &amp;lt;/template&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/lightning-card&amp;gt;
&amp;lt;/template&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🧠 LWC JavaScript (JS)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { LightningElement, api, track, wire } from 'lwc';
import { getRecord, updateRecord } from 'lightning/uiRecordApi';
import QUESTION_SET_FIELD from '@salesforce/schema/Auditor_Question__c.QuestionSet__c';
import NAME_FIELD from '@salesforce/schema/Auditor_Question__c.Name';

const FIELDS = [NAME_FIELD, QUESTION_SET_FIELD];

export default class AddMoreQuestionsNew extends LightningElement {
    @api recordId;
    @track recordName = '';
    @track inputValue = '';
    @track questionArray = [];
    @track isEdit = false;

    @wire(getRecord, { recordId: '$recordId', fields: FIELDS })
    wiredRecord({ error, data }) {
        if (data) {
            this.recordName = data.fields.Name.value;
            try {
                const decoded = data.fields.QuestionSet__c.value.replace(/&amp;amp;quot;/g, '"');
                this.questionArray = JSON.parse(decoded);
            } catch (e) {
                console.error("Failed to parse JSON:", e);
            }
        } else if (error) {
            console.error('Error fetching record:', error);
        }
    }

    handleInputChange(event) {
        this.inputValue = event.target.value;
    }

    handleAdd() {
        const trimmed = this.inputValue.trim();
        if (trimmed) {
            const newQuestion = {
                id: Date.now(),
                Question: this.inputValue
            };
            this.questionArray = [...this.questionArray, newQuestion];
            this.inputValue = '';
            this.updateQuestionSet(JSON.stringify(this.questionArray));
        }
    }

    handleEdit() {
        this.isEdit = !this.isEdit;
    }

    handleChangeUpdateQuestion(event) {
        const id = parseInt(event.target.dataset.id, 10);
        const updatedValue = event.target.value;
        this.questionArray = this.questionArray.map(item =&amp;gt;
            item.id === id ? { ...item, Question: updatedValue } : item
        );
    }

    handleUpdate() {
        this.updateQuestionSet(JSON.stringify(this.questionArray));
        this.handleEdit();
    }

    handleDelete(event) {
        const idToDelete = parseInt(event.target.dataset.id, 10);
        this.questionArray = this.questionArray.filter(q =&amp;gt; q.id !== idToDelete);
        this.updateQuestionSet(JSON.stringify(this.questionArray));
    }

    updateQuestionSet(questionJsonString) {
        const fields = {
            Id: this.recordId,
            [QUESTION_SET_FIELD.fieldApiName]: questionJsonString
        };

        updateRecord({ fields })
            .then(() =&amp;gt; {
                // Success message or toast can be shown here
            })
            .catch(error =&amp;gt; {
                console.error('Update error:', error);
                alert('Failed to update: ' + (error.body?.message || error.message));
            });
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;✅ AddMoreQuestionsNew.js-meta.xml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata"&amp;gt;
    &amp;lt;apiVersion&amp;gt;63.0&amp;lt;/apiVersion&amp;gt;
      &amp;lt;isExposed&amp;gt;true&amp;lt;/isExposed&amp;gt;
    &amp;lt;targets&amp;gt;
        &amp;lt;target&amp;gt;lightning__AppPage&amp;lt;/target&amp;gt;
        &amp;lt;target&amp;gt;lightning__RecordPage&amp;lt;/target&amp;gt;
        &amp;lt;target&amp;gt;lightning__HomePage&amp;lt;/target&amp;gt;
    &amp;lt;/targets&amp;gt;
&amp;lt;/LightningComponentBundle&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
