Recipe - Stripe webhook integration

These recipes cover Stripe webhooks and Stripe checkout sessions for payment integration.

How to create Checkout Sessions

How to create Checkout Sessions
Step 1 - In Stripe, obtain your API keys in Test Mode
Step 2 - In Salesforce, create a Named Credential
Step 3 - Build the Screen Flow

Checkout Sessions are special links that redirect the user to Stripe. The link includes their shopping cart contents. Stripe collects payment, then redirects the user back to Salesforce.

In this example we will create the checkout session (highlighted above) using a script. The checkout session collects payment when the user finishes a screen flow.

Step 1 - In Stripe, obtain your API keys in Test Mode

January 2025 update: click the gearwheel in Stripe to get to settings. The first time you visit the Developer settings, click Enable Workbench then click Start Using Workbench. This reveals the hidden Webhooks tab used in this recipe.

Step 2 - In Salesforce, create a Named Credential to hold your API keys

Step 3 - Build the Screen Flow

# Streamscript to create a Stripe Checkout Session
$url = 'callout:https_api_stripe_com/v1/checkout/sessions'
$headers = {}
$headers.Content-Type = 'application/x-www-form-urlencoded'
$headers.Authorization = 'Bearer {!$Credential.Password}'

# Shopping cart
$params = {}
$params.mode = 'payment'
$params.cancel_url = 'https://www.example.com/cancel'
$params.success_url = 'https://www.example.com/success'
$params.put('line_items[0][quantity]', 2)
$params.put('line_items[0][price_data][product_data][name]', 'GenWatt')
$params.put('line_items[0][price_data][unit_amount]', 99900)
$params.put('line_items[0][price_data][currency]', 'USD')
$params.put('metadata[sf-order-id]', 'my_id_123')

# Form-encoded POST
$payload = $params.toUrl();
$response = Http-Post $url $headers $payload
$result = Json-Decode $response.body
Log $result; return $result.url

Comments: This script uses the protected fields of a Named Credential as a best practice. Refer to the Salesforce docs for an explanation on how the callout and $Credential merge fields work. Starting in 2024, Stripe has new API params for checkout: https://stripe.com/docs/payments/checkout/migrating-prices

Comments: By using rich text you can display a clickable hyperlink to the user. It is a good place to set expectations about opening a new window and having the card ready. This pattern may also be used with flows in sites/communities.

The checkout flow is ready!

How to receive Stripe webhooks

How to receive Stripe webhooks
Step 1 - In Salesforce, prepare the webhook flow
Step 2 - In Stripe, add the webhook endpoint
Step 3 - In Salesforce, verify the webhook

Webhooks listen for Stripe activities like subscription payments sent to Salesforce. You collect the events using Streamscript and execute flows to handle them. Here's how:

Step 1 - In Salesforce, prepare the webhook flow

Step 2 - In Stripe, add the webhook endpoint in Test Mode

Step 3 - In Salesforce, verify the webhook requests and store them

# Streamscript to verify the signature
$key = Base64-Encode {!Stripe_mdt}.Secret__c
$timestamp = $Webhook.requestHeaders.Stripe-Signature.substr(2, 12)
$hmac = Hex-Decode $Webhook.requestHeaders.Stripe-Signature.substr(16, 80)
$input = Base64-Encode `$timestamp.$Webhook.request`
if (!Crypto-Verify-Hmac 'hmacSHA256' $input $key $hmac) {throw $hmac}

# Streamscript to parse the incoming payload
$event = Json-Decode $Webhook.request

# Prepare a task
$Task = New-Task
$Task.Subject = $event.type
$Task.Description = Json-Encode $event.data.object
return $Task

Comments: first the script verifies the signature using protected fields of a Custom Metadata Type as a best practice. Then it converts the payload into a Task record. Using the fields of a record allows us to return several values at once from the script. We set the task's subject to the event type, so that a decision can be made in the next flow step.

Step 4 - Decide how to handle each event type

Insert a task record for each webhook request:

Finally click the gearwheel to enable the Site Guest User to insert records safely. In Flow Properties > Advanced > How to Run the Flow: System Context With Sharing.

The saved record provides an audit trail. Use a scheduled flow to process the task records in the context of an integration user. The original webhook payload is stored in the Description field.

The webhook is ready! Use the Resend button in Stripe to iterate and test.