Split DB Updates into seperate files, with the cutoff being 2.0.0

This commit is contained in:
johnnyq
2026-07-22 18:43:11 -04:00
parent 17e4c61067
commit 2b756f6ea4
252 changed files with 4161 additions and 4875 deletions

View File

@@ -118,11 +118,14 @@ Per [SECURITY.md](SECURITY.md) — never in a public issue.
**Database naming.** Every column is prefixed with its table's singular name: `tickets.ticket_id`, `tickets.ticket_subject`, `clients.client_name`. This makes JOIN results unambiguous and is why queries can `SELECT *` across joins safely. New tables must follow it.
**Schema changes require three edits in one PR:**
**Schema changes require two edits in one PR:**
1. `db.sql` — so fresh installs get the new schema.
2. `includes/database_version.php` — bump `LATEST_DATABASE_VERSION`.
3. `admin/database_updates.php` — add an `if (CURRENT_DATABASE_VERSION == 'x.y.z')` block that applies the change and steps the version, so existing installs migrate. Migrations are sequential and rolling-release; never edit a historical block.
2. `admin/database_updates/<x.y.z>.php` — a new file named for the version it upgrades **to**, containing only the queries that apply the change. Migrations are sequential and rolling-release; never edit a historical file.
That is the whole job. `LATEST_DATABASE_VERSION` is derived from the highest-numbered filename in `admin/database_updates/`, and the runner (`admin/database_updates.php`) steps `config_current_database_version` after each file succeeds — so there is no constant to bump and no version-bump query to write. Each migration file needs the standard `defined('FROM_DB_UPDATER') || die(...)` guard at the top; copy an existing file's header.
A single update run applies every pending migration in order, stopping at the first failure with the version left at the last file that completed, so a re-run resumes at the one that broke.
**After acting, log and notify.** State changes call `logAudit($type, $action, $description, $client_id, $entity_id)` for the audit trail. User-facing events may also call `appNotify()`. Fire `triggerCustomAction()` where a site might reasonably want a hook. Then call `flashAlert($message, $type)` and `redirect()` (defaults to the referer) rather than setting session keys or `header()` manually.
**Function names (post-rename).** Helpers were renamed for clarity in 2026; the old names **no longer exist** — code calling them fatals. If you're rebasing an old PR or following an old tutorial, translate: `sanitizeInput``escapeSql`, `nullable_htmlentities``escapeHtml`, `logAction``logAudit`, `flash_alert``flashAlert`, `customAction``triggerCustomAction`, `encryptLoginEntry`/`decryptLoginEntry``encryptCredentialEntry`/`decryptCredentialEntry`, `strtoAZaz09``toAlphanumeric`, `fetchUpdates``checkForUpdates`.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
<?php
/*
* ITFlow - Database update to version 2.0.0 (from 1.9.9)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "RENAME TABLE `logins` TO `credentials`");
mysqli_query($mysqli, "
ALTER TABLE `credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL AUTO_INCREMENT,
CHANGE COLUMN `login_name` `credential_name` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE COLUMN `login_description` `credential_description` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_category` `credential_category` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_uri` `credential_uri` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_uri_2` `credential_uri_2` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_username` `credential_username` VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_password` `credential_password` VARBINARY(200) NULL DEFAULT NULL,
CHANGE COLUMN `login_otp_secret` `credential_otp_secret` VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_note` `credential_note` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE COLUMN `login_important` `credential_important` TINYINT(1) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_created_at` `credential_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
CHANGE COLUMN `login_updated_at` `credential_updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(),
CHANGE COLUMN `login_archived_at` `credential_archived_at` DATETIME NULL DEFAULT NULL,
CHANGE COLUMN `login_accessed_at` `credential_accessed_at` DATETIME NULL DEFAULT NULL,
CHANGE COLUMN `login_password_changed_at` `credential_password_changed_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP(),
CHANGE COLUMN `login_folder_id` `credential_folder_id` INT(11) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_contact_id` `credential_contact_id` INT(11) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_asset_id` `credential_asset_id` INT(11) NOT NULL DEFAULT '0',
CHANGE COLUMN `login_client_id` `credential_client_id` INT(11) NOT NULL DEFAULT '0'
");
// Rename table contact_logins to contact_credentials
mysqli_query($mysqli, "RENAME TABLE `contact_logins` TO `contact_credentials`");
// Alter contact_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `contact_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned contact_id rows in contact_credentials
mysqli_query($mysqli, "
DELETE FROM `contact_credentials`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Clean up orphaned credential_id rows in contact_credentials
mysqli_query($mysqli, "
DELETE FROM `contact_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to contact_credentials
mysqli_query($mysqli, "
ALTER TABLE `contact_credentials`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table service_logins to service_credentials
mysqli_query($mysqli, "RENAME TABLE `service_logins` TO `service_credentials`");
// Alter service_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `service_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned service_id rows in service_credentials
mysqli_query($mysqli, "
DELETE FROM `service_credentials`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
// Clean up orphaned credential_id rows in service_credentials
mysqli_query($mysqli, "
DELETE FROM `service_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to service_credentials
mysqli_query($mysqli, "
ALTER TABLE `service_credentials`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table software_logins to software_credentials
mysqli_query($mysqli, "RENAME TABLE `software_logins` TO `software_credentials`");
// Alter software_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `software_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned software_id rows in software_credentials
mysqli_query($mysqli, "
DELETE FROM `software_credentials`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
// Clean up orphaned credential_id rows in software_credentials
mysqli_query($mysqli, "
DELETE FROM `software_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to software_credentials
mysqli_query($mysqli, "
ALTER TABLE `software_credentials`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table vendor_logins to vendor_credentials
mysqli_query($mysqli, "RENAME TABLE `vendor_logins` TO `vendor_credentials`");
// Alter vendor_credentials table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `vendor_credentials`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned vendor_id rows in vendor_credentials
mysqli_query($mysqli, "
DELETE FROM `vendor_credentials`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
// Clean up orphaned credential_id rows in vendor_credentials
mysqli_query($mysqli, "
DELETE FROM `vendor_credentials`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to vendor_credentials
mysqli_query($mysqli, "
ALTER TABLE `vendor_credentials`
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Rename table login_tags to credential_tags
mysqli_query($mysqli, "RENAME TABLE `login_tags` TO `credential_tags`");
// Alter credential_tags table and change login_id to credential_id
mysqli_query($mysqli, "
ALTER TABLE `credential_tags`
CHANGE COLUMN `login_id` `credential_id` INT(11) NOT NULL
");
// Clean up orphaned tag_id rows in credential_tags
mysqli_query($mysqli, "
DELETE FROM `credential_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Clean up orphaned credential_id rows in credential_tags
mysqli_query($mysqli, "
DELETE FROM `credential_tags`
WHERE `credential_id` NOT IN (SELECT `credential_id` FROM `credentials`);
");
// Add foreign keys to credential_tags
mysqli_query($mysqli, "
ALTER TABLE `credential_tags`
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE
");
// Create asset_credentials table with foreign keys
mysqli_query($mysqli, "
CREATE TABLE `asset_credentials` (
`credential_id` INT(11) NOT NULL,
`asset_id` INT(11) NOT NULL,
PRIMARY KEY (`credential_id`, `asset_id`),
FOREIGN KEY (`credential_id`) REFERENCES `credentials`(`credential_id`) ON DELETE CASCADE,
FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
)
");

View File

@@ -0,0 +1,15 @@
<?php
/*
* ITFlow - Database update to version 2.0.1 (from 2.0.0)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
//Dropping patch panel as a patch panel can be documented as an asset with interfaces.
mysqli_query($mysqli, "DROP TABLE `patch_panel_ports`");
mysqli_query($mysqli, "DROP TABLE `patch_panels`");
mysqli_query($mysqli, "RENAME TABLE `events` TO `calendar_events`");
mysqli_query($mysqli, "RENAME TABLE `event_attendees` TO `calendar_event_attendees`");

View File

@@ -0,0 +1,153 @@
<?php
/*
* ITFlow - Database update to version 2.0.2 (from 2.0.1)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Clean up orphaned data before adding foreign keys
// Clean up orphaned asset_custom_asset_id rows in asset_custom
mysqli_query($mysqli, "
DELETE FROM `asset_custom`
WHERE `asset_custom_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_custom
mysqli_query($mysqli, "
ALTER TABLE `asset_custom`
ADD FOREIGN KEY (`asset_custom_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_id rows in asset_documents
mysqli_query($mysqli, "
DELETE FROM `asset_documents`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Clean up orphaned document_id rows in asset_documents
mysqli_query($mysqli, "
DELETE FROM `asset_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign keys to asset_documents
mysqli_query($mysqli, "
ALTER TABLE `asset_documents`
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_id rows in asset_files
mysqli_query($mysqli, "
DELETE FROM `asset_files`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Clean up orphaned file_id rows in asset_files
mysqli_query($mysqli, "
DELETE FROM `asset_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign keys to asset_files
mysqli_query($mysqli, "
ALTER TABLE `asset_files`
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_history_asset_id rows in asset_history
mysqli_query($mysqli, "
DELETE FROM `asset_history`
WHERE `asset_history_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_history
mysqli_query($mysqli, "
ALTER TABLE `asset_history`
ADD FOREIGN KEY (`asset_history_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned interface_asset_id rows in asset_interfaces
mysqli_query($mysqli, "
DELETE FROM `asset_interfaces`
WHERE `interface_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_interfaces
mysqli_query($mysqli, "
ALTER TABLE `asset_interfaces`
ADD FOREIGN KEY (`interface_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned asset_note_asset_id rows in asset_notes
mysqli_query($mysqli, "
DELETE FROM `asset_notes`
WHERE `asset_note_asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key to asset_notes
mysqli_query($mysqli, "
ALTER TABLE `asset_notes`
ADD FOREIGN KEY (`asset_note_asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned contact_id rows in contact_assets
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Clean up orphaned asset_id rows in contact_assets
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign keys to contact_assets
mysqli_query($mysqli, "
ALTER TABLE `contact_assets`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned service_id rows in service_assets
mysqli_query($mysqli, "
DELETE FROM `service_assets`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
// Clean up orphaned asset_id rows in service_assets
mysqli_query($mysqli, "
DELETE FROM `service_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign keys to service_assets
mysqli_query($mysqli, "
ALTER TABLE `service_assets`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Clean up orphaned software_id rows in software_assets
mysqli_query($mysqli, "
DELETE FROM `software_assets`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
// Clean up orphaned asset_id rows in software_assets
mysqli_query($mysqli, "
DELETE FROM `software_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign keys to software_assets
mysqli_query($mysqli, "
ALTER TABLE `software_assets`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");

View File

@@ -0,0 +1,31 @@
<?php
/*
* ITFlow - Database update to version 2.0.3 (from 2.0.2)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Clean up orphans
mysqli_query($mysqli, "
DELETE FROM `calendar_event_attendees`
WHERE `attendee_event_id` NOT IN (SELECT `event_id` FROM `calendar_events`);
");
mysqli_query($mysqli, "
DELETE FROM `calendar_events`
WHERE `event_calendar_id` NOT IN (SELECT `calendar_id` FROM `calendars`);
");
// Add foreign key to calendar_event_attendees
mysqli_query($mysqli, "
ALTER TABLE `calendar_event_attendees`
ADD FOREIGN KEY (`attendee_event_id`) REFERENCES `calendar_events`(`event_id`) ON DELETE CASCADE
");
// Add foreign key to calendar_events
mysqli_query($mysqli, "
ALTER TABLE `calendar_events`
ADD FOREIGN KEY (`event_calendar_id`) REFERENCES `calendars`(`calendar_id`) ON DELETE CASCADE
");

View File

@@ -0,0 +1,20 @@
<?php
/*
* ITFlow - Database update to version 2.0.4 (from 2.0.3)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `certificate_history`
WHERE `certificate_history_certificate_id` NOT IN (SELECT `certificate_id` FROM `certificates`);
");
// Add foreign key certificate history
mysqli_query($mysqli, "
ALTER TABLE `certificate_history`
ADD FOREIGN KEY (`certificate_history_certificate_id`) REFERENCES `certificates`(`certificate_id`) ON DELETE CASCADE
");

View File

@@ -0,0 +1,364 @@
<?php
/*
* ITFlow - Database update to version 2.0.5 (from 2.0.4)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `client_notes`
WHERE `client_note_client_id` NOT IN (SELECT `client_id` FROM `clients`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `client_notes`
ADD FOREIGN KEY (`client_note_client_id`) REFERENCES `clients`(`client_id`) ON DELETE CASCADE
");
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `client_tags`
WHERE `client_id` NOT IN (SELECT `client_id` FROM `clients`);
");
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `client_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `client_tags`
ADD FOREIGN KEY (`client_id`) REFERENCES `clients`(`client_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE
");
//Contact Assets
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_assets`
WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `assets`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_assets`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
");
// Contact Documents
// Clean up orphaned history
mysqli_query($mysqli, "
DELETE FROM `contact_documents`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_documents`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// contact_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `contact_files`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_files`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// contact_notes
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `contact_notes`
WHERE `contact_note_contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_notes`
ADD FOREIGN KEY (`contact_note_contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
");
// contact_tags
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `contact_tags`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
mysqli_query($mysqli, "
DELETE FROM `contact_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `contact_tags`
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE
");
// document_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `document_files`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
mysqli_query($mysqli, "
DELETE FROM `document_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `document_files`
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// domain_history
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `domain_history`
WHERE `domain_history_domain_id` NOT IN (SELECT `domain_id` FROM `domains`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `domain_history`
ADD FOREIGN KEY (`domain_history_domain_id`) REFERENCES `domains`(`domain_id`) ON DELETE CASCADE
");
// location_tags
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `location_tags`
WHERE `location_id` NOT IN (SELECT `location_id` FROM `locations`);
");
mysqli_query($mysqli, "
DELETE FROM `location_tags`
WHERE `tag_id` NOT IN (SELECT `tag_id` FROM `tags`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `location_tags`
ADD FOREIGN KEY (`location_id`) REFERENCES `locations`(`location_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`tag_id`) REFERENCES `tags`(`tag_id`) ON DELETE CASCADE
");
// quote_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `quote_files`
WHERE `quote_id` NOT IN (SELECT `quote_id` FROM `quotes`);
");
mysqli_query($mysqli, "
DELETE FROM `quote_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `quote_files`
ADD FOREIGN KEY (`quote_id`) REFERENCES `quotes`(`quote_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// service_certificates
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_certificates`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_certificates`
WHERE `certificate_id` NOT IN (SELECT `certificate_id` FROM `certificates`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_certificates`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`certificate_id`) REFERENCES `certificates`(`certificate_id`) ON DELETE CASCADE
");
// service_contacts
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_contacts`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_contacts`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_contacts`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
");
// service_documents
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_documents`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_documents`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// service_domains
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_domains`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_domains`
WHERE `domain_id` NOT IN (SELECT `domain_id` FROM `domains`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_domains`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`domain_id`) REFERENCES `domains`(`domain_id`) ON DELETE CASCADE
");
// service_vendors
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `service_vendors`
WHERE `service_id` NOT IN (SELECT `service_id` FROM `services`);
");
mysqli_query($mysqli, "
DELETE FROM `service_vendors`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `service_vendors`
ADD FOREIGN KEY (`service_id`) REFERENCES `services`(`service_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE
");
// software_contacts
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `software_contacts`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
mysqli_query($mysqli, "
DELETE FROM `software_contacts`
WHERE `contact_id` NOT IN (SELECT `contact_id` FROM `contacts`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `software_contacts`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
");
// software_documents
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `software_documents`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
mysqli_query($mysqli, "
DELETE FROM `software_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `software_documents`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// software_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `software_files`
WHERE `software_id` NOT IN (SELECT `software_id` FROM `software`);
");
mysqli_query($mysqli, "
DELETE FROM `software_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `software_files`
ADD FOREIGN KEY (`software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");
// vendor_documents
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `vendor_documents`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
mysqli_query($mysqli, "
DELETE FROM `vendor_documents`
WHERE `document_id` NOT IN (SELECT `document_id` FROM `documents`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `vendor_documents`
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`document_id`) REFERENCES `documents`(`document_id`) ON DELETE CASCADE
");
// vendor_files
// Clean up orphaned rows
mysqli_query($mysqli, "
DELETE FROM `vendor_files`
WHERE `vendor_id` NOT IN (SELECT `vendor_id` FROM `vendors`);
");
mysqli_query($mysqli, "
DELETE FROM `vendor_files`
WHERE `file_id` NOT IN (SELECT `file_id` FROM `files`);
");
// Add foreign key
mysqli_query($mysqli, "
ALTER TABLE `vendor_files`
ADD FOREIGN KEY (`vendor_id`) REFERENCES `vendors`(`vendor_id`) ON DELETE CASCADE,
ADD FOREIGN KEY (`file_id`) REFERENCES `files`(`file_id`) ON DELETE CASCADE
");

View File

@@ -0,0 +1,36 @@
<?php
/*
* ITFlow - Database update to version 2.0.6 (from 2.0.5)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// CONVERT All tables TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
$tables = [
'accounts', 'api_keys', 'app_logs', 'asset_credentials', 'asset_custom', 'asset_documents',
'asset_files', 'asset_history', 'asset_interface_links', 'asset_interfaces', 'asset_notes', 'assets',
'auth_logs', 'budget', 'calendar_event_attendees', 'calendar_events', 'calendars', 'categories',
'certificate_history', 'certificates', 'client_notes', 'client_stripe', 'client_tags', 'clients',
'companies', 'contact_assets', 'contact_credentials', 'contact_documents', 'contact_files', 'contact_notes',
'contact_tags', 'contacts', 'credential_tags', 'credentials', 'custom_fields', 'custom_links',
'custom_values', 'document_files', 'documents', 'domain_history', 'domains', 'email_queue', 'expenses',
'files', 'folders', 'history', 'invoice_items', 'invoices', 'location_tags', 'locations', 'logs',
'modules', 'networks', 'notifications', 'payments', 'products', 'project_template_ticket_templates',
'project_templates', 'projects', 'quote_files', 'quotes', 'rack_units', 'racks', 'records',
'recurring_expenses', 'recurring_invoices', 'recurring_payments', 'recurring_ticket_assets', 'recurring_tickets',
'remember_tokens', 'revenues', 'service_assets', 'service_certificates', 'service_contacts', 'service_credentials',
'service_documents', 'service_domains', 'service_vendors', 'services', 'settings', 'shared_items',
'software', 'software_assets', 'software_contacts', 'software_credentials', 'software_documents', 'software_files',
'tags', 'task_templates', 'tasks', 'taxes', 'ticket_assets', 'ticket_attachments', 'ticket_history', 'ticket_replies',
'ticket_statuses', 'ticket_templates', 'ticket_views', 'ticket_watchers', 'tickets', 'transfers', 'trips',
'user_client_permissions', 'user_role_permissions', 'user_roles', 'user_settings', 'users', 'vendor_credentials',
'vendor_documents', 'vendor_files', 'vendors'
];
foreach ($tables as $table) {
$sql = "ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;";
mysqli_query($mysqli, $sql);
}

View File

@@ -0,0 +1,11 @@
<?php
/*
* ITFlow - Database update to version 2.0.7 (from 2.0.6)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Fix service_domains to yse InnoDB instead of MyISAM
mysqli_query($mysqli, "ALTER TABLE service_domains ENGINE = InnoDB;");

View File

@@ -0,0 +1,10 @@
<?php
/*
* ITFlow - Database update to version 2.0.8 (from 2.0.7)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_hash`");

View File

@@ -0,0 +1,12 @@
<?php
/*
* ITFlow - Database update to version 2.0.9 (from 2.0.8)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_has_thumbnail`");
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_has_preview`");
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_asset_id`");

View File

@@ -0,0 +1,19 @@
<?php
/*
* ITFlow - Database update to version 2.1.0 (from 2.0.9)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `contacts` ADD `contact_phone_country_code` VARCHAR(10) DEFAULT 1 AFTER `contact_email`");
mysqli_query($mysqli, "ALTER TABLE `contacts` ADD `contact_mobile_country_code` VARCHAR(10) DEFAULT 1 AFTER `contact_extension`");
mysqli_query($mysqli, "ALTER TABLE `locations` ADD `location_phone_country_code` VARCHAR(10) DEFAULT 1 AFTER `location_zip`");
mysqli_query($mysqli, "ALTER TABLE `locations` ADD `location_phone_extension` VARCHAR(10) DEFAULT NULL AFTER `location_phone`");
mysqli_query($mysqli, "ALTER TABLE `locations` ADD `location_fax_country_code` VARCHAR(10) DEFAULT 1 AFTER `location_phone_extension`");
mysqli_query($mysqli, "ALTER TABLE `vendors` ADD `vendor_phone_country_code` VARCHAR(10) DEFAULT 1 AFTER `vendor_contact_name`");
mysqli_query($mysqli, "ALTER TABLE `companies` ADD `company_phone_country_code` VARCHAR(10) DEFAULT 1 AFTER `company_country`");

View File

@@ -0,0 +1,10 @@
<?php
/*
* ITFlow - Database update to version 2.1.1 (from 2.1.0)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `user_settings` ADD `user_config_signature` TEXT DEFAULT NULL AFTER `user_config_calendar_first_day`");

View File

@@ -0,0 +1,10 @@
<?php
/*
* ITFlow - Database update to version 2.1.2 (from 2.1.1)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_phone_mask`");

View File

@@ -0,0 +1,36 @@
<?php
/*
* ITFlow - Database update to version 2.1.3 (from 2.1.2)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Update country_code to NULL for `contacts` table
mysqli_query($mysqli, "ALTER TABLE `contacts` MODIFY `contact_phone_country_code` VARCHAR(10) DEFAULT NULL");
mysqli_query($mysqli, "ALTER TABLE `contacts` MODIFY `contact_mobile_country_code` VARCHAR(10) DEFAULT NULL");
// Update country_code to NULL for `locations` table
mysqli_query($mysqli, "ALTER TABLE `locations` MODIFY `location_phone_country_code` VARCHAR(10) DEFAULT NULL");
mysqli_query($mysqli, "ALTER TABLE `locations` MODIFY `location_fax_country_code` VARCHAR(10) DEFAULT NULL");
// Update country_code to NULL for `vendors` table
mysqli_query($mysqli, "ALTER TABLE `vendors` MODIFY `vendor_phone_country_code` VARCHAR(10) DEFAULT NULL");
// Update country_code to NULL for `companies` table
mysqli_query($mysqli, "ALTER TABLE `companies` MODIFY `company_phone_country_code` VARCHAR(10) DEFAULT NULL");
// Set country_code to NULL for `contacts` table
mysqli_query($mysqli, "UPDATE `contacts` SET `contact_phone_country_code` = NULL");
mysqli_query($mysqli, "UPDATE `contacts` SET `contact_mobile_country_code` = NULL");
// Set country_code to NULL for `locations` table
mysqli_query($mysqli, "UPDATE `locations` SET `location_phone_country_code` = NULL");
mysqli_query($mysqli, "UPDATE `locations` SET `location_fax_country_code` = NULL");
// Set country_code to NULL for `vendors` table
mysqli_query($mysqli, "UPDATE `vendors` SET `vendor_phone_country_code` = NULL");
// Set country_code to NULL for `companies` table
mysqli_query($mysqli, "UPDATE `companies` SET `company_phone_country_code` = NULL");

View File

@@ -0,0 +1,11 @@
<?php
/*
* ITFlow - Database update to version 2.1.4 (from 2.1.3)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `client_stripe` ADD `stripe_pm_details` VARCHAR(200) DEFAULT NULL AFTER `stripe_pm`");
mysqli_query($mysqli, "ALTER TABLE `client_stripe` ADD `stripe_pm_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `stripe_pm_details`");

View File

@@ -0,0 +1,13 @@
<?php
/*
* ITFlow - Database update to version 2.1.5 (from 2.1.4)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_ticket_timer_autostart` TINYINT(1) NOT NULL DEFAULT '0' AFTER `config_ticket_default_billable`");
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_due_at` DATETIME DEFAULT NULL AFTER `ticket_updated_at`");
mysqli_query($mysqli, "ALTER TABLE `companies` ADD `company_tax_id` VARCHAR(200) DEFAULT NULL AFTER `company_currency`");
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_invoice_show_tax_id` TINYINT(1) NOT NULL DEFAULT '0' AFTER `config_invoice_paid_notification_email`");

View File

@@ -0,0 +1,27 @@
<?php
/*
* ITFlow - Database update to version 2.1.6 (from 2.1.5)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "CREATE TABLE `document_versions` (
`document_version_id` INT(11) NOT NULL AUTO_INCREMENT,
`document_version_name` VARCHAR(200) NOT NULL,
`document_version_description` TEXT DEFAULT NULL,
`document_version_content` LONGTEXT NOT NULL,
`document_version_created_by` INT(11) DEFAULT 0,
`document_version_created_at` DATETIME NOT NULL,
`document_version_document_id` INT(11) NOT NULL,
PRIMARY KEY (`document_version_id`)
)");
// Delete all Current Document Versions
mysqli_query($mysqli, "
DELETE FROM `documents`
WHERE `document_parent` > 0 AND `document_parent` != `document_id`
");
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_parent`");

View File

@@ -0,0 +1,52 @@
<?php
/*
* ITFlow - Database update to version 2.1.7 (from 2.1.6)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "CREATE TABLE `document_templates` (
`document_template_id` INT(11) NOT NULL AUTO_INCREMENT,
`document_template_name` VARCHAR(200) NOT NULL,
`document_template_description` TEXT DEFAULT NULL,
`document_template_content` LONGTEXT NOT NULL,
`document_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`document_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`document_template_archived_at` DATETIME NULL DEFAULT NULL,
`document_template_created_by` INT(11) NOT NULL DEFAULT 0,
`document_template_updated_by` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`document_template_id`)
)");
// Copy Document Templates over to new document templates table
mysqli_query($mysqli, "
INSERT INTO document_templates (
document_template_name,
document_template_description,
document_template_content,
document_template_created_at,
document_template_updated_at,
document_template_archived_at,
document_template_created_by,
document_template_updated_by
)
SELECT
document_name,
document_description,
document_content,
document_created_at,
document_updated_at,
document_archived_at,
document_created_by,
document_updated_by
FROM
documents
WHERE
document_template = 1
");
mysqli_query($mysqli, "DELETE FROM documents WHERE document_template = 1");
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_template`");

View File

@@ -0,0 +1,57 @@
<?php
/*
* ITFlow - Database update to version 2.1.8 (from 2.1.7)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "CREATE TABLE `software_templates` (
`software_template_id` INT(11) NOT NULL AUTO_INCREMENT,
`software_template_name` VARCHAR(200) NOT NULL,
`software_template_description` TEXT DEFAULT NULL,
`software_template_version` VARCHAR(200) DEFAULT NULL,
`software_template_type` VARCHAR(200) NOT NULL,
`software_template_license_type` VARCHAR(200) DEFAULT NULL,
`software_template_notes` TEXT DEFAULT NULL,
`software_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`software_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`software_template_archived_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`software_template_id`)
)");
// Copy software Templates over to new software templates table
mysqli_query($mysqli, "
INSERT INTO software_templates (
software_template_name,
software_template_description,
software_template_version,
software_template_type,
software_template_license_type,
software_template_notes,
software_template_created_at,
software_template_updated_at,
software_template_archived_at
)
SELECT
software_name,
software_description,
software_version,
software_type,
software_license_type,
software_notes,
software_created_at,
software_updated_at,
software_archived_at
FROM
software
WHERE
software_template = 1
");
mysqli_query($mysqli, "DELETE FROM software WHERE software_template = 1");
mysqli_query($mysqli, "ALTER TABLE `software` DROP `software_template`");
mysqli_query($mysqli, "ALTER TABLE `software` DROP `software_template_id`");

View File

@@ -0,0 +1,76 @@
<?php
/*
* ITFlow - Database update to version 2.1.9 (from 2.1.8)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "CREATE TABLE `vendor_templates` (
`vendor_template_id` INT(11) NOT NULL AUTO_INCREMENT,
`vendor_template_name` VARCHAR(200) NOT NULL,
`vendor_template_description` VARCHAR(200) DEFAULT NULL,
`vendor_template_contact_name` VARCHAR(200) DEFAULT NULL,
`vendor_template_phone_country_code` VARCHAR(10) DEFAULT NULL,
`vendor_template_phone` VARCHAR(200) DEFAULT NULL,
`vendor_template_extension` VARCHAR(200) DEFAULT NULL,
`vendor_template_email` VARCHAR(200) DEFAULT NULL,
`vendor_template_website` VARCHAR(200) DEFAULT NULL,
`vendor_template_hours` VARCHAR(200) DEFAULT NULL,
`vendor_template_sla` VARCHAR(200) DEFAULT NULL,
`vendor_template_code` VARCHAR(200) DEFAULT NULL,
`vendor_template_account_number` VARCHAR(200) DEFAULT NULL,
`vendor_template_notes` TEXT DEFAULT NULL,
`vendor_template_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`vendor_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`vendor_template_archived_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`vendor_template_id`)
)");
// Copy Vendor Templates over to new vendor templates table
mysqli_query($mysqli, "
INSERT INTO vendor_templates (
vendor_template_name,
vendor_template_description,
vendor_template_contact_name,
vendor_template_phone_country_code,
vendor_template_phone,
vendor_template_extension,
vendor_template_email,
vendor_template_website,
vendor_template_hours,
vendor_template_sla,
vendor_template_code,
vendor_template_account_number,
vendor_template_notes,
vendor_template_created_at,
vendor_template_updated_at,
vendor_template_archived_at
)
SELECT
vendor_name,
vendor_description,
vendor_contact_name,
vendor_phone_country_code,
vendor_phone,
vendor_extension,
vendor_email,
vendor_website,
vendor_hours,
vendor_sla,
vendor_code,
vendor_account_number,
vendor_notes,
vendor_created_at,
vendor_updated_at,
vendor_archived_at
FROM
vendors
WHERE
vendor_template = 1
");
mysqli_query($mysqli, "DELETE FROM vendors WHERE vendor_template = 1");
mysqli_query($mysqli, "ALTER TABLE `vendors` DROP `vendor_template`");

View File

@@ -0,0 +1,10 @@
<?php
/*
* ITFlow - Database update to version 2.2.0 (from 2.1.9)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `companies` MODIFY `company_currency` VARCHAR(200) DEFAULT 'USD'");

View File

@@ -0,0 +1,10 @@
<?php
/*
* ITFlow - Database update to version 2.2.1 (from 2.2.0)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `tickets` ADD `ticket_quote_id` INT(11) NOT NULL DEFAULT 0 AFTER `ticket_asset_id`");

View File

@@ -0,0 +1,34 @@
<?php
/*
* ITFlow - Database update to version 2.2.2 (from 2.2.1)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "CREATE TABLE `ai_providers` (
`ai_provider_id` INT(11) NOT NULL AUTO_INCREMENT,
`ai_provider_name` VARCHAR(200) NOT NULL,
`ai_provider_api_url` VARCHAR(200) NOT NULL,
`ai_provider_api_key` VARCHAR(200) DEFAULT NULL,
`ai_provider_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ai_provider_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`ai_provider_id`)
)");
mysqli_query($mysqli, "
CREATE TABLE `ai_models` (
`ai_model_id` INT(11) NOT NULL AUTO_INCREMENT,
`ai_model_name` VARCHAR(200) NOT NULL,
`ai_model_prompt` TEXT DEFAULT NULL,
`ai_model_use_case` VARCHAR(200) DEFAULT NULL,
`ai_model_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ai_model_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`ai_model_ai_provider_id` INT(11) NOT NULL,
PRIMARY KEY (`ai_model_id`),
FOREIGN KEY (`ai_model_ai_provider_id`)
REFERENCES `ai_providers`(`ai_provider_id`)
ON DELETE CASCADE
)
");

View File

@@ -0,0 +1,62 @@
<?php
/*
* ITFlow - Database update to version 2.2.3 (from 2.2.2)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "CREATE TABLE `payment_methods` (
`payment_method_id` INT(11) NOT NULL AUTO_INCREMENT,
`payment_method_name` VARCHAR(200) NOT NULL,
`payment_method_description` VARCHAR(250) DEFAULT NULL,
`payment_method_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`payment_method_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`payment_method_id`)
)");
mysqli_query($mysqli, "CREATE TABLE `payment_providers` (
`payment_provider_id` INT(11) NOT NULL AUTO_INCREMENT,
`payment_provider_name` VARCHAR(200) NOT NULL,
`payment_provider_description` VARCHAR(250) DEFAULT NULL,
`payment_provider_public_key` VARCHAR(250) DEFAULT NULL,
`payment_provider_private_key` VARCHAR(250) DEFAULT NULL,
`payment_provider_threshold` DECIMAL(15,2) DEFAULT NULL,
`payment_provider_active` TINYINT(1) NOT NULL DEFAULT 1,
`payment_provider_account` INT(11) NOT NULL,
`payment_provider_expense_vendor` INT(11) NOT NULL DEFAULT 0,
`payment_provider_expense_category` INT(11) NOT NULL DEFAULT 0,
`payment_provider_expense_percentage_fee` DECIMAL(4,4) DEFAULT NULL,
`payment_provider_expense_flat_fee` DECIMAL(15,2) DEFAULT NULL,
`payment_provider_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`payment_provider_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`payment_provider_id`)
)");
mysqli_query($mysqli, "CREATE TABLE `client_saved_payment_methods` (
`saved_payment_id` INT(11) NOT NULL AUTO_INCREMENT,
`saved_payment_provider_method` VARCHAR(200) NOT NULL,
`saved_payment_description` VARCHAR(200) DEFAULT NULL,
`saved_payment_client_id` INT(11) NOT NULL,
`saved_payment_provider_id` INT(11) NOT NULL,
`saved_payment_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`saved_payment_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`saved_payment_id`),
FOREIGN KEY (`saved_payment_client_id`) REFERENCES clients(`client_id`) ON DELETE CASCADE,
FOREIGN KEY (`saved_payment_provider_id`) REFERENCES payment_providers(`payment_provider_id`) ON DELETE CASCADE
)");
mysqli_query($mysqli, "CREATE TABLE `client_payment_provider` (
`client_id` INT(11) NOT NULL,
`payment_provider_id` INT(11) NOT NULL,
`payment_provider_client` VARCHAR(200) NOT NULL,
`client_payment_provider_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`client_id`, `payment_provider_id`),
FOREIGN KEY (`client_id`) REFERENCES clients(`client_id`) ON DELETE CASCADE,
FOREIGN KEY (`payment_provider_id`) REFERENCES payment_providers(`payment_provider_id`) ON DELETE CASCADE
)");
mysqli_query($mysqli, "ALTER TABLE `recurring_payments` ADD `recurring_payment_saved_payment_id` INT(11) DEFAULT NULL AFTER `recurring_payment_recurring_invoice_id`");
mysqli_query($mysqli, "ALTER TABLE `recurring_payments` ADD CONSTRAINT `fk_recurring_saved_payment` FOREIGN KEY (`recurring_payment_saved_payment_id`) REFERENCES `client_saved_payment_methods`(`saved_payment_id`) ON DELETE CASCADE");

View File

@@ -0,0 +1,34 @@
<?php
/*
* ITFlow - Database update to version 2.2.4 (from 2.2.3)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "CREATE TABLE `credits` (
`credit_id` INT(11) NOT NULL AUTO_INCREMENT,
`credit_amount` DECIMAL(15,2) NOT NULL,
`credit_reference` VARCHAR(250) DEFAULT NULL,
`credit_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
`credit_created_by` INT(11) NOT NULL,
`credit_expire_at` DATE DEFAULT NULL,
`credit_client_id` INT(11) NOT NULL,
PRIMARY KEY (`credit_id`)
)");
mysqli_query($mysqli, "ALTER TABLE `invoices` ADD `invoice_credit_amount` DECIMAL(15,2) NOT NULL DEFAULT 0.00 AFTER `invoice_discount_amount`");
mysqli_query($mysqli, "CREATE TABLE `discount_codes` (
`discount_code_id` INT(11) NOT NULL AUTO_INCREMENT,
`discount_code_description` VARCHAR(250) DEFAULT NULL,
`discount_code_amount` DECIMAL(15,2) NOT NULL,
`discount_code` VARCHAR(200) NOT NULL,
`discount_code_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
`discount_code_created_by` INT(11) NOT NULL,
`discount_code_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`discount_code_archived_at` DATETIME NULL DEFAULT NULL,
`discount_code_expire_at` DATE DEFAULT NULL,
PRIMARY KEY (`discount_code_id`)
)");

View File

@@ -0,0 +1,10 @@
<?php
/*
* ITFlow - Database update to version 2.2.5 (from 2.2.4)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `settings` ADD `config_theme_dark` TINYINT(1) NOT NULL DEFAULT 0 AFTER `config_theme`");

View File

@@ -0,0 +1,10 @@
<?php
/*
* ITFlow - Database update to version 2.2.6 (from 2.2.5)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `assets` ADD `asset_uri_client` VARCHAR(500) NULL DEFAULT NULL AFTER `asset_uri_2`");

View File

@@ -0,0 +1,16 @@
<?php
/*
* ITFlow - Database update to version 2.2.7 (from 2.2.6)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `credits` DROP `credit_reference`");
mysqli_query($mysqli, "ALTER TABLE `credits` ADD `credit_type` ENUM('prepaid', 'manual', 'refund', 'promotion', 'usage') NOT NULL DEFAULT 'manual' AFTER `credit_amount`");
mysqli_query($mysqli, "ALTER TABLE `credits` ADD `credit_note` TEXT NULL DEFAULT NULL AFTER `credit_type`");
mysqli_query($mysqli, "ALTER TABLE `credits` ADD `credit_invoice_id` INT(11) NULL DEFAULT NULL AFTER `credit_expire_at`");
mysqli_query($mysqli, "ALTER TABLE `credits` ADD INDEX (`credit_client_id`)");
mysqli_query($mysqli, "ALTER TABLE `credits` ADD INDEX (`credit_invoice_id`)");
mysqli_query($mysqli, "ALTER TABLE `credits` ADD INDEX (`credit_created_at`)");

View File

@@ -0,0 +1,11 @@
<?php
/*
* ITFlow - Database update to version 2.2.8 (from 2.2.7)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `user_settings` ADD `user_config_theme_dark` TINYINT(1) NOT NULL DEFAULT 0 AFTER `user_config_signature`");
mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_theme_dark`");

View File

@@ -0,0 +1,23 @@
<?php
/*
* ITFlow - Database update to version 2.2.9 (from 2.2.8)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `products` ADD `product_type` ENUM('service', 'product') NOT NULL DEFAULT 'service' AFTER `product_name`");
mysqli_query($mysqli, "ALTER TABLE `products` ADD `product_code` VARCHAR(200) DEFAULT NULL AFTER `product_description`");
mysqli_query($mysqli, "ALTER TABLE `products` ADD `product_location` VARCHAR(250) DEFAULT NULL AFTER `product_code`");
mysqli_query($mysqli, "CREATE TABLE `product_stock` (
`stock_id` INT(11) NOT NULL AUTO_INCREMENT,
`stock_qty` INT(11) NOT NULL,
`stock_note` TEXT DEFAULT NULL,
`stock_created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP(),
`stock_expense_id` INT(11) DEFAULT NULL,
`stock_item_id` INT(11) DEFAULT NULL,
`stock_product_id` INT(11) NOT NULL,
PRIMARY KEY (`stock_id`)
)");

View File

@@ -0,0 +1,84 @@
<?php
/*
* ITFlow - Database update to version 2.3.0 (from 2.2.9)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Migrate Stripe Settings over to new Tables
// Get Current Stripe Settings
$sql_stripe_settings = mysqli_query($mysqli, "SELECT * FROM settings WHERE company_id = 1");
$row = mysqli_fetch_assoc($sql_stripe_settings);
$config_stripe_enable = intval($row['config_stripe_enable']);
if ($config_stripe_enable === 1) {
$config_stripe_publishable = mysqli_real_escape_string($mysqli, $row['config_stripe_publishable']);
$config_stripe_secret = mysqli_real_escape_string($mysqli, $row['config_stripe_secret']);
$config_stripe_account = intval($row['config_stripe_account']);
$config_stripe_expense_vendor = intval($row['config_stripe_expense_vendor']);
$config_stripe_expense_category = intval($row['config_stripe_expense_category']);
$config_stripe_percentage_fee = floatval($row['config_stripe_percentage_fee']);
$config_stripe_flat_fee = floatval($row['config_stripe_flat_fee']);
mysqli_query($mysqli,"INSERT INTO payment_providers SET
payment_provider_name = 'Stripe',
payment_provider_public_key = '$config_stripe_publishable',
payment_provider_private_key = '$config_stripe_secret',
payment_provider_account = $config_stripe_account,
payment_provider_expense_vendor = $config_stripe_expense_vendor,
payment_provider_expense_category = $config_stripe_expense_category,
payment_provider_expense_percentage_fee = $config_stripe_percentage_fee,
payment_provider_expense_flat_fee = $config_stripe_flat_fee"
);
$provider_id = mysqli_insert_id($mysqli);
// Migrate Clients and Payment Method over
$sql_stripe_clients = mysqli_query($mysqli, "SELECT * FROM client_stripe WHERE stripe_pm IS NOT NULL AND stripe_pm != ''");
while ($row = mysqli_fetch_assoc($sql_stripe_clients)) {
$client_id = intval($row['client_id']);
$stripe_id = mysqli_real_escape_string($mysqli, $row['stripe_id']);
$stripe_pm = mysqli_real_escape_string($mysqli, $row['stripe_pm']);
$stripe_pm_details = mysqli_real_escape_string($mysqli, $row['stripe_pm_details'] ?? 'Saved Card');
mysqli_query($mysqli,"INSERT INTO client_payment_provider SET
client_id = $client_id,
payment_provider_id = $provider_id,
payment_provider_client = '$stripe_id'"
);
mysqli_query($mysqli,"INSERT INTO client_saved_payment_methods SET
saved_payment_provider_method = '$stripe_pm',
saved_payment_description = '$stripe_pm_details',
saved_payment_client_id = $client_id,
saved_payment_provider_id = $provider_id"
);
}
}
// Get Stripe provider id
$res = mysqli_query($mysqli, "
SELECT payment_provider_id
FROM payment_providers
WHERE payment_provider_name = 'Stripe'
ORDER BY payment_provider_id DESC
LIMIT 1
");
$stripe = mysqli_fetch_assoc($res);
$stripe_provider_id = intval($stripe['payment_provider_id']);
// Correct mapping: RP -> Recurring Invoice -> Client -> Client's Stripe saved method
mysqli_query($mysqli, "
UPDATE recurring_payments rp
INNER JOIN recurring_invoices ri
ON ri.recurring_invoice_id = rp.recurring_payment_recurring_invoice_id
INNER JOIN client_saved_payment_methods spm
ON spm.saved_payment_client_id = ri.recurring_invoice_client_id
AND spm.saved_payment_provider_id = $stripe_provider_id
SET
rp.recurring_payment_method = 'Credit Card',
rp.recurring_payment_saved_payment_id = spm.saved_payment_id
WHERE rp.recurring_payment_method = 'Stripe'
");

View File

@@ -0,0 +1,17 @@
<?php
/*
* ITFlow - Database update to version 2.3.1 (from 2.3.0)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Migrate Payment Methods from Categories Table to new payment_methods table
$sql_categories = mysqli_query($mysqli, "SELECT * FROM categories WHERE category_type = 'Payment Method' AND category_name != 'Stripe' AND category_archived_at IS NULL");
while ($row = mysqli_fetch_assoc($sql_categories)) {
$category_name = escapeSql($row['category_name']);
mysqli_query($mysqli,"INSERT INTO payment_methods SET payment_method_name = '$category_name'");
}

View File

@@ -0,0 +1,31 @@
<?php
/*
* ITFlow - Database update to version 2.3.2 (from 2.3.1)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Delete all Recurring Payments that are Stripe
mysqli_query($mysqli, "DELETE FROM recurring_payments WHERE recurring_payment_method = 'Stripe'");
// Delete Stripe Specific ITFlow Client Stripe Client Relationship Table
mysqli_query($mysqli, "DROP TABLE client_stripe");
// Delete Unused Stripe and AI Settings now in their own tables
mysqli_query($mysqli, "ALTER TABLE `settings`
DROP `config_stripe_enable`,
DROP `config_stripe_publishable`,
DROP `config_stripe_secret`,
DROP `config_stripe_account`,
DROP `config_stripe_expense_vendor`,
DROP `config_stripe_expense_category`,
DROP `config_stripe_percentage_fee`,
DROP `config_stripe_flat_fee`,
DROP `config_ai_enable`,
DROP `config_ai_provider`,
DROP `config_ai_model`,
DROP `config_ai_url`,
DROP `config_ai_api_key`
");

View File

@@ -0,0 +1,18 @@
<?php
/*
* ITFlow - Database update to version 2.3.3 (from 2.3.2)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE settings
ADD `config_imap_provider` ENUM('standard_imap','google_oauth','microsoft_oauth') NULL DEFAULT NULL AFTER `config_mail_from_name`,
ADD `config_mail_oauth_client_id` VARCHAR(255) NULL AFTER `config_imap_provider`,
ADD `config_mail_oauth_client_secret` VARCHAR(255) NULL AFTER `config_mail_oauth_client_id`,
ADD `config_mail_oauth_tenant_id` VARCHAR(255) NULL AFTER `config_mail_oauth_client_secret`,
ADD `config_mail_oauth_refresh_token` TEXT NULL AFTER `config_mail_oauth_tenant_id`,
ADD `config_mail_oauth_access_token` TEXT NULL AFTER `config_mail_oauth_refresh_token`,
ADD `config_mail_oauth_access_token_expires_at` DATETIME NULL AFTER `config_mail_oauth_access_token`
");

View File

@@ -0,0 +1,12 @@
<?php
/*
* ITFlow - Database update to version 2.3.4 (from 2.3.3)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE settings
ADD `config_smtp_provider` ENUM('standard_smtp','google_oauth','microsoft_oauth') NULL DEFAULT NULL AFTER `config_start_page`
");

View File

@@ -0,0 +1,37 @@
<?php
/*
* ITFlow - Database update to version 2.3.5 (from 2.3.4)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Add Software Keys
mysqli_query($mysqli, "CREATE TABLE `software_keys` (
`software_key_id` INT(11) NOT NULL AUTO_INCREMENT,
`software_key` VARCHAR(400) NOT NULL,
`software_key_software_id` INT(11) NOT NULL,
PRIMARY KEY (`software_key_id`),
FOREIGN KEY (`software_key_software_id`) REFERENCES `software`(`software_id`) ON DELETE CASCADE
)");
// Software Key Assignments to Contacts
mysqli_query($mysqli, "CREATE TABLE `software_key_contact_assignments` (
`software_key_id` INT(11) NOT NULL,
`contact_id` INT(11) NOT NULL,
`software_key_assigned_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`software_key_id`, `contact_id`),
FOREIGN KEY (`software_key_id`) REFERENCES `software_keys`(`software_key_id`) ON DELETE CASCADE,
FOREIGN KEY (`contact_id`) REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE
)");
// Software Key Assignments to Assets
mysqli_query($mysqli, "CREATE TABLE `software_key_asset_assignments` (
`software_key_id` INT(11) NOT NULL,
`asset_id` INT(11) NOT NULL,
`software_key_assigned_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`software_key_id`, `asset_id`),
FOREIGN KEY (`software_key_id`) REFERENCES `software_keys`(`software_key_id`) ON DELETE CASCADE,
FOREIGN KEY (`asset_id`) REFERENCES `assets`(`asset_id`) ON DELETE CASCADE
)");

View File

@@ -0,0 +1,11 @@
<?php
/*
* ITFlow - Database update to version 2.3.6 (from 2.3.5)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `settings` CHANGE `config_smtp_provider` `config_smtp_provider` VARCHAR(200) DEFAULT NULL");
mysqli_query($mysqli, "ALTER TABLE `settings` CHANGE `config_imap_provider` `config_imap_provider` VARCHAR(200) DEFAULT NULL");

View File

@@ -0,0 +1,84 @@
<?php
/*
* ITFlow - Database update to version 2.3.7 (from 2.3.6)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Create New Contract Templates Table
mysqli_query($mysqli, "CREATE TABLE `contract_templates` (
`contract_template_id` INT(11) AUTO_INCREMENT PRIMARY KEY,
`contract_template_name` VARCHAR(255) NOT NULL,
`contract_template_description` TEXT NULL DEFAULT NULL,
`contract_template_type` VARCHAR(50) NULL DEFAULT NULL,
`contract_template_sla_low_response_time` INT(11) NULL DEFAULT NULL,
`contract_template_sla_low_resolution_time` INT(11) NULL DEFAULT NULL,
`contract_template_sla_medium_response_time` INT(11) NULL DEFAULT NULL,
`contract_template_sla_medium_resolution_time` INT(11) NULL DEFAULT NULL,
`contract_template_sla_high_response_time` INT(11) NULL DEFAULT NULL,
`contract_template_sla_high_resolution_time` INT(11) NULL DEFAULT NULL,
`contract_template_rate_standard` DECIMAL(10,2) NULL DEFAULT NULL,
`contract_template_rate_after_hours` DECIMAL(10,2) NULL DEFAULT NULL,
`contract_template_net_terms` VARCHAR(50) NULL DEFAULT NULL,
`contract_template_support_hours` VARCHAR(100) NULL DEFAULT NULL,
`contract_template_renewal_frequency` VARCHAR(50) NULL DEFAULT NULL,
`contract_template_details` TEXT NULL DEFAULT NULL,
`contract_template_created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`contract_template_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`contract_template_archived_at` DATETIME NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
// Create New Contracts Table
mysqli_query($mysqli, "CREATE TABLE `contracts` (
`contract_id` INT(11) AUTO_INCREMENT PRIMARY KEY,
`contract_name` VARCHAR(255) NOT NULL,
`contract_status` VARCHAR(50) NOT NULL,
`contract_type` VARCHAR(50) NOT NULL,
`contract_sla_low_response_time` INT(11) NULL DEFAULT NULL,
`contract_sla_low_resolution_time` INT(11) NULL DEFAULT NULL,
`contract_sla_medium_response_time` INT(11) NULL DEFAULT NULL,
`contract_sla_medium_resolution_time` INT(11) NULL DEFAULT NULL,
`contract_sla_high_response_time` INT(11) NULL DEFAULT NULL,
`contract_sla_high_resolution_time` INT(11) NULL DEFAULT NULL,
`contract_details` TEXT NULL DEFAULT NULL,
`contract_client_id` INT(11) NULL DEFAULT NULL,
`contract_client_name` VARCHAR(255) NULL DEFAULT NULL,
`contract_client_address` TEXT NULL DEFAULT NULL,
`contract_client_email` VARCHAR(255) NULL DEFAULT NULL,
`contract_client_phone` VARCHAR(100) NULL DEFAULT NULL,
`contract_contact_name` VARCHAR(255) NULL DEFAULT NULL,
`contract_contact_signature` TEXT NULL DEFAULT NULL,
`contract_contact_signature_date` DATETIME NULL DEFAULT NULL,
`contract_agent_name` VARCHAR(255) NULL DEFAULT NULL,
`contract_agent_signature` TEXT NULL DEFAULT NULL,
`contract_agent_signature_date` DATETIME NULL DEFAULT NULL,
`contract_rate_standard` DECIMAL(10,2) NULL DEFAULT NULL,
`contract_rate_after_hours` DECIMAL(10,2) NULL DEFAULT NULL,
`contract_net_terms` VARCHAR(50) NULL DEFAULT NULL,
`contract_support_hours` VARCHAR(100) NULL DEFAULT NULL,
`contract_start_date` DATE NULL DEFAULT NULL,
`contract_end_date` DATE NULL DEFAULT NULL,
`contract_renewal_frequency` VARCHAR(50) NULL DEFAULT NULL,
`contract_created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`contract_updated_at` DATETIME NULL ON UPDATE CURRENT_TIMESTAMP,
`contract_archived_at` DATETIME NULL DEFAULT NULL,
FOREIGN KEY (`contract_client_id`) REFERENCES `clients`(`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

View File

@@ -0,0 +1,24 @@
<?php
/*
* ITFlow - Database update to version 2.3.8 (from 2.3.7)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "
CREATE TABLE `asset_tags` (
`asset_tag_asset_id` INT(11) NOT NULL,
`asset_tag_tag_id` INT(11) NOT NULL,
PRIMARY KEY (`asset_tag_asset_id`, `asset_tag_tag_id`),
CONSTRAINT `fk_asset`
FOREIGN KEY (`asset_tag_asset_id`)
REFERENCES `assets`(`asset_id`)
ON DELETE CASCADE,
CONSTRAINT `fk_tag`
FOREIGN KEY (`asset_tag_tag_id`)
REFERENCES `tags`(`tag_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");

View File

@@ -0,0 +1,23 @@
<?php
/*
* ITFlow - Database update to version 2.3.9 (from 2.3.8)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "
CREATE TABLE `task_approvals` (
`approval_id` int(11) NOT NULL AUTO_INCREMENT,
`approval_scope` enum('client','internal') NOT NULL,
`approval_type` enum('any','technical','billing','specific') NOT NULL,
`approval_required_user_id` int(11) DEFAULT NULL,
`approval_status` enum('pending','approved','declined') NOT NULL,
`approval_created_by` int(11) NOT NULL,
`approval_approved_by` varchar(255) DEFAULT NULL,
`approval_url_key` varchar(200) NOT NULL,
`approval_task_id` int(11) NOT NULL,
PRIMARY KEY (`approval_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");

View File

@@ -0,0 +1,43 @@
<?php
/*
* ITFlow - Database update to version 2.4.0 (from 2.3.9)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `clients` ADD `client_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `client_notes`");
mysqli_query($mysqli, "ALTER TABLE `locations` ADD `location_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `location_notes`");
mysqli_query($mysqli, "ALTER TABLE `vendors` ADD `vendor_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `vendor_notes`");
mysqli_query($mysqli, "ALTER TABLE `software` ADD `software_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `software_notes`");
mysqli_query(
$mysqli,
"ALTER TABLE `credentials`
CHANGE `credential_important` `credential_favorite`
TINYINT(1) NOT NULL DEFAULT 0
AFTER `credential_note`"
);
mysqli_query($mysqli, "ALTER TABLE `assets` DROP `asset_important`");
mysqli_query($mysqli, "ALTER TABLE `assets` ADD `asset_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `asset_notes`");
mysqli_query($mysqli, "ALTER TABLE `documents` DROP `document_important`");
mysqli_query($mysqli, "ALTER TABLE `documents` ADD `document_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `document_client_visible`");
mysqli_query($mysqli, "ALTER TABLE `racks` ADD `rack_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `rack_notes`");
mysqli_query($mysqli, "ALTER TABLE `files` DROP `file_important`");
mysqli_query($mysqli, "ALTER TABLE `files` ADD `file_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `file_mime_type`");
mysqli_query($mysqli, "ALTER TABLE `networks` ADD `network_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `network_notes`");
mysqli_query($mysqli, "ALTER TABLE `domains` ADD `domain_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `domain_notes`");
mysqli_query($mysqli, "ALTER TABLE `certificates` ADD `certificate_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `certificate_notes`");
mysqli_query($mysqli, "ALTER TABLE `services` ADD `service_favorite` TINYINT(1) NOT NULL DEFAULT '0' AFTER `service_notes`");

View File

@@ -0,0 +1,50 @@
<?php
/*
* ITFlow - Database update to version 2.4.1 (from 2.4.0)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "
CREATE TABLE `quote_items` (
`item_id` int(11) NOT NULL AUTO_INCREMENT,
`item_name` varchar(200) NOT NULL,
`item_description` text DEFAULT NULL,
`item_quantity` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_price` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_subtotal` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_tax` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_total` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_order` int(11) NOT NULL DEFAULT 0,
`item_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`item_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`item_archived_at` datetime DEFAULT NULL,
`item_tax_id` int(11) NOT NULL DEFAULT 0,
`item_product_id` int(11) NOT NULL DEFAULT 0,
`item_quote_id` int(11) NOT NULL,
PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
mysqli_query($mysqli, "
CREATE TABLE `recurring_invoice_items` (
`item_id` int(11) NOT NULL AUTO_INCREMENT,
`item_name` varchar(200) NOT NULL,
`item_description` text DEFAULT NULL,
`item_quantity` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_price` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_subtotal` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_tax` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_total` decimal(15,2) NOT NULL DEFAULT 0.00,
`item_order` int(11) NOT NULL DEFAULT 0,
`item_created_at` datetime NOT NULL DEFAULT current_timestamp(),
`item_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(),
`item_archived_at` datetime DEFAULT NULL,
`item_tax_id` int(11) NOT NULL DEFAULT 0,
`item_product_id` int(11) NOT NULL DEFAULT 0,
`item_recurring_invoice_id` int(11) NOT NULL,
PRIMARY KEY (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");

View File

@@ -0,0 +1,97 @@
<?php
/*
* ITFlow - Database update to version 2.4.2 (from 2.4.1)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Migrate Items
mysqli_query($mysqli, "
INSERT INTO `recurring_invoice_items` (
`item_name`,
`item_description`,
`item_quantity`,
`item_price`,
`item_subtotal`,
`item_tax`,
`item_total`,
`item_order`,
`item_created_at`,
`item_updated_at`,
`item_archived_at`,
`item_tax_id`,
`item_product_id`,
`item_recurring_invoice_id`
)
SELECT
`item_name`,
`item_description`,
`item_quantity`,
`item_price`,
`item_subtotal`,
`item_tax`,
`item_total`,
`item_order`,
`item_created_at`,
`item_updated_at`,
`item_archived_at`,
`item_tax_id`,
`item_product_id`,
`item_recurring_invoice_id`
FROM `invoice_items`
WHERE `item_recurring_invoice_id` != 0
");
mysqli_query($mysqli, "
INSERT INTO `quote_items` (
`item_name`,
`item_description`,
`item_quantity`,
`item_price`,
`item_subtotal`,
`item_tax`,
`item_total`,
`item_order`,
`item_created_at`,
`item_updated_at`,
`item_archived_at`,
`item_tax_id`,
`item_product_id`,
`item_quote_id`
)
SELECT
`item_name`,
`item_description`,
`item_quantity`,
`item_price`,
`item_subtotal`,
`item_tax`,
`item_total`,
`item_order`,
`item_created_at`,
`item_updated_at`,
`item_archived_at`,
`item_tax_id`,
`item_product_id`,
`item_quote_id`
FROM `invoice_items`
WHERE `item_quote_id` != 0
");
mysqli_query($mysqli, "
DELETE FROM `invoice_items`
WHERE `item_recurring_invoice_id` != 0
");
mysqli_query($mysqli, "
DELETE FROM `invoice_items`
WHERE `item_quote_id` != 0
");
mysqli_query($mysqli, "
ALTER TABLE `invoice_items`
DROP COLUMN `item_quote_id`,
DROP COLUMN `item_recurring_invoice_id`
");

View File

@@ -0,0 +1,21 @@
<?php
/*
* ITFlow - Database update to version 2.4.3 (from 2.4.2)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
mysqli_query($mysqli, "ALTER TABLE `categories` ADD `category_description` VARCHAR(255) DEFAULT NULL AFTER `category_name`");
mysqli_query($mysqli, "ALTER TABLE `categories` ADD `category_order` INT(11) NOT NULL DEFAULT 0 AFTER `category_icon`");
// Create network_interfaces
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Ethernet', category_type = 'network_interface', category_order = 1"); // 1
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'SFP', category_type = 'network_interface', category_order = 2"); // 2
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'SFP+', category_type = 'network_interface', category_order = 3"); // 3
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'QSFP28', category_type = 'network_interface', category_order = 4"); // 4
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'QSFP-DD', category_type = 'network_interface', category_order = 5"); // 5
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Coaxial', category_type = 'network_interface', category_order = 6"); // 6
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Fiber', category_type = 'network_interface', category_order = 7"); // 7
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'WiFi', category_type = 'network_interface', category_order = 8"); // 8

View File

@@ -0,0 +1,42 @@
<?php
/*
* ITFlow - Database update to version 2.4.4 (from 2.4.3)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Asset Status
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Ready to Deploy', category_description = 'Asset is configured and ready to be assigned', category_type = 'asset_status', category_order = 1"); // 1
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Deployed', category_description = 'Asset is actively in use and assigned to a client or location', category_type = 'asset_status', category_order = 2"); // 2
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Out for Repair', category_description = 'Asset has been sent out for servicing or repair', category_type = 'asset_status', category_order = 3"); // 3
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Lost', category_description = 'Asset location is unknown and cannot be accounted for', category_type = 'asset_status', category_order = 4"); // 4
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Stolen', category_description = 'Asset has been reported stolen', category_type = 'asset_status', category_order = 5"); // 5
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Retired', category_description = 'Asset has been decommissioned and is no longer in service', category_type = 'asset_status', category_order = 6"); // 6
// Contact note types
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Call', category_description = 'Phone call with a client or contact', category_icon = 'fa-phone-alt', category_type = 'contact_note_type', category_order = 1"); // 1
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Email', category_description = 'Email correspondence with a client or contact', category_icon = 'fa-envelope', category_type = 'contact_note_type', category_order = 2"); // 2
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Meeting', category_description = 'Scheduled meeting with a client or contact', category_icon = 'fa-handshake', category_type = 'contact_note_type', category_order = 3"); // 3
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'In Person', category_description = 'In person visit or on-site interaction', category_icon = 'fa-people-arrows', category_type = 'contact_note_type', category_order = 4"); // 4
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Note', category_description = 'General note or internal comment', category_icon = 'fa-sticky-note', category_type = 'contact_note_type', category_order = 5"); // 5
// Rack Types
mysqli_query($mysqli, "INSERT INTO categories SET category_name = '2-Post Open Frame', category_description = 'Two-post open frame rack for patch panels and lightweight equipment', category_type = 'rack_type', category_order = 1"); // 1
mysqli_query($mysqli, "INSERT INTO categories SET category_name = '4-Post Open Frame', category_description = 'Four-post open frame rack for servers and heavier equipment', category_type = 'rack_type', category_order = 2"); // 2
mysqli_query($mysqli, "INSERT INTO categories SET category_name = '4-Post Enclosed Cabinet', category_description = 'Four-post enclosed cabinet with doors and sides for secure equipment housing', category_type = 'rack_type', category_order = 3"); // 3
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Wall-Mount Open', category_description = 'Open frame rack mounted directly to a wall for small deployments', category_type = 'rack_type', category_order = 4"); // 4
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Wall-Mount Enclosed', category_description = 'Enclosed cabinet rack mounted to a wall with a locking door', category_type = 'rack_type', category_order = 5"); // 5
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Other', category_description = 'Rack type does not fit any standard category', category_type = 'rack_type', category_order = 6"); // 6
// Software Types
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Software as a Service (SaaS)', category_description = 'Cloud-hosted software accessed via a web browser or API', category_type = 'software_type', category_order = 1"); // 1
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Productivity Suite', category_description = 'Bundled office and collaboration tools such as Microsoft 365 or Google Workspace', category_type = 'software_type', category_order = 2"); // 2
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Web Application', category_description = 'Application hosted on a web server and accessed through a browser', category_type = 'software_type', category_order = 3"); // 3
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Desktop Application', category_description = 'Application installed and run locally on a workstation or laptop', category_type = 'software_type', category_order = 4"); // 4
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Mobile Application', category_description = 'Application installed and run on a mobile device or tablet', category_type = 'software_type', category_order = 5"); // 5
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Security Software', category_description = 'Software providing antivirus, endpoint protection, or security monitoring', category_type = 'software_type', category_order = 6"); // 6
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'System Software', category_description = 'Low-level software managing hardware resources and system operations', category_type = 'software_type', category_order = 7"); // 7
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Operating System', category_description = 'Core software managing hardware and providing a platform for applications', category_type = 'software_type', category_order = 8"); // 8
mysqli_query($mysqli, "INSERT INTO categories SET category_name = 'Other', category_description = 'Software type does not fit any standard category', category_type = 'software_type', category_order = 9"); // 9

View File

@@ -0,0 +1,11 @@
<?php
/*
* ITFlow - Database update to version 2.4.5 (from 2.4.4)
* Included by admin/database_updates.php - do not access directly
*/
defined('FROM_DB_UPDATER') || die("Direct file access is not allowed");
// Gateway fee expense now uses the actual fee from Stripe's balance transaction
mysqli_query($mysqli, "ALTER TABLE `payment_providers` DROP `payment_provider_expense_percentage_fee`, DROP `payment_provider_expense_flat_fee`");

View File

@@ -287,12 +287,16 @@ if (isset($_GET['update_db'])) {
// Get the current version
require_once ('../includes/database_version.php');
// Perform upgrades, if required
// Perform upgrades, if required - populates $database_updates_applied and $database_updates_error
require_once ('database_updates.php');
logAudit("Database", "Update", "$session_name updated the database structure");
flashAlert("Database structure update successful");
if ($database_updates_error) {
logAudit("Database", "Update", "$session_name ran a database update that failed at $database_updates_error");
flashAlert("Database update failed at $database_updates_error - the version was not advanced past the last successful update, so it is safe to retry", "error");
} else {
logAudit("Database", "Update", "$session_name updated the database structure");
flashAlert("Database structure update successful");
}
sleep(1);

View File

@@ -3,6 +3,25 @@
* ITFlow
* This file defines the current "latest" database version
* It is used in conjunction with database_updates.php
*
* The latest version is derived from the migration files in
* admin/database_updates/ - the highest-versioned filename wins.
* Adding a migration file automatically raises the latest version.
*/
DEFINE("LATEST_DATABASE_VERSION", "2.4.5");
$database_latest_version = "0.0.0";
foreach (glob(dirname(__DIR__) . "/admin/database_updates/*.php") as $database_version_file) {
$database_file_version = basename($database_version_file, ".php");
if (preg_match('/^\d+(\.\d+)+$/', $database_file_version)
&& version_compare($database_file_version, $database_latest_version, ">")
) {
$database_latest_version = $database_file_version;
}
}
if ($database_latest_version == "0.0.0") {
exit("Error: admin/database_updates/ is missing or empty - the install may be incomplete.");
}
DEFINE("LATEST_DATABASE_VERSION", $database_latest_version);

View File

@@ -1,4 +1,192 @@
# Changelog
## 21.0.0 - 2026-07-15
This release **does not** change the pinned API version. It's still `2026-06-24.dahlia`.
We're releasing it as a major out of an abundance of caution, but it should be functionally a patch release for most users. See below.
* [#2097](https://github.com/stripe/stripe-php/pull/2097) ⚠️ Correctly type properties on `ErrorObject`
* the properties of `ErrorObject` were typed as `string` when many of them should have been `null|string`. If you (or your typechecker) were treating these as plain strings, you'll need to be more defensive in your code.
* to be clear: no runtime code has changed, we've just made the types more accurate. We didn't want to break any builds in a patch version, so this is released as a major
* [#2098](https://github.com/stripe/stripe-php/pull/2098) Replace source hash with Telemetry UUID
* [#2095](https://github.com/stripe/stripe-php/pull/2095) Remove unused Retry-After header support
## 20.3.1 - 2026-07-09
* [#2093](https://github.com/stripe/stripe-php/pull/2093) Add TStripeObject to iterator PHPDoc comments (fixes [#2091](https://github.com/stripe/stripe-php/issues/2091))
- Fixed: PHPStan no longer infers iterated Collection values as `mixed`; loop variables are now correctly typed as the collection's generic type parameter
## 20.3.0 - 2026-06-24
This release changes the pinned API version to 2026-06-24.dahlia.
* [#2088](https://github.com/stripe/stripe-php/pull/2088) Update generated code
* Add support for `release_details` on `Reserve.Hold`
* Add support for new value `tax_fund` on enum `BalanceTransaction.type`
* Change `Billing.CreditGrant.priority` to be required
* Add support for `buyer_id` on `Charge.payment_method_details.bizum`, `ConfirmationToken.payment_method_preview.bizum`, `ConfirmationToken.payment_method_preview.blik`, `PaymentAttemptRecord.payment_method_details.bizum`, `PaymentMethod.bizum`, `PaymentMethod.blik`, and `PaymentRecord.payment_method_details.bizum`
* Add support for `transaction_link_id` on `Charge.payment_method_details.card`
* Add support for new value `sui` on enums `Charge.payment_method_details.crypto.network`, `PaymentAttemptRecord.payment_method_details.crypto.network`, and `PaymentRecord.payment_method_details.crypto.network`
* Add support for new value `usdsui` on enums `Charge.payment_method_details.crypto.token_currency`, `PaymentAttemptRecord.payment_method_details.crypto.token_currency`, and `PaymentRecord.payment_method_details.crypto.token_currency`
* Add support for `fingerprint` on `Charge.payment_method_details.pix`, `ConfirmationToken.payment_method_preview.pix`, `PaymentMethod.pix`, and `SetupAttempt.payment_method_details.pix`
* Add support for `sunbit` on `Checkout.Session.payment_method_options`, `Checkout\Session.create().$params.payment_method_option`, `PaymentIntent.confirm().$params.payment_method_option`, `PaymentIntent.create().$params.payment_method_option`, `PaymentIntent.payment_method_options`, and `PaymentIntent.update().$params.payment_method_option`
* Add support for `billing_cycle_anchor_config` on `Checkout\Session.create().$params.subscription_datum`
* Add support for `wechat_pay` on `Checkout.Session.payment_method_options`
* Add support for `mastercard_compliance` on `Dispute.evidence.enhanced_evidence`, `Dispute.evidence_details.enhanced_eligibility`, and `Dispute.update().$params.evidence.enhanced_evidence`
* Add support for new value `mastercard_compliance` on enum `Dispute.enhanced_eligibility_types`
* Add support for `status_details` on `FinancialConnections.Account`
* Add support for new value `validated` on enum `Identity.VerificationSession.redaction.status`
* Add support for new value `satispay` on enums `Invoice.payment_settings.payment_method_types` and `Subscription.payment_settings.payment_method_types`
* ⚠️ Remove support for `stored_credential_usage` on `PaymentAttemptRecord.payment_method_details.card` and `PaymentRecord.payment_method_details.card`
* ⚠️ Change `PaymentAttemptRecord.payment_method_details.card.description` and `PaymentRecord.payment_method_details.card.description` to be optional
* ⚠️ Change `PaymentAttemptRecord.payment_method_details.card.iin` and `PaymentRecord.payment_method_details.card.iin` to be optional
* ⚠️ Change `PaymentAttemptRecord.payment_method_details.card.issuer` and `PaymentRecord.payment_method_details.card.issuer` to be optional
* Add support for `setup_future_usage` on `PaymentIntent.confirm().$params.payment_method_option.satispay`, `PaymentIntent.create().$params.payment_method_option.satispay`, `PaymentIntent.payment_method_options.satispay`, and `PaymentIntent.update().$params.payment_method_option.satispay`
* Change `PaymentRecord.report_refund().$params.refunded` to be optional
* Add support for `satispay` on `SetupAttempt.payment_method_details`
* Add support for `custom_fields`, `description`, and `footer` on `Subscription.create().$params.invoice_setting`, `Subscription.invoice_settings`, and `Subscription.update().$params.invoice_setting`
* Add support for `payment_method_options` and `payment_method` on `Topup.create().$params`
* Add support for `mode` on `V2.Commerce.ProductCatalogImport`
* Add support for new value `promotion` on enum `V2.Commerce.ProductCatalogImport.feed_type`
* Add support for `sunbit_payments` on `V2.Core.Account.configuration.merchant.capabilities`, `V2\Core\Account.create().$params.configuration.merchant.capability`, and `V2\Core\Account.update().$params.configuration.merchant.capability`
* Add support for `crypto_money_manager` and `money_manager` on `V2\Core\Account.update().$params.identity.attestation.terms_of_service`
* ⚠️ Remove support for `crypto_storer` and `storer` on `V2\Core\Account.update().$params.identity.attestation.terms_of_service`
* Add support for new value `sunbit_payments` on enum `EventsV2CoreAccountIncludingConfigurationMerchantCapabilityStatusUpdatedEvent.updated_capability`
* Add support for error codes `anomalous_money_movement_request`, `failed_tax_calculation`, `financial_account_balance_does_not_support_currency`, `financial_account_capability_not_enabled`, and `financial_account_capability_restricted` on `Invoice.last_finalization_error`, `PaymentIntent.last_payment_error`, `SetupAttempt.setup_error`, `SetupIntent.last_setup_error`, `StripeError`, and `Terminal.Reader.action.api_error`
## 20.2.1 - 2026-06-12
* [#2079](https://github.com/stripe/stripe-php/pull/2079) Add "source" field to user-agent header
## 20.2.0 - 2026-05-27
This release changes the pinned API version to 2026-05-27.dahlia.
* [#2072](https://github.com/stripe/stripe-php/pull/2072) Update generated code
* Add support for new resource `V2.Commerce.ProductCatalogImport`
* Add support for `create` and `retrieve` methods on resource `V2.Commerce.ProductCatalogImport`
* Add support for `bizum_payments` and `scalapay_payments` on `Account.capabilities`, `Account.create().$params.capability`, and `Account.update().$params.capability`
* Add support for `automatic_transfer_rules_by_currency` on `BalanceSettings.payments.payouts` and `BalanceSettings.update().$params.payment.payout`
* Add support for `start_of_day` on `BalanceSettings.payments.settlement_timing` and `BalanceSettings.update().$params.payment.settlement_timing`
* Add support for `description` on `Charge.create().$params.transfer_datum`, `PaymentIntent.create().$params.transfer_datum`, `PaymentIntent.transfer_data`, and `PaymentIntent.update().$params.transfer_datum`
* Add support for `bizum` on `Charge.payment_method_details`, `ConfirmationToken.create().$params.payment_method_datum`, `ConfirmationToken.payment_method_preview`, `PaymentAttemptRecord.payment_method_details`, `PaymentIntent.confirm().$params.payment_method_datum`, `PaymentIntent.confirm().$params.payment_method_option`, `PaymentIntent.create().$params.payment_method_datum`, `PaymentIntent.create().$params.payment_method_option`, `PaymentIntent.payment_method_options`, `PaymentIntent.update().$params.payment_method_datum`, `PaymentIntent.update().$params.payment_method_option`, `PaymentMethod.create().$params`, `PaymentMethodConfiguration.create().$params`, `PaymentMethodConfiguration.update().$params`, `PaymentMethodConfiguration`, `PaymentMethod`, `PaymentRecord.payment_method_details`, `SetupIntent.confirm().$params.payment_method_datum`, `SetupIntent.confirm().$params.payment_method_option`, `SetupIntent.create().$params.payment_method_datum`, `SetupIntent.create().$params.payment_method_option`, `SetupIntent.payment_method_options`, `SetupIntent.update().$params.payment_method_datum`, and `SetupIntent.update().$params.payment_method_option`
* Add support for `scalapay` on `Charge.payment_method_details`, `Checkout.Session.payment_method_options`, `Checkout\Session.create().$params.payment_method_option`, `ConfirmationToken.create().$params.payment_method_datum`, `ConfirmationToken.payment_method_preview`, `PaymentAttemptRecord.payment_method_details`, `PaymentIntent.confirm().$params.payment_method_datum`, `PaymentIntent.confirm().$params.payment_method_option`, `PaymentIntent.create().$params.payment_method_datum`, `PaymentIntent.create().$params.payment_method_option`, `PaymentIntent.payment_method_options`, `PaymentIntent.update().$params.payment_method_datum`, `PaymentIntent.update().$params.payment_method_option`, `PaymentMethod.create().$params`, `PaymentMethodConfiguration.create().$params`, `PaymentMethodConfiguration.update().$params`, `PaymentMethodConfiguration`, `PaymentMethod`, `PaymentRecord.payment_method_details`, `Refund.destination_details`, `SetupIntent.confirm().$params.payment_method_datum`, `SetupIntent.create().$params.payment_method_datum`, and `SetupIntent.update().$params.payment_method_datum`
* Add support for `mandate` on `Charge.payment_method_details.twint`, `PaymentAttemptRecord.payment_method_details.twint`, and `PaymentRecord.payment_method_details.twint`
* Change type of `Checkout\Session.create().$params.payment_method_option.twint.setup_future_usage`, `PaymentIntent.confirm().$params.payment_method_option.twint.setup_future_usage`, `PaymentIntent.create().$params.payment_method_option.twint.setup_future_usage`, and `PaymentIntent.update().$params.payment_method_option.twint.setup_future_usage` from `literal('none')` to `enum('none'|'off_session')`
* ⚠️ Change type of `Checkout.Session.payment_method_options.twint.setup_future_usage` and `PaymentIntent.payment_method_options.twint.setup_future_usage` from `literal('none')` to `enum('none'|'off_session')`
* Add support for new values `bizum` and `scalapay` on enums `ConfirmationToken.payment_method_preview.type` and `PaymentMethod.type`
* Add support for `credited_items` on `InvoiceItem.proration_details`
* Add support for `discountable` on `Invoice.create_preview().$params.schedule_detail.phase.add_invoice_item`, `Subscription.create().$params.add_invoice_item`, `Subscription.update().$params.add_invoice_item`, `SubscriptionSchedule.create().$params.phase.add_invoice_item`, `SubscriptionSchedule.phases[].add_invoice_items[]`, and `SubscriptionSchedule.update().$params.phase.add_invoice_item`
* Add support for `billing_schedules` on `Invoice.create_preview().$params.subscription_detail`, `Subscription.create().$params`, `Subscription.update().$params`, and `Subscription`
* Add support for `amount_paid_off_stripe` on `Invoice`
* Add support for new value `twint` on enums `Invoice.payment_settings.payment_method_types` and `Subscription.payment_settings.payment_method_types`
* Add support for `twint` on `Mandate.payment_method_details` and `SetupAttempt.payment_method_details`
* Add support for `metadata` on `PaymentIntent.create().$params.transfer_datum`, `PaymentIntent.transfer_data`, `PaymentIntent.update().$params.transfer_datum`, and `Subscription.pending_update`
* Add support for `payment_data` on `PaymentIntent.create().$params.transfer_datum`, `PaymentIntent.transfer_data`, and `PaymentIntent.update().$params.transfer_datum`
* Add support for new values `bizum` and `scalapay` on enums `PaymentIntent.excluded_payment_method_types` and `SetupIntent.excluded_payment_method_types`
* Add support for `blik_authorize` on `PaymentIntent.next_action` and `SetupIntent.next_action`
* Add support for `payment_method_options` on `PaymentLink.create().$params`, `PaymentLink.update().$params`, and `PaymentLink`
* Add support for new value `bizum` on enum `PaymentLink.payment_method_types`
* Add support for `active` on `PaymentMethodConfiguration.all().$params`
* Add support for `billed_until` on `SubscriptionItem`
* Add support for `discount` and `discounts` on `Subscription.pending_update`
* Add support for `verifone_m425`, `verifone_p630`, `verifone_ux700`, and `verifone_v660p` on `Terminal.Configuration`, `Terminal\Configuration.create().$params`, and `Terminal\Configuration.update().$params`
* Add support for `api_error` and `print_content` on `Terminal.Reader.action`
* Add support for new value `print_content` on enum `Terminal.Reader.action.type`
* Add support for new values `simulated_verifone_m425`, `simulated_verifone_p630`, `simulated_verifone_ux700`, `simulated_verifone_v660p`, `verifone_m425`, `verifone_p630`, `verifone_ux700`, and `verifone_v660p` on enum `Terminal.Reader.device_type`
* Add support for `customer` on `TestHelpers\TestClock.create().$params`
* Add support for `signer` on `V2.Core.Account.identity.business_details.documents.proof_of_registration`, `V2.Core.Account.identity.business_details.documents.proof_of_ultimate_beneficial_ownership`, `V2\Core\Account.create().$params.identity.business_detail.document.proof_of_registration`, `V2\Core\Account.create().$params.identity.business_detail.document.proof_of_ultimate_beneficial_ownership`, `V2\Core\Account.update().$params.identity.business_detail.document.proof_of_registration`, `V2\Core\Account.update().$params.identity.business_detail.document.proof_of_ultimate_beneficial_ownership`, `V2\Core\AccountToken.create().$params.identity.business_detail.document.proof_of_registration`, and `V2\Core\AccountToken.create().$params.identity.business_detail.document.proof_of_ultimate_beneficial_ownership`
* Add support for `azure_event_grid` on `V2.Core.EventDestination` and `V2\Core\EventDestination.create().$params`
* Add support for new value `no_azure_partner_topic_exists` on enum `V2.Core.EventDestination.status_details.disabled.reason`
* Add support for new value `azure_event_grid` on enum `V2.Core.EventDestination.type`
* Add support for new value `meter_event_value_too_many_digits` on enums `EventsV1BillingMeterErrorReportTriggeredEvent.reason.error_types[].code` and `EventsV1BillingMeterNoMeterFoundEvent.reason.error_types[].code`
* Add support for event notifications `V2CommerceProductCatalogImportsFailedEvent`, `V2CommerceProductCatalogImportsProcessingEvent`, `V2CommerceProductCatalogImportsSucceededEvent`, and `V2CommerceProductCatalogImportsSucceededWithErrorsEvent` with related object `V2.Commerce.ProductCatalogImport`
* Add support for error codes `payment_method_microdeposit_processing_error` and `siret_invalid` on `Invoice.last_finalization_error`, `PaymentIntent.last_payment_error`, `SetupAttempt.setup_error`, `SetupIntent.last_setup_error`, and `StripeError`
* [#2071](https://github.com/stripe/stripe-php/pull/2071) Emit warning when `stripe-notify` header is present in response
## 20.1.0 - 2026-04-23
This release changes the pinned API version to 2026-04-22.dahlia.
* [#2056](https://github.com/stripe/stripe-php/pull/2056) Update generated code
* Add support for `balance_report` and `payout_reconciliation_report` on `AccountSession.components` and `AccountSession.create().$params.component`
* Add support for `app_distribution` and `sunbit_payments` on `Account.capabilities`, `Account.create().$params.capability`, and `Account.update().$params.capability`
* Add support for new values `fee_credit_funding`, `inbound_transfer_reversal`, and `inbound_transfer` on enum `BalanceTransaction.type`
* Add support for `sunbit` on `Charge.payment_method_details`, `ConfirmationToken.create().$params.payment_method_datum`, `ConfirmationToken.payment_method_preview`, `PaymentAttemptRecord.payment_method_details`, `PaymentIntent.confirm().$params.payment_method_datum`, `PaymentIntent.create().$params.payment_method_datum`, `PaymentIntent.update().$params.payment_method_datum`, `PaymentMethod.create().$params`, `PaymentMethodConfiguration.create().$params`, `PaymentMethodConfiguration.update().$params`, `PaymentMethodConfiguration`, `PaymentMethod`, `PaymentRecord.payment_method_details`, `SetupIntent.confirm().$params.payment_method_datum`, `SetupIntent.create().$params.payment_method_datum`, and `SetupIntent.update().$params.payment_method_datum`
* Add support for new values `phantom_cash` and `usdt` on enums `Charge.payment_method_details.crypto.token_currency`, `PaymentAttemptRecord.payment_method_details.crypto.token_currency`, and `PaymentRecord.payment_method_details.crypto.token_currency`
* Add support for `location` and `reader` on `Charge.payment_method_details.klarna`, `PaymentAttemptRecord.payment_method_details.klarna`, and `PaymentRecord.payment_method_details.klarna`
* Add support for `mandate` on `Charge.payment_method_details.pix`, `PaymentAttemptRecord.payment_method_details.pix`, and `PaymentRecord.payment_method_details.pix`
* Add support for `managed_payments` on `Checkout.Session`, `Checkout\Session.create().$params`, `PaymentIntent`, `PaymentLink.create().$params`, `PaymentLink`, `SetupIntent`, and `Subscription`
* Add support for `mandate_options` on `Checkout.Session.payment_method_options.pix`, `Checkout\Session.create().$params.payment_method_option.pix`, `PaymentIntent.confirm().$params.payment_method_option.pix`, `PaymentIntent.create().$params.payment_method_option.pix`, `PaymentIntent.payment_method_options.pix`, and `PaymentIntent.update().$params.payment_method_option.pix`
* Change type of `Checkout\Session.create().$params.payment_method_option.pix.setup_future_usage`, `PaymentIntent.confirm().$params.payment_method_option.pix.setup_future_usage`, `PaymentIntent.create().$params.payment_method_option.pix.setup_future_usage`, and `PaymentIntent.update().$params.payment_method_option.pix.setup_future_usage` from `literal('none')` to `enum('none'|'off_session')`
* Add support for new values `fo_vat`, `gi_tin`, `it_cf`, and `py_ruc` on enums `Checkout.Session.customer_details.tax_ids[].type`, `Invoice.customer_tax_ids[].type`, `Tax.Calculation.customer_details.tax_ids[].type`, `Tax.Transaction.customer_details.tax_ids[].type`, and `TaxId.type`
* ⚠️ Change type of `Checkout.Session.payment_method_options.pix.setup_future_usage` and `PaymentIntent.payment_method_options.pix.setup_future_usage` from `literal('none')` to `enum('none'|'off_session')`
* Add support for new value `sunbit` on enums `ConfirmationToken.payment_method_preview.type` and `PaymentMethod.type`
* Add support for `pix` on `Invoice.create().$params.payment_setting.payment_method_option`, `Invoice.payment_settings.payment_method_options`, `Invoice.update().$params.payment_setting.payment_method_option`, `Mandate.payment_method_details`, `SetupAttempt.payment_method_details`, `SetupIntent.confirm().$params.payment_method_option`, `SetupIntent.create().$params.payment_method_option`, `SetupIntent.payment_method_options`, `SetupIntent.update().$params.payment_method_option`, `Subscription.create().$params.payment_setting.payment_method_option`, `Subscription.payment_settings.payment_method_options`, and `Subscription.update().$params.payment_setting.payment_method_option`
* Add support for `upi` on `Invoice.create().$params.payment_setting.payment_method_option`, `Invoice.payment_settings.payment_method_options`, `Invoice.update().$params.payment_setting.payment_method_option`, `Subscription.create().$params.payment_setting.payment_method_option`, `Subscription.payment_settings.payment_method_options`, and `Subscription.update().$params.payment_setting.payment_method_option`
* Add support for new values `pix` and `upi` on enums `Invoice.payment_settings.payment_method_types` and `Subscription.payment_settings.payment_method_types`
* Add support for `card_presence` on `Issuing.Authorization`
* Add support for `allowed_card_presences` and `blocked_card_presences` on `Issuing.Card.spending_controls`, `Issuing.Cardholder.spending_controls`, `Issuing\Card.create().$params.spending_control`, `Issuing\Card.update().$params.spending_control`, `Issuing\Cardholder.create().$params.spending_control`, and `Issuing\Cardholder.update().$params.spending_control`
* Add support for new value `fulfillment_error` on enum `Issuing.Card.cancellation_reason`
* Add support for new value `fulfillment_error` on enum `Issuing.Card.replacement_reason`
* Add support for `amount` and `currency` on `Mandate.multi_use`
* Add support for `amount_to_confirm` on `PaymentIntent.confirm().$params`
* Add support for new value `sunbit` on enums `PaymentIntent.excluded_payment_method_types` and `SetupIntent.excluded_payment_method_types`
* Add support for `klarna_display_qr_code` on `PaymentIntent.next_action`
* Add support for new value `sunbit` on enum `PaymentLink.payment_method_types`
* Add support for new values `low`, `not_assessed`, and `unknown` on enum `Radar.PaymentEvaluation.signals.fraudulent_payment.risk_level`
* Add support for new value `account` on enum `Radar.ValueList.item_type`
* Add support for `moto` on `SetupAttempt.payment_method_details.card`
* Add support for `pix_display_qr_code` on `SetupIntent.next_action`
* Add support for error codes `action_blocked` and `approval_required` on `Invoice.last_finalization_error`, `PaymentIntent.last_payment_error`, `SetupAttempt.setup_error`, `SetupIntent.last_setup_error`, and `StripeError`
* [#2052](https://github.com/stripe/stripe-php/pull/2052) Fix 2D array parameter encoding
- Fixes an issue encoding two-dimensional array request params where the SDK incorrectly flattens the array.
## 20.0.0 - 2026-03-25
This release changes the pinned API version to `2026-03-25.dahlia` and contains breaking changes (prefixed with ⚠️ below). There's also a [detailed migration guide](https://github.com/stripe/stripe-php/wiki/Migration-guide-for-v20) to simplify your upgrade process.
Please review details for the breaking changes and alternatives in the [Stripe API changelog](https://docs.stripe.com/changelog/dahlia) before upgrading.
* ⚠️ **Breaking change:** [#2038](https://github.com/stripe/stripe-php/pull/2038) Drop support for PHP < 7.2. This is also the **last major version to support PHP 7.2 and 7.3**. Please upgrade to 7.4+ before September 2026. See the [versioning policy](https://docs.stripe.com/sdks/versioning?lang=php#stripe-sdk-language-version-support-policy) for more information.
* ⚠️ **Breaking change:** [#2042](https://github.com/stripe/stripe-php/pull/2042) Preserve null values in v2 JSON request bodies
- The SDK now preserves and sends `null` when set in V2 API metadata and params, enabling you to clear metadata entries and some unsettable properties for V2 APIs.
- ⚠️ The `Util::objectsToIds()` method now has a required `$serializeNull` parameter to indicate if null values set in the object should be output in the resulting hash. This is relevant for V2 POST APIs to let callers clear emptyable values.
* [#1917](https://github.com/stripe/stripe-php/pull/1917) Avoid using func_get_args
* [#2011](https://github.com/stripe/stripe-php/pull/2011) Ensure that `previous_attributes` is always an instance of `StripeObject`
* [#2033](https://github.com/stripe/stripe-php/pull/2033) Add runtime support for V2 int64 string-encoded fields
### ⚠️ Breaking changes due to changes in the Stripe API
* [#2041](https://github.com/stripe/stripe-php/pull/2041) ⚠️ Throw an error when using the wrong webhook parsing method
* Generated changes from [#2046](https://github.com/stripe/stripe-php/pull/2046), [#2044](https://github.com/stripe/stripe-php/pull/2044), [#2025](https://github.com/stripe/stripe-php/pull/2025)
* Add support for `upi_payments` on `Account.capabilities`, `Account.create().$params.capability`, and `Account.update().$params.capability`
* Add support for `upi` on `Charge.payment_method_details`, `Checkout.Session.payment_method_options`, `Checkout\Session.create().$params.payment_method_option`, `ConfirmationToken.create().$params.payment_method_datum`, `ConfirmationToken.payment_method_preview`, `Mandate.payment_method_details`, `PaymentAttemptRecord.payment_method_details`, `PaymentIntent.confirm().$params.payment_method_datum`, `PaymentIntent.confirm().$params.payment_method_option`, `PaymentIntent.create().$params.payment_method_datum`, `PaymentIntent.create().$params.payment_method_option`, `PaymentIntent.payment_method_options`, `PaymentIntent.update().$params.payment_method_datum`, `PaymentIntent.update().$params.payment_method_option`, `PaymentMethod.create().$params`, `PaymentMethodConfiguration.create().$params`, `PaymentMethodConfiguration.update().$params`, `PaymentMethodConfiguration`, `PaymentMethod`, `PaymentRecord.payment_method_details`, `SetupAttempt.payment_method_details`, `SetupIntent.confirm().$params.payment_method_datum`, `SetupIntent.confirm().$params.payment_method_option`, `SetupIntent.create().$params.payment_method_datum`, `SetupIntent.create().$params.payment_method_option`, `SetupIntent.payment_method_options`, `SetupIntent.update().$params.payment_method_datum`, and `SetupIntent.update().$params.payment_method_option`
* Add support for new value `tempo` on enums `Charge.payment_method_details.crypto.network`, `PaymentAttemptRecord.payment_method_details.crypto.network`, and `PaymentRecord.payment_method_details.crypto.network`
* Add support for `integration_identifier` on `Checkout.Session` and `Checkout\Session.create().$params`
* Add support for `crypto` on `Checkout\Session.create().$params.payment_method_option`
* Add support for `pending_invoice_item_interval` on `Checkout\Session.create().$params.subscription_datum`
* Add support for new values `elements`, `embedded_page`, `form`, and `hosted_page` on enum `Checkout.Session.ui_mode`
* Add support for new value `marine_carbon_removal` on enum `Climate.Supplier.removal_pathway`
* Add support for new value `upi` on enums `ConfirmationToken.payment_method_preview.type` and `PaymentMethod.type`
* Add support for `metadata` on `CreditNote.create().$params.line`, `CreditNote.preview().$params.line`, `CreditNote.preview_lines().$params.line`, and `CreditNoteLineItem`
* Add support for `quantity_decimal` on `Invoice.add_lines().$params.line`, `Invoice.create_preview().$params.invoice_item`, `Invoice.update_lines().$params.line`, `InvoiceItem.create().$params`, `InvoiceItem.update().$params`, `InvoiceItem`, `InvoiceLineItem.update().$params`, and `InvoiceLineItem`
* ⚠️ Add support for `level` on `Issuing\Authorization.create().$params.risk_assessment.card_testing_risk` and `Issuing\Authorization.create().$params.risk_assessment.merchant_dispute_risk`
* ⚠️ Remove support for `risk_level` on `Issuing\Authorization.create().$params.risk_assessment.card_testing_risk` and `Issuing\Authorization.create().$params.risk_assessment.merchant_dispute_risk`
* Add support for `lifecycle_controls` on `Issuing.Card` and `Issuing\Card.create().$params`
* ⚠️ Change type of `Issuing.Token.network_data.visa.card_reference_id` from `string` to `nullable(string)`
* ⚠️ Change type of `PaymentAttemptRecord.payment_method_details.card.brand` and `PaymentRecord.payment_method_details.card.brand` from `enum` to `nullable(enum)`
* ⚠️ Change type of `PaymentAttemptRecord.payment_method_details.card.exp_month` and `PaymentRecord.payment_method_details.card.exp_month` from `longInteger` to `nullable(longInteger)`
* ⚠️ Change type of `PaymentAttemptRecord.payment_method_details.card.exp_year` and `PaymentRecord.payment_method_details.card.exp_year` from `longInteger` to `nullable(longInteger)`
* ⚠️ Change type of `PaymentAttemptRecord.payment_method_details.card.funding` and `PaymentRecord.payment_method_details.card.funding` from `enum('credit'|'debit'|'prepaid'|'unknown')` to `nullable(enum('credit'|'debit'|'prepaid'|'unknown'))`
* ⚠️ Change type of `PaymentAttemptRecord.payment_method_details.card.last4` and `PaymentRecord.payment_method_details.card.last4` from `string` to `nullable(string)`
* ⚠️ Change type of `PaymentAttemptRecord.payment_method_details.card.moto` and `PaymentRecord.payment_method_details.card.moto` from `boolean` to `nullable(boolean)`
* Add support for `cryptogram`, `electronic_commerce_indicator`, `exemption_indicator_applied`, and `exemption_indicator` on `PaymentAttemptRecord.payment_method_details.card.three_d_secure` and `PaymentRecord.payment_method_details.card.three_d_secure`
* Add support for new value `upi` on enums `PaymentIntent.excluded_payment_method_types` and `SetupIntent.excluded_payment_method_types`
* Add support for `upi_handle_redirect_or_display_qr_code` on `PaymentIntent.next_action` and `SetupIntent.next_action`
* Add support for new value `upi` on enum `PaymentLink.payment_method_types`
* Add support for `recommended_action` and `signals` on `Radar.PaymentEvaluation`
* ⚠️ Remove support for `insights` on `Radar.PaymentEvaluation`
* Add support for new value `crypto_fingerprint` on enum `Radar.ValueList.item_type`
* Add support for new value `canceled_by_retention_policy` on enum `Subscription.cancellation_details.reason`
* ⚠️ Change type of `V2.Core.EventDestination.events_from` from `enum('other_accounts'|'self')` to `string`
* Add support for error code `service_period_coupon_with_metered_tiered_item_unsupported` on `Invoice.last_finalization_error`, `PaymentIntent.last_payment_error`, `SetupAttempt.setup_error`, `SetupIntent.last_setup_error`, and `StripeError`
## 19.4.1 - 2026-03-06
* [#2024](https://github.com/stripe/stripe-php/pull/2024) Add Stripe-Request-Trigger header
* [#2022](https://github.com/stripe/stripe-php/pull/2022) Add agent information to UserAgent

View File

@@ -1 +1 @@
e65e48569f6dfad2d5f1b58018017856520c3ae6
6012b623b1c09ad54d466947da04511a042ee45a

View File

@@ -1 +1 @@
v2186
v2324

View File

@@ -5,6 +5,9 @@
[![Total Downloads](https://poser.pugx.org/stripe/stripe-php/downloads.svg)](https://packagist.org/packages/stripe/stripe-php)
[![License](https://poser.pugx.org/stripe/stripe-php/license.svg)](https://packagist.org/packages/stripe/stripe-php)
> [!TIP]
> Want to chat live with Stripe engineers? Join us on our [Discord server](https://stripe.com/go/discord/php).
The Stripe PHP library provides convenient access to the Stripe API from
applications written in the PHP language. It includes a pre-defined set of
classes for API resources that initialize themselves dynamically from API
@@ -13,9 +16,9 @@ API.
## Requirements
PHP 5.6.0 and later.
PHP 7.2.0 and later.
Note that per our [language version support policy](https://docs.stripe.com/sdks/versioning?lang=php#stripe-sdk-language-version-support-policy), support for PHP 5.6, 7.0, and 7.1 will be removed in the March 2026 major version.
Note that per our [language version support policy](https://docs.stripe.com/sdks/versioning?lang=php#stripe-sdk-language-version-support-policy), support for PHP 7.2 and 7.3 will be removed soon, so upgrade your runtime if you're able to.
Additional PHP versions will be dropped in future major versions, so upgrade to supported versions if possible.
@@ -45,9 +48,9 @@ require_once '/path/to/stripe-php/init.php';
The bindings require the following extensions in order to work properly:
- [`curl`](https://secure.php.net/manual/en/book.curl.php), although you can use your own non-cURL client if you prefer
- [`json`](https://secure.php.net/manual/en/book.json.php)
- [`mbstring`](https://secure.php.net/manual/en/book.mbstring.php) (Multibyte String)
- [`curl`](https://secure.php.net/manual/en/book.curl.php), although you can use your own non-cURL client if you prefer
- [`json`](https://secure.php.net/manual/en/book.json.php)
- [`mbstring`](https://secure.php.net/manual/en/book.mbstring.php) (Multibyte String)
If you use Composer, these dependencies should be handled automatically. If you install manually, you'll want to make sure that these extensions are available.
@@ -206,7 +209,7 @@ You can disable this behavior if you prefer:
### How to use undocumented parameters and properties
In some cases, you might encounter parameters on an API request or fields on an API response that arent available in the SDKs.
This might happen when theyre undocumented or when theyre in preview and you arent using a preview SDK.
This might happen when theyre undocumented or when theyre in preview and you arent using a preview SDK.
See [undocumented params and properties](https://docs.stripe.com/sdks/server-side?lang=php#undocumented-params-and-fields) to send those parameters or access those fields.
### Public Preview SDKs
@@ -231,7 +234,7 @@ Stripe::addBetaVersion("feature_beta", "v3");
### Private Preview SDKs
Stripe has features in the [private preview phase](https://docs.stripe.com/release-phases) that can be accessed via versions of this package that have the `-alpha.X` suffix like `12.2.0-alpha.2`. These are invite-only features. Once invited, you can install the private preview SDKs by following the same instructions as for the [public preview SDKs](https://github.com/stripe/stripe-php?tab=readme-ov-file#public-preview-sdks) above and replacing the term `beta` with `alpha`.
Stripe has features in the [private preview phase](https://docs.stripe.com/release-phases) that can be accessed via versions of this package that have the `-alpha.X` suffix like `12.2.0-alpha.2`. You can install the private preview SDKs by following the same instructions as for the [public preview SDKs](https://github.com/stripe/stripe-php?tab=readme-ov-file#public-preview-sdks) above and replacing the term `beta` with `alpha`. Note that access to specific private preview API features may require separate approval.
### Custom requests
@@ -261,6 +264,9 @@ New features and bug fixes are released on the latest major version of the Strip
## Development
> [!WARNING]
> External contributions to this repo from first-time contributors are currently on hiatus. If you'd like to see a change made to the package, please open an issue.
[Contribution guidelines for this project](CONTRIBUTING.md)
We use [just](https://github.com/casey/just) for conveniently running development tasks. You can use them directly, or copy the commands out of the `justfile`. To our help docs, run `just`.

View File

@@ -1 +1 @@
19.4.1
21.0.0

View File

@@ -15,20 +15,23 @@
}
],
"require": {
"php": ">=5.6.0",
"php": ">=7.2.0",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*"
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^9.0",
"phpunit/phpunit": "^8.0 || ^9.0",
"friendsofphp/php-cs-fixer": "3.94.0",
"phpstan/phpstan": "^1.2"
},
"autoload": {
"psr-4": {
"Stripe\\": "lib/"
}
},
"files": [
"lib/version_check.php"
]
},
"autoload-dev": {
"psr-4": {
@@ -42,12 +45,5 @@
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"config": {
"audit": {
"ignore": {
"PKSA-z3gr-8qht-p93v": "PHPUnit is only a dev dependency. Temporarily ignore PHPUnit security advisory to ensure continued support for PHP 5.6 in CI."
}
}
}
}

View File

@@ -1,5 +1,7 @@
<?php
require __DIR__ . '/lib/version_check.php';
require __DIR__ . '/lib/Util/ApiVersion.php';
// Stripe singleton
@@ -18,6 +20,7 @@ require __DIR__ . '/lib/Util/Set.php';
require __DIR__ . '/lib/Util/Util.php';
require __DIR__ . '/lib/Util/EventTypes.php';
require __DIR__ . '/lib/Util/EventNotificationTypes.php';
require __DIR__ . '/lib/Util/Int64.php';
require __DIR__ . '/lib/Util/ObjectTypes.php';
// HttpClient
@@ -36,7 +39,6 @@ require __DIR__ . '/lib/Exception/IdempotencyException.php';
require __DIR__ . '/lib/Exception/InvalidArgumentException.php';
require __DIR__ . '/lib/Exception/InvalidRequestException.php';
require __DIR__ . '/lib/Exception/PermissionException.php';
require __DIR__ . '/lib/Exception/RateLimitException.php';
require __DIR__ . '/lib/Exception/SignatureVerificationException.php';
require __DIR__ . '/lib/Exception/UnexpectedValueException.php';
require __DIR__ . '/lib/Exception/UnknownApiErrorException.php';
@@ -65,6 +67,7 @@ require __DIR__ . '/lib/ApiOperations/Update.php';
// Plumbing
require __DIR__ . '/lib/ApiResponse.php';
require __DIR__ . '/lib/RequestTelemetry.php';
require __DIR__ . '/lib/TelemetryId.php';
require __DIR__ . '/lib/StripeObject.php';
require __DIR__ . '/lib/ApiRequestor.php';
require __DIR__ . '/lib/ApiResource.php';
@@ -152,6 +155,14 @@ require __DIR__ . '/lib/Events/V1BillingMeterErrorReportTriggeredEvent.php';
require __DIR__ . '/lib/Events/V1BillingMeterErrorReportTriggeredEventNotification.php';
require __DIR__ . '/lib/Events/V1BillingMeterNoMeterFoundEvent.php';
require __DIR__ . '/lib/Events/V1BillingMeterNoMeterFoundEventNotification.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsFailedEvent.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsFailedEventNotification.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsProcessingEvent.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsProcessingEventNotification.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsSucceededEvent.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsSucceededEventNotification.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsSucceededWithErrorsEvent.php';
require __DIR__ . '/lib/Events/V2CommerceProductCatalogImportsSucceededWithErrorsEventNotification.php';
require __DIR__ . '/lib/Events/V2CoreAccountClosedEvent.php';
require __DIR__ . '/lib/Events/V2CoreAccountClosedEventNotification.php';
require __DIR__ . '/lib/Events/V2CoreAccountCreatedEvent.php';
@@ -188,6 +199,7 @@ require __DIR__ . '/lib/Events/V2CoreAccountUpdatedEvent.php';
require __DIR__ . '/lib/Events/V2CoreAccountUpdatedEventNotification.php';
require __DIR__ . '/lib/Events/V2CoreEventDestinationPingEvent.php';
require __DIR__ . '/lib/Events/V2CoreEventDestinationPingEventNotification.php';
require __DIR__ . '/lib/Exception/RateLimitException.php';
require __DIR__ . '/lib/Exception/TemporarySessionExpiredException.php';
require __DIR__ . '/lib/ExchangeRate.php';
require __DIR__ . '/lib/File.php';
@@ -396,6 +408,9 @@ require __DIR__ . '/lib/Service/V2/Billing/MeterEventAdjustmentService.php';
require __DIR__ . '/lib/Service/V2/Billing/MeterEventService.php';
require __DIR__ . '/lib/Service/V2/Billing/MeterEventSessionService.php';
require __DIR__ . '/lib/Service/V2/Billing/MeterEventStreamService.php';
require __DIR__ . '/lib/Service/V2/Commerce/CommerceServiceFactory.php';
require __DIR__ . '/lib/Service/V2/Commerce/ProductCatalog/ImportService.php';
require __DIR__ . '/lib/Service/V2/Commerce/ProductCatalog/ProductCatalogServiceFactory.php';
require __DIR__ . '/lib/Service/V2/Core/AccountLinkService.php';
require __DIR__ . '/lib/Service/V2/Core/AccountService.php';
require __DIR__ . '/lib/Service/V2/Core/AccountTokenService.php';
@@ -451,6 +466,7 @@ require __DIR__ . '/lib/Treasury/TransactionEntry.php';
require __DIR__ . '/lib/V2/Billing/MeterEvent.php';
require __DIR__ . '/lib/V2/Billing/MeterEventAdjustment.php';
require __DIR__ . '/lib/V2/Billing/MeterEventSession.php';
require __DIR__ . '/lib/V2/Commerce/ProductCatalogImport.php';
require __DIR__ . '/lib/V2/Core/Account.php';
require __DIR__ . '/lib/V2/Core/AccountLink.php';
require __DIR__ . '/lib/V2/Core/AccountPerson.php';

View File

@@ -23,7 +23,7 @@ test *args: install
# run tests in CI; can use autoload mode (or not)
[confirm("This will modify local files and is intended for use in CI; do you want to proceed?")]
ci-test autoload:
./build.php {{ autoload }}
php build.php {{ autoload }}
# ⭐ format all files
format *args: install
@@ -36,6 +36,10 @@ format-check: (format "--dry-run")
lint *args:
php -d memory_limit=512M vendor/bin/phpstan analyse lib tests {{args}}
# statically analyze code (strict)
lint-test:
phpstan analyse examples/IteratorExample.php --level=9
# for backwards compatibility; ideally removed later
[private]
alias phpstan := lint

File diff suppressed because one or more lines are too long

View File

@@ -16,9 +16,9 @@ namespace Stripe;
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property string $account The ID of the account the AccountSession was created for
* @property string $client_secret <p>The client secret of this AccountSession. Used on the client to set up secure access to the given <code>account</code>.</p><p>The client secret can be used to provide access to <code>account</code> from your frontend. It should not be stored, logged, or exposed to anyone other than the connected account. Make sure that you have TLS enabled on any page that includes the client secret.</p><p>Refer to our docs to <a href="https://docs.stripe.com/connect/get-started-connect-embedded-components">setup Connect embedded components</a> and learn about how <code>client_secret</code> should be handled.</p>
* @property (object{account_management: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool}&StripeObject)}&StripeObject), account_onboarding: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool}&StripeObject)}&StripeObject), balances: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, edit_payout_schedule: bool, external_account_collection: bool, instant_payouts: bool, standard_payouts: bool}&StripeObject)}&StripeObject), disputes_list: (object{enabled: bool, features: (object{capture_payments: bool, destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), documents: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), financial_account: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool, send_money: bool, transfer_balance: bool}&StripeObject)}&StripeObject), financial_account_transactions: (object{enabled: bool, features: (object{card_spend_dispute_management: bool}&StripeObject)}&StripeObject), instant_payouts_promotion: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool, instant_payouts: bool}&StripeObject)}&StripeObject), issuing_card: (object{enabled: bool, features: (object{card_management: bool, card_spend_dispute_management: bool, cardholder_management: bool, spend_control_management: bool}&StripeObject)}&StripeObject), issuing_cards_list: (object{enabled: bool, features: (object{card_management: bool, card_spend_dispute_management: bool, cardholder_management: bool, disable_stripe_user_authentication: bool, spend_control_management: bool}&StripeObject)}&StripeObject), notification_banner: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool}&StripeObject)}&StripeObject), payment_details: (object{enabled: bool, features: (object{capture_payments: bool, destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), payment_disputes: (object{enabled: bool, features: (object{destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), payments: (object{enabled: bool, features: (object{capture_payments: bool, destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), payout_details: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), payouts: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, edit_payout_schedule: bool, external_account_collection: bool, instant_payouts: bool, standard_payouts: bool}&StripeObject)}&StripeObject), payouts_list: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), tax_registrations: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), tax_settings: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject)}&StripeObject) $components
* @property (object{account_management: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool}&StripeObject)}&StripeObject), account_onboarding: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool}&StripeObject)}&StripeObject), balance_report: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), balances: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, edit_payout_schedule: bool, external_account_collection: bool, instant_payouts: bool, standard_payouts: bool}&StripeObject)}&StripeObject), disputes_list: (object{enabled: bool, features: (object{capture_payments: bool, destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), documents: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), financial_account: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool, send_money: bool, transfer_balance: bool}&StripeObject)}&StripeObject), financial_account_transactions: (object{enabled: bool, features: (object{card_spend_dispute_management: bool}&StripeObject)}&StripeObject), instant_payouts_promotion: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool, instant_payouts: bool}&StripeObject)}&StripeObject), issuing_card: (object{enabled: bool, features: (object{card_management: bool, card_spend_dispute_management: bool, cardholder_management: bool, spend_control_management: bool}&StripeObject)}&StripeObject), issuing_cards_list: (object{enabled: bool, features: (object{card_management: bool, card_spend_dispute_management: bool, cardholder_management: bool, disable_stripe_user_authentication: bool, spend_control_management: bool}&StripeObject)}&StripeObject), notification_banner: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, external_account_collection: bool}&StripeObject)}&StripeObject), payment_details: (object{enabled: bool, features: (object{capture_payments: bool, destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), payment_disputes: (object{enabled: bool, features: (object{destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), payments: (object{enabled: bool, features: (object{capture_payments: bool, destination_on_behalf_of_charge_management: bool, dispute_management: bool, refund_management: bool}&StripeObject)}&StripeObject), payout_details: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), payout_reconciliation_report: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), payouts: (object{enabled: bool, features: (object{disable_stripe_user_authentication: bool, edit_payout_schedule: bool, external_account_collection: bool, instant_payouts: bool, standard_payouts: bool}&StripeObject)}&StripeObject), payouts_list: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), tax_registrations: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject), tax_settings: (object{enabled: bool, features: (object{}&StripeObject)}&StripeObject)}&StripeObject) $components
* @property int $expires_at The timestamp at which this AccountSession will expire.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
*/
class AccountSession extends ApiResource
{
@@ -28,7 +28,7 @@ class AccountSession extends ApiResource
* Creates a AccountSession object that includes a single-use token that the
* platform can use on their front-end to grant client-side API access.
*
* @param null|array{account: string, components: array{account_management?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool}}, account_onboarding?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool}}, balances?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, edit_payout_schedule?: bool, external_account_collection?: bool, instant_payouts?: bool, standard_payouts?: bool}}, disputes_list?: array{enabled: bool, features?: array{capture_payments?: bool, destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, documents?: array{enabled: bool, features?: array{}}, financial_account?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool, send_money?: bool, transfer_balance?: bool}}, financial_account_transactions?: array{enabled: bool, features?: array{card_spend_dispute_management?: bool}}, instant_payouts_promotion?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool, instant_payouts?: bool}}, issuing_card?: array{enabled: bool, features?: array{card_management?: bool, card_spend_dispute_management?: bool, cardholder_management?: bool, spend_control_management?: bool}}, issuing_cards_list?: array{enabled: bool, features?: array{card_management?: bool, card_spend_dispute_management?: bool, cardholder_management?: bool, disable_stripe_user_authentication?: bool, spend_control_management?: bool}}, notification_banner?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool}}, payment_details?: array{enabled: bool, features?: array{capture_payments?: bool, destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, payment_disputes?: array{enabled: bool, features?: array{destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, payments?: array{enabled: bool, features?: array{capture_payments?: bool, destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, payout_details?: array{enabled: bool, features?: array{}}, payouts?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, edit_payout_schedule?: bool, external_account_collection?: bool, instant_payouts?: bool, standard_payouts?: bool}}, payouts_list?: array{enabled: bool, features?: array{}}, tax_registrations?: array{enabled: bool, features?: array{}}, tax_settings?: array{enabled: bool, features?: array{}}}, expand?: string[]} $params
* @param null|array{account: string, components: array{account_management?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool}}, account_onboarding?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool}}, balance_report?: array{enabled: bool, features?: array{}}, balances?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, edit_payout_schedule?: bool, external_account_collection?: bool, instant_payouts?: bool, standard_payouts?: bool}}, disputes_list?: array{enabled: bool, features?: array{capture_payments?: bool, destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, documents?: array{enabled: bool, features?: array{}}, financial_account?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool, send_money?: bool, transfer_balance?: bool}}, financial_account_transactions?: array{enabled: bool, features?: array{card_spend_dispute_management?: bool}}, instant_payouts_promotion?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool, instant_payouts?: bool}}, issuing_card?: array{enabled: bool, features?: array{card_management?: bool, card_spend_dispute_management?: bool, cardholder_management?: bool, spend_control_management?: bool}}, issuing_cards_list?: array{enabled: bool, features?: array{card_management?: bool, card_spend_dispute_management?: bool, cardholder_management?: bool, disable_stripe_user_authentication?: bool, spend_control_management?: bool}}, notification_banner?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, external_account_collection?: bool}}, payment_details?: array{enabled: bool, features?: array{capture_payments?: bool, destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, payment_disputes?: array{enabled: bool, features?: array{destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, payments?: array{enabled: bool, features?: array{capture_payments?: bool, destination_on_behalf_of_charge_management?: bool, dispute_management?: bool, refund_management?: bool}}, payout_details?: array{enabled: bool, features?: array{}}, payout_reconciliation_report?: array{enabled: bool, features?: array{}}, payouts?: array{enabled: bool, features?: array{disable_stripe_user_authentication?: bool, edit_payout_schedule?: bool, external_account_collection?: bool, instant_payouts?: bool, standard_payouts?: bool}}, payouts_list?: array{enabled: bool, features?: array{}}, tax_registrations?: array{enabled: bool, features?: array{}}, tax_settings?: array{enabled: bool, features?: array{}}}, expand?: string[]} $params
* @param null|array|string $options
*
* @return AccountSession the created resource

View File

@@ -134,6 +134,7 @@ class ApiRequestor
$headers = $headers ?: [];
list($rbody, $rcode, $rheaders, $myApiKey)
= $this->_requestRaw($method, $url, $params, $headers, $apiMode, $usage, $maxNetworkRetries);
$this->_maybeEmitStripeNotice($rheaders);
$json = $this->_interpretResponse($rbody, $rcode, $rheaders, $apiMode);
$resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
@@ -158,6 +159,7 @@ class ApiRequestor
$headers = $headers ?: [];
list($rbody, $rcode, $rheaders, $myApiKey)
= $this->_requestRawStreaming($method, $url, $params, $headers, $apiMode, $usage, $readBodyChunkCallable, $maxNetworkRetries);
$this->_maybeEmitStripeNotice($rheaders);
if ($rcode >= 300) {
$this->_interpretResponse($rbody, $rcode, $rheaders, $apiMode);
}
@@ -270,6 +272,16 @@ class ApiRequestor
return Exception\IdempotencyException::factory($msg, $rcode, $rbody, $resp, $rheaders, $code);
// switchCases: The beginning of the section generated from our OpenAPI spec
case 'rate_limit':
return Exception\RateLimitException::factory(
$msg,
$rcode,
$rbody,
$resp,
$rheaders,
$code
);
case 'temporary_session_expired':
return Exception\TemporarySessionExpiredException::factory(
$msg,
@@ -385,6 +397,7 @@ class ApiRequestor
['CODEX_CI', 'codex_cli'],
['CURSOR_AGENT', 'cursor'],
['GEMINI_CLI', 'gemini_cli'],
['OPENCLAW_SHELL', 'openclaw'],
['OPENCODE', 'open_code'],
// aiAgents: The end of the section generated from our OpenAPI spec
];
@@ -419,18 +432,26 @@ class ApiRequestor
$uaString = "Stripe/{$apiMode} PhpBindings/" . Stripe::VERSION;
$langVersion = \PHP_VERSION;
$uname_disabled = self::_isDisabled(\ini_get('disable_functions'), 'php_uname');
$uname = $uname_disabled ? '(disabled)' : \php_uname();
// Fallback to global configuration to maintain backwards compatibility.
$appInfo = $appInfo ?: Stripe::getAppInfo();
$ua = [
'bindings_version' => Stripe::VERSION,
'lang' => 'php',
'lang_version' => $langVersion,
'publisher' => 'stripe',
'uname' => $uname,
];
if (Stripe::getEnableTelemetry()) {
$telemetryId = TelemetryId::get();
if (null !== $telemetryId) {
$ua['telemetry_id'] = $telemetryId;
}
$uname_disabled = self::_isDisabled(\ini_get('disable_functions'), 'php_uname');
$ua['platform'] = $uname_disabled
? '(disabled)'
// only get general platform information, e.g. `Darwin 25.3.0 arm64`
: \php_uname('s') . ' ' . \php_uname('r') . ' ' . \php_uname('m');
}
if ($clientInfo) {
$ua = \array_merge($clientInfo, $ua);
}
@@ -543,6 +564,13 @@ class ApiRequestor
return [$absUrl, $rawHeaders, $params, $hasFile, $myApiKey];
}
private function _maybeEmitStripeNotice($rheaders)
{
if (isset($rheaders['stripe-notice']) && \is_string($rheaders['stripe-notice'])) {
\trigger_error($rheaders['stripe-notice'], \E_USER_WARNING);
}
}
/**
* @param 'delete'|'get'|'post' $method
* @param string $url

View File

@@ -9,7 +9,7 @@ namespace Stripe;
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $domain_name
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
*/
class ApplePayDomain extends ApiResource
{

View File

@@ -16,7 +16,7 @@ namespace Stripe;
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property null|(object{charge?: string, payout?: string, type: string}&StripeObject) $fee_source Polymorphic source of the application fee. Includes the ID of the object the application fee was created from.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|Charge|string $originating_transaction ID of the corresponding charge on the platform account, if this fee was the result of a charge using the <code>destination</code> parameter.
* @property bool $refunded Whether the fee has been fully refunded. If the fee is only partially refunded, this attribute will still be false.
* @property Collection<ApplicationFeeRefund> $refunds A list of refunds that have been applied to the fee.

View File

@@ -20,7 +20,7 @@ namespace Stripe\Apps;
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property null|bool $deleted If true, indicates that this secret has been deleted
* @property null|int $expires_at The Unix timestamp for the expiry time of the secret, after which the secret deletes.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property string $name A name for the secret that's unique within the scope.
* @property null|string $payload The plaintext secret value to be stored.
* @property (object{type: string, user?: string}&\Stripe\StripeObject) $scope

View File

@@ -17,7 +17,7 @@ namespace Stripe;
* @property null|(object{amount: int, currency: string, source_types?: (object{bank_account?: int, card?: int, fpx?: int}&StripeObject)}&StripeObject)[] $connect_reserved Funds held due to negative balances on connected accounts where <a href="/api/accounts/object#account_object-controller-requirement_collection">account.controller.requirement_collection</a> is <code>application</code>, which includes Custom accounts. You can find the connect reserve balance for each currency and payment type in the <code>source_types</code> property.
* @property null|(object{amount: int, currency: string, net_available?: (object{amount: int, destination: string, source_types?: (object{bank_account?: int, card?: int, fpx?: int}&StripeObject)}&StripeObject)[], source_types?: (object{bank_account?: int, card?: int, fpx?: int}&StripeObject)}&StripeObject)[] $instant_available Funds that you can pay out using Instant Payouts.
* @property null|(object{available: (object{amount: int, currency: string, source_types?: (object{bank_account?: int, card?: int, fpx?: int}&StripeObject)}&StripeObject)[]}&StripeObject) $issuing
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property (object{amount: int, currency: string, source_types?: (object{bank_account?: int, card?: int, fpx?: int}&StripeObject)}&StripeObject)[] $pending Funds that aren't available in the balance yet. You can find the pending balance for each currency and each payment type in the <code>source_types</code> property.
* @property null|(object{available: (object{amount: int, currency: string, source_types?: (object{bank_account?: int, card?: int, fpx?: int}&StripeObject)}&StripeObject)[], pending: (object{amount: int, currency: string, source_types?: (object{bank_account?: int, card?: int, fpx?: int}&StripeObject)}&StripeObject)[]}&StripeObject) $refund_and_dispute_prefunding
*/

View File

@@ -8,7 +8,7 @@ namespace Stripe;
* Options for customizing account balances and payout settings for a Stripe platforms connected accounts.
*
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property (object{debit_negative_balances: null|bool, payouts: null|(object{minimum_balance_by_currency: null|StripeObject, schedule: null|(object{interval: null|string, monthly_payout_days?: int[], weekly_payout_days?: string[]}&StripeObject), statement_descriptor: null|string, status: string}&StripeObject), settlement_timing: (object{delay_days: int, delay_days_override?: int}&StripeObject)}&StripeObject) $payments
* @property (object{debit_negative_balances: null|bool, payouts: null|(object{automatic_transfer_rules_by_currency: null|StripeObject, minimum_balance_by_currency: null|StripeObject, schedule: null|(object{interval: null|string, monthly_payout_days?: int[], weekly_payout_days?: string[]}&StripeObject), statement_descriptor: null|string, status: string}&StripeObject), settlement_timing: (object{delay_days: int, delay_days_override?: int, start_of_day: null|(object{hour: int, minutes: int, timezone: string}&StripeObject)}&StripeObject)}&StripeObject) $payments
*/
class BalanceSettings extends SingletonApiResource
{
@@ -40,7 +40,7 @@ class BalanceSettings extends SingletonApiResource
* href="/connect/authentication">Making API calls for connected accounts</a>.
*
* @param string $id the ID of the resource to update
* @param null|array{expand?: string[], payments?: array{debit_negative_balances?: bool, payouts?: array{minimum_balance_by_currency?: null|array<string, null|int>, schedule?: array{interval?: string, monthly_payout_days?: int[], weekly_payout_days?: string[]}, statement_descriptor?: string}, settlement_timing?: array{delay_days_override?: null|int}}} $params
* @param null|array{expand?: string[], payments?: array{debit_negative_balances?: bool, payouts?: array{automatic_transfer_rules_by_currency?: null|array<string, null|array{payout_method: string, transfer_up_to_amount?: int, type: string}[]>, minimum_balance_by_currency?: null|array<string, null|int>, schedule?: array{interval?: string, monthly_payout_days?: int[], weekly_payout_days?: string[]}, statement_descriptor?: string}, settlement_timing?: array{delay_days_override?: null|int, start_of_day?: null|array{hour?: int, minutes?: int, timezone?: string}}}} $params
* @param null|array|string $opts
*
* @return BalanceSettings the updated resource

View File

@@ -25,7 +25,7 @@ namespace Stripe;
* @property string $reporting_category Learn more about how <a href="https://stripe.com/docs/reports/reporting-categories">reporting categories</a> can help you understand balance transactions from an accounting perspective.
* @property null|ApplicationFee|ApplicationFeeRefund|Charge|ConnectCollectionTransfer|CustomerCashBalanceTransaction|Dispute|Issuing\Authorization|Issuing\Dispute|Issuing\Transaction|Payout|Refund|ReserveTransaction|string|TaxDeductedAtSource|Topup|Transfer|TransferReversal $source This transaction relates to the Stripe object.
* @property string $status The transaction's net funds status in the Stripe balance, which are either <code>available</code> or <code>pending</code>.
* @property string $type Transaction type: <code>adjustment</code>, <code>advance</code>, <code>advance_funding</code>, <code>anticipation_repayment</code>, <code>application_fee</code>, <code>application_fee_refund</code>, <code>charge</code>, <code>climate_order_purchase</code>, <code>climate_order_refund</code>, <code>connect_collection_transfer</code>, <code>contribution</code>, <code>issuing_authorization_hold</code>, <code>issuing_authorization_release</code>, <code>issuing_dispute</code>, <code>issuing_transaction</code>, <code>obligation_outbound</code>, <code>obligation_reversal_inbound</code>, <code>payment</code>, <code>payment_failure_refund</code>, <code>payment_network_reserve_hold</code>, <code>payment_network_reserve_release</code>, <code>payment_refund</code>, <code>payment_reversal</code>, <code>payment_unreconciled</code>, <code>payout</code>, <code>payout_cancel</code>, <code>payout_failure</code>, <code>payout_minimum_balance_hold</code>, <code>payout_minimum_balance_release</code>, <code>refund</code>, <code>refund_failure</code>, <code>reserve_transaction</code>, <code>reserved_funds</code>, <code>reserve_hold</code>, <code>reserve_release</code>, <code>stripe_fee</code>, <code>stripe_fx_fee</code>, <code>stripe_balance_payment_debit</code>, <code>stripe_balance_payment_debit_reversal</code>, <code>tax_fee</code>, <code>topup</code>, <code>topup_reversal</code>, <code>transfer</code>, <code>transfer_cancel</code>, <code>transfer_failure</code>, or <code>transfer_refund</code>. Learn more about <a href="https://stripe.com/docs/reports/balance-transaction-types">balance transaction types and what they represent</a>. To classify transactions for accounting purposes, consider <code>reporting_category</code> instead.
* @property string $type Transaction type: <code>tax_fund</code>, <code>adjustment</code>, <code>advance</code>, <code>advance_funding</code>, <code>anticipation_repayment</code>, <code>application_fee</code>, <code>application_fee_refund</code>, <code>charge</code>, <code>climate_order_purchase</code>, <code>climate_order_refund</code>, <code>connect_collection_transfer</code>, <code>contribution</code>, <code>inbound_transfer</code>, <code>inbound_transfer_reversal</code>, <code>issuing_authorization_hold</code>, <code>issuing_authorization_release</code>, <code>issuing_dispute</code>, <code>issuing_transaction</code>, <code>obligation_outbound</code>, <code>obligation_reversal_inbound</code>, <code>payment</code>, <code>payment_failure_refund</code>, <code>payment_network_reserve_hold</code>, <code>payment_network_reserve_release</code>, <code>payment_refund</code>, <code>payment_reversal</code>, <code>payment_unreconciled</code>, <code>payout</code>, <code>payout_cancel</code>, <code>payout_failure</code>, <code>payout_minimum_balance_hold</code>, <code>payout_minimum_balance_release</code>, <code>refund</code>, <code>refund_failure</code>, <code>reserve_transaction</code>, <code>reserved_funds</code>, <code>reserve_hold</code>, <code>reserve_release</code>, <code>stripe_fee</code>, <code>stripe_fx_fee</code>, <code>stripe_balance_payment_debit</code>, <code>stripe_balance_payment_debit_reversal</code>, <code>tax_fee</code>, <code>topup</code>, <code>topup_reversal</code>, <code>transfer</code>, <code>transfer_cancel</code>, <code>transfer_failure</code>, <code>transfer_refund</code>, or <code>fee_credit_funding</code>. Learn more about <a href="https://stripe.com/docs/reports/balance-transaction-types">balance transaction types and what they represent</a>. To classify transactions for accounting purposes, consider <code>reporting_category</code> instead.
*/
class BalanceTransaction extends ApiResource
{
@@ -47,6 +47,9 @@ class BalanceTransaction extends ApiResource
const TYPE_CLIMATE_ORDER_REFUND = 'climate_order_refund';
const TYPE_CONNECT_COLLECTION_TRANSFER = 'connect_collection_transfer';
const TYPE_CONTRIBUTION = 'contribution';
const TYPE_FEE_CREDIT_FUNDING = 'fee_credit_funding';
const TYPE_INBOUND_TRANSFER = 'inbound_transfer';
const TYPE_INBOUND_TRANSFER_REVERSAL = 'inbound_transfer_reversal';
const TYPE_ISSUING_AUTHORIZATION_HOLD = 'issuing_authorization_hold';
const TYPE_ISSUING_AUTHORIZATION_RELEASE = 'issuing_authorization_release';
const TYPE_ISSUING_DISPUTE = 'issuing_dispute';
@@ -76,6 +79,7 @@ class BalanceTransaction extends ApiResource
const TYPE_STRIPE_FEE = 'stripe_fee';
const TYPE_STRIPE_FX_FEE = 'stripe_fx_fee';
const TYPE_TAX_FEE = 'tax_fee';
const TYPE_TAX_FUND = 'tax_fund';
const TYPE_TOPUP = 'topup';
const TYPE_TOPUP_REVERSAL = 'topup_reversal';
const TYPE_TRANSFER = 'transfer';
@@ -85,11 +89,11 @@ class BalanceTransaction extends ApiResource
/**
* Returns a list of transactions that have contributed to the Stripe account
* balance (e.g., charges, transfers, and so forth). The transactions are returned
* in sorted order, with the most recent transactions appearing first.
* balance (for example, charges, transfers, and so on). The transactions return in
* sorted order, with the most recent transactions appearing first.
*
* Note that this endpoint was previously called “Balance history” and used the
* path <code>/v1/balance/history</code>.
* The previous name of this endpoint was “Balance history,” and it used the path
* <code>/v1/balance/history</code>.
*
* @param null|array{created?: array|int, currency?: string, ending_before?: string, expand?: string[], limit?: int, payout?: string, source?: string, starting_after?: string, type?: string} $params
* @param null|array|string $opts

View File

@@ -10,7 +10,7 @@ namespace Stripe\Billing;
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property string $alert_type Defines the type of the alert.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|string $status Status of the alert. This can be active, inactive or archived.
* @property string $title Title of the alert.
* @property null|(object{filters: null|((object{customer: null|string|\Stripe\Customer, type: string}&\Stripe\StripeObject))[], gte: int, meter: Meter|string, recurrence: string}&\Stripe\StripeObject) $usage_threshold Encapsulates configuration of the alert to monitor usage on a specific <a href="https://docs.stripe.com/api/billing/meter">Billing Meter</a>.

View File

@@ -9,7 +9,7 @@ namespace Stripe\Billing;
* @property Alert $alert A billing alert is a resource that notifies you when a certain usage threshold on a meter is crossed. For example, you might create a billing alert to notify you when a certain user made 100 API requests.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $customer ID of customer for which the alert triggered
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property int $value The value triggering the alert
*/
class AlertTriggered extends \Stripe\ApiResource

View File

@@ -11,7 +11,7 @@ namespace Stripe\Billing;
* @property ((object{available_balance: (object{monetary: null|(object{currency: string, value: int}&\Stripe\StripeObject), type: string}&\Stripe\StripeObject), ledger_balance: (object{monetary: null|(object{currency: string, value: int}&\Stripe\StripeObject), type: string}&\Stripe\StripeObject)}&\Stripe\StripeObject))[] $balances The billing credit balances. One entry per credit grant currency. If a customer only has credit grants in a single currency, then this will have a single balance entry.
* @property string|\Stripe\Customer $customer The customer the balance is for.
* @property null|string $customer_account The account the balance is for.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
*/
class CreditBalanceSummary extends \Stripe\SingletonApiResource
{

View File

@@ -14,7 +14,7 @@ namespace Stripe\Billing;
* @property CreditGrant|string $credit_grant The credit grant associated with this credit balance transaction.
* @property null|(object{amount: (object{monetary: null|(object{currency: string, value: int}&\Stripe\StripeObject), type: string}&\Stripe\StripeObject), credits_applied: null|(object{invoice: string|\Stripe\Invoice, invoice_line_item: string}&\Stripe\StripeObject), type: string}&\Stripe\StripeObject) $debit Debit details for this credit balance transaction. Only present if type is <code>debit</code>.
* @property int $effective_at The effective time of this credit balance transaction.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|string|\Stripe\TestHelpers\TestClock $test_clock ID of the test clock this credit balance transaction belongs to.
* @property null|string $type The type of credit balance transaction (credit or debit).
*/

View File

@@ -19,7 +19,7 @@ namespace Stripe\Billing;
* @property null|string $customer_account ID of the account representing the customer receiving the billing credits
* @property null|int $effective_at The time when the billing credits become effective-when they're eligible for use.
* @property null|int $expires_at The time when the billing credits expire. If not present, the billing credits don't expire.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property \Stripe\StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|string $name A descriptive name shown in dashboard.
* @property null|int $priority The priority for applying this credit grant. The highest priority is 0 and the lowest is 100.

View File

@@ -17,7 +17,7 @@ namespace Stripe\Billing;
* @property string $display_name The meter's name.
* @property string $event_name The name of the meter event to record usage for. Corresponds with the <code>event_name</code> field on meter events.
* @property null|string $event_time_window The time window which meter events have been pre-aggregated for, if any.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property string $status The meter's status.
* @property (object{deactivated_at: null|int}&\Stripe\StripeObject) $status_transitions
* @property int $updated Time at which the object was last updated. Measured in seconds since the Unix epoch.

View File

@@ -11,7 +11,7 @@ namespace Stripe\Billing;
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $event_name The name of the meter event. Corresponds with the <code>event_name</code> field on a meter.
* @property string $identifier A unique identifier for the event.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property \Stripe\StripeObject $payload The payload of the event. This contains the fields corresponding to a meter's <code>customer_mapping.event_payload_key</code> (default is <code>stripe_customer_id</code>) and <code>value_settings.event_payload_key</code> (default is <code>value</code>). Read more about the <a href="https://docs.stripe.com/billing/subscriptions/usage-based/meters/configure#meter-configuration-attributes">payload</a>.
* @property int $timestamp The timestamp passed in when creating the event. Measured in seconds since the Unix epoch.
*/

View File

@@ -10,7 +10,7 @@ namespace Stripe\Billing;
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|(object{identifier: null|string}&\Stripe\StripeObject) $cancel Specifies which event to cancel.
* @property string $event_name The name of the meter event. Corresponds with the <code>event_name</code> field on a meter.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property string $status The meter event adjustment's status.
* @property string $type Specifies whether to cancel a single event or a range of events for a time period. Time period cancellation is not supported yet.
*/

View File

@@ -14,7 +14,7 @@ namespace Stripe\Billing;
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property float $aggregated_value Aggregated value of all the events within <code>start_time</code> (inclusive) and <code>end_time</code> (inclusive). The aggregation strategy is defined on meter via <code>default_aggregation</code>.
* @property int $end_time End timestamp for this event summary (exclusive). Must be aligned with minute boundaries.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property string $meter The meter associated with this event summary.
* @property int $start_time Start timestamp for this event summary (inclusive). Must be aligned with minute boundaries.
*/

View File

@@ -16,7 +16,7 @@ namespace Stripe\BillingPortal;
* @property null|string $default_return_url The default URL to redirect customers to when they click on the portal's link to return to your website. This can be <a href="https://docs.stripe.com/api/customer_portal/sessions/create#create_portal_session-return_url">overriden</a> when creating the session.
* @property (object{customer_update: (object{allowed_updates: string[], enabled: bool}&\Stripe\StripeObject), invoice_history: (object{enabled: bool}&\Stripe\StripeObject), payment_method_update: (object{enabled: bool, payment_method_configuration: null|string}&\Stripe\StripeObject), subscription_cancel: (object{cancellation_reason: (object{enabled: bool, options: string[]}&\Stripe\StripeObject), enabled: bool, mode: string, proration_behavior: string}&\Stripe\StripeObject), subscription_update: (object{billing_cycle_anchor: null|string, default_allowed_updates: string[], enabled: bool, products?: null|((object{adjustable_quantity: (object{enabled: bool, maximum: null|int, minimum: int}&\Stripe\StripeObject), prices: string[], product: string}&\Stripe\StripeObject))[], proration_behavior: string, schedule_at_period_end: (object{conditions: (object{type: string}&\Stripe\StripeObject)[]}&\Stripe\StripeObject), trial_update_behavior: string}&\Stripe\StripeObject)}&\Stripe\StripeObject) $features
* @property bool $is_default Whether the configuration is the default. If <code>true</code>, this configuration can be managed in the Dashboard and portal sessions will use this configuration unless it is overriden when creating the session.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property (object{enabled: bool, url: null|string}&\Stripe\StripeObject) $login_page
* @property null|\Stripe\StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|string $name The name of the configuration.

View File

@@ -27,7 +27,7 @@ namespace Stripe\BillingPortal;
* @property string $customer The ID of the customer for this session.
* @property null|string $customer_account The ID of the account for this session.
* @property null|(object{after_completion: (object{hosted_confirmation: null|(object{custom_message: null|string}&\Stripe\StripeObject), redirect: null|(object{return_url: string}&\Stripe\StripeObject), type: string}&\Stripe\StripeObject), subscription_cancel: null|(object{retention: null|(object{coupon_offer: null|(object{coupon: string}&\Stripe\StripeObject), type: string}&\Stripe\StripeObject), subscription: string}&\Stripe\StripeObject), subscription_update: null|(object{subscription: string}&\Stripe\StripeObject), subscription_update_confirm: null|(object{discounts: null|((object{coupon: null|string, promotion_code: null|string}&\Stripe\StripeObject))[], items: ((object{id: null|string, price: null|string, quantity?: int}&\Stripe\StripeObject))[], subscription: string}&\Stripe\StripeObject), type: string}&\Stripe\StripeObject) $flow Information about a specific flow for the customer to go through. See the <a href="https://docs.stripe.com/customer-management/portal-deep-links">docs</a> to learn more about using customer portal deep links and flows.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|string $locale The IETF language tag of the locale Customer Portal is displayed in. If blank or auto, the customers <code>preferred_locales</code> or browsers locale is used.
* @property null|string $on_behalf_of The account for which the session was created on behalf of. When specified, only subscriptions and invoices with this <code>on_behalf_of</code> account appear in the portal. For more information, see the <a href="https://docs.stripe.com/connect/separate-charges-and-transfers#settlement-merchant">docs</a>. Use the <a href="https://docs.stripe.com/api/accounts/object#account_object-settings-branding">Accounts API</a> to modify the <code>on_behalf_of</code> account's branding settings, which the portal displays.
* @property null|string $return_url The URL to redirect customers to when they click on the portal's link to return to your website.

View File

@@ -11,7 +11,7 @@ namespace Stripe;
* @property null|StripeObject $available A hash of all cash balances available to this customer. You cannot delete a customer with any cash balances, even if the balance is 0. Amounts are represented in the <a href="https://docs.stripe.com/currencies#zero-decimal">smallest currency unit</a>.
* @property string $customer The ID of the customer whose cash balance this object represents.
* @property null|string $customer_account The ID of an Account representing a customer whose cash balance this object represents.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property (object{reconciliation_mode: string, using_merchant_default: bool}&StripeObject) $settings
*/
class CashBalance extends ApiResource

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -22,6 +22,7 @@ class Supplier extends \Stripe\ApiResource
const REMOVAL_PATHWAY_BIOMASS_CARBON_REMOVAL_AND_STORAGE = 'biomass_carbon_removal_and_storage';
const REMOVAL_PATHWAY_DIRECT_AIR_CAPTURE = 'direct_air_capture';
const REMOVAL_PATHWAY_ENHANCED_WEATHERING = 'enhanced_weathering';
const REMOVAL_PATHWAY_MARINE_CARBON_REMOVAL = 'marine_carbon_removal';
/**
* Lists all available Climate supplier objects.

View File

@@ -147,7 +147,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
}
/**
* @return \ArrayIterator an iterator that can be used to iterate
* @return \ArrayIterator<int, TStripeObject> an iterator that can be used to iterate
* across objects in the current page
*/
#[\ReturnTypeWillChange]
@@ -157,7 +157,7 @@ class Collection extends StripeObject implements \Countable, \IteratorAggregate
}
/**
* @return \ArrayIterator an iterator that can be used to iterate
* @return \ArrayIterator<int, TStripeObject> an iterator that can be used to iterate
* backwards across objects in the current page
*/
public function getReverseIterator()

File diff suppressed because one or more lines are too long

View File

@@ -10,7 +10,7 @@ namespace Stripe;
* @property int $amount Amount transferred, in cents (or local equivalent).
* @property string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property Account|string $destination ID of the account that funds are being collected for.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
*/
class ConnectCollectionTransfer extends ApiResource
{

View File

@@ -7,7 +7,7 @@ namespace Stripe;
/**
* A coupon contains information about a percent-off or amount-off discount you
* might want to apply to a customer. Coupons may be applied to <a href="https://api.stripe.com#subscriptions">subscriptions</a>, <a href="https://api.stripe.com#invoices">invoices</a>,
* <a href="https://docs.stripe.com/api/checkout/sessions">checkout sessions</a>, <a href="https://api.stripe.com#quotes">quotes</a>, and more. Coupons do not work with conventional one-off <a href="https://api.stripe.com#create_charge">charges</a> or <a href="https://docs.stripe.com/api/payment_intents">payment intents</a>.
* <a href="https://docs.stripe.com/api/checkout/sessions">checkout sessions</a>, <a href="https://api.stripe.com#quotes">quotes</a>, and more. Coupons do not work with conventional one-off <a href="/api/charges/create">charges</a> or <a href="https://docs.stripe.com/api/payment_intents">payment intents</a>.
*
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
@@ -18,7 +18,7 @@ namespace Stripe;
* @property null|StripeObject $currency_options Coupons defined in each available currency option. Each key must be a three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a> and a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property string $duration One of <code>forever</code>, <code>once</code>, or <code>repeating</code>. Describes how long a customer who applies this coupon will get the discount.
* @property null|int $duration_in_months If <code>duration</code> is <code>repeating</code>, the number of months the coupon applies. Null if coupon <code>duration</code> is <code>forever</code> or <code>once</code>.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|int $max_redemptions Maximum number of times this coupon can be redeemed, in total, across all customers, before it is no longer valid.
* @property null|StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|string $name Name of the coupon displayed to customers on for instance invoices or receipts.

View File

@@ -23,7 +23,7 @@ namespace Stripe;
* @property null|int $effective_at The date when this credit note is in effect. Same as <code>created</code> unless overwritten. When defined, this value replaces the system-generated 'Date of issue' printed on the credit note PDF.
* @property Invoice|string $invoice ID of the invoice.
* @property Collection<CreditNoteLineItem> $lines Line items that make up the credit note
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|string $memo Customer-facing text that appears on the credit note PDF.
* @property null|StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property string $number A unique number that identifies this particular credit note and appears on the PDF of the credit note and its associated invoice.
@@ -86,7 +86,13 @@ class CreditNote extends ApiResource
* <code>post_payment_credit_notes_amount</code>, or both, depending on the
* invoices <code>amount_remaining</code> at the time of credit note creation.
*
* @param null|array{amount?: int, credit_amount?: int, effective_at?: int, email_type?: string, expand?: string[], invoice: string, lines?: (array{amount?: int, description?: string, invoice_line_item?: string, quantity?: int, tax_amounts?: null|array{amount: int, tax_rate: string, taxable_amount: int}[], tax_rates?: null|string[], type: string, unit_amount?: int, unit_amount_decimal?: string})[], memo?: string, metadata?: array<string, string>, out_of_band_amount?: int, reason?: string, refund_amount?: int, refunds?: array{amount_refunded?: int, payment_record_refund?: array{payment_record: string, refund_group: string}, refund?: string, type?: string}[], shipping_cost?: array{shipping_rate?: string}} $params
* For invoices that also have refunds created through the <a
* href="/docs/api/refunds">Refund API</a>, the credit note API subtracts those
* refund amounts from the maximum creditable amount. This prevents the combined
* credit notes and refunds from exceeding the invoice amount. If you use both,
* ensure the combined total does not exceed the invoices paid amount.
*
* @param null|array{amount?: int, credit_amount?: int, effective_at?: int, email_type?: string, expand?: string[], invoice: string, lines?: (array{amount?: int, description?: string, invoice_line_item?: string, metadata?: array<string, string>, quantity?: int, tax_amounts?: null|array{amount: int, tax_rate: string, taxable_amount: int}[], tax_rates?: null|string[], type: string, unit_amount?: int, unit_amount_decimal?: string})[], memo?: string, metadata?: array<string, string>, out_of_band_amount?: int, reason?: string, refund_amount?: int, refunds?: array{amount_refunded?: int, payment_record_refund?: array{payment_record: string, refund_group: string}, refund?: string, type?: string}[], shipping_cost?: array{shipping_rate?: string}} $params
* @param null|array|string $options
*
* @return CreditNote the created resource

View File

@@ -14,7 +14,8 @@ namespace Stripe;
* @property int $discount_amount The integer amount in cents (or local equivalent) representing the discount being credited for this line item.
* @property ((object{amount: int, discount: Discount|string}&StripeObject))[] $discount_amounts The amount of discount calculated per discount for this line item
* @property null|string $invoice_line_item ID of the invoice line item being credited
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property ((object{amount: int, credit_balance_transaction?: Billing\CreditBalanceTransaction|string, discount?: Discount|string, type: string}&StripeObject))[] $pretax_credit_amounts The pretax credit amounts (ex: discount, credit grants, etc) for this line item.
* @property null|int $quantity The number of units of product being credited.
* @property TaxRate[] $tax_rates The tax rates which apply to the line item.

View File

@@ -26,7 +26,7 @@ namespace Stripe;
* @property null|StripeObject $invoice_credit_balance The current multi-currency balances, if any, that's stored on the customer. If positive in a currency, the customer has a credit to apply to their next invoice denominated in that currency. If negative, the customer has an amount owed that's added to their next invoice denominated in that currency. These balances don't apply to unpaid invoices. They solely track amounts that Stripe hasn't successfully applied to any invoice. Stripe only applies a balance in a specific currency to an invoice after that invoice (which is in the same currency) finalizes.
* @property null|string $invoice_prefix The prefix for the customer used to generate unique invoice numbers.
* @property null|(object{custom_fields: null|(object{name: string, value: string}&StripeObject)[], default_payment_method: null|PaymentMethod|string, footer: null|string, rendering_options: null|(object{amount_tax_display: null|string, template: null|string}&StripeObject)}&StripeObject) $invoice_settings
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|string $name The customer's full name or business name.
* @property null|int $next_invoice_sequence The suffix of the customer's next invoice number (for example, 0001). When the account uses account level sequencing, this parameter is ignored in API requests and the field omitted in API responses.

View File

@@ -24,7 +24,7 @@ namespace Stripe;
* @property null|string $description An arbitrary string attached to the object. Often useful for displaying to users.
* @property int $ending_balance The customer's <code>balance</code> after the transaction was applied. A negative value decreases the amount due on the customer's next invoice. A positive value increases the amount due on the customer's next invoice.
* @property null|Invoice|string $invoice The ID of the invoice (if any) related to the transaction.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property string $type Transaction type: <code>adjustment</code>, <code>applied_to_invoice</code>, <code>credit_note</code>, <code>initial</code>, <code>invoice_overpaid</code>, <code>invoice_too_large</code>, <code>invoice_too_small</code>, <code>unspent_receiver_credit</code>, <code>unapplied_from_invoice</code>, <code>checkout_session_subscription_payment</code>, or <code>checkout_session_subscription_payment_canceled</code>. See the <a href="https://docs.stripe.com/billing/customer/balance#types">Customer Balance page</a> to learn more about transaction types.
*/

View File

@@ -20,7 +20,7 @@ namespace Stripe;
* @property null|string $customer_account The ID of an Account representing a customer whose available cash balance changed as a result of this transaction.
* @property int $ending_balance The total available cash balance for the specified currency after this transaction was applied. Represented in the <a href="https://docs.stripe.com/currencies#zero-decimal">smallest currency unit</a>.
* @property null|(object{bank_transfer: (object{eu_bank_transfer?: (object{bic: null|string, iban_last4: null|string, sender_name: null|string}&StripeObject), gb_bank_transfer?: (object{account_number_last4: null|string, sender_name: null|string, sort_code: null|string}&StripeObject), jp_bank_transfer?: (object{sender_bank: null|string, sender_branch: null|string, sender_name: null|string}&StripeObject), reference: null|string, type: string, us_bank_transfer?: (object{network?: string, sender_name: null|string}&StripeObject)}&StripeObject)}&StripeObject) $funded
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property int $net_amount The amount by which the cash balance changed, represented in the <a href="https://docs.stripe.com/currencies#zero-decimal">smallest currency unit</a>. A positive value represents funds being added to the cash balance, a negative value represents funds being removed from the cash balance.
* @property null|(object{refund: Refund|string}&StripeObject) $refunded_from_payment
* @property null|(object{balance_transaction: BalanceTransaction|string}&StripeObject) $transferred_to_balance

View File

@@ -19,7 +19,7 @@ namespace Stripe;
* @property Customer|string $customer The Customer the Customer Session was created for.
* @property null|string $customer_account The Account that the Customer Session was created for.
* @property int $expires_at The timestamp at which this Customer Session will expire.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
*/
class CustomerSession extends ApiResource
{

View File

@@ -10,9 +10,9 @@ namespace Stripe;
*
* Related guide: <a href="https://docs.stripe.com/billing/subscriptions/discounts">Applying discounts to subscriptions</a>
*
* @property string $id The ID of the discount object. Discounts cannot be fetched by ID. Use <code>expand[]=discounts</code> in API calls to expand discount IDs in an array.
* @property string $id The ID of the discount object. Discounts can't be fetched by ID. Use <code>expand[]=discounts</code> in API calls to expand discount IDs in an array.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property null|string $checkout_session The Checkout session that this coupon is applied to, if it is applied to a particular session in payment mode. Will not be present for subscription mode.
* @property null|string $checkout_session The Checkout session that this coupon is applied to, if it is applied to a particular session in payment mode. Not present for subscription mode.
* @property null|Customer|string $customer The ID of the customer associated with this discount.
* @property null|string $customer_account The ID of the account representing the customer associated with this discount.
* @property null|int $end If the coupon has a duration of <code>repeating</code>, the date that this discount will end. If the coupon has a duration of <code>once</code> or <code>forever</code>, this attribute will be null.

View File

@@ -19,10 +19,10 @@ namespace Stripe;
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property string $currency Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
* @property string[] $enhanced_eligibility_types List of eligibility types that are included in <code>enhanced_evidence</code>.
* @property (object{access_activity_log: null|string, billing_address: null|string, cancellation_policy: null|File|string, cancellation_policy_disclosure: null|string, cancellation_rebuttal: null|string, customer_communication: null|File|string, customer_email_address: null|string, customer_name: null|string, customer_purchase_ip: null|string, customer_signature: null|File|string, duplicate_charge_documentation: null|File|string, duplicate_charge_explanation: null|string, duplicate_charge_id: null|string, enhanced_evidence: (object{visa_compelling_evidence_3?: (object{disputed_transaction: null|(object{customer_account_id: null|string, customer_device_fingerprint: null|string, customer_device_id: null|string, customer_email_address: null|string, customer_purchase_ip: null|string, merchandise_or_services: null|string, product_description: null|string, shipping_address: null|(object{city: null|string, country: null|string, line1: null|string, line2: null|string, postal_code: null|string, state: null|string}&StripeObject)}&StripeObject), prior_undisputed_transactions: ((object{charge: string, customer_account_id: null|string, customer_device_fingerprint: null|string, customer_device_id: null|string, customer_email_address: null|string, customer_purchase_ip: null|string, product_description: null|string, shipping_address: null|(object{city: null|string, country: null|string, line1: null|string, line2: null|string, postal_code: null|string, state: null|string}&StripeObject)}&StripeObject))[]}&StripeObject), visa_compliance?: (object{fee_acknowledged: bool}&StripeObject)}&StripeObject), product_description: null|string, receipt: null|File|string, refund_policy: null|File|string, refund_policy_disclosure: null|string, refund_refusal_explanation: null|string, service_date: null|string, service_documentation: null|File|string, shipping_address: null|string, shipping_carrier: null|string, shipping_date: null|string, shipping_documentation: null|File|string, shipping_tracking_number: null|string, uncategorized_file: null|File|string, uncategorized_text: null|string}&StripeObject) $evidence
* @property (object{due_by: null|int, enhanced_eligibility: (object{visa_compelling_evidence_3?: (object{required_actions: string[], status: string}&StripeObject), visa_compliance?: (object{status: string}&StripeObject)}&StripeObject), has_evidence: bool, past_due: bool, submission_count: int}&StripeObject) $evidence_details
* @property (object{access_activity_log: null|string, billing_address: null|string, cancellation_policy: null|File|string, cancellation_policy_disclosure: null|string, cancellation_rebuttal: null|string, customer_communication: null|File|string, customer_email_address: null|string, customer_name: null|string, customer_purchase_ip: null|string, customer_signature: null|File|string, duplicate_charge_documentation: null|File|string, duplicate_charge_explanation: null|string, duplicate_charge_id: null|string, enhanced_evidence: (object{mastercard_compliance?: (object{fee_acknowledged: bool}&StripeObject), visa_compelling_evidence_3?: (object{disputed_transaction: null|(object{customer_account_id: null|string, customer_device_fingerprint: null|string, customer_device_id: null|string, customer_email_address: null|string, customer_purchase_ip: null|string, merchandise_or_services: null|string, product_description: null|string, shipping_address: null|(object{city: null|string, country: null|string, line1: null|string, line2: null|string, postal_code: null|string, state: null|string}&StripeObject)}&StripeObject), prior_undisputed_transactions: ((object{charge: string, customer_account_id: null|string, customer_device_fingerprint: null|string, customer_device_id: null|string, customer_email_address: null|string, customer_purchase_ip: null|string, product_description: null|string, shipping_address: null|(object{city: null|string, country: null|string, line1: null|string, line2: null|string, postal_code: null|string, state: null|string}&StripeObject)}&StripeObject))[]}&StripeObject), visa_compliance?: (object{fee_acknowledged: bool}&StripeObject)}&StripeObject), product_description: null|string, receipt: null|File|string, refund_policy: null|File|string, refund_policy_disclosure: null|string, refund_refusal_explanation: null|string, service_date: null|string, service_documentation: null|File|string, shipping_address: null|string, shipping_carrier: null|string, shipping_date: null|string, shipping_documentation: null|File|string, shipping_tracking_number: null|string, uncategorized_file: null|File|string, uncategorized_text: null|string}&StripeObject) $evidence
* @property (object{due_by: null|int, enhanced_eligibility: (object{mastercard_compliance?: (object{status: string}&StripeObject), visa_compelling_evidence_3?: (object{required_actions: string[], status: string}&StripeObject), visa_compliance?: (object{status: string}&StripeObject)}&StripeObject), has_evidence: bool, past_due: bool, submission_count: int}&StripeObject) $evidence_details
* @property bool $is_charge_refundable If true, it's still possible to refund the disputed payment. After the payment has been fully refunded, no further funds are withdrawn from your Stripe account as a result of this dispute.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property StripeObject $metadata Set of <a href="https://docs.stripe.com/api/metadata">key-value pairs</a> that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property null|string $network_reason_code Network-dependent reason code for the dispute.
* @property null|PaymentIntent|string $payment_intent ID of the PaymentIntent that's disputed.
@@ -108,7 +108,7 @@ class Dispute extends ApiResource
* see our <a href="/docs/disputes/categories">guide to dispute types</a>.
*
* @param string $id the ID of the resource to update
* @param null|array{evidence?: array{access_activity_log?: string, billing_address?: string, cancellation_policy?: string, cancellation_policy_disclosure?: string, cancellation_rebuttal?: string, customer_communication?: string, customer_email_address?: string, customer_name?: string, customer_purchase_ip?: string, customer_signature?: string, duplicate_charge_documentation?: string, duplicate_charge_explanation?: string, duplicate_charge_id?: string, enhanced_evidence?: null|array{visa_compelling_evidence_3?: array{disputed_transaction?: array{customer_account_id?: null|string, customer_device_fingerprint?: null|string, customer_device_id?: null|string, customer_email_address?: null|string, customer_purchase_ip?: null|string, merchandise_or_services?: string, product_description?: null|string, shipping_address?: array{city?: null|string, country?: null|string, line1?: null|string, line2?: null|string, postal_code?: null|string, state?: null|string}}, prior_undisputed_transactions?: (array{charge: string, customer_account_id?: null|string, customer_device_fingerprint?: null|string, customer_device_id?: null|string, customer_email_address?: null|string, customer_purchase_ip?: null|string, product_description?: null|string, shipping_address?: array{city?: null|string, country?: null|string, line1?: null|string, line2?: null|string, postal_code?: null|string, state?: null|string}})[]}, visa_compliance?: array{fee_acknowledged?: bool}}, product_description?: string, receipt?: string, refund_policy?: string, refund_policy_disclosure?: string, refund_refusal_explanation?: string, service_date?: string, service_documentation?: string, shipping_address?: string, shipping_carrier?: string, shipping_date?: string, shipping_documentation?: string, shipping_tracking_number?: string, uncategorized_file?: string, uncategorized_text?: string}, expand?: string[], metadata?: null|array<string, string>, submit?: bool} $params
* @param null|array{evidence?: array{access_activity_log?: string, billing_address?: string, cancellation_policy?: string, cancellation_policy_disclosure?: string, cancellation_rebuttal?: string, customer_communication?: string, customer_email_address?: string, customer_name?: string, customer_purchase_ip?: string, customer_signature?: string, duplicate_charge_documentation?: string, duplicate_charge_explanation?: string, duplicate_charge_id?: string, enhanced_evidence?: null|array{mastercard_compliance?: array{fee_acknowledged?: bool}, visa_compelling_evidence_3?: array{disputed_transaction?: array{customer_account_id?: null|string, customer_device_fingerprint?: null|string, customer_device_id?: null|string, customer_email_address?: null|string, customer_purchase_ip?: null|string, merchandise_or_services?: string, product_description?: null|string, shipping_address?: array{city?: null|string, country?: null|string, line1?: null|string, line2?: null|string, postal_code?: null|string, state?: null|string}}, prior_undisputed_transactions?: (array{charge: string, customer_account_id?: null|string, customer_device_fingerprint?: null|string, customer_device_id?: null|string, customer_email_address?: null|string, customer_purchase_ip?: null|string, product_description?: null|string, shipping_address?: array{city?: null|string, country?: null|string, line1?: null|string, line2?: null|string, postal_code?: null|string, state?: null|string}})[]}, visa_compliance?: array{fee_acknowledged?: bool}}, product_description?: string, receipt?: string, refund_policy?: string, refund_policy_disclosure?: string, refund_refusal_explanation?: string, service_date?: string, service_documentation?: string, shipping_address?: string, shipping_carrier?: string, shipping_date?: string, shipping_documentation?: string, shipping_tracking_number?: string, uncategorized_file?: string, uncategorized_text?: string}, expand?: string[], metadata?: null|array<string, string>, submit?: bool} $params
* @param null|array|string $opts
*
* @return Dispute the updated resource

View File

@@ -10,7 +10,7 @@ namespace Stripe\Entitlements;
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property Feature|string $feature The <a href="https://docs.stripe.com/api/entitlements/feature">Feature</a> that the customer is entitled to.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property string $lookup_key A unique key you provide as your own system identifier. This may be up to 80 characters.
*/
class ActiveEntitlement extends \Stripe\ApiResource

View File

@@ -10,7 +10,7 @@ namespace Stripe\Entitlements;
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property string $customer The customer that is entitled to this feature.
* @property \Stripe\Collection<ActiveEntitlement> $entitlements The list of entitlements this customer has.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
*/
class ActiveEntitlementSummary extends \Stripe\ApiResource
{

View File

@@ -11,7 +11,7 @@ namespace Stripe\Entitlements;
* @property string $id Unique identifier for the object.
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property bool $active Inactive features cannot be attached to new products and will not be returned from the features list endpoint.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property string $lookup_key A unique key you provide as your own system identifier. This may be up to 80 characters.
* @property \Stripe\StripeObject $metadata Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
* @property string $name The feature's name, for your own purpose, not meant to be displayable to the customer.

View File

@@ -9,7 +9,7 @@ namespace Stripe;
* @property string $object String representing the object's type. Objects of the same type share the same value.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property int $expires Time at which the key will expire. Measured in seconds since the Unix epoch.
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property null|string $secret The key's secret. You can use this value to make authorized requests to the Stripe API.
*/
class EphemeralKey extends ApiResource

View File

@@ -5,35 +5,26 @@ namespace Stripe;
/**
* Class ErrorObject.
*
* @property string $charge For card errors, the ID of the failed charge.
* @property string $code For some errors that could be handled
* programmatically, a short string indicating the error code reported.
* @property string $decline_code For card errors resulting from a card issuer
* decline, a short string indicating the card issuer's reason for the
* decline if they provide one.
* @property string $doc_url A URL to more information about the error code
* reported.
* @property string $message A human-readable message providing more details
* about the error. For card errors, these messages can be shown to your
* users.
* @property string $param If the error is parameter-specific, the parameter
* related to the error. For example, you can use this to display a message
* near the correct form field.
* @property PaymentIntent $payment_intent The PaymentIntent object for errors
* returned on a request involving a PaymentIntent.
* @property PaymentMethod $payment_method The PaymentMethod object for errors
* returned on a request involving a PaymentMethod.
* @property string $payment_method_type If the error is specific to the type
* of payment method, the payment method type that had a problem. This
* field is only populated for invoice-related errors.
* @property string $request_log_url A URL to the request log entry in your
* dashboard.
* @property SetupIntent $setup_intent The SetupIntent object for errors
* returned on a request involving a SetupIntent.
* @property StripeObject $source The source object for errors returned on a
* request involving a source.
* @property string $type The type of error returned. One of `api_error`,
* `card_error`, `idempotency_error`, or `invalid_request_error`.
* // errorProperties: The beginning of the section generated from our OpenAPI spec
*
* @property null|string $advice_code For card errors resulting from a card issuer decline, a short string indicating [how to proceed with an error](https://docs.stripe.com/declines#retrying-issuer-declines) if they provide one.
* @property null|string $charge For card errors, the ID of the failed charge.
* @property null|string $code For some errors that could be handled programmatically, a short string indicating the [error code](https://docs.stripe.com/error-codes) reported.
* @property null|string $decline_code For card errors resulting from a card issuer decline, a short string indicating the [card issuer's reason for the decline](https://docs.stripe.com/declines#issuer-declines) if they provide one.
* @property null|string $doc_url A URL to more information about the [error code](https://docs.stripe.com/error-codes) reported.
* @property null|string $message A human-readable message providing more details about the error. For card errors, these messages can be shown to your users.
* @property null|string $network_advice_code For card errors resulting from a card issuer decline, a 2 digit code which indicates the advice given to merchant by the card network on how to proceed with an error.
* @property null|string $network_decline_code For payments declined by the network, an alphanumeric code which indicates the reason the payment failed.
* @property null|string $param If the error is parameter-specific, the parameter related to the error. For example, you can use this to display a message near the correct form field.
* @property null|PaymentIntent $payment_intent The PaymentIntent object for errors returned on a request involving a PaymentIntent.
* @property null|PaymentMethod $payment_method The PaymentMethod object for errors returned on a request involving a PaymentMethod.
* @property null|string $payment_method_type If the error is specific to the type of payment method, the payment method type that had a problem. This field is only populated for invoice-related errors.
* @property null|string $request_log_url A URL to the request log entry in your dashboard.
* @property null|SetupIntent $setup_intent The SetupIntent object for errors returned on a request involving a SetupIntent.
* @property null|PaymentSource $source The PaymentSource object for errors returned on a request involving a PaymentSource.
* @property string $type The type of error returned. One of `api_error`, `card_error`, `idempotency_error`, or `invalid_request_error`
* @property null|string $user_message The user message associated with the error.
* // errorProperties: The end of the section generated from our OpenAPI spec
*/
class ErrorObject extends StripeObject
{
@@ -42,7 +33,7 @@ class ErrorObject extends StripeObject
*
* @see https://stripe.com/docs/error-codes
*/
// The beginning of the section generated from our OpenAPI spec
// errorCodes: The beginning of the section generated from our OpenAPI spec
const CODE_ACCOUNT_CLOSED = 'account_closed';
const CODE_ACCOUNT_COUNTRY_INVALID_ADDRESS = 'account_country_invalid_address';
const CODE_ACCOUNT_ERROR_COUNTRY_CHANGE_REQUIRES_ADDITIONAL_STEPS = 'account_error_country_change_requires_additional_steps';
@@ -51,11 +42,14 @@ class ErrorObject extends StripeObject
const CODE_ACCOUNT_NUMBER_INVALID = 'account_number_invalid';
const CODE_ACCOUNT_TOKEN_REQUIRED_FOR_V2_ACCOUNT = 'account_token_required_for_v2_account';
const CODE_ACSS_DEBIT_SESSION_INCOMPLETE = 'acss_debit_session_incomplete';
const CODE_ACTION_BLOCKED = 'action_blocked';
const CODE_ALIPAY_UPGRADE_REQUIRED = 'alipay_upgrade_required';
const CODE_AMOUNT_TOO_LARGE = 'amount_too_large';
const CODE_AMOUNT_TOO_SMALL = 'amount_too_small';
const CODE_ANOMALOUS_MONEY_MOVEMENT_REQUEST = 'anomalous_money_movement_request';
const CODE_API_KEY_EXPIRED = 'api_key_expired';
const CODE_APPLICATION_FEES_NOT_ALLOWED = 'application_fees_not_allowed';
const CODE_APPROVAL_REQUIRED = 'approval_required';
const CODE_AUTHENTICATION_REQUIRED = 'authentication_required';
const CODE_BALANCE_INSUFFICIENT = 'balance_insufficient';
const CODE_BALANCE_INVALID_PARAMETER = 'balance_invalid_parameter';
@@ -92,6 +86,10 @@ class ErrorObject extends StripeObject
const CODE_DEBIT_NOT_AUTHORIZED = 'debit_not_authorized';
const CODE_EMAIL_INVALID = 'email_invalid';
const CODE_EXPIRED_CARD = 'expired_card';
const CODE_FAILED_TAX_CALCULATION = 'failed_tax_calculation';
const CODE_FINANCIAL_ACCOUNT_BALANCE_DOES_NOT_SUPPORT_CURRENCY = 'financial_account_balance_does_not_support_currency';
const CODE_FINANCIAL_ACCOUNT_CAPABILITY_NOT_ENABLED = 'financial_account_capability_not_enabled';
const CODE_FINANCIAL_ACCOUNT_CAPABILITY_RESTRICTED = 'financial_account_capability_restricted';
const CODE_FINANCIAL_CONNECTIONS_ACCOUNT_INACTIVE = 'financial_connections_account_inactive';
const CODE_FINANCIAL_CONNECTIONS_ACCOUNT_PENDING_ACCOUNT_NUMBERS = 'financial_connections_account_pending_account_numbers';
const CODE_FINANCIAL_CONNECTIONS_ACCOUNT_UNAVAILABLE_ACCOUNT_NUMBERS = 'financial_connections_account_unavailable_account_numbers';
@@ -165,6 +163,7 @@ class ErrorObject extends StripeObject
const CODE_PAYMENT_METHOD_INVALID_PARAMETER = 'payment_method_invalid_parameter';
const CODE_PAYMENT_METHOD_INVALID_PARAMETER_TESTMODE = 'payment_method_invalid_parameter_testmode';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_FAILED = 'payment_method_microdeposit_failed';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_PROCESSING_ERROR = 'payment_method_microdeposit_processing_error';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_AMOUNTS_INVALID = 'payment_method_microdeposit_verification_amounts_invalid';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_AMOUNTS_MISMATCH = 'payment_method_microdeposit_verification_amounts_mismatch';
const CODE_PAYMENT_METHOD_MICRODEPOSIT_VERIFICATION_ATTEMPTS_EXCEEDED = 'payment_method_microdeposit_verification_attempts_exceeded';
@@ -195,6 +194,7 @@ class ErrorObject extends StripeObject
const CODE_ROUTING_NUMBER_INVALID = 'routing_number_invalid';
const CODE_SECRET_KEY_REQUIRED = 'secret_key_required';
const CODE_SEPA_UNSUPPORTED_ACCOUNT = 'sepa_unsupported_account';
const CODE_SERVICE_PERIOD_COUPON_WITH_METERED_TIERED_ITEM_UNSUPPORTED = 'service_period_coupon_with_metered_tiered_item_unsupported';
const CODE_SETUP_ATTEMPT_FAILED = 'setup_attempt_failed';
const CODE_SETUP_INTENT_AUTHENTICATION_FAILURE = 'setup_intent_authentication_failure';
const CODE_SETUP_INTENT_INVALID_PARAMETER = 'setup_intent_invalid_parameter';
@@ -204,6 +204,7 @@ class ErrorObject extends StripeObject
const CODE_SETUP_INTENT_UNEXPECTED_STATE = 'setup_intent_unexpected_state';
const CODE_SHIPPING_ADDRESS_INVALID = 'shipping_address_invalid';
const CODE_SHIPPING_CALCULATION_FAILED = 'shipping_calculation_failed';
const CODE_SIRET_INVALID = 'siret_invalid';
const CODE_SKU_INACTIVE = 'sku_inactive';
const CODE_STATE_UNSUPPORTED = 'state_unsupported';
const CODE_STATUS_TRANSITION_INVALID = 'status_transition_invalid';
@@ -228,7 +229,7 @@ class ErrorObject extends StripeObject
const CODE_TRANSFER_SOURCE_BALANCE_PARAMETERS_MISMATCH = 'transfer_source_balance_parameters_mismatch';
const CODE_TRANSFERS_NOT_ALLOWED = 'transfers_not_allowed';
const CODE_URL_INVALID = 'url_invalid';
// The end of the section generated from our OpenAPI spec
// errorCodes: The end of the section generated from our OpenAPI spec
/**
* Refreshes this object using the provided values.
@@ -244,17 +245,25 @@ class ErrorObject extends StripeObject
// error objects when they have a null value. We manually set default
// values here to facilitate generic error handling.
$values = \array_merge([
// errorRefreshFrom: The beginning of the section generated from our OpenAPI spec
'advice_code' => null,
'charge' => null,
'code' => null,
'decline_code' => null,
'doc_url' => null,
'message' => null,
'network_advice_code' => null,
'network_decline_code' => null,
'param' => null,
'payment_intent' => null,
'payment_method' => null,
'payment_method_type' => null,
'request_log_url' => null,
'setup_intent' => null,
'source' => null,
'type' => null,
'user_message' => null,
// errorRefreshFrom: The end of the section generated from our OpenAPI spec
], $values);
parent::refreshFrom($values, $opts, $partial);
}

View File

@@ -34,7 +34,7 @@ namespace Stripe;
* @property null|string $context Authentication context needed to fetch the event or related object.
* @property int $created Time at which the object was created. Measured in seconds since the Unix epoch.
* @property (object{object: StripeObject, previous_attributes?: StripeObject}&StripeObject) $data
* @property bool $livemode Has the value <code>true</code> if the object exists in live mode or the value <code>false</code> if the object exists in test mode.
* @property bool $livemode If the object exists in live mode, the value is <code>true</code>. If the object exists in test mode, the value is <code>false</code>.
* @property int $pending_webhooks Number of webhooks that haven't been successfully delivered (for example, to return a 20x response) to the URLs you specify.
* @property null|(object{id: null|string, idempotency_key: null|string}&StripeObject) $request Information on the API request that triggers the event.
* @property string $type Description of the event (for example, <code>invoice.created</code> or <code>charge.refunded</code>).

Some files were not shown because too many files have changed in this diff Show More