diff --git a/models/processor/BaseProcessor.cfc b/models/processor/BaseProcessor.cfc
index 04bd44a..3448563 100755
--- a/models/processor/BaseProcessor.cfc
+++ b/models/processor/BaseProcessor.cfc
@@ -98,6 +98,25 @@ component accessors="true" {
 		throw( "This method must be implemented in the child processor" );
 	}
 
+		/**
+	 * Create a payment intent which can be used for recurring billing
+	 *
+	 * @amount The amount in cents to charge, example: $20 = 2000, $20.5 = 2050, it is required
+	 * @currency Usually the three-letter ISO Currency code (Optional)
+	 * @customerId A customer identifier to attach to the charge (Optional)
+	 * @description The description of the charge (Optional)
+	 */
+	ProcessorResponse function createPaymentIntent(
+		required numeric amount,
+		required string customer,
+		required string payment_method,
+		string description = "",
+		string currency = "usd",
+		struct metadata = {}
+	){
+		throw( "This method must be implemented in the child processor" );
+	}
+
 	/**
 	 * Create a subscription in the provider
 	 * The processor implementation must take care of them.
diff --git a/models/processor/IPaymentProcessor.cfc b/models/processor/IPaymentProcessor.cfc
index c733f8f..b86ebd7 100644
--- a/models/processor/IPaymentProcessor.cfc
+++ b/models/processor/IPaymentProcessor.cfc
@@ -76,6 +76,23 @@ interface {
 		struct metadata = {}
 	);
 
+	/**
+	 * Create a payment intent which can be used for recurring billing
+	 *
+	 * @amount The amount in cents to charge, example: $20 = 2000, $20.5 = 2050, it is required
+	 * @currency Usually the three-letter ISO Currency code (Optional)
+	 * @customerId A customer identifier to attach to the charge (Optional)
+	 * @description The description of the charge (Optional)
+	 */
+	ProcessorResponse function createPaymentIntent(
+		required numeric amount,
+		required string customer,
+		required string payment_method,
+		string description = "",
+		string currency = "usd",
+		struct metadata = {}
+	);
+
 	/**
 	 * Create a subscription in the provider
 	 * The processor implementation must take care of them.
diff --git a/models/processor/StripeProcessor.cfc b/models/processor/StripeProcessor.cfc
index 157d38b..e00df10 100755
--- a/models/processor/StripeProcessor.cfc
+++ b/models/processor/StripeProcessor.cfc
@@ -302,6 +302,125 @@ component
 		return oResponse;
 	}
 
+
+	/**
+	 * Make a charge on the processor
+	 * TODO: Add this to the interface
+	 *
+	 * @amount The amount in cents to charge, example: $20 = 2000, $20.5 = 2050, it is required
+	 * @currency Usually the three-letter ISO Currency code (Optional)
+	 * @customerId A customer identifier to attach to the charge (Optional)
+	 * @description The description of the charge (Optional)
+	 */
+	ProcessorResponse function createSetupIntent(
+		required string customer,
+		string description = "",
+		string currency = "usd",
+		string usage = "off_session",
+		boolean attach_to_self = false,
+		string flow_directions = "inbound",
+		struct metadata = {}
+	) {
+		var oResponse = newResponse();
+
+		if ( log.canDebug() ) {
+			log.debug( "Stripe setup intent creation request: #serializeJSON( arguments )#" );
+		}
+
+		var processorResponse = variables.stripe.setupIntents.create( argumentCollection = arguments );
+
+		oResponse.setContent( processorResponse.content );
+
+		// Check for errors
+		if ( processorResponse.status >= 300 ) {
+			oResponse.setError( true );
+		}
+
+		if ( log.canDebug() ) {
+			log.debug( "Stripe setup intent creation response: #serializeJSON( oResponse.getContent() )#" );
+		}
+
+		return oResponse;
+	}
+
+	ProcessorResponse function getSetupIntent( required intentId ){
+
+	}
+
+	/**
+	 * Make a charge on the processor
+	 * TODO: Add this to the interface
+	 *
+	 * @amount The amount in cents to charge, example: $20 = 2000, $20.5 = 2050, it is required
+	 * @currency Usually the three-letter ISO Currency code (Optional)
+	 * @customerId A customer identifier to attach to the charge (Optional)
+	 * @description The description of the charge (Optional)
+	 */
+	ProcessorResponse function createPaymentIntent(
+		required numeric amount,
+		required string customer,
+		required string payment_method,
+		string description = "",
+		string currency = "usd",
+		struct metadata = {}
+	) {
+		var oResponse = newResponse();
+
+		if ( log.canDebug() ) {
+			log.debug( "Stripe payment intent creation request: #serializeJSON( arguments )#" );
+		}
+
+		var processorResponse = variables.stripe.paymentIntents.create( argumentCollection = arguments );
+
+		oResponse.setContent( processorResponse.content );
+
+		// Check for errors
+		if ( processorResponse.status >= 300 ) {
+			oResponse.setError( true );
+		}
+
+		if ( log.canDebug() ) {
+			log.debug( "Stripe payment intent creation response: #serializeJSON( oResponse.getContent() )#" );
+		}
+
+		return oResponse;
+	}
+
+
+
+	/**
+	 * Retrieve the payment intent status
+	 *
+	 * @providerCustomerId
+	 * @planId
+	 * @quantity
+	 * @metadata
+	 */
+	public string function fetchPaymentIntentStatus( required string paymentIntentId ) {
+
+		var oResponse = newResponse();
+
+		if ( log.canDebug() ) {
+			log.debug( "Stripe payment intent status request: #serializeJSON( arguments )#" );
+		}
+
+		var processorResponse = variables.stripe.paymentIntents.retrieve( arguments.paymentIntentId );
+
+		oResponse.setContent( processorResponse.content );
+
+		// Check for errors
+		if ( processorResponse.status >= 300 ) {
+			oResponse.setError( true );
+		}
+
+		if ( log.canDebug() ) {
+			log.debug( "Stripe payment intent status response: #serializeJSON( oResponse.getContent() )#" );
+		}
+
+		return oResponse;
+	}
+
+
 	/**
 	 * Create a subscription, combine a plan with a customer
 	 *
@@ -648,6 +767,26 @@ component
 		return oResponse;
 	}
 
+	/**
+	 * Validate a promotion code
+	 *
+	 * @code The promotion code to validate
+	 */
+	ProcessorResponse function validatePromotionCode( required code ) {
+		var oResponse = newResponse();
+
+		var promotionCodes = variables.stripe.promotionCodes.list( { code: code, active: true, limit: 1 } ).content;
+
+		if ( promotionCodes.data.len() <= 0 ) {
+			oResponse.setError( true );
+			oResponse.setContent( "Not promotion code found for [#code#]." );
+			return oResponse;
+		}
+
+		oResponse.setContent( promotionCodes.data[ 1 ] );
+		return oResponse;
+	}
+
 	/**
 	 * Returns an ISO formatted date from unixSeconds
 	 *