Accepting Stripe Payments in Embeddables
How to accept payments with our deep Stripe integration
Payments in Embeddables are handled via Stripe, with a dedicated Stripe component that is integrated deeply into our platform.
Keys and IDs that you’ll need
- Your Stripe Publishable Key
- A Restricted Key generated in Stripe, with the following scopes/permissions:
Customers
:Write
Payment Intents
:Write
Setup Intents
:Write
Checkout Session
:Write
Credit notes
:Read
Subscriptions
:Write
- Any Price IDs for specific products you want to offer
Setting up Stripe
The following are the minimum steps required to add a Stripe component to your Embeddable:
Generate and share the necessary Stripe keys
- Get your Publishable Key, and generate a Restricted Key with the scopes/permissions listed above, from the API Keys section of your Stripe Dashboard.
- Pass these keys to the Embeddables Team (make sure to share the Restricted Key in a secure way).
Add a Stripe component to your Embeddable
- In the Builder, switch to the checkout page that should contain the Stripe component.
- Select a Container to insert the Stripe component into, or a copmonent that it should be added next to.
- Open the
+
left-hand sidebar, and selectStripe
from the list of components.
Choose the type of payment you want to accept
- Under Checkout mode, select one of the following options:
- Payment: If you’re accepting only one-time payments, or want to place a hold on a user’s card.
- Setup: For setting up a user’s payment method to take payments in the future.
- Subscription: If your line items will include at least one recurring payment.
Please note that Stripe only supports placing a hold on one-time payments, not recurring payments.
Choose which payment methods you want to accept
- Under Payment methods, select the payment methods you want to accept, from the following options:
- Credit card
- Link (Stripe’s own quick purchase login system)
- US Bank Account
- Buy now, pay later services: Afterpay/Clearpay, Klarna, Affirm
You need to have the relevant payment methods enabled in your Stripe account in order for them to appear for users.
Add line items to the checkout
-
There are two different types of line item that you can add:
- Price ID: This corresponds to a product and price that you’ve already created in Stripe.
Make sure to grab the Price ID from Stripe, rather than the Product ID.
How to find the Price ID
- Go to the Product Catalog section of your Stripe Dashboard.
- Select the product you want to use.
- Click on the more options (three dots) icon button in the Price that you want to use.
- Select
Copy price ID
.
- Custom line item: This lets you manually enter an amount, currency and name for the line item in Embeddables.
-
Both types of line item require you to enter a quantity.
If you need your line items to be dynamic (i.e. change based on the user’s answers, like what plan they select), see the Add dynamic line items section below.
Include the customer email address (and, optionally, phone number)
- To insert the user’s given email address into the Stripe checkout, add the key name of the component you use to collect the user’s email, using Templating (e.g.
{{email}}
). - You can optionally collect a user’s phone number, using the same method.
By default, Stripe’s credit card fields will also include Country and Zipcode / Postal Code fields.
These are all Stripe needs for a customer billing address, so you don’t need to provide any billing address fields.
Optional: Additional Stripe configurations
These features are not required in order to successfully accept payments, but they can be useful in different scenarios.
Collect shipping information
Collect shipping information
To collect shipping information from the user, you need to make sure you have the relevant input components in your Embeddable:
- Address Line 1
- Address Line 2
- City
- State
- Zipcode / Postal Code
- Country
Then, enter the keys of these components in the Shipping Address fields in the Stripe component using Templating, e.g. {{address_line_1}}
.
Shipping information is optional, depending on whether you’re sending the customer a physical product.
Billing information is required, but only country and postal code. This is handled automatically by the Stripe component, as described above, so you don’t need to add your own billing address fields.
Add dynamic line items
Add dynamic line items
Sometimes you need your line items to be dynamic - i.e. change based on the user’s answers, such as the plan that they select.
To do this:
- Use a Computed Field` to generate the JSON for the line items.
- Refernce the key of that Computed Field in the Line Items section of the Stripe component.
In order for the Stripe component to still work when the Embeddable is in test mode, you need to ensure that the Computed Field handles test mode correctly by returning a test price_id.
Example Computed Field code:
Set values based on dynamic data
Set values based on dynamic data
You can set pretty much any value in the Stripe component based on dynamic data, such as the user’s answers to a question (e.g. their email address), or a value that’s computed from an answer (e.g. the post-purchase success message).
For values that come directly from user answers (like email, phone number, or shipping address):
-
Add an input component (like Email Input, Phone Input, etc.) to your Embeddable where you want to collect the user’s information.
-
In the Stripe component settings, locate the field you want to set dynamically.
-
Use templating syntax to reference the input component’s key, e.g.
{{email}}
or{{phone}}
.
This works for any field in the Stripe component that accepts templating, including:
- Customer email
- Customer phone
- Shipping address fields
- Success message
For values that come directly from user answers (like email, phone number, or shipping address):
-
Add an input component (like Email Input, Phone Input, etc.) to your Embeddable where you want to collect the user’s information.
-
In the Stripe component settings, locate the field you want to set dynamically.
-
Use templating syntax to reference the input component’s key, e.g.
{{email}}
or{{phone}}
.
This works for any field in the Stripe component that accepts templating, including:
- Customer email
- Customer phone
- Shipping address fields
- Success message
For values that need to be calculated or transformed (like a dynamic success message):
Create a Computed Field
Create a Computed Field that will generate the value you want.
Write the computation logic
In the Computed Field, write code that returns the final value. For example:
Reference in Stripe component
In the Stripe component settings, use templating to reference the Computed Field’s key, e.g. {{success_message}}
.
You can mix and match both approaches - some fields might use simple templating while others use computed fields, depending on your needs.
Control Stripe prices from the Embeddables CMS
Control Stripe prices from the Embeddables CMS
If you handle multiple Stripe products or prices in your Embeddable, we recommend adding them to a table in the Embeddables CMS, and pulling those records into your Embeddable to use in your Stripe component.
See the How To: Control Stripe Prices from the Embeddables CMS guide for more information.
Apply coupons and promo codes
Apply coupons and promo codes
You can offer discounts to your customers using Stripe’s coupon and promo code system. This lets you create both customer-facing promo codes (like “BLACKFRIDAY50”) and automatic discounts.
See the How To: Use Stripe Coupons and Promo Codes guide for more information.
Place a hold on the customer's card
Place a hold on the customer's card
See the How To: Place a Hold on a Payment guide for more information on this feature.
You will need to manually release the hold on the user’s card at a later date to complete the payment.
Please note that Stripe only supports placing a hold on one-time payments, not recurring payments.
Add a custom success message
Add a custom success message
This lets you customize the message that users see after they complete the payment.
If the payment fails, for example if the credit card is declined, the error message returned from Stripe will be displayed to the user.
Choose a layout for the Stripe component
Choose a layout for the Stripe component
This lets you choose a layout for the Stripe component, which affects how different payment method options are displayed to the user. The following options are available:
- Tabs (default): This displays different payment methods in separate tabs, in a horizontal row across the top of the component.
- Accordion: This displays different payment methods in an accordion of expanded and collapsed sections, with one payment method option open at a time.
Set up Apple Pay and Google Pay
Set up Apple Pay and Google Pay
Apple Pay and Google Pay can be enabled as payment methods in your Stripe checkout. Here’s how to set them up:
Google Pay
- Enable Google Pay in your Stripe Dashboard under Payment Methods
- Once enabled, Google Pay will automatically appear as a payment option for users who:
- Are using Chrome browser
- Are logged into a Google account
- Have Google Pay set up on their account
- No additional configuration is required in Embeddables
Apple Pay
- Enable Apple Pay in your Stripe Dashboard under Payment Methods
- You must verify your domain with Apple through the Stripe Dashboard:
- Go to the Apple Pay Settings in your Stripe Dashboard
- Add and verify your domain(s) where you’ll be accepting Apple Pay
- Follow Stripe’s verification process to complete domain verification
- Once enabled and verified, Apple Pay will automatically appear as a payment option for users who:
- Are using Safari browser
- Are logged into an Apple account
- Have Apple Pay set up on their device
- No additional configuration is required in Embeddables
Both Apple Pay and Google Pay will only appear as payment options when the user’s browser and account settings support them. If a user doesn’t meet the requirements, they won’t see these payment options.
Set up Stripe Link
Set up Stripe Link
Stripe Link is a fast-checkout payment method that lets users save and reuse their payment info across Stripe merchants.
- Enable Stripe Link in your Stripe Dashboard under Payment Methods.
- Enable Stripe Link in Embeddables:
In the Stripe component Options sidebar, select “Link” under the list of available Payment method types. - Once enabled in both places, Stripe Link will automatically appear as a payment option for users who:
- Have a Link account (or choose to create one at checkout)
- Are using a supported browser and device
Trigger actions on payment events
Trigger actions on payment events
You can trigger Actions on the following payment events:
Event | Triggered when |
---|---|
Payment attempted | The user clicks the Pay button (regardless of success or failure) |
Payment successful | The payment is completed |
Payment failed | The payment is declined |
To do this:
- Create a new Action and type the JavaScript code you want to run.
- Add a Trigger to the Action that fires on one of the above payment events.
Collect Stripe IDs to send to your backend
Collect Stripe IDs to send to your backend
You can collect the following IDs that Stripe provides when a payment is completed:
Stripe ID | Provided for |
---|---|
Customer ID | All payment types |
Invoice ID | All payments except on-hold payments and collecting card details |
Payment Intent ID | One-time payments only |
Subscription ID | Recurring payments only |
To collect these IDs:
- Specify a User Data key to store the ID in, in the relevant field in the Stripe component options.
- Add that key to the Registered Keys in the Embeddable-wide settings.
To send them to your backend:
- Set up an Action that’s triggered when the payment is completed, as specified above in Trigger actions on payment events.
- Use the relevant keys in
userData
, provided in the Action function’s first argument.
Example Action code:
Store the selected plan/product and payment status in User Data
Store the selected plan/product and payment status in User Data
Storing the plan or product that the user selected, and the status of the payment, can be useful when looking at your users’ data later, or sending that data to your own backend or CRM.
The good news is that this information is almost certainly already being stored!
Storing the plan or product
If you’re offering multiple plans or products to the user, then that probably means you’re either:
- Using an Option Selector component to let the user select the plan or product they want to purchase, or
- Using a Computed Field to calculate the appropriate plan or product based on the user’s answers.
In both cases, just make sure that the key you’re using to store the plan or product is set to be stored in the ‘Embedables Cloud Context’ - i.e. stored in Embeddables’ database.
If you’re offering multiple plans or products, you’re also probably using a Computed Field to generate the line items for the Stripe component, including the price_id(s).
You can then opt to store this in the ‘Embedables Cloud Context’ as well.
Alternatively, you can store a simplified version with just the price_id(s), by computing with with another Computed Field.
Storing the payment status
The payment status is automatically stored in User Data, using the key of the Stripe component.
For this reason, we recommend choosing a straightforward key name for the Stripe component, e.g. stripe_payment
.
The status will then appear in the User Data as one of the following:
stripe_payment: 'fresh'
- The Stripe checkout has been reset and is ready for another attemptstripe_payment: 'pending'
- The payment has just been attempted, and is awaiting a success or failure response from Stripestripe_payment: 'error'
- The payment failedstripe_payment: 'completed'
- The payment was successful
Just make sure that the key of the Stripe component is set to be stored in the ‘Embedables Cloud Context’ - i.e. stored in Embeddables’ database.
Send custom metadata to Stripe
Send custom metadata to Stripe
You can send custom metadata to Stripe with each payment, which is useful for tracking additional information about the customer or transaction.
In the Stripe component settings, look for the Metadata section. Here, you can add key-value pairs that will be sent to Stripe as metadata on the Checkout Session or Payment Intent.
- Enter a key (e.g.,
user_id
,order_source
, etc.) and a value. - You can use templating in the value field, such as
{{user_id}}
or{{email}}
, to dynamically insert user data. You can even compute a new value in a Computed Field and use that in the metadata. - Click the
+
button to add more metadata fields.
Metadata is visible in the Stripe Dashboard and can be used for reporting, searching, or integrating with your backend.
Troubleshooting
I'm getting an error about a missing publishable key
I'm getting an error about a missing publishable key
This likely means that you need to grab your Publishable Key from the API Keys section of your Stripe Dashboard, and pass it to the Embeddables Team to set up for you.
It might also mean that the Stripe publishable key has not been set up for your Embeddable.
How to fix:
- Make sure you have sent your Stripe Publishable Key to the Embeddables team.
- If you are testing, ensure you are using the correct mode (test or live) and that the corresponding key is set up. See: I’m seeing test mode errors on a live link.
- To use test keys, add
?savvy_test=true
to your URL.
I'm getting an error about a missing restricted key
I'm getting an error about a missing restricted key
This means that you need to generate a Restricted Key with the scopes/permissions listed above, from the API Keys section of your Stripe Dashboard, and pass it to the Embeddables Team to set up for you.
Error: You must provide one of `price` or `price_data` for each line item when using prices.
Error: You must provide one of `price` or `price_data` for each line item when using prices.
This means that you have at least one line item that is not using a Price ID (a pre-created price in Stripe), nor is it using a Price Data object (a custom price created in the Embeddables Builder).
If you’re using a Computed Field to generate the line items, check the value that it’s returning, and make sure it’s being passed into the Stripe component.
Error: No such price: 'price_xxxxxx'; a similar object exists in test mode, but a live mode key was used to make this request.
Error: No such price: 'price_xxxxxx'; a similar object exists in test mode, but a live mode key was used to make this request.
This means that you’re using a test mode Price ID, but are testing Stripe in live mode.
There are two common causes of this:
- You’re using a test mode Price ID in your Computed Field, but have not set the Embeddable to test mode.
To make sure that you’re in Test Mode, ensure that one of the following is true:
- You’re testing on a link with
?savvy_test=true
in the URL, OR - You’re testing on a
preview.embeddables.com
link
- You’ve set the Embeddable to test mode, but the Public and Restricted keys that you gave to the Embeddables Team to use for Test Mode were actually live mode keys.
To check which Stripe keys are being used:
- Open the Developer Tools in your browser and go to the Elements tab.
- Use
Cmd+F
/Ctrl+F
to search fordata-flow-stripe-publishable-key-value
. - Check whether the value starts with
pk_live_
orpk_test_
.
See: Adding dynamic line items for more information on how to handle this.
Error: No such price: 'price_xxxxxx'
Error: No such price: 'price_xxxxxx'
This likely means that you’re testing with a Price ID that comes from a different Stripe account from the one that you’re using to accept payments.
For example, you might be using a live mode Price ID from your own Stripe account, but the Embeddable is currently in Test Mode and connected to the Embeddables-provided Stripe account.
See: Adding dynamic line items for more information on how to handle this.
I'm seeing test mode errors on a live link
I'm seeing test mode errors on a live link
If you see errors about test keys or test Price IDs while using a live link, it usually means that the keys provided to Embeddables are for test mode only.
How to fix:
- Confirm with your team which keys (publishable and restricted) have been sent to Embeddables.
- If you want to test in live mode, you must provide live mode keys to Embeddables.
- If both keys are test keys, you can only test in test mode (
?savvy_test=true
).
I'm seeing live mode errors on a test link
I'm seeing live mode errors on a test link
If you see errors about live keys or live Price IDs while using a test link (or with ?savvy_test=true
), it usually means that the keys provided to Embeddables are for live mode only.
How to fix:
- Confirm with your team which keys (publishable and restricted) have been sent to Embeddables.
- If you want to test in test mode, you must provide test mode keys to Embeddables.
- If both keys are live keys, you can only test in live mode (remove
?savvy_test=true
from the URL).