From f867f076d9872a6392580710b4a7fd31d6b771a7 Mon Sep 17 00:00:00 2001 From: Rob Woodgate Date: Wed, 9 Oct 2024 13:48:30 +0100 Subject: [PATCH] Enforce types to prevent Paddle API errors in edge cases --- README.md | 7 ++++++- paddle-billing.php | 37 ++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index c271919..140e05f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ Paddle Billing is the evolution of Paddle Classic, and is the default billing AP If you signed up for Paddle before this date, [you need to opt-in](https://developer.paddle.com/changelog/2023/enable-paddle-billing) to Paddle Billing. After you opt in, you can toggle between Paddle Billing and Paddle Classic, and run the two side by side for as long as you need. - ### REQUIREMENTS This plugin requires [aMember](https://www.cogmentis.com/go/amember) v6.x and PHP 7.2 or higher @@ -15,6 +14,12 @@ This plugin requires [aMember](https://www.cogmentis.com/go/amember) v6.x and PH 2. Enable and configure the plugin in *aMember CP -> Setup/Configuration -> Plugins* +### TROUBLESHOOTING + +This plugin writes Paddle responses to the aMember Invoice log (aMember admin > Utilities > Logs > Invoice). + +In case of an error, please check there as well as in the aMember Error Log (aMember admin > Utilities > Logs > Errors). + ### LICENCE / CREDITS This plugin is provided under the MIT License. diff --git a/paddle-billing.php b/paddle-billing.php index 4393dba..a6f5039 100644 --- a/paddle-billing.php +++ b/paddle-billing.php @@ -11,7 +11,7 @@ class Am_Paysystem_PaddleBilling extends Am_Paysystem_Abstract { public const PLUGIN_STATUS = self::STATUS_BETA; - public const PLUGIN_REVISION = '2.5'; + public const PLUGIN_REVISION = '2.6'; public const CUSTOM_DATA_INV = 'am_invoice'; public const PRICE_ID = 'paddle-billing_pri_id'; public const SUBSCRIPTION_ID = 'paddle-billing_sub_id'; @@ -335,7 +335,7 @@ public function _process($invoice, $request, $result): void // Build the core transaction item payload $txnitm = [ - 'quantity' => $item->qty, + 'quantity' => (int) $item->qty, 'price' => [ 'description' => $product->getBillingPlan()->getTerms(), 'name' => ___('Subscription').$sptext, @@ -356,8 +356,8 @@ public function _process($invoice, $request, $result): void 'currency_code' => $item->currency, ], 'quantity' => [ - 'minimum' => $item->qty, - 'maximum' => $item->qty, + 'minimum' => (int) $item->qty, + 'maximum' => (int) $item->qty, ], 'custom_data' => [ 'invoice_item' => $item->item_id, @@ -763,6 +763,8 @@ public function getReadme() $whk_url = $this->getPluginUrl('ipn'); $pay_url = $this->getPluginUrl('pay'); $paddleJs = $this->paddleJsSetupCode(true); + $ilog_url = Am_Di::getInstance()->url('default/admin-logs/p/invoice'); + $elog_url = Am_Di::getInstance()->url('default/admin-logs/'); return <<Paddle Billing Plugin v{$version} @@ -801,6 +803,11 @@ public function getReadme() + TROUBLESHOOTING + This plugin writes Paddle responses to the aMember Invoice log. + + In case of an error, please check there as well as in the aMember Error log. + ------------------------------------------------------------------------------- Copyright 2024 (c) Rob Woodgate, Cogmentis Ltd. @@ -990,7 +997,7 @@ protected function getAmount($amount, $currency = 'USD'): string return (string) ($amount * pow(10, Am_Currency::$currencyList[$currency]['precision'])); } - protected function getText($period) + protected function getText($period): string { // Convert string if needed if (!$period instanceof Am_Period) { @@ -1000,7 +1007,7 @@ protected function getText($period) return ucwords($period->getText()); } - protected function getRebillText($rebill_times) + protected function getRebillText($rebill_times): string { switch ($rebill_times) { case '0': @@ -1019,7 +1026,7 @@ protected function getRebillText($rebill_times) return ucwords($period->getText()); } - protected function getFrequency($period) + protected function getFrequency($period): int { // Convert string if needed if (!$period instanceof Am_Period) { @@ -1032,10 +1039,10 @@ protected function getFrequency($period) return 1; } - return $period->getCount(); + return (int) $period->getCount(); } - protected function getInterval($period) + protected function getInterval($period): string { // Convert string if needed if (!$period instanceof Am_Period) { @@ -1051,7 +1058,7 @@ protected function getInterval($period) return $map[$period->getUnit()] ?? 'year'; } - protected function getDays($period) + protected function getDays($period): int { // Convert string if needed if (!$period instanceof Am_Period) { @@ -1060,26 +1067,26 @@ protected function getDays($period) switch ($period->getUnit()) { case Am_Period::DAY: - return $period->getCount(); + return (int) $period->getCount(); case Am_Period::MONTH: - return $period->getCount() * 30; + return (int) ($period->getCount() * 30); case Am_Period::YEAR: - return $period->getCount() * 365; + return (int) ($period->getCount() * 365); case Am_Period::FIXED: case Am_Period::MAX_SQL_DATE: $date = new DateTime($period->getCount()); - return $date->diff(new DateTime('now'))->days + 1; + return (int) ($date->diff(new DateTime('now'))->days + 1); default: return 10; // actual value in this case does not matter } } - protected function paddleJsSetupCode($snippet = false) + protected function paddleJsSetupCode($snippet = false): string { $environment = $this->isSandbox() ? 'Paddle.Environment.set("sandbox");' : ''; $client_token = $this->getConfig('client_token');