From 75b50ee3b80220677c4064261e5568f4d5597651 Mon Sep 17 00:00:00 2001
From: drastik <jwjoshuawalker@gmail.com>
Date: Sat, 11 Aug 2012 19:03:22 -0700
Subject: [PATCH] added 4.2 version

---
 .../info.xml                                  |   2 +-
 .../extern/civicrm_stripe_cron_live.php       |   7 +-
 .../extern/civicrm_stripe_cron_test.php       |   7 +-
 .../CRM/Core/BillingBlock.tpl                 | 221 +++++++++++
 .../info.xml                                  |  36 ++
 .../stripe.php                                | 347 ++++++++++++++++++
 source/extern/civicrm_stripe_cron_live.php    |   7 +-
 source/extern/civicrm_stripe_cron_test.php    |   7 +-
 8 files changed, 617 insertions(+), 17 deletions(-)
 create mode 100644 extension-4.2/civicrm_templates/CRM/Core/BillingBlock.tpl
 create mode 100644 extension-4.2/com.drastikbydesign.payment.stripe/info.xml
 create mode 100644 extension-4.2/com.drastikbydesign.payment.stripe/stripe.php

diff --git a/extension-4.1/com.drastikbydesign.payment.stripe/info.xml b/extension-4.1/com.drastikbydesign.payment.stripe/info.xml
index 78b4ae19..78a837d5 100644
--- a/extension-4.1/com.drastikbydesign.payment.stripe/info.xml
+++ b/extension-4.1/com.drastikbydesign.payment.stripe/info.xml
@@ -29,7 +29,7 @@
    <urlRecurTestDefault>https://api.stripe.com/v1</urlRecurTestDefault>
    <urlButtonDefault></urlButtonDefault>
    <urlButtonTestDefault></urlButtonTestDefault>
-   <billingMode>notify</billingMode>
+   <billingMode>form</billingMode>
    <isRecur>1</isRecur>
    <paymentType>1</paymentType>
   </typeInfo>
diff --git a/extension-4.1/extern/civicrm_stripe_cron_live.php b/extension-4.1/extern/civicrm_stripe_cron_live.php
index 2f45723c..079f2773 100644
--- a/extension-4.1/extern/civicrm_stripe_cron_live.php
+++ b/extension-4.1/extern/civicrm_stripe_cron_live.php
@@ -15,11 +15,10 @@ require_once("packages/stripe-php/lib/Stripe.php");
 Stripe::setApiKey($stripe_key);
 
 $time = time();
-print $time;
 $query = "
-SELECT  customer_id, invoice_id 
-FROM    civicrm_stripe_subscriptions 
-WHERE   end_time <= '$time' 
+  SELECT  customer_id, invoice_id 
+  FROM    civicrm_stripe_subscriptions 
+  WHERE   end_time <= '$time' 
 ";
 
 $end_recur_query = CRM_Core_DAO::executeQuery($query);
diff --git a/extension-4.1/extern/civicrm_stripe_cron_test.php b/extension-4.1/extern/civicrm_stripe_cron_test.php
index 64638938..85cd2770 100644
--- a/extension-4.1/extern/civicrm_stripe_cron_test.php
+++ b/extension-4.1/extern/civicrm_stripe_cron_test.php
@@ -15,11 +15,10 @@ require_once("packages/stripe-php/lib/Stripe.php");
 Stripe::setApiKey($stripe_key);
 
 $time = time();
-print $time;
 $query = "
-SELECT  customer_id, invoice_id 
-FROM    civicrm_stripe_subscriptions 
-WHERE   end_time <= '$time' 
+  SELECT  customer_id, invoice_id 
+  FROM    civicrm_stripe_subscriptions 
+  WHERE   end_time <= '$time' 
 ";
 
 $end_recur_query = CRM_Core_DAO::executeQuery($query);
diff --git a/extension-4.2/civicrm_templates/CRM/Core/BillingBlock.tpl b/extension-4.2/civicrm_templates/CRM/Core/BillingBlock.tpl
new file mode 100644
index 00000000..96a007b2
--- /dev/null
+++ b/extension-4.2/civicrm_templates/CRM/Core/BillingBlock.tpl
@@ -0,0 +1,221 @@
+{*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.1                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2011                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*}
+{if $form.credit_card_number or $form.bank_account_number}
+<!-- START Stripe -->
+  {if $paymentProcessor.payment_processor_type == 'Stripe'}
+
+    <script type="text/javascript" src="https://js.stripe.com/v1/"></script>
+  	<script type="text/javascript">
+  	var stripe_publishable_key = '{$paymentProcessor.password}';
+  	
+	{literal}
+	  cj(function() {
+		cj(document).ready(function(){
+		  //Identify the payment form.  Don't reference by form#id since it changes between payment pages (Contribution / Event / etc).
+		  cj("#crm-container>form").addClass('stripe-payment-form');
+		  Stripe.setPublishableKey(stripe_publishable_key);
+		  cj("form.stripe-payment-form").submit(function(event) {
+    	    // disable the submit button to prevent repeated clicks
+    	  	cj('form.stripe-payment-form input.form-submit').attr("disabled", "disabled");
+
+    	 	Stripe.createToken({
+        	  number: cj('#credit_card_number').val(),
+        	  cvc: cj('#cvv2').val(),
+        	  exp_month: cj('#credit_card_exp_date\\[M\\]').val(),
+        	  exp_year: cj('#credit_card_exp_date\\[Y\\]').val()
+    	  	}, stripeResponseHandler);
+
+    	  	// prevent the form from submitting with the default action
+    	  	return false;
+  		  });
+		});
+		
+		//Response from Stripe.createToken.
+		function stripeResponseHandler(status, response) {		  
+		  if (response.error) {
+        	// show the errors on the form
+			cj("form.stripe-payment-form").prepend('<div class="messages crm-error">'
+				+'<strong>Payment Error Response:</strong>'
+	   			  +'<ul id="errorList">'
+	         		+'<li>Error: ' + response.error.message + '</li>'
+	   			  +'</ul>'
+   				+'</div>');
+
+        	cj('form.stripe-payment-form input.form-submit').removeAttr("disabled");
+
+    	  } else {
+        	var token = response['id'];
+        	// Update form with the token & submit
+        	cj("input#stripe-token").val(token);
+        	cj("form.stripe-payment-form").get(0).submit();
+    	  }
+		}
+	  });
+    {/literal}
+    </script>
+  {/if}
+<!-- END Stripe -->
+    <div id="payment_information">
+        <fieldset class="billing_mode-group {if $paymentProcessor.payment_type & 2}direct_debit_info-group{else}credit_card_info-group{/if}">
+            <legend>
+               {if $paymentProcessor.payment_type & 2}
+                    {ts}Direct Debit Information{/ts}
+               {else}
+                   {ts}Credit Card Information{/ts}
+               {/if}
+            </legend> 
+            {if $paymentProcessor.billing_mode & 2 and !$hidePayPalExpress }
+            <div class="crm-section no-label paypal_button_info-section">	
+			    <div class="content description">
+			        {ts}If you have a PayPal account, you can click the PayPal button to continue. Otherwise, fill in the credit card and billing information on this form and click <strong>Continue</strong> at the bottom of the page.{/ts}
+				</div>
+			</div>
+			 <div class="crm-section no-label {$form.$expressButtonName.name}-section">	
+			    <div class="content description">
+			        {$form.$expressButtonName.html}
+			        <div class="description">Save time. Checkout securely. Pay without sharing your financial information. </div>
+				</div>
+			</div>
+            {/if} 
+
+            {if $paymentProcessor.billing_mode & 1}
+                <div class="crm-section billing_mode-section {if $paymentProcessor.payment_type & 2}direct_debit_info-section{else}credit_card_info-section{/if}">
+                   {if $paymentProcessor.payment_type & 2}
+                        <div class="crm-section {$form.account_holder.name}-section">	
+							<div class="label">{$form.account_holder.label}</div>
+                            <div class="content">{$form.account_holder.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        <div class="crm-section {$form.bank_account_number.name}-section">	
+							<div class="label">{$form.bank_account_number.label}</div>
+                            <div class="content">{$form.bank_account_number.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        <div class="crm-section {$form.bank_identification_number.name}-section">	
+							<div class="label">{$form.bank_identification_number.label}</div>
+                            <div class="content">{$form.bank_identification_number.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        <div class="crm-section {$form.bank_name.name}-section">	
+							<div class="label">{$form.bank_name.label}</div>
+                            <div class="content">{$form.bank_name.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                   {else}
+                		<div class="crm-section {$form.credit_card_type.name}-section">	
+							<div class="label">{$form.credit_card_type.label}</div>
+                			<div class="content">{$form.credit_card_type.html}</div>
+                			<div class="clear"></div> 
+                		</div>
+                		<div class="crm-section {$form.credit_card_number.name}-section">	
+							<div class="label">{$form.credit_card_number.label}</div>
+                			<div class="content">{$form.credit_card_number.html}
+                				<div class="description">{ts}Enter numbers only, no spaces or dashes.{/ts}</div>
+                			</div>
+                			<div class="clear"></div> 
+                		</div>
+                		<div class="crm-section {$form.cvv2.name}-section">	
+							<div class="label">{$form.cvv2.label}</div>
+                			<div class="content">
+                				{$form.cvv2.html}
+                				<img src="{$config->resourceBase}i/mini_cvv2.gif" alt="{ts}Security Code Location on Credit Card{/ts}" style="vertical-align: text-bottom;" />
+                				<div class="description">{ts}Usually the last 3-4 digits in the signature area on the back of the card.{/ts}</div>
+                			</div>
+                			<div class="clear"></div> 
+                		</div>
+                		<div class="crm-section {$form.credit_card_exp_date.name}-section">	
+							<div class="label">{$form.credit_card_exp_date.label}</div>
+                			<div class="content">{$form.credit_card_exp_date.html}</div>
+                			<div class="clear"></div> 
+                		</div>
+                    {/if}
+                </div>
+                </fieldset>
+
+                <fieldset class="billing_name_address-group">
+                	<legend>{ts}Billing Name and Address{/ts}</legend>
+                    <div class="crm-section billing_name_address-section">
+                        <div class="crm-section billingNameInfo-section">	
+                        	<div class="content description">
+                        	  {if $paymentProcessor.payment_type & 2}
+                        	     {ts}Enter the name of the account holder, and the corresponding billing address.{/ts}
+                        	  {else}
+                        	     {ts}Enter the name as shown on your credit or debit card, and the billing address for this card.{/ts}
+                        	  {/if}
+                        	</div>
+                        </div>
+                        <div class="crm-section {$form.billing_first_name.name}-section">	
+							<div class="label">{$form.billing_first_name.label}</div>
+                            <div class="content">{$form.billing_first_name.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        <div class="crm-section {$form.billing_middle_name.name}-section">	
+							<div class="label">{$form.billing_middle_name.label}</div>
+                            <div class="content">{$form.billing_middle_name.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        <div class="crm-section {$form.billing_last_name.name}-section">	
+							<div class="label">{$form.billing_last_name.label}</div>
+                            <div class="content">{$form.billing_last_name.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        {assign var=n value=billing_street_address-$bltID}
+                        <div class="crm-section {$form.$n.name}-section">	
+							<div class="label">{$form.$n.label}</div>
+                            <div class="content">{$form.$n.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        {assign var=n value=billing_city-$bltID}
+                        <div class="crm-section {$form.$n.name}-section">	
+							<div class="label">{$form.$n.label}</div>
+                            <div class="content">{$form.$n.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        {assign var=n value=billing_country_id-$bltID}
+                        <div class="crm-section {$form.$n.name}-section">	
+							<div class="label">{$form.$n.label}</div>
+                            <div class="content">{$form.$n.html|crmReplace:class:big}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        {assign var=n value=billing_state_province_id-$bltID}
+                        <div class="crm-section {$form.$n.name}-section">	
+							<div class="label">{$form.$n.label}</div>
+                            <div class="content">{$form.$n.html|crmReplace:class:big}</div>
+                            <div class="clear"></div> 
+                        </div>
+                        {assign var=n value=billing_postal_code-$bltID}
+                        <div class="crm-section {$form.$n.name}-section">	
+							<div class="label">{$form.$n.label}</div>
+                            <div class="content">{$form.$n.html}</div>
+                            <div class="clear"></div> 
+                        </div>
+                    </div>
+                </fieldset>
+            {else}
+                </fieldset>
+            {/if}
+    </div>
+{/if}
\ No newline at end of file
diff --git a/extension-4.2/com.drastikbydesign.payment.stripe/info.xml b/extension-4.2/com.drastikbydesign.payment.stripe/info.xml
new file mode 100644
index 00000000..c481d743
--- /dev/null
+++ b/extension-4.2/com.drastikbydesign.payment.stripe/info.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<extension key="com.drastikbydesign.payment.stripe" type="payment">
+  <file>stripe</file>
+  <name>Stripe</name>
+  <description>Stripe Payment Processor</description>
+  <urls>
+    <url desc="Main Extension Page">http://drastikbydesign.com</url>
+  </urls>
+  <license>AGPL</license>
+  <maintainer>
+    <author>Joshua Walker (drastik) - Drastik by Design</author>
+    <email>admin (at) drastikbydesign.com</email>
+  </maintainer>
+  <releaseDate>2012-08-11</releaseDate>
+  <version>1.0</version>
+  <develStage>stable</develStage>
+  <compatibility><ver>4.2</ver></compatibility>
+  <comments></comments>
+  <typeInfo>
+   <userNameLabel>Secret Key</userNameLabel>
+   <passwordLabel>Publishable Key</passwordLabel>
+   <signatureLabel></signatureLabel>
+   <subjectLabel></subjectLabel>
+   <urlSiteDefault>https://api.stripe.com/v1</urlSiteDefault>
+   <urlApiDefault></urlApiDefault>
+   <urlRecurDefault>https://api.stripe.com/v1</urlRecurDefault>
+   <urlSiteTestDefault>https://api.stripe.com/v1</urlSiteTestDefault>
+   <urlApiTestDefault></urlApiTestDefault>
+   <urlRecurTestDefault>https://api.stripe.com/v1</urlRecurTestDefault>
+   <urlButtonDefault></urlButtonDefault>
+   <urlButtonTestDefault></urlButtonTestDefault>
+   <billingMode>form</billingMode>
+   <isRecur>1</isRecur>
+   <paymentType>1</paymentType>
+  </typeInfo>
+</extension>
\ No newline at end of file
diff --git a/extension-4.2/com.drastikbydesign.payment.stripe/stripe.php b/extension-4.2/com.drastikbydesign.payment.stripe/stripe.php
new file mode 100644
index 00000000..cd42409d
--- /dev/null
+++ b/extension-4.2/com.drastikbydesign.payment.stripe/stripe.php
@@ -0,0 +1,347 @@
+<?php
+ 
+require_once 'CRM/Core/Payment.php';
+ 
+class com_drastikbydesign_payment_stripe extends CRM_Core_Payment {
+  /**
+   * We only need one instance of this object. So we use the singleton
+   * pattern and cache the instance in this variable
+   *
+   * @var object
+   * @static
+   */
+  static private $_singleton = null;
+ 
+  /**
+   * mode of operation: live or test
+   *
+   * @var object
+   * @static
+   */
+  static protected $_mode = null;
+ 
+  /**
+   * Constructor
+   *
+   * @param string $mode the mode of operation: live or test
+   *
+   * @return void
+   */
+  function __construct($mode, &$paymentProcessor) {
+    $this->_mode             = $mode;
+    $this->_paymentProcessor = $paymentProcessor;
+    $this->_processorName    = ts('Stripe');
+  }
+ 
+  /**
+   * Singleton function used to manage this object
+   *
+   * @param string $mode the mode of operation: live or test
+   *
+   * @return object
+   * @static
+   *
+   */
+  static function &singleton($mode, &$paymentProcessor) {
+      $processorName = $paymentProcessor['name'];
+      if (self::$_singleton[$processorName] === NULL ) {
+          self::$_singleton[$processorName] = new com_drastikbydesign_payment_stripe($mode, $paymentProcessor);
+      } 
+      return self::$_singleton[$processorName];
+  }
+ 
+  /**
+   * This function checks to see if we have the right config values
+   *
+   * @return string the error message if any
+   * @public
+   */
+  function checkConfig() {
+    $config = CRM_Core_Config::singleton();
+    $error = array();
+
+    if (empty($this->_paymentProcessor['user_name'])) {
+      $error[] = ts('The "Secret Key" is not set in the Stripe Payment Processor settings.');
+    }
+
+    if (empty($this->_paymentProcessor['password'])) {
+      $error[] = ts('The "Publishable Key" is not set in the Stripe Payment Processor settings.');
+    }
+
+    if (!empty($error)) {
+      return implode('<p>', $error);
+    }
+    else {
+      return NULL;
+    }
+  }
+
+  /*
+   * CiviCRM extension install()
+   */
+  public function install() {
+    //Create required tables for Stripe
+    require_once "CRM/Core/DAO.php";
+    CRM_Core_DAO::executeQuery("
+		CREATE TABLE IF NOT EXISTS `civicrm_stripe_customers` (
+  			`email` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+  			`id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
+  			UNIQUE KEY `email` (`email`)
+			) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+			");
+      
+    CRM_Core_DAO::executeQuery("
+		CREATE TABLE IF NOT EXISTS `civicrm_stripe_plans` (
+  			`plan_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
+  			UNIQUE KEY `plan_id` (`plan_id`)
+			) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+		");
+      
+    CRM_Core_DAO::executeQuery("
+		CREATE TABLE IF NOT EXISTS `civicrm_stripe_subscriptions` (
+			`customer_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
+  			`invoice_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
+  			`end_time` int(11) NOT NULL DEFAULT '0',
+  			KEY `end_time` (`end_time`)
+			) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+    	");
+    
+    CRM_Core_DAO::executeQuery("
+		INSERT INTO civicrm_job (
+			id, domain_id, run_frequency, last_run, name, description, 
+			api_prefix, api_entity, api_action, parameters, is_active
+        ) VALUES (
+			NULL, %1, 'Daily', NULL, 'Check ending Stripe Recurring Payments', 
+			'End any Stripe recurring payments that have fufilled last installment',
+			'civicrm_api3', 'job', 'run_payment_cron', 'processor_name=Stripe', 0
+                )
+	", array(
+      1 => array(CIVICRM_DOMAIN_ID, 'Integer')
+      )
+    );
+    
+  }
+
+  /*
+   * CiviCRM extension uninstall()
+   */
+  public function uninstall() {
+    //Remove Stripe tables on uninstall
+    require_once "CRM/Core/DAO.php";
+    CRM_Core_DAO::executeQuery("DROP TABLE civicrm_stripe_customers");
+    CRM_Core_DAO::executeQuery("DROP TABLE civicrm_stripe_plans");
+    CRM_Core_DAO::executeQuery("DROP TABLE civicrm_stripe_subscriptions");
+    CRM_Core_DAO::executeQuery("
+		DELETE FROM civicrm_job 
+		  WHERE api_prefix = 'civicrm_api3'
+			AND api_entity = 'job'
+			AND api_action = 'run_payment_cron'
+			AND parameters = 'processor_name=Stripe'
+			AND domain_id  = %1
+	", array(
+      1 => array(CIVICRM_DOMAIN_ID, 'Integer')
+      )
+    );
+    
+  }
+  
+  /*
+   * Cron (Job Scheduler) callback (New, CiviCRM 4.2)
+   */
+  public function handlePaymentCron() {
+    $stripe_key = CRM_Core_DAO::singleValueQuery("SELECT user_name FROM civicrm_payment_processor WHERE payment_processor_type = 'Stripe' AND is_test = '0'");
+    require_once("packages/stripe-php/lib/Stripe.php");
+    Stripe::setApiKey($stripe_key);
+
+    $time = time();
+    $query = "
+		SELECT  customer_id, invoice_id 
+		FROM    civicrm_stripe_subscriptions 
+		WHERE   end_time <= '$time' 
+	";
+
+    $end_recur_query = CRM_Core_DAO::executeQuery($query);
+
+    while($end_recur_query->fetch()) {
+      $end_date = date("Y-m-d H:i:s");
+      $stripe_customer = Stripe_Customer::retrieve($end_recur_query->customer_id);
+      if(isset($stripe_customer)) {
+        $stripe_customer->cancelSubscription();
+        CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution_recur SET end_date = '$end_date', contribution_status_id = '1' WHERE invoice_id = '$end_recur_query->invoice_id'");
+        //Delete the Stripe Subscription from our cron watch list.
+        CRM_Core_DAO::executeQuery("DELETE FROM civicrm_stripe_subscriptions WHERE invoice_id = '$end_recur_query->invoice_id'");
+      }
+    }
+  }
+  
+  /**
+   * Submit a payment using Stripe's PHP API:
+   * https://stripe.com/docs/api?lang=php
+   *
+   * @param  array $params assoc array of input parameters for this transaction
+   *
+   * @return array the result in a nice formatted array (or an error object)
+   * @public
+   */
+  function doDirectPayment(&$params) {
+    //Include Stripe library & Set API credentials.
+    require_once("stripe-php/lib/Stripe.php");
+    Stripe::setApiKey($this->_paymentProcessor['user_name']);
+
+    //Stripe amount required in cents.
+    $amount = $params['amount'] * 100;
+    //It would require 3 digits after the decimal for one to make it this far, CiviCRM prevents this, but let's be redundant.
+    $amount = number_format($amount, 0, '', '');
+
+    //Check for existing customer, create new otherwise.
+    $email = $params['email'];
+    $customer_query = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_stripe_customers WHERE email = '$email'");
+
+    //Use Stripe.js instead of raw card details.
+    if(isset($params['stripe_token'])) {
+      $card_details = $params['stripe_token'];
+    } else {
+      CRM_Core_Error::fatal(ts('Stripe.js token was not passed!  Have you turned on the CiviCRM-Stripe CMS module?'));
+    }
+
+    /****
+     * If for some reason you cannot use Stripe.js and you are aware of PCI Compliance issues, here is the alternative to Stripe.js:
+     ****/ 
+    //Prepare Card details in advance to use for new Stripe Customer object if we need.
+/*   
+    $cc_name = $params['first_name'] . " ";
+    if (strlen($params['middle_name']) > 0) {
+      $cc_name .= $params['middle_name'] . " ";
+    }
+    $cc_name .= $params['last_name'];
+    
+    $card_details = array(
+  	  'number' => $params['credit_card_number'], 
+  	  'exp_month' => $params['month'], 
+  	  'exp_year' => $params['year'],
+      'cvc' => $params['cvv2'],
+      'name' => $cc_name,
+      'address_line1' => $params['street_address'],
+      'address_state' => $params['state_province'],
+      'address_zip' => $params['postal_code'],
+    );
+    */
+    
+    //Create a new Customer in Stripe
+    if(!isset($customer_query)) {
+      $stripe_customer = Stripe_Customer::create(array(
+  		'description' => 'Payment from CiviCRM',
+  		'card' => $card_details,
+        'email' => $email,
+      ));
+      
+      //Store the relationship between CiviCRM's email address for the Contact & Stripe's Customer ID
+      if(isset($stripe_customer)) {
+        CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_customers (email, id) VALUES ('$email', '$stripe_customer->id')");
+      } else {
+        CRM_Core_Error::fatal(ts('There was an error saving new customer within Stripe.  Is Stripe down?'));
+      }
+    } else {
+      $stripe_customer = Stripe_Customer::retrieve($customer_query);
+      if(!empty($stripe_customer)) {
+        $stripe_customer->card = $card_details;
+        $stripe_customer->save();
+      } else {
+        $stripe_customer = Stripe_Customer::create(array(
+  		  'description' => 'Donor from CiviCRM',
+  		  'card' => $card_details,
+          'email' => $email,
+        ));
+        
+        //Somehow a customer ID saved in the system no longer pairs with a Customer within Stripe.  (Perhaps deleted using Stripe interface?) 
+        //Store the relationship between CiviCRM's email address for the Contact & Stripe's Customer ID
+        if(isset($stripe_customer)) {
+          CRM_Core_DAO::executeQuery("DELETE FROM civicrm_stripe_customers WHERE email = '$email'");
+          CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_customers (email, id) VALUES ('$email', '$stripe_customer->id')");
+        } else {
+          CRM_Core_Error::fatal(ts('There was an error saving new customer within Stripe.  Is Stripe down?'));
+        }
+      }
+    }
+    
+    //Prepare the charge array, minus Customer/Card details.
+    $stripe_charge = array(
+      'amount' => $amount, 
+      'currency' => 'usd',
+      'description' => '# CiviCRM Donation Page # ' . $params['description'] .  ' # Invoice ID # ' . $params['invoiceID'],
+    );
+
+    //Use Stripe Customer if we have a valid one.  Otherwise just use the card.
+    if(!empty($stripe_customer->id)) {
+      $stripe_charge['customer'] = $stripe_customer->id;
+    } else {
+      $stripe_charge['card'] = $card_details;
+    }
+    
+    //Handle recurring payments in doRecurPayment().
+    if (CRM_Utils_Array::value('is_recur', $params) && $params['contributionRecurID']) {
+      return $this->doRecurPayment($params, $amount, $stripe_customer);
+    }
+       
+    //Fire away!
+    $stripe_response = Stripe_Charge::create($stripe_charge);
+    $params['trxn_id'] = $stripe_response->id;
+
+    return $params;
+  }
+  
+  function doRecurPayment(&$params, $amount, $stripe_customer) {
+    $frequency = $params['frequency_unit'];
+    $installments = $params['installments'];
+    $plan_id = "$frequency-$amount";
+    
+    $stripe_plan_query = CRM_Core_DAO::singleValueQuery("SELECT plan_id FROM civicrm_stripe_plans WHERE plan_id = '$plan_id'");
+
+    if(!isset($stripe_plan_query)) {
+      $formatted_amount =  "$" . number_format(($amount / 100), 2);
+      //Create a new Plan
+      $stripe_plan = Stripe_Plan::create(array( 
+      	"amount" => $amount,
+      	"interval" => $frequency,
+      	"name" => "CiviCRM $frequency" . 'ly ' . $formatted_amount,
+      	"currency" => "usd",
+      	"id" => $plan_id));
+      CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_plans (plan_id) VALUES ('$plan_id')");
+    }
+    
+    //Attach the Subscription to the Stripe Customer
+    $stripe_response = $stripe_customer->updateSubscription(array('prorate' => FALSE, 'plan' => $plan_id));
+    
+    $existing_subscription_query = CRM_Core_DAO::singleValueQuery("SELECT invoice_id FROM civicrm_stripe_subscriptions WHERE customer_id = '$stripe_customer->id'");
+    if(!empty($existing_subscription_query)) {
+      //Cancel existing Recurring Contribution in CiviCRM
+      $cancel_date = date("Y-m-d H:i:s");
+      CRM_Core_DAO::executeQuery("UPDATE civicrm_contribution_recur SET cancel_date = '$cancel_date', contribution_status_id = '3' WHERE invoice_id = '$existing_subscription_query'");
+      //Delete the Stripe Subscription from our cron watch list.
+      CRM_Core_DAO::executeQuery("DELETE FROM civicrm_stripe_subscriptions WHERE invoice_id = '$existing_subscription_query'");
+    }
+
+    //Calculate timestamp for the last installment
+    $end_time = strtotime("+$installments $frequency");
+    $invoice_id = $params['invoiceID'];
+    CRM_Core_DAO::executeQuery("INSERT INTO civicrm_stripe_subscriptions (customer_id, invoice_id, end_time) VALUES ('$stripe_customer->id', '$invoice_id', '$end_time')");
+    
+    $trxn_id = $stripe_customer->id . '-' . $end_time;
+    $params['trxn_id'] = $trxn_id;
+    
+    return $params;
+  }
+ 
+  /**
+   * Transfer method not in use
+   *
+   * @param array $params  name value pair of contribution data
+   *
+   * @return void
+   * @access public
+   *
+   */
+  function doTransferCheckout(&$params, $component) {
+    CRM_Core_Error::fatal(ts('Use direct billing instead of Transfer method.'));
+  }
+}
\ No newline at end of file
diff --git a/source/extern/civicrm_stripe_cron_live.php b/source/extern/civicrm_stripe_cron_live.php
index 2f45723c..079f2773 100644
--- a/source/extern/civicrm_stripe_cron_live.php
+++ b/source/extern/civicrm_stripe_cron_live.php
@@ -15,11 +15,10 @@ require_once("packages/stripe-php/lib/Stripe.php");
 Stripe::setApiKey($stripe_key);
 
 $time = time();
-print $time;
 $query = "
-SELECT  customer_id, invoice_id 
-FROM    civicrm_stripe_subscriptions 
-WHERE   end_time <= '$time' 
+  SELECT  customer_id, invoice_id 
+  FROM    civicrm_stripe_subscriptions 
+  WHERE   end_time <= '$time' 
 ";
 
 $end_recur_query = CRM_Core_DAO::executeQuery($query);
diff --git a/source/extern/civicrm_stripe_cron_test.php b/source/extern/civicrm_stripe_cron_test.php
index 64638938..85cd2770 100644
--- a/source/extern/civicrm_stripe_cron_test.php
+++ b/source/extern/civicrm_stripe_cron_test.php
@@ -15,11 +15,10 @@ require_once("packages/stripe-php/lib/Stripe.php");
 Stripe::setApiKey($stripe_key);
 
 $time = time();
-print $time;
 $query = "
-SELECT  customer_id, invoice_id 
-FROM    civicrm_stripe_subscriptions 
-WHERE   end_time <= '$time' 
+  SELECT  customer_id, invoice_id 
+  FROM    civicrm_stripe_subscriptions 
+  WHERE   end_time <= '$time' 
 ";
 
 $end_recur_query = CRM_Core_DAO::executeQuery($query);
-- 
GitLab