Whatever message this page gives is out now! Go check it out!

cfhttpparam

Last update:
May 18, 2026

Description

Allowed inside cfhttp tag bodies only. Required for cfhttp POST operations. Optional for all others. Specifies parameters to build an HTTP request.

Category

Syntax

<cfhttpparam 
 type = "transaction type" 
 encoded = "yes|no" 
 file = "filename" 
 mimeType = "MIME type designator" 
 name = "data name" 
 value = "data value">
Note: You can specify this tag's attributes in an attributeCollection attribute whose value is a structure. Specify the structure name in the attributeCollection attribute and use the tag's attribute names as structure keys. The cfhttpparam tag ignores -_.!~*'() characters while encoding. If these characters are used as its values, then these characters are not encoded. This feature helps to avoid any issues with the URL at the receiving end.

See also

History

ColdFusion MX 6.1:
  • Added the header and body types.
  • Added the encoded and mimeType attributes.
  • Changed HTTP method behavior: all HTTP methods can have httpparam tags.
  • Changed the name attribute requirements: it is not required for all types.

Attributes

Attribute
Req/Opt
Default
Description
type
Required
Information type:
  • header: specifies an HTTP header. ColdFusion does not URL encode the header.
  • CGI: specifies an HTTP header. ColdFusion URL encodes the header by default.
  • body: specifies the body of the HTTP request. ColdFusion does not automatically set a content-type header or URL encode the body contents. To specify the content-type, use a separate cfhttpparam tag with type=header.
  • XML: identifies the request as having a content-type of text/xml. Specifies that the value attribute contains the body of the HTTP request. Used to send XML to the destination URL. ColdFusion does not URL encode the XML data.
  • file: tells ColdFusion to send the contents of the specified file. ColdFusion does not URL encode the file contents.
  • URL: specifies a URL query string name-value pair to append to the cfhttp url attribute. ColdFusion URL encodes the query string.
  • formField: specifies a form field to send. ColdFusion URL encodes the Form field by default.
  • cookie: specifies a cookie to send as an HTTP header. ColdFusion URL encodes the cookie.
encoded
Optional
yes
Applies to FormField and CGI types; ignored for all other types. Specifies whether to URL encode the form field or header.
file
Required only if type="File"
Applies to File type; ignored for all other types. The absolute path to the file that is sent in the request body.
mimeType
Optional
Applies to File type; invalid for all other types. Specifies the MIME media type of the file contents. The content type can include an identifier for the character encoding of the file; for example, text/html; charset=ISO-8859-1 indicates that the file is HTML text in the ISO Latin-1 character encoding.
name
Required. Optional (and ignored) for Body and XML types
Variable name for data that is passed. Ignored for Body and XML types. For File type, specifies the filename to send in the request.
value
Required. Optional (and ignored) for File type
Value of the data that is sent. Ignored for File type. The value must contain string data or data that ColdFusion can convert to a string for all type attributes except Body. Body types can have string or binary values.

Usage

Specifies header or body data to send in the HTTP request. The type attribute identifies the information that the parameter specifies. A cfhttp tag can have multiple cfhttpparam tags, subject to the following limitations:
  • An XML type attribute cannot be used with additional XML type attributes, or with body, file, or formField type attributes.
  • A body type attribute cannot be used with additional body type attributes, or with XML, file, or formField type attributes.
  • The XML and body type attributes cannot be used with the cfhttp tag TRACE method.
  • The file type attribute is only meaningful**with the cfhttp tag POST and PUT methods.
  • The formField type attribute is only meaningful**with the cfhttp tag POST and GET methods. If you send an HTTP request to a ColdFusion page, all HTTP headers, not just those sent using the CGI type, are available as CGI scope variables, However, any custom variables (such as "myVar") do not appear in a dump of the CGI scope. When you send a file using the type="file" attribute, the file content is sent in the body of a multipart/form-data request. If you send the file to a ColdFusion page, the Form scope of the receiving page contains an entry with the name you specified in the cfhttpparam tag name attribute as the key. The value of this variable is the path to a temporary file containing the file that you sent. If you also send Form field data, the location of the filename in the form.fieldnames key list depends on the position of the cfhttpparam tag with the file relative to the cfhttp tags with the form data.URL-encoding preserves special characters (such as the ampersand) when they are passed to the server. For more information, see the function URLEncodedFormat. To send arbitrary data in a "raw" HTTP message, use a cfhttpparam tag with a type="body" attribute to specify the body content and use cfhttpparam tags with a type="header" attributes to specify the headers.

Example

<!--- This example consists of two CFML pages. 
The first page posts to the second. ---> 

<!--- The first, posting page. 
This page posts variables to another page and displays the body of the response from 
the second page. Change the URL and port as necessary for your environment. ---> 

<cfhttp 
method="post" 
url="http://127.0.0.1/tests/http/cfhttpparamexample.cfm" 
port="8500" 
throwonerror="Yes"> 
<cfhttpparam name="form_test" type="FormField" value="This is a form variable"> 
<cfhttpparam name="url_test" type="URL" value="This is a URL variable"> 
<cfhttpparam name="cgi_test" type="CGI" value="This is a CGI variable"> 
<cfhttpparam name="cookie_test" type="Cookie" value="This is a cookie"> 
</cfhttp> 

<!--- Output the results returned by the posted-to page. ---> 
<cfoutput> 
#cfhttp.fileContent# 
</cfoutput> 


<!--- This is the cfhttpparamexample.cfm page that receives and processes the Post request. Its response body is the generated HTML output. ---> 

<h3>Output the passed variables</h3> 
<cfoutput> 
Form variable: #form.form_test# 
<br>URL variable: #URL.url_test# 
<br>Cookie variable: #Cookie.cookie_test# 
<br>CGI variable: #CGI.cgi_test#<br> 
<br>Note that the CGI variable is URL encoded. 
</cfoutput>

Real-world uses of the cfhttpparam tag

Payment gateway API integration

E-commerce platforms must securely process customer payments by integrating with payment gateways like Stripe, PayPal, or Authorize.net. Each transaction requires sending sensitive payment information, customer details, and order data to the gateway's API endpoints with proper authentication headers, encrypted transmission, and real-time response handling for immediate order confirmation or error notification to customers at checkout.
Problem statement
  • Manual HTTP request construction for APIs prone to parameter formatting errors
  • Authentication tokens and API keys must be sent securely in headers not URL parameters
  • Payment data requires proper content-type headers and JSON/XML body formatting
  • Missing or incorrect parameters cause transaction failures and lost sales
Solution
This sample demonstrates using cfhttp with multiple cfhttpparam tags to construct  proper payment API requests where authentication tokens are sent as secure headers,  customer and payment details are sent as form fields or JSON body depending on  gateway requirements, and custom headers specify content types and API versions.
<cfset orderData = {
    orderId = "ORD-" & dateFormat(now(), "yyyymmdd") & "-" & randRange(1000, 9999),
    amount = 149.99,
    currency = "USD",
    customerName = "Sarah Johnson",
    customerEmail = "sarah.johnson@example.com",
    cardLast4 = "4242"
}>

<cfset apiEndpoint = "https://api.paymentgateway.example/v1/charges">
<cfset apiKey = "sk_test_" & hash("secret", "MD5")>

<!--- Simulated payment processing --->
<cfset paymentAttempted = structKeyExists(form, "processPayment")>
<cfset paymentResult = {}>

<cfif paymentAttempted>
    <cftry>
        <!--- Simulate API call to payment gateway --->
        <cfhttp 
            url="#apiEndpoint#" 
            method="POST" 
            result="httpResult"
            timeout="30">
            
            <!--- Authentication Header --->
            <cfhttpparam 
                type="header" 
                name="Authorization" 
                value="Bearer #apiKey#">
            
            <!--- Content Type Header --->
            <cfhttpparam 
                type="header" 
                name="Content-Type" 
                value="application/x-www-form-urlencoded">
            
            <!--- API Version Header --->
            <cfhttpparam 
                type="header" 
                name="X-API-Version" 
                value="2024-01">
            
            <!--- Payment Form Fields --->
            <cfhttpparam 
                type="formfield" 
                name="amount" 
                value="#int(orderData.amount * 100)#">
            
            <cfhttpparam 
                type="formfield" 
                name="currency" 
                value="#orderData.currency#">
            
            <cfhttpparam 
                type="formfield" 
                name="description" 
                value="Order #orderData.orderId#">
            
            <cfhttpparam 
                type="formfield" 
                name="customer_email" 
                value="#orderData.customerEmail#">
            
            <cfhttpparam 
                type="formfield" 
                name="metadata[order_id]" 
                value="#orderData.orderId#">
            
            <cfhttpparam 
                type="formfield" 
                name="metadata[customer_name]" 
                value="#orderData.customerName#">
        </cfhttp>
        
        <!--- Process response (simulated) --->
        <cfset paymentResult.success = true>
        <cfset paymentResult.transactionId = "txn_" & createUUID()>
        <cfset paymentResult.status = "succeeded">
        <cfset paymentResult.timestamp = now()>
        <cfset paymentResult.requestSent = {
            endpoint = apiEndpoint,
            method = "POST",
            headers = ["Authorization", "Content-Type", "X-API-Version"],
            fields = ["amount", "currency", "description", "customer_email", "metadata"]
        }>
        
    <cfcatch type="any">
        <cfset paymentResult.success = false>
        <cfset paymentResult.error = cfcatch.message>
    </cfcatch>
    </cftry>
</cfif>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Payment Gateway Integration</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
               background: linear-gradient(135deg, ##667eea 0%, ##764ba2 100%); 
               min-height: 100vh; padding: 20px; }
        .container { max-width: 900px; margin: 0 auto; }
        .card { background: white; border-radius: 15px; padding: 30px; 
                box-shadow: 0 10px 40px rgba(0,0,0,0.2); margin-bottom: 20px; }
        .header { text-align: center; margin-bottom: 30px; }
        .header h1 { color: ##2c3e50; font-size: 32px; margin-bottom: 10px; }
        .order-summary { background: ##f8f9fa; padding: 20px; border-radius: 10px; 
                         margin-bottom: 20px; border-left: 4px solid ##667eea; }
        .order-row { display: flex; justify-content: space-between; padding: 10px 0; 
                     border-bottom: 1px solid ##dee2e6; }
        .order-row:last-child { border-bottom: none; font-weight: bold; font-size: 18px; }
        .process-btn { width: 100%; background: ##28a745; color: white; padding: 15px; 
                       border: none; border-radius: 8px; font-size: 16px; font-weight: bold; 
                       cursor: pointer; transition: all 0.3s; }
        .process-btn:hover { background: ##218838; transform: translateY(-2px); }
        .result-success { background: ##d4edda; padding: 20px; border-radius: 10px; 
                          border-left: 4px solid ##28a745; margin-bottom: 20px; }
        .result-error { background: ##f8d7da; padding: 20px; border-radius: 10px; 
                        border-left: 4px solid ##dc3545; margin-bottom: 20px; }
        .api-details { background: ##2d2d2d; color: ##f8f8f2; padding: 20px; 
                       border-radius: 10px; font-family: 'Courier New', monospace; 
                       font-size: 13px; margin-top: 20px; }
        .api-section { margin-bottom: 15px; }
        .api-label { color: ##6a9955; font-weight: bold; }
        .api-value { color: ##ce9178; }
        .info-panel { background: ##fff3cd; padding: 20px; border-radius: 10px; 
                      border-left: 4px solid ##ffc107; }
        .badge { display: inline-block; padding: 5px 12px; border-radius: 15px; 
                 font-size: 12px; font-weight: bold; margin-left: 10px; }
        .badge-success { background: ##28a745; color: white; }
    </style>
</head>
<body>
    <div class="container">
        <div class="card">
            <div class="header">
                <h1>💳 Payment Gateway Integration</h1>
                <p style="color: ##7f8c8d;">Secure API Payment Processing with cfhttpparam</p>
            </div>
            
            <div class="order-summary">
                <h3 style="color: ##2c3e50; margin-bottom: 15px;">Order Summary</h3>
                <cfoutput>
                    <div class="order-row">
                        <span>Order ID:</span>
                        <strong>#orderData.orderId#</strong>
                    </div>
                    <div class="order-row">
                        <span>Customer:</span>
                        <span>#orderData.customerName#</span>
                    </div>
                    <div class="order-row">
                        <span>Email:</span>
                        <span>#orderData.customerEmail#</span>
                    </div>
                    <div class="order-row">
                        <span>Payment Method:</span>
                        <span>Card ending in #orderData.cardLast4#</span>
                    </div>
                    <div class="order-row">
                        <span>Amount:</span>
                        <span>#dollarFormat(orderData.amount)# #orderData.currency#</span>
                    </div>
                </cfoutput>
            </div>
            
            <cfif paymentAttempted>
                <cfif paymentResult.success>
                    <div class="result-success">
                        <h3 style="color: ##155724; margin-bottom: 15px;">✓ Payment Successful!</h3>
                        <cfoutput>
                            <p><strong>Transaction ID:</strong> #paymentResult.transactionId#</p>
                            <p><strong>Status:</strong> #paymentResult.status# 
                               <span class="badge badge-success">APPROVED</span></p>
                            <p><strong>Processed:</strong> #dateTimeFormat(paymentResult.timestamp, "yyyy-mm-dd HH:nn:ss")#</p>
                        </cfoutput>
                    </div>
                    
                    <div class="api-details">
                        <div class="api-section">
                            <span class="api-label">// HTTP Request Sent:</span><br>
                            <cfoutput>
                                POST #paymentResult.requestSent.endpoint#
                            </cfoutput>
                        </div>
                        <div class="api-section">
                            <span class="api-label">// Headers (via cfhttpparam type="header"):</span><br>
                            Authorization: Bearer sk_test_****<br>
                            Content-Type: application/x-www-form-urlencoded<br>
                            X-API-Version: 2024-01
                        </div>
                        <div class="api-section">
                            <span class="api-label">// Form Fields (via cfhttpparam type="formfield"):</span><br>
                            <cfoutput>
                                amount=#int(orderData.amount * 100)#<br>
                                currency=#orderData.currency#<br>
                                description=Order #orderData.orderId#<br>
                                customer_email=#orderData.customerEmail#<br>
                                metadata[order_id]=#orderData.orderId#<br>
                                metadata[customer_name]=#orderData.customerName#
                            </cfoutput>
                        </div>
                    </div>
                <cfelse>
                    <div class="result-error">
                        <h3 style="color: ##721c24; margin-bottom: 10px;">✗ Payment Failed</h3>
                        <cfoutput>
                            <p>Error: #paymentResult.error#</p>
                        </cfoutput>
                    </div>
                </cfif>
            <cfelse>
                <form method="post">
                    <input type="hidden" name="processPayment" value="true">
                    <button type="submit" class="process-btn">
                        💳 Process Payment - <cfoutput>#dollarFormat(orderData.amount)#</cfoutput>
                    </button>
                </form>
            </cfif>
            
        </div>
    </div>
</body>
</html>

Cloud storage file upload system

Modern applications store user-generated content like profile photos, document uploads, and media files in cloud storage services (AWS S3, Azure Blob, Google Cloud Storage) rather than local servers for scalability, redundancy, and global CDN distribution. The application must upload files from ColdFusion server to cloud storage APIs using HTTP multipart form-data requests with proper authentication, content-type detection, and metadata tagging for organization and retrieval.
Problem statement
  • Local server storage doesn't scale with growing user file uploads and media libraries
  • Manual HTTP multipart file upload construction complex and error-prone
  • Cloud storage APIs require specific authentication headers and request formats
  • File metadata (original filename, content type, custom tags) must accompany upload
Solution
This sample demonstrates using cfhttp with cfhttpparam type="file" to upload files  to cloud storage APIs where the file parameter handles binary file reading and multipart  encoding automatically, additional cfhttpparam type="formfield" tags send metadata like  original filename and content type alongside the file, type="header" parameters provide  authentication credentials and API tokens, and ColdFusion manages the complex multipart/form-data  request construction allowing seamless integration with any cloud storage provider's REST API for scalable, reliable file storage without managing local disk space.
<cfset uploadDemo = {
    enabled = true,
    fileName = "sample_document.pdf",
    fileSize = "245 KB",
    contentType = "application/pdf",
    uploadPath = "/uploads/documents/",
    cloudProvider = "AWS S3"
}>

<cfset uploadAttempted = structKeyExists(form, "uploadFile")>
<cfset uploadResult = {}>

<cfif uploadAttempted>
    <cftry>
        <!--- In production, this would be actual file path --->
        <cfset localFilePath = expandPath("./temp/#uploadDemo.fileName#")>
        <cfset cloudEndpoint = "https://my-bucket.s3.amazonaws.com/uploads/documents/">
        <cfset accessKey = "AKIA" & hash("access", "MD5", "UTF-8", 100)>
        
        <!--- Simulate cloud storage upload --->
        <cfhttp 
            url="#cloudEndpoint##uploadDemo.fileName#" 
            method="PUT" 
            result="httpResult"
            timeout="60">
            
            <!--- Authentication Header --->
            <cfhttpparam 
                type="header" 
                name="Authorization" 
                value="AWS4-HMAC-SHA256 Credential=#accessKey#">
            
            <!--- Content Type Header --->
            <cfhttpparam 
                type="header" 
                name="Content-Type" 
                value="#uploadDemo.contentType#">
            
            <!--- Cache Control Header --->
            <cfhttpparam 
                type="header" 
                name="Cache-Control" 
                value="max-age=31536000">
            
            <!--- Custom Metadata Headers --->
            <cfhttpparam 
                type="header" 
                name="x-amz-meta-original-name" 
                value="#uploadDemo.fileName#">
            
            <cfhttpparam 
                type="header" 
                name="x-amz-meta-upload-date" 
                value="#dateTimeFormat(now(), 'iso8601')#">
            
            <cfhttpparam 
                type="header" 
                name="x-amz-meta-uploaded-by" 
                value="user_12345">
            
            <!--- File Upload (in production, this would reference actual file) --->
            <!--- <cfhttpparam 
                type="file" 
                name="file" 
                file="#localFilePath#"
                mimetype="#uploadDemo.contentType#"> --->
        </cfhttp>
        
        <!--- Simulated success response --->
        <cfset uploadResult.success = true>
        <cfset uploadResult.cloudUrl = cloudEndpoint & uploadDemo.fileName>
        <cfset uploadResult.etag = createUUID()>
        <cfset uploadResult.timestamp = now()>
        <cfset uploadResult.requestDetails = {
            method = "PUT",
            endpoint = cloudEndpoint & uploadDemo.fileName,
            fileSize = uploadDemo.fileSize,
            contentType = uploadDemo.contentType
        }>
        
    <cfcatch type="any">
        <cfset uploadResult.success = false>
        <cfset uploadResult.error = cfcatch.message>
    </cfcatch>
    </cftry>
</cfif>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Cloud Storage File Upload</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Arial', sans-serif; background: ##ecf0f1; padding: 20px; }
        .container { max-width: 1000px; margin: 0 auto; }
        .header { background: linear-gradient(135deg, ##3498db 0%, ##2c3e50 100%); 
                  color: white; padding: 40px; border-radius: 15px 15px 0 0; 
                  box-shadow: 0 -5px 20px rgba(0,0,0,0.1); }
        .header h1 { font-size: 32px; margin-bottom: 10px; }
        .content { background: white; padding: 40px; border-radius: 0 0 15px 15px; 
                   box-shadow: 0 10px 40px rgba(0,0,0,0.15); }
        .upload-card { background: ##f8f9fa; padding: 30px; border-radius: 10px; 
                       margin-bottom: 20px; border-left: 4px solid ##3498db; }
        .file-icon { font-size: 64px; text-align: center; margin-bottom: 20px; }
        .file-details { display: grid; grid-template-columns: 200px 1fr; gap: 15px; 
                        margin: 20px 0; }
        .file-detail-label { font-weight: bold; color: ##7f8c8d; }
        .upload-btn { width: 100%; background: ##3498db; color: white; padding: 15px; 
                      border: none; border-radius: 8px; font-size: 16px; font-weight: bold; 
                      cursor: pointer; transition: all 0.3s; }
        .upload-btn:hover { background: ##2980b9; transform: translateY(-2px); }
        .success-panel { background: ##d5f4e6; padding: 25px; border-radius: 10px; 
                         border-left: 4px solid ##27ae60; margin-bottom: 20px; }
        .code-block { background: ##2d2d2d; color: ##f8f8f2; padding: 20px; 
                      border-radius: 10px; font-family: 'Courier New', monospace; 
                      font-size: 13px; overflow-x: auto; margin: 15px 0; }
        .code-comment { color: ##6a9955; }
        .code-tag { color: ##569cd6; }
        .code-attr { color: ##9cdcfe; }
        .code-value { color: ##ce9178; }
        .info-box { background: ##fff3cd; padding: 20px; border-radius: 10px; 
                    border-left: 4px solid ##ffc107; }
        .provider-badge { background: ##ff9900; color: white; padding: 5px 15px; 
                          border-radius: 20px; font-size: 14px; font-weight: bold; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>☁️ Cloud Storage File Upload</h1>
            <p>Upload files to cloud storage using cfhttpparam</p>
        </div>
        
        <div class="content">
            <div class="upload-card">
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
                    <h2 style="color: ##2c3e50;">File Upload Demo</h2>
                    <cfoutput><span class="provider-badge">#uploadDemo.cloudProvider#</span></cfoutput>
                </div>
                
                <div class="file-icon">📄</div>
                
                <div class="file-details">
                    <cfoutput>
                        <span class="file-detail-label">File Name:</span>
                        <span>#uploadDemo.fileName#</span>
                        
                        <span class="file-detail-label">File Size:</span>
                        <span>#uploadDemo.fileSize#</span>
                        
                        <span class="file-detail-label">Content Type:</span>
                        <span>#uploadDemo.contentType#</span>
                        
                        <span class="file-detail-label">Upload Path:</span>
                        <span>#uploadDemo.uploadPath#</span>
                        
                        <span class="file-detail-label">Cloud Provider:</span>
                        <span>#uploadDemo.cloudProvider#</span>
                    </cfoutput>
                </div>
                
                <cfif uploadAttempted>
                    <cfif uploadResult.success>
                        <div class="success-panel">
                            <h3 style="color: ##155724; margin-bottom: 15px;">✓ Upload Successful!</h3>
                            <cfoutput>
                                <p><strong>Cloud URL:</strong> #uploadResult.cloudUrl#</p>
                                <p><strong>ETag:</strong> #uploadResult.etag#</p>
                                <p><strong>Uploaded:</strong> #dateTimeFormat(uploadResult.timestamp, "yyyy-mm-dd HH:nn:ss")#</p>
                            </cfoutput>
                        </div>
                    <cfelse>
                        <div style="background: ##f8d7da; padding: 20px; border-radius: 10px; border-left: 4px solid ##dc3545;">
                            <h3 style="color: ##721c24; margin-bottom: 10px;">✗ Upload Failed</h3>
                            <cfoutput><p>Error: #uploadResult.error#</p></cfoutput>
                        </div>
                    </cfif>
                <cfelse>
                    <form method="post" style="margin-top: 20px;">
                        <input type="hidden" name="uploadFile" value="true">
                        <button type="submit" class="upload-btn">
                            ☁️ Upload to Cloud Storage
                        </button>
                    </form>
                </cfif>
            </div>
            
            
    </div>
</body>
</html>

Webhook event notification system

SaaS platforms and e-commerce systems need to notify external applications and customer systems about events like new orders, payment confirmations, user registrations,  or status updates in real-time. Webhooks provide this capability by sending HTTP POST  requests with event data in JSON format to customer-configured endpoints, requiring  proper authentication signatures, custom headers for event identification, and reliable  delivery with retry logic for failed notifications.
Problem statement
  • External systems need real-time notifications without constantly polling for updates
  • JSON event data must be sent in HTTP request body with proper content-type headers
  • Webhook signatures required for recipients to verify notification authenticity
  • Custom headers needed to identify event types and API versions for routing
Solution
his sample demonstrates using cfhttp with cfhttpparam type="body" to send JSON event  data in the request body, type="header" parameters to include webhook signatures for  authentication verification, custom event-type headers for consumer routing logic, and  content-type specification for proper JSON parsing by recipients.
<cfset webhookEvents = {
    "order.created" = {
        type = "order.created",
        icon = "🛒",
        label = "New Order",
        data = {
            event = "order.created",
            order_id = "ORD-2024-1001",
            customer = "John Doe",
            amount = 299.99,
            items = 3,
            timestamp = dateTimeFormat(now(), "iso8601")
        }
    },
    "payment.success" = {
        type = "payment.success",
        icon = "💳",
        label = "Payment Confirmed",
        data = {
            event = "payment.success",
            transaction_id = "txn_" & createUUID(),
            amount = 299.99,
            currency = "USD",
            method = "credit_card",
            timestamp = dateTimeFormat(now(), "iso8601")
        }
    },
    "user.registered" = {
        type = "user.registered",
        icon = "👤",
        label = "User Registered",
        data = {
            event = "user.registered",
            user_id = "user_" & randRange(10000, 99999),
            email = "newuser@example.com",
            plan = "premium",
            timestamp = dateTimeFormat(now(), "iso8601")
        }
    }
}>

<cfset selectedEvent = structKeyExists(url, "event") ? url.event : "order.created">
<cfif NOT structKeyExists(webhookEvents, selectedEvent)>
    <cfset selectedEvent = "order.created">
</cfif>

<cfset webhookSent = structKeyExists(form, "sendWebhook")>
<cfset webhookResult = {}>

<cfif webhookSent>
    <cftry>
        <cfset eventData = webhookEvents[selectedEvent]>
        <cfset jsonPayload = serializeJSON(eventData.data)>
        <cfset webhookUrl = "https://customer-app.example.com/webhooks">
        <cfset webhookSecret = "whsec_" & hash("secret", "SHA-256")>
        <cfset signature = hash(jsonPayload & webhookSecret, "SHA-256")>
        
        <!--- Send webhook notification --->
        <cfhttp 
            url="#webhookUrl#" 
            method="POST" 
            result="httpResult"
            timeout="30">
            
            <!--- Webhook Signature Header for Authentication --->
            <cfhttpparam 
                type="header" 
                name="X-Webhook-Signature" 
                value="#signature#">
            
            <!--- Event Type Header --->
            <cfhttpparam 
                type="header" 
                name="X-Event-Type" 
                value="#eventData.type#">
            
            <!--- Webhook ID Header for Idempotency --->
            <cfhttpparam 
                type="header" 
                name="X-Webhook-ID" 
                value="wh_#createUUID()#">
            
            <!--- Timestamp Header --->
            <cfhttpparam 
                type="header" 
                name="X-Webhook-Timestamp" 
                value="#dateTimeFormat(now(), 'epoch')#">
            
            <!--- Content Type Header --->
            <cfhttpparam 
                type="header" 
                name="Content-Type" 
                value="application/json">
            
            <!--- User Agent Header --->
            <cfhttpparam 
                type="header" 
                name="User-Agent" 
                value="MyApp-Webhooks/1.0">
            
            <!--- JSON Body Content --->
            <cfhttpparam 
                type="body" 
                value="#jsonPayload#">
        </cfhttp>
        
        <!--- Simulated success response --->
        <cfset webhookResult.success = true>
        <cfset webhookResult.webhookId = "wh_" & createUUID()>
        <cfset webhookResult.eventType = eventData.type>
        <cfset webhookResult.endpoint = webhookUrl>
        <cfset webhookResult.timestamp = now()>
        <cfset webhookResult.payload = jsonPayload>
        <cfset webhookResult.signature = signature>
        
    <cfcatch type="any">
        <cfset webhookResult.success = false>
        <cfset webhookResult.error = cfcatch.message>
    </cfcatch>
    </cftry>
</cfif>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Webhook Notifications</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
               background: linear-gradient(135deg, ##f093fb 0%, ##f5576c 100%); 
               min-height: 100vh; padding: 20px; }
        .container { max-width: 1100px; margin: 0 auto; }
        .header { background: white; padding: 40px; border-radius: 15px 15px 0 0; 
                  box-shadow: 0 -5px 20px rgba(0,0,0,0.1); }
        .header h1 { color: ##2c3e50; font-size: 32px; margin-bottom: 10px; }
        .content { background: white; padding: 40px; border-radius: 0 0 15px 15px; 
                   box-shadow: 0 10px 40px rgba(0,0,0,0.2); }
        .event-selector { display: grid; grid-template-columns: repeat(3, 1fr); 
                          gap: 15px; margin-bottom: 30px; }
        .event-card { padding: 20px; background: ##f8f9fa; border-radius: 10px; 
                      border: 2px solid transparent; cursor: pointer; 
                      text-align: center; transition: all 0.3s; }
        .event-card:hover { border-color: ##f5576c; transform: translateY(-3px); }
        .event-card.active { border-color: ##f5576c; background: ##ffe7ec; }
        .event-icon { font-size: 48px; margin-bottom: 10px; }
        .event-label { font-weight: bold; color: ##2c3e50; }
        .payload-display { background: ##2d2d2d; color: ##f8f8f2; padding: 20px; 
                           border-radius: 10px; font-family: 'Courier New', monospace; 
                           font-size: 13px; margin: 20px 0; }
        .send-btn { width: 100%; background: linear-gradient(135deg, ##f093fb 0%, ##f5576c 100%); 
                    color: white; padding: 15px; border: none; border-radius: 8px; 
                    font-size: 16px; font-weight: bold; cursor: pointer; transition: all 0.3s; }
        .send-btn:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(245,87,108,0.4); }
        .result-success { background: ##d4edda; padding: 20px; border-radius: 10px; 
                          border-left: 4px solid ##28a745; margin-bottom: 20px; }
        .result-detail { display: grid; grid-template-columns: 200px 1fr; gap: 10px; 
                         margin: 10px 0; font-size: 14px; }
        .info-panel { background: ##fff3cd; padding: 20px; border-radius: 10px; 
                      border-left: 4px solid ##ffc107; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📡 Webhook Event Notifications</h1>
            <p style="color: ##7f8c8d;">Send real-time event data with cfhttpparam</p>
        </div>
        
        <div class="content">
            <h3 style="color: ##2c3e50; margin-bottom: 15px;">Select Event Type:</h3>
            <div class="event-selector">
                <cfloop collection="#webhookEvents#" item="eventKey">
                    <cfset event = webhookEvents[eventKey]>
                    <cfoutput>
                        <a href="?event=#eventKey#" style="text-decoration: none;">
                            <div class="event-card #selectedEvent EQ eventKey ? 'active' : ''#">
                                <div class="event-icon">#event.icon#</div>
                                <div class="event-label">#event.label#</div>
                                <div style="font-size: 12px; color: ##7f8c8d; margin-top: 5px;">
                                    #event.type#
                                </div>
                            </div>
                        </a>
                    </cfoutput>
                </cfloop>
            </div>
            
            <h3 style="color: ##2c3e50; margin-bottom: 15px;">Event Payload (JSON):</h3>
            <div class="payload-display">
                <cfoutput>#serializeJSON(webhookEvents[selectedEvent].data)#</cfoutput>
            </div>
            
            <cfif webhookSent>
                <cfif webhookResult.success>
                    <div class="result-success">
                        <h3 style="color: ##155724; margin-bottom: 15px;">✓ Webhook Sent Successfully!</h3>
                        <div class="result-detail">
                            <strong>Webhook ID:</strong>
                            <cfoutput><code>#webhookResult.webhookId#</code></cfoutput>
                        </div>
                        <div class="result-detail">
                            <strong>Event Type:</strong>
                            <cfoutput><span>#webhookResult.eventType#</span></cfoutput>
                        </div>
                        <div class="result-detail">
                            <strong>Endpoint:</strong>
                            <cfoutput><span>#webhookResult.endpoint#</span></cfoutput>
                        </div>
                        <div class="result-detail">
                            <strong>Timestamp:</strong>
                            <cfoutput><span>#dateTimeFormat(webhookResult.timestamp, "yyyy-mm-dd HH:nn:ss")#</span></cfoutput>
                        </div>
                        <div class="result-detail">
                            <strong>Signature (SHA-256):</strong>
                            <cfoutput><code style="font-size: 11px;">#left(webhookResult.signature, 40)#...</code></cfoutput>
                        </div>
                        
                        <h4 style="color: ##155724; margin-top: 20px; margin-bottom: 10px;">HTTP Headers Sent:</h4>
                        <div style="background: ##2d2d2d; color: ##f8f8f2; padding: 15px; 
                                    border-radius: 5px; font-family: 'Courier New', monospace; font-size: 12px;">
                            <cfoutput>
                            X-Webhook-Signature: #webhookResult.signature#<br>
                            X-Event-Type: #webhookResult.eventType#<br>
                            X-Webhook-ID: #webhookResult.webhookId#<br>
                            X-Webhook-Timestamp: #dateTimeFormat(webhookResult.timestamp, "epoch")#<br>
                            Content-Type: application/json<br>
                            User-Agent: MyApp-Webhooks/1.0
                            </cfoutput>
                        </div>
                    </div>
                <cfelse>
                    <div style="background: ##f8d7da; padding: 20px; border-radius: 10px; 
                                border-left: 4px solid ##dc3545; margin-bottom: 20px;">
                        <h3 style="color: ##721c24;">✗ Webhook Failed</h3>
                        <cfoutput><p>Error: #webhookResult.error#</p></cfoutput>
                    </div>
                </cfif>
            <cfelse>
                <form method="post">
                    <input type="hidden" name="sendWebhook" value="true">
                    <button type="submit" class="send-btn">
                        📤 Send Webhook Notification
                    </button>
                </form>
            </cfif>
            
            
        </div>
    </div>
</body>
</html>

Share this page

Was this page helpful?
We're glad. Tell us how this page helped.
We're sorry. Can you tell us what didn't work for you?
Thank you for your feedback. Your response will help improve this page.

On this page