From 2a02d30405c84d1f1291c6ec471f15bd3d3a472f Mon Sep 17 00:00:00 2001
From: Matthew Wire <mjw@mjwconsult.co.uk>
Date: Sun, 13 Oct 2024 19:03:24 +0100
Subject: [PATCH] Upgrade to EntityFrameworkV2

---
 CRM/Stripe/DAO/StripeCustomer.php             | 275 +---------
 CRM/Stripe/DAO/StripePaymentintent.php        | 474 +-----------------
 info.xml                                      |   8 +-
 mixin/lib/civimix-schema@5.78.beta1.phar      | Bin 0 -> 31692 bytes
 schema/StripeCustomer.entityType.php          |  67 +++
 schema/StripePaymentintent.entityType.php     | 114 +++++
 sql/auto_uninstall.sql                        |  23 -
 sql/customers_install.sql                     |  18 -
 sql/paymentintent_install.sql                 |  26 -
 stripe.civix.php                              |  36 ++
 tests/civicarrot.json                         |   2 +-
 .../CRM/Stripe/StripeCustomer.entityType.php  |  10 -
 xml/schema/CRM/Stripe/StripeCustomer.xml      |  80 ---
 .../Stripe/StripePaymentintent.entityType.php |  11 -
 xml/schema/CRM/Stripe/StripePaymentintent.xml | 129 -----
 15 files changed, 255 insertions(+), 1018 deletions(-)
 create mode 100644 mixin/lib/civimix-schema@5.78.beta1.phar
 create mode 100644 schema/StripeCustomer.entityType.php
 create mode 100644 schema/StripePaymentintent.entityType.php
 delete mode 100644 sql/auto_uninstall.sql
 delete mode 100644 sql/customers_install.sql
 delete mode 100644 sql/paymentintent_install.sql
 delete mode 100644 xml/schema/CRM/Stripe/StripeCustomer.entityType.php
 delete mode 100644 xml/schema/CRM/Stripe/StripeCustomer.xml
 delete mode 100644 xml/schema/CRM/Stripe/StripePaymentintent.entityType.php
 delete mode 100644 xml/schema/CRM/Stripe/StripePaymentintent.xml

diff --git a/CRM/Stripe/DAO/StripeCustomer.php b/CRM/Stripe/DAO/StripeCustomer.php
index 6cc55b2e..f842980b 100644
--- a/CRM/Stripe/DAO/StripeCustomer.php
+++ b/CRM/Stripe/DAO/StripeCustomer.php
@@ -1,274 +1,25 @@
 <?php
 
 /**
- * @package CRM
- * @copyright CiviCRM LLC https://civicrm.org/licensing
+ * DAOs provide an OOP-style facade for reading and writing database records.
  *
- * Generated from com.drastikbydesign.stripe/xml/schema/CRM/Stripe/StripeCustomer.xml
- * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:dd1ed7f28d02b0186afd06a69db33b83)
- */
-use CRM_Stripe_ExtensionUtil as E;
-
-/**
- * Database access object for the StripeCustomer entity.
+ * DAOs are a primary source for metadata in older versions of CiviCRM (<5.74)
+ * and are required for some subsystems (such as APIv3).
+ *
+ * This stub provides compatibility. It is not intended to be modified in a
+ * substantive way. Property annotations may be added, but are not required.
+ * @property string $id 
+ * @property string $customer_id 
+ * @property string $contact_id 
+ * @property string $processor_id 
+ * @property string $currency 
  */
-class CRM_Stripe_DAO_StripeCustomer extends CRM_Core_DAO {
-  const EXT = E::LONG_NAME;
-  const TABLE_ADDED = '';
+class CRM_Stripe_DAO_StripeCustomer extends CRM_Stripe_DAO_Base {
 
   /**
-   * Static instance to hold the table name.
-   *
+   * Required by older versions of CiviCRM (<5.74).
    * @var string
    */
   public static $_tableName = 'civicrm_stripe_customers';
 
-  /**
-   * Should CiviCRM log any modifications to this table in the civicrm_log table.
-   *
-   * @var bool
-   */
-  public static $_log = TRUE;
-
-  /**
-   * Unique ID
-   *
-   * @var int|string|null
-   *   (SQL type: int unsigned)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $id;
-
-  /**
-   * Stripe Customer ID
-   *
-   * @var string|null
-   *   (SQL type: varchar(255))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $customer_id;
-
-  /**
-   * FK to Contact
-   *
-   * @var int|string|null
-   *   (SQL type: int unsigned)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $contact_id;
-
-  /**
-   * ID from civicrm_payment_processor
-   *
-   * @var int|string|null
-   *   (SQL type: int unsigned)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $processor_id;
-
-  /**
-   * 3 character string, value from Stripe customer.
-   *
-   * @var string|null
-   *   (SQL type: varchar(3))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $currency;
-
-  /**
-   * Class constructor.
-   */
-  public function __construct() {
-    $this->__table = 'civicrm_stripe_customers';
-    parent::__construct();
-  }
-
-  /**
-   * Returns localized title of this entity.
-   *
-   * @param bool $plural
-   *   Whether to return the plural version of the title.
-   */
-  public static function getEntityTitle($plural = FALSE) {
-    return $plural ? E::ts('Stripe Customers') : E::ts('Stripe Customer');
-  }
-
-  /**
-   * Returns all the column names of this table
-   *
-   * @return array
-   */
-  public static function &fields() {
-    if (!isset(Civi::$statics[__CLASS__]['fields'])) {
-      Civi::$statics[__CLASS__]['fields'] = [
-        'id' => [
-          'name' => 'id',
-          'type' => CRM_Utils_Type::T_INT,
-          'title' => E::ts('ID'),
-          'description' => E::ts('Unique ID'),
-          'required' => TRUE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_customers.id',
-          'table_name' => 'civicrm_stripe_customers',
-          'entity' => 'StripeCustomer',
-          'bao' => 'CRM_Stripe_DAO_StripeCustomer',
-          'localizable' => 0,
-          'readonly' => TRUE,
-          'add' => NULL,
-        ],
-        'customer_id' => [
-          'name' => 'customer_id',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Stripe Customer ID'),
-          'description' => E::ts('Stripe Customer ID'),
-          'maxlength' => 255,
-          'size' => CRM_Utils_Type::HUGE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_customers.customer_id',
-          'table_name' => 'civicrm_stripe_customers',
-          'entity' => 'StripeCustomer',
-          'bao' => 'CRM_Stripe_DAO_StripeCustomer',
-          'localizable' => 0,
-          'html' => [
-            'type' => 'Text',
-          ],
-          'add' => NULL,
-        ],
-        'contact_id' => [
-          'name' => 'contact_id',
-          'type' => CRM_Utils_Type::T_INT,
-          'title' => E::ts('Contact ID'),
-          'description' => E::ts('FK to Contact'),
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_customers.contact_id',
-          'table_name' => 'civicrm_stripe_customers',
-          'entity' => 'StripeCustomer',
-          'bao' => 'CRM_Stripe_DAO_StripeCustomer',
-          'localizable' => 0,
-          'FKClassName' => 'CRM_Contact_DAO_Contact',
-          'html' => [
-            'type' => 'EntityRef',
-          ],
-          'add' => NULL,
-        ],
-        'processor_id' => [
-          'name' => 'processor_id',
-          'type' => CRM_Utils_Type::T_INT,
-          'title' => E::ts('Payment Processor ID'),
-          'description' => E::ts('ID from civicrm_payment_processor'),
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_customers.processor_id',
-          'table_name' => 'civicrm_stripe_customers',
-          'entity' => 'StripeCustomer',
-          'bao' => 'CRM_Stripe_DAO_StripeCustomer',
-          'localizable' => 0,
-          'html' => [
-            'type' => 'EntityRef',
-          ],
-          'pseudoconstant' => [
-            'table' => 'civicrm_payment_processor',
-            'keyColumn' => 'id',
-            'labelColumn' => 'name',
-          ],
-          'add' => NULL,
-        ],
-        'currency' => [
-          'name' => 'currency',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Currency'),
-          'description' => E::ts('3 character string, value from Stripe customer.'),
-          'maxlength' => 3,
-          'size' => CRM_Utils_Type::FOUR,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_customers.currency',
-          'headerPattern' => '/cur(rency)?/i',
-          'dataPattern' => '/^[A-Z]{3}$/i',
-          'default' => NULL,
-          'table_name' => 'civicrm_stripe_customers',
-          'entity' => 'StripeCustomer',
-          'bao' => 'CRM_Stripe_DAO_StripeCustomer',
-          'localizable' => 0,
-          'html' => [
-            'type' => 'Text',
-          ],
-          'add' => NULL,
-        ],
-      ];
-      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
-    }
-    return Civi::$statics[__CLASS__]['fields'];
-  }
-
-  /**
-   * Returns the list of fields that can be imported
-   *
-   * @param bool $prefix
-   *
-   * @return array
-   */
-  public static function &import($prefix = FALSE) {
-    $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'stripe_customers', $prefix, []);
-    return $r;
-  }
-
-  /**
-   * Returns the list of fields that can be exported
-   *
-   * @param bool $prefix
-   *
-   * @return array
-   */
-  public static function &export($prefix = FALSE) {
-    $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'stripe_customers', $prefix, []);
-    return $r;
-  }
-
-  /**
-   * Returns the list of indices
-   *
-   * @param bool $localize
-   *
-   * @return array
-   */
-  public static function indices($localize = TRUE) {
-    $indices = [
-      'customer_id' => [
-        'name' => 'customer_id',
-        'field' => [
-          0 => 'customer_id',
-        ],
-        'localizable' => FALSE,
-        'unique' => TRUE,
-        'sig' => 'civicrm_stripe_customers::1::customer_id',
-      ],
-    ];
-    return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
-  }
-
 }
diff --git a/CRM/Stripe/DAO/StripePaymentintent.php b/CRM/Stripe/DAO/StripePaymentintent.php
index 17dd296d..fe577463 100644
--- a/CRM/Stripe/DAO/StripePaymentintent.php
+++ b/CRM/Stripe/DAO/StripePaymentintent.php
@@ -1,466 +1,32 @@
 <?php
 
 /**
- * @package CRM
- * @copyright CiviCRM LLC https://civicrm.org/licensing
+ * DAOs provide an OOP-style facade for reading and writing database records.
  *
- * Generated from com.drastikbydesign.stripe/xml/schema/CRM/Stripe/StripePaymentintent.xml
- * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:b67646ad6a172031ee010ed01449d20e)
- */
-use CRM_Stripe_ExtensionUtil as E;
-
-/**
- * Database access object for the StripePaymentintent entity.
+ * DAOs are a primary source for metadata in older versions of CiviCRM (<5.74)
+ * and are required for some subsystems (such as APIv3).
+ *
+ * This stub provides compatibility. It is not intended to be modified in a
+ * substantive way. Property annotations may be added, but are not required.
+ * @property string $id 
+ * @property string $stripe_intent_id 
+ * @property string $contribution_id 
+ * @property string $payment_processor_id 
+ * @property string $description 
+ * @property string $status 
+ * @property string $identifier 
+ * @property string $contact_id 
+ * @property string $created_date 
+ * @property string $flags 
+ * @property string $referrer 
+ * @property string $extra_data 
  */
-class CRM_Stripe_DAO_StripePaymentintent extends CRM_Core_DAO {
-  const EXT = E::LONG_NAME;
-  const TABLE_ADDED = '';
+class CRM_Stripe_DAO_StripePaymentintent extends CRM_Stripe_DAO_Base {
 
   /**
-   * Static instance to hold the table name.
-   *
+   * Required by older versions of CiviCRM (<5.74).
    * @var string
    */
   public static $_tableName = 'civicrm_stripe_paymentintent';
 
-  /**
-   * Should CiviCRM log any modifications to this table in the civicrm_log table.
-   *
-   * @var bool
-   */
-  public static $_log = TRUE;
-
-  /**
-   * Unique ID
-   *
-   * @var int|string|null
-   *   (SQL type: int unsigned)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $id;
-
-  /**
-   * The Stripe PaymentIntent/SetupIntent/PaymentMethod ID
-   *
-   * @var string|null
-   *   (SQL type: varchar(255))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $stripe_intent_id;
-
-  /**
-   * FK ID from civicrm_contribution
-   *
-   * @var int|string|null
-   *   (SQL type: int unsigned)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $contribution_id;
-
-  /**
-   * Foreign key to civicrm_payment_processor.id
-   *
-   * @var int|string|null
-   *   (SQL type: int unsigned)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $payment_processor_id;
-
-  /**
-   * Description of this paymentIntent
-   *
-   * @var string
-   *   (SQL type: varchar(255))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $description;
-
-  /**
-   * The status of the paymentIntent
-   *
-   * @var string
-   *   (SQL type: varchar(25))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $status;
-
-  /**
-   * An identifier that we can use in CiviCRM to find the paymentIntent if we do not have the ID (eg. session key)
-   *
-   * @var string
-   *   (SQL type: varchar(255))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $identifier;
-
-  /**
-   * FK to Contact
-   *
-   * @var int|string|null
-   *   (SQL type: int unsigned)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $contact_id;
-
-  /**
-   * When was paymentIntent created
-   *
-   * @var string|null
-   *   (SQL type: timestamp)
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $created_date;
-
-  /**
-   * Flags associated with this PaymentIntent (NC=no contributionID when doPayment called)
-   *
-   * @var string
-   *   (SQL type: varchar(100))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $flags;
-
-  /**
-   * HTTP referrer of this paymentIntent
-   *
-   * @var string
-   *   (SQL type: varchar(255))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $referrer;
-
-  /**
-   * Extra data collected to help with diagnostics (such as email, name)
-   *
-   * @var string
-   *   (SQL type: varchar(255))
-   *   Note that values will be retrieved from the database as a string.
-   */
-  public $extra_data;
-
-  /**
-   * Class constructor.
-   */
-  public function __construct() {
-    $this->__table = 'civicrm_stripe_paymentintent';
-    parent::__construct();
-  }
-
-  /**
-   * Returns localized title of this entity.
-   *
-   * @param bool $plural
-   *   Whether to return the plural version of the title.
-   */
-  public static function getEntityTitle($plural = FALSE) {
-    return $plural ? E::ts('Stripe Paymentintents') : E::ts('Stripe Paymentintent');
-  }
-
-  /**
-   * Returns all the column names of this table
-   *
-   * @return array
-   */
-  public static function &fields() {
-    if (!isset(Civi::$statics[__CLASS__]['fields'])) {
-      Civi::$statics[__CLASS__]['fields'] = [
-        'id' => [
-          'name' => 'id',
-          'type' => CRM_Utils_Type::T_INT,
-          'title' => E::ts('ID'),
-          'description' => E::ts('Unique ID'),
-          'required' => TRUE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.id',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'readonly' => TRUE,
-          'add' => NULL,
-        ],
-        'stripe_intent_id' => [
-          'name' => 'stripe_intent_id',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Stripe Intent ID'),
-          'description' => E::ts('The Stripe PaymentIntent/SetupIntent/PaymentMethod ID'),
-          'maxlength' => 255,
-          'size' => CRM_Utils_Type::HUGE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.stripe_intent_id',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'contribution_id' => [
-          'name' => 'contribution_id',
-          'type' => CRM_Utils_Type::T_INT,
-          'title' => E::ts('Contribution ID'),
-          'description' => E::ts('FK ID from civicrm_contribution'),
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.contribution_id',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'payment_processor_id' => [
-          'name' => 'payment_processor_id',
-          'type' => CRM_Utils_Type::T_INT,
-          'title' => E::ts('Payment Processor'),
-          'description' => E::ts('Foreign key to civicrm_payment_processor.id'),
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.payment_processor_id',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'FKClassName' => 'CRM_Financial_DAO_PaymentProcessor',
-          'pseudoconstant' => [
-            'table' => 'civicrm_payment_processor',
-            'keyColumn' => 'id',
-            'labelColumn' => 'name',
-          ],
-          'add' => NULL,
-        ],
-        'description' => [
-          'name' => 'description',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Description'),
-          'description' => E::ts('Description of this paymentIntent'),
-          'required' => FALSE,
-          'maxlength' => 255,
-          'size' => CRM_Utils_Type::HUGE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.description',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'status' => [
-          'name' => 'status',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Status'),
-          'description' => E::ts('The status of the paymentIntent'),
-          'required' => FALSE,
-          'maxlength' => 25,
-          'size' => CRM_Utils_Type::MEDIUM,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.status',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'identifier' => [
-          'name' => 'identifier',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Identifier'),
-          'description' => E::ts('An identifier that we can use in CiviCRM to find the paymentIntent if we do not have the ID (eg. session key)'),
-          'required' => FALSE,
-          'maxlength' => 255,
-          'size' => CRM_Utils_Type::HUGE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.identifier',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'contact_id' => [
-          'name' => 'contact_id',
-          'type' => CRM_Utils_Type::T_INT,
-          'title' => E::ts('Contact ID'),
-          'description' => E::ts('FK to Contact'),
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.contact_id',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'FKClassName' => 'CRM_Contact_DAO_Contact',
-          'add' => NULL,
-        ],
-        'created_date' => [
-          'name' => 'created_date',
-          'type' => CRM_Utils_Type::T_TIMESTAMP,
-          'title' => E::ts('Created Date'),
-          'description' => E::ts('When was paymentIntent created'),
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.created_date',
-          'default' => 'CURRENT_TIMESTAMP',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'flags' => [
-          'name' => 'flags',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Flags'),
-          'description' => E::ts('Flags associated with this PaymentIntent (NC=no contributionID when doPayment called)'),
-          'required' => FALSE,
-          'maxlength' => 100,
-          'size' => CRM_Utils_Type::HUGE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.flags',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'referrer' => [
-          'name' => 'referrer',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Referrer'),
-          'description' => E::ts('HTTP referrer of this paymentIntent'),
-          'required' => FALSE,
-          'maxlength' => 255,
-          'size' => CRM_Utils_Type::HUGE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.referrer',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-        'extra_data' => [
-          'name' => 'extra_data',
-          'type' => CRM_Utils_Type::T_STRING,
-          'title' => E::ts('Extra Data'),
-          'description' => E::ts('Extra data collected to help with diagnostics (such as email, name)'),
-          'required' => FALSE,
-          'maxlength' => 255,
-          'size' => CRM_Utils_Type::HUGE,
-          'usage' => [
-            'import' => FALSE,
-            'export' => FALSE,
-            'duplicate_matching' => FALSE,
-            'token' => FALSE,
-          ],
-          'where' => 'civicrm_stripe_paymentintent.extra_data',
-          'table_name' => 'civicrm_stripe_paymentintent',
-          'entity' => 'StripePaymentintent',
-          'bao' => 'CRM_Stripe_DAO_StripePaymentintent',
-          'localizable' => 0,
-          'add' => NULL,
-        ],
-      ];
-      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
-    }
-    return Civi::$statics[__CLASS__]['fields'];
-  }
-
-  /**
-   * Returns the list of fields that can be imported
-   *
-   * @param bool $prefix
-   *
-   * @return array
-   */
-  public static function &import($prefix = FALSE) {
-    $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'stripe_paymentintent', $prefix, []);
-    return $r;
-  }
-
-  /**
-   * Returns the list of fields that can be exported
-   *
-   * @param bool $prefix
-   *
-   * @return array
-   */
-  public static function &export($prefix = FALSE) {
-    $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'stripe_paymentintent', $prefix, []);
-    return $r;
-  }
-
-  /**
-   * Returns the list of indices
-   *
-   * @param bool $localize
-   *
-   * @return array
-   */
-  public static function indices($localize = TRUE) {
-    $indices = [
-      'UI_stripe_intent_id' => [
-        'name' => 'UI_stripe_intent_id',
-        'field' => [
-          0 => 'stripe_intent_id',
-        ],
-        'localizable' => FALSE,
-        'unique' => TRUE,
-        'sig' => 'civicrm_stripe_paymentintent::1::stripe_intent_id',
-      ],
-    ];
-    return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
-  }
-
 }
diff --git a/info.xml b/info.xml
index 42832211..bb209bb8 100644
--- a/info.xml
+++ b/info.xml
@@ -31,7 +31,7 @@
   </requires>
   <civix>
     <namespace>CRM/Stripe</namespace>
-    <format>23.02.1</format>
+    <format>24.09.1</format>
   </civix>
   <classloader>
     <psr0 prefix="CRM_" path="."/>
@@ -41,9 +41,9 @@
     <mixin>menu-xml@1.0.0</mixin>
     <mixin>mgd-php@1.0.0</mixin>
     <mixin>setting-php@1.0.0</mixin>
-    <mixin>smarty-v2@1.0.1</mixin>
-    <mixin>entity-types-php@1.0.0</mixin>
     <mixin>setting-admin@1.0.1</mixin>
+    <mixin>entity-types-php@2.0.0</mixin>
+    <mixin>smarty@1.0.3</mixin>
   </mixins>
-  <upgrader>CRM_Stripe_Upgrader</upgrader>
+  <upgrader>CiviMix\Schema\Stripe\AutomaticUpgrader</upgrader>
 </extension>
diff --git a/mixin/lib/civimix-schema@5.78.beta1.phar b/mixin/lib/civimix-schema@5.78.beta1.phar
new file mode 100644
index 0000000000000000000000000000000000000000..079ec3621bbf0b61249d15b6934ec3a0ac19dc65
GIT binary patch
literal 31692
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
Y&AWrA|MgdY{+B<Guc?0Wc<b^10Led<q5uE@

literal 0
HcmV?d00001

diff --git a/schema/StripeCustomer.entityType.php b/schema/StripeCustomer.entityType.php
new file mode 100644
index 00000000..b5a97b7c
--- /dev/null
+++ b/schema/StripeCustomer.entityType.php
@@ -0,0 +1,67 @@
+<?php
+use CRM_Stripe_ExtensionUtil as E;
+return [
+  'name' => 'StripeCustomer',
+  'table' => 'civicrm_stripe_customers',
+  'class' => 'CRM_Stripe_DAO_StripeCustomer',
+  'getInfo' => fn() => [
+    'title' => E::ts('Stripe Customer'),
+    'title_plural' => E::ts('Stripe Customers'),
+    'description' => E::ts('Stripe Customers'),
+    'log' => TRUE,
+  ],
+  'getIndices' => fn() => [
+    'customer_id' => [
+      'fields' => [
+        'customer_id' => TRUE,
+      ],
+      'unique' => TRUE,
+    ],
+  ],
+  'getFields' => fn() => [
+    'id' => [
+      'title' => E::ts('ID'),
+      'sql_type' => 'int unsigned',
+      'input_type' => 'Number',
+      'required' => TRUE,
+      'description' => E::ts('Unique ID'),
+      'primary_key' => TRUE,
+      'auto_increment' => TRUE,
+    ],
+    'customer_id' => [
+      'title' => E::ts('Stripe Customer ID'),
+      'sql_type' => 'varchar(255)',
+      'input_type' => 'Text',
+      'description' => E::ts('Stripe Customer ID'),
+    ],
+    'contact_id' => [
+      'title' => E::ts('Contact ID'),
+      'sql_type' => 'int unsigned',
+      'input_type' => 'EntityRef',
+      'description' => E::ts('FK to Contact'),
+      'entity_reference' => [
+        'entity' => 'Contact',
+        'key' => 'id',
+        'on_delete' => 'CASCADE',
+      ],
+    ],
+    'processor_id' => [
+      'title' => E::ts('Payment Processor ID'),
+      'sql_type' => 'int unsigned',
+      'input_type' => 'EntityRef',
+      'description' => E::ts('ID from civicrm_payment_processor'),
+      'pseudoconstant' => [
+        'table' => 'civicrm_payment_processor',
+        'key_column' => 'id',
+        'label_column' => 'name',
+      ],
+    ],
+    'currency' => [
+      'title' => E::ts('Currency'),
+      'sql_type' => 'varchar(3)',
+      'input_type' => 'Text',
+      'description' => E::ts('3 character string, value from Stripe customer.'),
+      'default' => NULL,
+    ],
+  ],
+];
diff --git a/schema/StripePaymentintent.entityType.php b/schema/StripePaymentintent.entityType.php
new file mode 100644
index 00000000..99ea17be
--- /dev/null
+++ b/schema/StripePaymentintent.entityType.php
@@ -0,0 +1,114 @@
+<?php
+use CRM_Stripe_ExtensionUtil as E;
+return [
+  'name' => 'StripePaymentintent',
+  'table' => 'civicrm_stripe_paymentintent',
+  'class' => 'CRM_Stripe_DAO_StripePaymentintent',
+  'getInfo' => fn() => [
+    'title' => E::ts('Stripe Paymentintent'),
+    'title_plural' => E::ts('Stripe Paymentintents'),
+    'description' => E::ts('Stripe PaymentIntents'),
+    'log' => TRUE,
+  ],
+  'getIndices' => fn() => [
+    'UI_stripe_intent_id' => [
+      'fields' => [
+        'stripe_intent_id' => TRUE,
+      ],
+      'unique' => TRUE,
+    ],
+  ],
+  'getFields' => fn() => [
+    'id' => [
+      'title' => E::ts('ID'),
+      'sql_type' => 'int unsigned',
+      'input_type' => 'Number',
+      'required' => TRUE,
+      'description' => E::ts('Unique ID'),
+      'primary_key' => TRUE,
+      'auto_increment' => TRUE,
+    ],
+    'stripe_intent_id' => [
+      'title' => E::ts('Stripe Intent ID'),
+      'sql_type' => 'varchar(255)',
+      'input_type' => 'Text',
+      'description' => E::ts('The Stripe PaymentIntent/SetupIntent/PaymentMethod ID'),
+    ],
+    'contribution_id' => [
+      'title' => E::ts('Contribution ID'),
+      'sql_type' => 'int unsigned',
+      'input_type' => 'Number',
+      'description' => E::ts('FK ID from civicrm_contribution'),
+    ],
+    'payment_processor_id' => [
+      'title' => E::ts('Payment Processor'),
+      'sql_type' => 'int unsigned',
+      'input_type' => 'EntityRef',
+      'description' => E::ts('Foreign key to civicrm_payment_processor.id'),
+      'pseudoconstant' => [
+        'table' => 'civicrm_payment_processor',
+        'key_column' => 'id',
+        'label_column' => 'name',
+      ],
+      'entity_reference' => [
+        'entity' => 'PaymentProcessor',
+        'key' => 'id',
+        'on_delete' => 'SET NULL',
+      ],
+    ],
+    'description' => [
+      'title' => E::ts('Description'),
+      'sql_type' => 'varchar(255)',
+      'input_type' => 'Text',
+      'description' => E::ts('Description of this paymentIntent'),
+    ],
+    'status' => [
+      'title' => E::ts('Status'),
+      'sql_type' => 'varchar(25)',
+      'input_type' => 'Text',
+      'description' => E::ts('The status of the paymentIntent'),
+    ],
+    'identifier' => [
+      'title' => E::ts('Identifier'),
+      'sql_type' => 'varchar(255)',
+      'input_type' => 'Text',
+      'description' => E::ts('An identifier that we can use in CiviCRM to find the paymentIntent if we do not have the ID (eg. session key)'),
+    ],
+    'contact_id' => [
+      'title' => E::ts('Contact ID'),
+      'sql_type' => 'int unsigned',
+      'input_type' => 'EntityRef',
+      'description' => E::ts('FK to Contact'),
+      'entity_reference' => [
+        'entity' => 'Contact',
+        'key' => 'id',
+        'on_delete' => 'CASCADE',
+      ],
+    ],
+    'created_date' => [
+      'title' => E::ts('Created Date'),
+      'sql_type' => 'timestamp',
+      'input_type' => NULL,
+      'description' => E::ts('When was paymentIntent created'),
+      'default' => 'CURRENT_TIMESTAMP',
+    ],
+    'flags' => [
+      'title' => E::ts('Flags'),
+      'sql_type' => 'varchar(100)',
+      'input_type' => 'Text',
+      'description' => E::ts('Flags associated with this PaymentIntent (NC=no contributionID when doPayment called)'),
+    ],
+    'referrer' => [
+      'title' => E::ts('Referrer'),
+      'sql_type' => 'varchar(255)',
+      'input_type' => 'Text',
+      'description' => E::ts('HTTP referrer of this paymentIntent'),
+    ],
+    'extra_data' => [
+      'title' => E::ts('Extra Data'),
+      'sql_type' => 'varchar(255)',
+      'input_type' => 'Text',
+      'description' => E::ts('Extra data collected to help with diagnostics (such as email, name)'),
+    ],
+  ],
+];
diff --git a/sql/auto_uninstall.sql b/sql/auto_uninstall.sql
deleted file mode 100644
index 58e53bec..00000000
--- a/sql/auto_uninstall.sql
+++ /dev/null
@@ -1,23 +0,0 @@
--- +--------------------------------------------------------------------+
--- | Copyright CiviCRM LLC. All rights reserved.                        |
--- |                                                                    |
--- | This work is published under the GNU AGPLv3 license with some      |
--- | permitted exceptions and without any warranty. For full license    |
--- | and copyright information, see https://civicrm.org/licensing       |
--- +--------------------------------------------------------------------+
---
--- Generated from drop.tpl
--- DO NOT EDIT.  Generated by CRM_Core_CodeGen
---
--- /*******************************************************
--- *
--- * Clean up the existing tables
--- *
--- *******************************************************/
-
-SET FOREIGN_KEY_CHECKS=0;
-
-DROP TABLE IF EXISTS `civicrm_stripe_paymentintent`;
-DROP TABLE IF EXISTS `civicrm_stripe_customers`;
-
-SET FOREIGN_KEY_CHECKS=1;
\ No newline at end of file
diff --git a/sql/customers_install.sql b/sql/customers_install.sql
deleted file mode 100644
index 4a6632b5..00000000
--- a/sql/customers_install.sql
+++ /dev/null
@@ -1,18 +0,0 @@
--- /*******************************************************
--- *
--- * civicrm_stripe_customers
--- *
--- * Stripe Customers
--- *
--- *******************************************************/
-CREATE TABLE `civicrm_stripe_customers` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique ID',
-  `customer_id` varchar(255) COMMENT 'Stripe Customer ID',
-  `contact_id` int unsigned COMMENT 'FK to Contact',
-  `processor_id` int unsigned COMMENT 'ID from civicrm_payment_processor',
-  `currency` varchar(3) DEFAULT NULL COMMENT '3 character string, value from Stripe customer.',
-  PRIMARY KEY (`id`),
-  UNIQUE INDEX `customer_id`(customer_id),
-  CONSTRAINT FK_civicrm_stripe_customers_contact_id FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact`(`id`) ON DELETE CASCADE
-)
-ENGINE=InnoDB;
diff --git a/sql/paymentintent_install.sql b/sql/paymentintent_install.sql
deleted file mode 100644
index 185bb588..00000000
--- a/sql/paymentintent_install.sql
+++ /dev/null
@@ -1,26 +0,0 @@
--- /*******************************************************
--- *
--- * civicrm_stripe_paymentintent
--- *
--- * Stripe PaymentIntents
--- *
--- *******************************************************/
-CREATE TABLE `civicrm_stripe_paymentintent` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique ID',
-  `stripe_intent_id` varchar(255) COMMENT 'The Stripe PaymentIntent/SetupIntent/PaymentMethod ID',
-  `contribution_id` int unsigned COMMENT 'FK ID from civicrm_contribution',
-  `payment_processor_id` int unsigned COMMENT 'Foreign key to civicrm_payment_processor.id',
-  `description` varchar(255) NULL COMMENT 'Description of this paymentIntent',
-  `status` varchar(25) NULL COMMENT 'The status of the paymentIntent',
-  `identifier` varchar(255) NULL COMMENT 'An identifier that we can use in CiviCRM to find the paymentIntent if we do not have the ID (eg. session key)',
-  `contact_id` int unsigned COMMENT 'FK to Contact',
-  `created_date` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT 'When was paymentIntent created',
-  `flags` varchar(100) NULL COMMENT 'Flags associated with this PaymentIntent (NC=no contributionID when doPayment called)',
-  `referrer` varchar(255) NULL COMMENT 'HTTP referrer of this paymentIntent',
-  `extra_data` varchar(255) NULL COMMENT 'Extra data collected to help with diagnostics (such as email, name)',
-  PRIMARY KEY (`id`),
-  UNIQUE INDEX `UI_stripe_intent_id`(stripe_intent_id),
-  CONSTRAINT FK_civicrm_stripe_paymentintent_payment_processor_id FOREIGN KEY (`payment_processor_id`) REFERENCES `civicrm_payment_processor`(`id`) ON DELETE SET NULL,
-  CONSTRAINT FK_civicrm_stripe_paymentintent_contact_id FOREIGN KEY (`contact_id`) REFERENCES `civicrm_contact`(`id`) ON DELETE CASCADE
-)
-ENGINE=InnoDB;
diff --git a/stripe.civix.php b/stripe.civix.php
index 15253e85..f9169749 100644
--- a/stripe.civix.php
+++ b/stripe.civix.php
@@ -75,10 +75,46 @@ class CRM_Stripe_ExtensionUtil {
     return self::CLASS_PREFIX . '_' . str_replace('\\', '_', $suffix);
   }
 
+  /**
+   * @return \CiviMix\Schema\SchemaHelperInterface
+   */
+  public static function schema() {
+    if (!isset($GLOBALS['CiviMixSchema'])) {
+      pathload()->loadPackage('civimix-schema@5', TRUE);
+    }
+    return $GLOBALS['CiviMixSchema']->getHelper(static::LONG_NAME);
+  }
+
 }
 
 use CRM_Stripe_ExtensionUtil as E;
 
+pathload()->addSearchDir(__DIR__ . '/mixin/lib');
+spl_autoload_register('_stripe_civix_class_loader', TRUE, TRUE);
+
+function _stripe_civix_class_loader($class) {
+  if ($class === 'CRM_Stripe_DAO_Base') {
+    if (version_compare(CRM_Utils_System::version(), '5.74.beta', '>=')) {
+      class_alias('CRM_Core_DAO_Base', 'CRM_Stripe_DAO_Base');
+      // ^^ Materialize concrete names -- encourage IDE's to pick up on this association.
+    }
+    else {
+      $realClass = 'CiviMix\\Schema\\Stripe\\DAO';
+      class_alias($realClass, $class);
+      // ^^ Abstract names -- discourage IDE's from picking up on this association.
+    }
+    return;
+  }
+
+  // This allows us to tap-in to the installation process (without incurring real file-reads on typical requests).
+  if (strpos($class, 'CiviMix\\Schema\\Stripe\\') === 0) {
+    // civimix-schema@5 is designed for backported use in download/activation workflows,
+    // where new revisions may become dynamically available.
+    pathload()->loadPackage('civimix-schema@5', TRUE);
+    CiviMix\Schema\loadClass($class);
+  }
+}
+
 /**
  * (Delegated) Implements hook_civicrm_config().
  *
diff --git a/tests/civicarrot.json b/tests/civicarrot.json
index b809162b..acc3585f 100644
--- a/tests/civicarrot.json
+++ b/tests/civicarrot.json
@@ -9,7 +9,7 @@
       {
         "php-versions": "7.4",
         "drupal": "9.5.*",
-        "civicrm": "5.65.*"
+        "civicrm": "5.74.*"
       }
     ]
   }
diff --git a/xml/schema/CRM/Stripe/StripeCustomer.entityType.php b/xml/schema/CRM/Stripe/StripeCustomer.entityType.php
deleted file mode 100644
index 923ead64..00000000
--- a/xml/schema/CRM/Stripe/StripeCustomer.entityType.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-// This file declares a new entity type. For more details, see "hook_civicrm_entityTypes" at:
-// https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes
-return [
-  [
-    'name' => 'StripeCustomer',
-    'class' => 'CRM_Stripe_DAO_StripeCustomer',
-    'table' => 'civicrm_stripe_customers',
-  ],
-];
diff --git a/xml/schema/CRM/Stripe/StripeCustomer.xml b/xml/schema/CRM/Stripe/StripeCustomer.xml
deleted file mode 100644
index 1da63da8..00000000
--- a/xml/schema/CRM/Stripe/StripeCustomer.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1" ?>
-
-<table>
-  <base>CRM/Stripe</base>
-  <class>StripeCustomer</class>
-  <name>civicrm_stripe_customers</name>
-  <comment>Stripe Customers</comment>
-  <log>true</log>
-
-  <field>
-    <name>id</name>
-    <type>int unsigned</type>
-    <required>true</required>
-    <comment>Unique ID</comment>
-  </field>
-  <primaryKey>
-    <name>id</name>
-    <autoincrement>true</autoincrement>
-  </primaryKey>
-
-  <field>
-    <name>customer_id</name>
-    <title>Stripe Customer ID</title>
-    <type>varchar</type>
-    <length>255</length>
-    <comment>Stripe Customer ID</comment>
-    <html>
-      <type>Text</type>
-    </html>
-  </field>
-  <index>
-    <name>customer_id</name>
-    <fieldName>customer_id</fieldName>
-    <unique>true</unique>
-  </index>
-
-  <field>
-    <name>contact_id</name>
-    <type>int unsigned</type>
-    <comment>FK to Contact</comment>
-    <html>
-      <type>EntityRef</type>
-    </html>
-  </field>
-  <foreignKey>
-    <name>contact_id</name>
-    <table>civicrm_contact</table>
-    <key>id</key>
-    <onDelete>CASCADE</onDelete>
-  </foreignKey>
-
-  <field>
-    <name>processor_id</name>
-    <title>Payment Processor ID</title>
-    <type>int unsigned</type>
-    <comment>ID from civicrm_payment_processor</comment>
-    <html>
-      <type>EntityRef</type>
-    </html>
-    <pseudoconstant>
-      <table>civicrm_payment_processor</table>
-      <keyColumn>id</keyColumn>
-      <labelColumn>name</labelColumn>
-    </pseudoconstant>
-  </field>
-  <field>
-    <name>currency</name>
-    <type>varchar</type>
-    <length>3</length>
-    <default>NULL</default>
-    <headerPattern>/cur(rency)?/i</headerPattern>
-    <dataPattern>/^[A-Z]{3}$/i</dataPattern>
-    <comment>3 character string, value from Stripe customer.</comment>
-    <html>
-      <type>Text</type>
-    </html>
-  </field>
-
-
-</table>
diff --git a/xml/schema/CRM/Stripe/StripePaymentintent.entityType.php b/xml/schema/CRM/Stripe/StripePaymentintent.entityType.php
deleted file mode 100644
index 999e2947..00000000
--- a/xml/schema/CRM/Stripe/StripePaymentintent.entityType.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-// This file declares a new entity type. For more details, see "hook_civicrm_entityTypes" at:
-// http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference
-return array (
-  0 => 
-  array (
-    'name' => 'StripePaymentintent',
-    'class' => 'CRM_Stripe_DAO_StripePaymentintent',
-    'table' => 'civicrm_stripe_paymentintent',
-  ),
-);
diff --git a/xml/schema/CRM/Stripe/StripePaymentintent.xml b/xml/schema/CRM/Stripe/StripePaymentintent.xml
deleted file mode 100644
index e1ca5e6c..00000000
--- a/xml/schema/CRM/Stripe/StripePaymentintent.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1" ?>
-
-<table>
-  <base>CRM/Stripe</base>
-  <class>StripePaymentintent</class>
-  <name>civicrm_stripe_paymentintent</name>
-  <comment>Stripe PaymentIntents</comment>
-  <log>true</log>
-
-  <field>
-    <name>id</name>
-    <type>int unsigned</type>
-    <required>true</required>
-    <comment>Unique ID</comment>
-  </field>
-  <primaryKey>
-    <name>id</name>
-    <autoincrement>true</autoincrement>
-  </primaryKey>
-
-  <field>
-    <name>stripe_intent_id</name>
-    <title>Stripe Intent ID</title>
-    <type>varchar</type>
-    <length>255</length>
-    <comment>The Stripe PaymentIntent/SetupIntent/PaymentMethod ID</comment>
-  </field>
-  <index>
-    <name>UI_stripe_intent_id</name>
-    <fieldName>stripe_intent_id</fieldName>
-    <unique>true</unique>
-  </index>
-
-  <field>
-    <name>contribution_id</name>
-    <title>Contribution ID</title>
-    <type>int unsigned</type>
-    <comment>FK ID from civicrm_contribution</comment>
-  </field>
-
-  <field>
-    <name>payment_processor_id</name>
-    <title>Payment Processor</title>
-    <type>int unsigned</type>
-    <comment>Foreign key to civicrm_payment_processor.id</comment>
-    <pseudoconstant>
-      <table>civicrm_payment_processor</table>
-      <keyColumn>id</keyColumn>
-      <labelColumn>name</labelColumn>
-    </pseudoconstant>
-  </field>
-  <foreignKey>
-    <name>payment_processor_id</name>
-    <table>civicrm_payment_processor</table>
-    <key>id</key>
-    <onDelete>SET NULL</onDelete>
-  </foreignKey>
-
-  <field>
-    <name>description</name>
-    <title>Description</title>
-    <type>varchar</type>
-    <required>false</required>
-    <length>255</length>
-    <comment>Description of this paymentIntent</comment>
-  </field>
-
-  <field>
-    <name>status</name>
-    <type>varchar</type>
-    <length>25</length>
-    <required>false</required>
-    <comment>The status of the paymentIntent</comment>
-  </field>
-
-  <field>
-    <name>identifier</name>
-    <type>varchar</type>
-    <length>255</length>
-    <required>false</required>
-    <comment>An identifier that we can use in CiviCRM to find the paymentIntent if we do not have the ID (eg. session key)</comment>
-  </field>
-
-  <field>
-    <name>contact_id</name>
-    <type>int unsigned</type>
-    <comment>FK to Contact</comment>
-  </field>
-  <foreignKey>
-    <name>contact_id</name>
-    <table>civicrm_contact</table>
-    <key>id</key>
-    <onDelete>CASCADE</onDelete>
-  </foreignKey>
-
-  <field>
-    <name>created_date</name>
-    <title>Created Date</title>
-    <type>timestamp</type>
-    <default>CURRENT_TIMESTAMP</default>
-    <comment>When was paymentIntent created</comment>
-  </field>
-
-  <field>
-    <name>flags</name>
-    <type>varchar</type>
-    <length>100</length>
-    <required>false</required>
-    <comment>Flags associated with this PaymentIntent (NC=no contributionID when doPayment called)</comment>
-  </field>
-
-  <field>
-    <name>referrer</name>
-    <title>Referrer</title>
-    <type>varchar</type>
-    <required>false</required>
-    <length>255</length>
-    <comment>HTTP referrer of this paymentIntent</comment>
-  </field>
-
-  <field>
-    <name>extra_data</name>
-    <title>Extra Data</title>
-    <type>varchar</type>
-    <required>false</required>
-    <length>255</length>
-    <comment>Extra data collected to help with diagnostics (such as email, name)</comment>
-  </field>
-</table>
-- 
GitLab