Tassos Marinos Developer of Joomla Extensions

How to create a Stripe Joomla Form

Published in Convert Forms
Updated 13 Sep, 2023

Would you like to collect payments with your form? You can now transform your form into a Stripe payment form where you can collect one-time payments, without your users ever leaving your site.

How to create a Stripe form

Step 1: Create a form

Start by creating a new Form via Components > Convert Forms > Forms > New or edit an existing one. Once you are in your Form, you will need to add a few fields into your form. Below you can field all fields required for your Stripe form to work.

Step 2: Populate your form

I want my users to select the payment amount.

If you want your users to enter the amount for the payment, create a Number field with the following settings:

Field TypeField Name
Number amount

I want to define a fixed payment amount.

If you want your payment to have a fixed amount, ceate a Hidden field with the following settings:

Field TypeField NameField Value
Hidden amount 50

Replace the number 50 with the amount of your choice.

You will also need to create the following fields:

Field TypeField Name
Hidden stripeToken
Field TypeCSS Class
HTML cf-card-element
HTML cf-card-errors

Step 3: Get your API Keys

You will need to get your Stripe publishable and secret API keys. The publishable API key is used to display the form on your site whereas the secret API key is used to make the payment request to Stripe. You can find both keys on Stripe's docs: Find your API Keys.

Step 4: Add custom code

Go to your Form > Design > Advanced > Custom CSS and enter the following:

.cf-card-errors {
	display: none;
	margin: 3px 9px;;
	border: 1px solid currentColor;
	color: #ff0000;
}

.cf-card-errors.is-visible {
	display: block;
}

Go to your Form > Design > Advanced > Custom Code and enter the following:

<script src="https://js.stripe.com/v3/"></script>
<script>
	// Enter your Form's ID
	var cf_form_id = 170;

	// Enter your Stripe Publishable Key
	var cf_stripe_publishable_key = 'pk_test_PUBLISHABLE_KEY';

	// Do not edit below
	document.addEventListener('DOMContentLoaded', function(e) {
		var stripe = Stripe(cf_stripe_publishable_key);
		var elements = stripe.elements();

		// Create an instance of the card Element.
		var card = elements.create('card');

		// Add an instance of the card Element into the `cf-card-element` element.
		card.mount('.cf-card-element');

		var form = document.querySelector("#cf_" + cf_form_id);
		form.querySelector('button[type="submit"]').addEventListener("click", function(event) {
			event.preventDefault();

			// form is working
			form.classList.add('cf-working');
			form.classList.add('cf-disabled');

			var errorElement = document.querySelector('.cf-card-errors');

			// store card options
			var card_options = {};

			// Check whether we have a card holder
			var card_holder = form.querySelector('input[type="text"].cf-card-holder');
			if (card_holder) {
				card_options.name = card_holder.value;
			}
			
			stripe.createToken(card, card_options).then(function(result) {
				// reset form
				form.classList.remove('cf-working');
				form.classList.remove('cf-disabled');
                
				if (result.error) {
					// Inform the customer that there was an error.
					errorElement.classList.add('is-visible');
					errorElement.innerHTML = result.error.message;
				} else {
					errorElement.classList.remove('is-visible');
                    
					// Save token ID into the form so it gets submitted to the server
					form.querySelector('input[name="cf[stripeToken]"]').value = result.token.id;

					// submit form
					form.ConvertForms.submit(event);
				}
			});
		});

		// Clear stripe field values on success
		form.addEventListener("success", function(event) {
			card.clear();
		});
	});
</script>
  • Set your form ID on variable cf_form_id.
  • Set your Stripe Publishable API Key on variable cf_stripe_publishable_key

Go to your Form > Behavior > PHP Scripts > After Form Submission and enter the following:

/**
 * Enter the currency. Should be a 3-letter lowercase value.
 * Find more: https://stripe.com/docs/currencies#presentment-currencies
 */
$currency = 'usd';

// Enter your Secret API Key
$secret_api_key = 'sk_test_SECRET_KEY';

/**
 * (Optional) Add a description to the transaction.
 * 
 * Useful as you can pass user-submitted data and know which user made this transaction.
 */
$payment_description = 'Transaction made by Convert Forms';

// Do not edit below
// Validate amount
if (empty($submission->params['amount']) || $submission->params['amount'] < 0)
{
	throw new Exception('Please enter a valid amount.');
}

// Validate stripe token
if (empty($submission->params['stripeToken']))
{
	throw new Exception('Could not verify credit card details. Please try again.');
}

$data = [
	'amount' => $submission->params['amount'] * 100,
	'currency' => $currency,
	'source' => $submission->params['stripeToken']
];

// add a description to the payment
if (!empty($payment_description))
{
	$data['description'] = $payment_description;
}

// add email address where the receipt will be sent
if (isset($submission->params['receipt_email']))
{
	$data['receipt_email'] = $submission->params['receipt_email'];
}

$headers = array(
	'Authorization' => 'Bearer ' . $secret_api_key,
);

$response = JHttpFactory::getHttp()->post('https://api.stripe.com/v1/charges', http_build_query($data), $headers);

// If an error HTTP code was returned, show the error
if ($response->code != 200 && $response->code != 100)
{
	$error = json_decode($response->body);
	throw new Exception($error->error->message);
}
  • Set the currency of the payment on $currency variable. You can find all Stripe supported currencies, here
  • Set your Stripe Secret API Key on $secret_api_key variable.
  • You may pass a description alongside each payment by setting a value to the variable $payment_description.

Stripe Form Preview

Below you can see how your Stripe form can appear.

Convert Forms Stripe Payments Form

Frequently Asked Questions

How can I store the card holder's name?

To save the card holders name, create a field with the following settings:

Field TypeField NameInput CSS Class
Text card_holder cf-card-holder

The card holder's name will now automatically be synced with each payment.

How can I send the receipt to the customer?

To automatically send the charge receipt to your customer, you will need to create either a hidden or a text field to store the user's email address. Field settings can be found below:

Field TypeField Name
Text or Hidden receipt_email

You may utilize Smart Tags if the form appears to registered users to automatically fill it with your users email address.

Can I calculate the amount based on field values?

Whether you have a simple or a complex calculation, using the Field Calculations you can now pass the calculated total as the amount to your payment or donation.

How can I include an idempotency key to prevent duplicate submissions?

The idempotency key helps prevent accidentally performing the same charge twice. You can read more on Stripe's documentation, here.

To include an idempotency key, replace:

$headers = [
	'Authorization' => 'Bearer ' . $secret_api_key
];

with:

$headers = [
	'Authorization' => 'Bearer ' . $secret_api_key,
	'Idempotency-Key' => uniqid('cf_submission_' . $submission->id)
];

This will automatically add a unique ID as the idempotency key ensuring its uniqueness given the submission ID.

Why is my card declined and requires authentication?

The method described above provides just the bare minimum to perform a Stripe payment and does not support 3DSecure, which is a way to validate that the person performing the purchase is the card owner. This will be supported in the future once we implement Payment Gateways.