Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
## 2.0.0

### Changed
- Updated Stripe API version from `2024-04-10` to `2026-01-28.clover`.

- Updated Stripe API version from `2024-04-10` to `2026-01-28.clover`.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## 1.7.1 - 2026-01-19

- Fixed typo in the Readme file.
- Fixed typo in the Readme file.
- Fixed XSS vulnerabilities.

## 1.7.0 - 2025-12-11
Expand Down
26 changes: 22 additions & 4 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use craft\events\DefineBehaviorsEvent;
use craft\events\DefineConsoleActionsEvent;
use craft\events\DefineEditUserScreensEvent;
use craft\events\DefineFieldLayoutElementsEvent;
use craft\events\DefineFieldLayoutFieldsEvent;
use craft\events\DefineMenuItemsEvent;
use craft\events\DefineMetadataEvent;
Expand All @@ -44,7 +45,9 @@
use craft\stripe\elements\Subscription;
use craft\stripe\feedme\fields\Products as FeedMeProducts;
use craft\stripe\feedme\fields\Subscriptions as FeedMeSubscriptions;
use craft\stripe\fieldlayoutelements\AssignmentLogs;
use craft\stripe\fieldlayoutelements\PricesField;
use craft\stripe\fieldlayoutelements\UserGroupAssignmentsField;
use craft\stripe\fields\Products as ProductsField;
use craft\stripe\fields\Subscriptions as SubscriptionsField;
use craft\stripe\jobs\SyncSingleCustomerData;
Expand Down Expand Up @@ -91,7 +94,7 @@ class Plugin extends BasePlugin
/**
* @var string
*/
public string $schemaVersion = '1.2.0';
public string $schemaVersion = '1.3.0';

/**
* @inheritdoc
Expand Down Expand Up @@ -473,8 +476,22 @@ private function registerFieldLayoutElements(): void
case Product::class:
$event->fields[] = PricesField::class;
break;
case Price::class:
$event->fields[] = UserGroupAssignmentsField::class;
break;
}
});

Event::on(FieldLayout::class, FieldLayout::EVENT_DEFINE_UI_ELEMENTS, function(DefineFieldLayoutElementsEvent $event) {
/** @var FieldLayout $fieldLayout */
$fieldLayout = $event->sender;

if ($fieldLayout->type !== Subscription::class) {
return;
}

$event->elements[] = AssignmentLogs::class;
});
}

/**
Expand Down Expand Up @@ -516,7 +533,7 @@ public function registerResaveCommands(): void
return $controller->resaveElements(Product::class);
},
'options' => ['withFields'],
'helpSummary' => 'Re-saves Stripe products.',
'helpSummary' => 'Re-saves Stripe Products.',
];

$e->actions['stripe-prices'] = [
Expand All @@ -535,7 +552,7 @@ public function registerResaveCommands(): void
return $controller->resaveElements(Price::class);
},
'options' => ['withFields'],
'helpSummary' => 'Re-saves Stripe prices.',
'helpSummary' => 'Re-saves Stripe Prices.',
];

$e->actions['stripe-subscriptions'] = [
Expand All @@ -554,7 +571,7 @@ public function registerResaveCommands(): void
return $controller->resaveElements(Subscription::class);
},
'options' => ['withFields'],
'helpSummary' => 'Re-saves Stripe subscriptions.',
'helpSummary' => 'Re-saves Stripe Subscriptions.',
];
});
}
Expand All @@ -573,6 +590,7 @@ private function registerCpRoutes(): void

$event->rules['stripe/products'] = 'stripe/products/index';
$event->rules['stripe/products/<elementId:\\d+>'] = 'elements/edit';
$event->rules['stripe/products/<productId:\\d+>/prices/<elementId:\\d+>'] = 'elements/edit';

$event->rules['stripe/subscriptions'] = 'stripe/subscriptions/index';
$event->rules['stripe/subscriptions/<elementId:\\d+>'] = 'elements/edit';
Expand Down
40 changes: 20 additions & 20 deletions src/console/controllers/SyncController.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ public function actionInvoices(): int
*/
private function syncProducts(): void
{
$this->stdout('Syncing Stripe products and prices…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Syncing Stripe Products and Prices…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);

$start = microtime(true);
Plugin::getInstance()->getProducts()->syncAllProducts();
$time = microtime(true) - $start;

$this->stdout('Finished syncing ' . Product::find()->count() . ' product(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Finished syncing ' . Product::find()->count() . ' Product(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
}

/**
Expand All @@ -149,13 +149,13 @@ private function syncProducts(): void
*/
private function syncPrices(): void
{
$this->stdout('Syncing Stripe prices…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Syncing Stripe Prices…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);

$start = microtime(true);
Plugin::getInstance()->getPrices()->syncAllPrices();
$time = microtime(true) - $start;

$this->stdout('Finished syncing ' . Price::find()->count() . ' price(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Finished syncing ' . Price::find()->count() . ' Price(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
}

/**
Expand All @@ -167,13 +167,13 @@ private function syncPrices(): void
*/
private function syncSubscriptions(): void
{
$this->stdout('Syncing Stripe subscriptions…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Syncing Stripe Subscriptions…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);

$start = microtime(true);
Plugin::getInstance()->getSubscriptions()->syncAllSubscriptions();
$time = microtime(true) - $start;

$this->stdout('Finished syncing ' . Subscription::find()->count() . ' subscription(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Finished syncing ' . Subscription::find()->count() . ' Subscription(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
}

/**
Expand All @@ -185,13 +185,13 @@ private function syncSubscriptions(): void
*/
private function syncCustomers(): void
{
$this->stdout('Syncing Stripe customers…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Syncing Stripe Customers…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);

$start = microtime(true);
$count = Plugin::getInstance()->getCustomers()->syncAllCustomers();
$time = microtime(true) - $start;

$this->stdout('Finished syncing ' . $count . ' customer(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Finished syncing ' . $count . ' Customer(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
}

/**
Expand All @@ -203,13 +203,13 @@ private function syncCustomers(): void
*/
private function syncPaymentMethods(): void
{
$this->stdout('Syncing Stripe payment methods…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Syncing Stripe Payment Methods…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);

$start = microtime(true);
$count = Plugin::getInstance()->getPaymentMethods()->syncAllPaymentMethods();
$time = microtime(true) - $start;

$this->stdout('Finished syncing ' . $count . ' payment method(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Finished syncing ' . $count . ' Payment Method(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
}

/**
Expand All @@ -221,13 +221,13 @@ private function syncPaymentMethods(): void
*/
private function syncInvoices(): void
{
$this->stdout('Syncing Stripe invoices…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Syncing Stripe Invoices…' . PHP_EOL . PHP_EOL, Console::FG_GREEN);

$start = microtime(true);
$count = Plugin::getInstance()->getInvoices()->syncAllInvoices();
$time = microtime(true) - $start;

$this->stdout('Finished syncing ' . $count . ' invoice(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
$this->stdout('Finished syncing ' . $count . ' Invoice(s) in ' . round($time, 2) . 's' . PHP_EOL . PHP_EOL, Console::FG_GREEN);
}

/**
Expand All @@ -243,32 +243,32 @@ private function syncSingleCustomer(string $customerId): void
$this->stdout("Syncing Stripe customer {$customerId} and related data…" . PHP_EOL . PHP_EOL, Console::FG_GREEN);

$start = microtime(true);

$plugin = Plugin::getInstance();
$api = $plugin->getApi();

try {
// Fetch the customer from Stripe
$stripeCustomer = $api->fetchCustomerById($customerId);

// Sync the customer data
$this->stdout('Syncing customer data…' . PHP_EOL, Console::FG_YELLOW);
$plugin->getCustomers()->createOrUpdateCustomer($stripeCustomer);

// Sync customer's subscriptions
$this->stdout('Syncing customer subscriptions…' . PHP_EOL, Console::FG_YELLOW);
$subscriptionCount = $plugin->getSubscriptions()->syncCustomerSubscriptions($stripeCustomer);

// Sync customer's invoices
$this->stdout('Syncing customer invoices…' . PHP_EOL, Console::FG_YELLOW);
$invoiceCount = $plugin->getInvoices()->syncCustomerInvoices($stripeCustomer);

// Sync customer's payment methods
$this->stdout('Syncing customer payment methods…' . PHP_EOL, Console::FG_YELLOW);
$paymentMethodCount = $plugin->getPaymentMethods()->syncCustomerPaymentMethods($stripeCustomer);

$time = microtime(true) - $start;

$this->stdout(PHP_EOL . "Finished syncing customer {$customerId}:" . PHP_EOL, Console::FG_GREEN);
$this->stdout(" - Customer data synced" . PHP_EOL, Console::FG_GREEN);
$this->stdout(" - {$subscriptionCount} subscription(s) synced" . PHP_EOL, Console::FG_GREEN);
Expand Down
29 changes: 14 additions & 15 deletions src/controllers/CheckoutController.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,20 @@ public function actionCheckout(): Response
}

$params = [];
$fields = $request->getBodyParam('fields');
if (!empty($fields)) {
// check the checkout mode - if it's subscription, proceed with creating a draft
$mode = $checkoutService->getCheckoutMode($lineItems);
if ($mode === StripeCheckoutSession::MODE_SUBSCRIPTION) {
// create an unpublished & unsaved draft subscription in Craft;
$subscription = Craft::createObject([
'class' => Subscription::class,
'attributes' => ['title' => DateTimeHelper::now()->format('Y-m-d H:i:s')],
]);
$subscription->setFieldValuesFromRequest('fields');
if (Craft::$app->getDrafts()->saveElementAsDraft($subscription, markAsSaved: false)) {
// send the uid of it to Stripe to be stored as metadata on the Session(!)
$params['metadata']['craftSubscriptionUid'] = $subscription->uid;
}

// Customers can save custom field values to subscriptions during checkout:
$mode = $checkoutService->getCheckoutMode($lineItems);
if ($mode === StripeCheckoutSession::MODE_SUBSCRIPTION) {
// Create a provisional draft element in Craft:
$subscription = new Subscription();
// Temporary title (because we don’t have a subscription ID yet):
$subscription->title = DateTimeHelper::now()->format('Y-m-d H:i:s');

$subscription->setFieldValuesFromRequest('fields');

if (Craft::$app->getDrafts()->saveElementAsDraft($subscription, markAsSaved: false)) {
// Attach the element’s UUID to the Stripe request as metadata on the Checkout Session:
$params['metadata']['craftSubscriptionUid'] = $subscription->uid;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/db/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ abstract class Table
public const CUSTOMERDATA = '{{%stripe_customerdata}}';
public const INVOICEDATA = '{{%stripe_invoicedata}}';
public const WEBHOOKS = '{{%stripe_webhooks}}';
public const PRICES_USERGROUPS = '{{%stripe_prices_usergroups}}';
public const SUBSCRIPTIONLOGS = '{{%stripe_subscriptionlogs}}';
}
Loading
Loading