From 890bdf9f5029de830089d62198f043db7cccb818 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Thu, 24 Sep 2026 12:21:30 +0200 Subject: [PATCH 1/4] fix: work on InvoiceShelf 2.3.0 and later InvoiceShelf 2.3.0 moved to Pinia 3, which dropped the defineStore({ id, ... }) form the store used, and stopped exposing window.axios, so the settings page rendered blank and the store's requests failed. The store now passes its id as the first argument and uses the host's HTTP client. Releases are built against InvoiceShelf's 2.x branch with its toolchain instead of the default branch, which is now 3.x. The README says the module is for 2.x only and adds the cache step after installing. --- .github/workflows/release.yaml | 17 +++++++--- CHANGELOG.md | 13 ++++++++ README.md | 35 +++++++++++++++----- Resources/scripts/stores/payment-provider.js | 26 +++++++++------ package.json | 2 +- 5 files changed, 67 insertions(+), 26 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5f049b9..ec5f606 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,15 +13,18 @@ jobs: runs-on: [ubuntu-latest] steps: - - name: Checkout InvoiceShelf + # The module is for InvoiceShelf 2.x and bundles host code from it, so it is + # built against the 2.x branch, not the default branch (3.x). + - name: Checkout InvoiceShelf 2.x uses: actions/checkout@v4 with: repository: InvoiceShelf/InvoiceShelf + ref: 2.x - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.4 extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip coverage: none @@ -30,13 +33,17 @@ jobs: with: composer-options: --no-dev + - name: Set up pnpm + uses: pnpm/action-setup@v4 + - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - - name: Install and build InvoiceShelf node dependencies - run: npm install && npm run build + # The module build resolves pinia, axios and host components from here. + - name: Install InvoiceShelf node dependencies + run: pnpm install --frozen-lockfile - name: Checkout Payments module uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 72ba5f7..b8f380a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.1.1](https://github.com/InvoiceShelf/module-payments/compare/v1.1.0...v1.1.1) (2026-09-24) + + +### Bug Fixes + +* work on InvoiceShelf 2.3.0 and later: the store uses Pinia 3's `defineStore(id, options)` form and the host's HTTP client instead of the removed `window.axios` +* build releases against InvoiceShelf's `2.x` branch with its toolchain (PHP 8.4, Node 24, pnpm) + + +### Documentation + +* say the module is for InvoiceShelf 2.x only, add a compatibility table and the cache step after installing + ## [1.1.0](https://github.com/rihards-simanovics/InvoiceShelf-payment-module/compare/v1.0.0...v1.1.0) (2024-09-30) diff --git a/README.md b/README.md index 1fd86bd..ee14a92 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,16 @@ Adds ability to process Payments using your InvoiceShelf instance. +> [!IMPORTANT] +> This module is for **InvoiceShelf 2.x only**. On 2.3.0 and later it needs version 1.1.1 or newer; +> 1.1.0 and older show a blank settings page there. It does not run on InvoiceShelf 3.x: payments +> on 3.x will come from a rebuilt module or not at all. + ![Preview of Invoice Shelf, Payments Settings page](./preview.png) ## Table of Contents +- [Compatibility](#compatibility) - [Installation](#installation) - [Update](#update) - [Hard Stops](#hard-stops) @@ -15,25 +21,36 @@ Adds ability to process Payments using your InvoiceShelf instance. - [Troubleshooting](#troubleshooting) - [Copyright](#copyright) +## Compatibility + +| InvoiceShelf | Payments module | +| --- | --- | +| 2.3.0 and later | 1.1.1 or newer | +| 1.3.0 to 2.2.x | 1.1.0 or newer | +| 3.x | not supported | + ## Installation 1. Download the zip with pre-built module from the [latest release](https://github.com/InvoiceShelf/module-payments/releases/latest) in this repo. Alternatively you can build from source, for that follow the steps in the [development](#development) section. 2. Create `/Modules/` dir in your server InvoiceShelf project root. **NOTE:** make sure it's capitalised like in example, it's not a typo. 3. Upload the `Payments.zip` into the newly created `/Modules/` dir. 4. Unzip it. -5. In your server InvoiceShelf project `/` root dir, run `php artisan install:module Payments 1.1.0`. -6. (optional) If you have any issues with your installed module, try clearing your browser's `cache`, `cookies`, and/or `site data`. +5. In your server InvoiceShelf project `/` root dir, run `php artisan install:module Payments 1.1.1`. +6. Run `php artisan optimize:clear`, or restart the container if you run InvoiceShelf in Docker. The + Docker image caches its routes when it starts, so the module's pages return 404 until then. +7. (optional) If you have any issues with your installed module, try clearing your browser's `cache`, `cookies`, and/or `site data`. ## Update 1. Download the zip with pre-built module from the [latest release](https://github.com/InvoiceShelf/module-payments/releases/latest) in this repo. Alternatively you can build from source, for that follow the steps in the [development](#development) section. -2. Upload the `WhiteLabel.zip` into the newly created `/Modules/` dir. -3. Remove old `WhiteLabel/` module folder. -4. Unzip it and visit the site. +2. Upload the `Payments.zip` into the `/Modules/` dir. +3. Remove the old `Payments/` module folder. +4. Unzip it, run `php artisan optimize:clear` (or restart the container in Docker) and visit the site. ### Hard Stops - InvoiceShelf >= 1.3.0 (upgrade this module to 1.1.0) +- InvoiceShelf >= 2.3.0 (upgrade this module to 1.1.1) ## Development @@ -42,15 +59,15 @@ This is a step by step guide on how to get started, with development. ### Prerequisites 1. nvm/fnm (optional) -2. Node JS: `20 LTS` -3. `yarn` +2. Node JS: `24` (what InvoiceShelf 2.x requires) +3. `pnpm` for InvoiceShelf and `yarn` for this module ### Steps -1. Clone the [InvoiceShelf repo](https://github.com/InvoiceShelf/InvoiceShelf) - needed for the admin components. In the future it's likely to be just a node package and you wont need this step. +1. Clone the [InvoiceShelf repo](https://github.com/InvoiceShelf/InvoiceShelf) and check out the `2.x` branch - needed for the admin components. In the future it's likely to be just a node package and you wont need this step. 2. Create `Modules/` dir, in the root dir. 3. Clone this repo into `Payments/` dir inside `/Modules/`. -4. Initialise `node_modules` by running `yarn` inside `/` of the InvoiceShelf repo. +4. Initialise `node_modules` by running `pnpm install` inside `/` of the InvoiceShelf repo. 5. Initialise `node_modules` by running `yarn` inside `/Modules/Payments/` of this repo. 6. Make the changes you wish to make. 7. Run `yarn build`, new `/Modules/Payments/dist/` dir will be created with built `css` and `js` bundles. diff --git a/Resources/scripts/stores/payment-provider.js b/Resources/scripts/stores/payment-provider.js index 8d24bdf..1c60885 100644 --- a/Resources/scripts/stores/payment-provider.js +++ b/Resources/scripts/stores/payment-provider.js @@ -1,9 +1,13 @@ import { useNotificationStore } from '@/scripts/stores/notification' +// InvoiceShelf 2.3.0 stopped exposing window.axios; its HTTP client (auth +// token, company header, credentials) is bundled from the host instead. +import http from '@/scripts/http' const { defineStore } = window.pinia import { handleError } from '../helpers/error-handling' -export const usePaymentProviderStore = defineStore({ - id: 'payment-provider', +// The id is the first argument: Pinia 3, which InvoiceShelf ships from 2.3.0, +// dropped the defineStore({ id, ... }) form. +export const usePaymentProviderStore = defineStore('payment-provider', { state: () => ({ paymentDrivers: [], paymentProviders: [], @@ -39,7 +43,7 @@ export const usePaymentProviderStore = defineStore({ payment_method_id: this.selectedProvider.id, } - window.axios + http .post( `/api/m/payments/${company}/generate-payment/${this.currentInvoice.id}`, data @@ -62,7 +66,7 @@ export const usePaymentProviderStore = defineStore({ return new Promise((resolve, reject) => { - window.axios + http .post( `/api/m/payments/${data.company_id}/confirm-transaction/${uniqueHash}`, data @@ -78,7 +82,7 @@ export const usePaymentProviderStore = defineStore({ fetchPaymentProviders() { return new Promise((resolve, reject) => { - window.axios + http .get(`/api/m/payments/payment-providers`) .then((response) => { this.paymentProviders = response.data.data @@ -92,7 +96,7 @@ export const usePaymentProviderStore = defineStore({ fetchPaymentProvider(id) { return new Promise((resolve, reject) => { - window.axios + http .get(`/api/m/payments/payment-providers/${id}`) .then((response) => { Object.assign(this.currentPaymentProvider, response.data.data) @@ -108,7 +112,7 @@ export const usePaymentProviderStore = defineStore({ const { global } = window.i18n const notificationStore = useNotificationStore(true) return new Promise((resolve, reject) => { - window.axios + http .post('/api/m/payments/payment-providers', data) .then((response) => { notificationStore.showNotification({ @@ -132,7 +136,7 @@ export const usePaymentProviderStore = defineStore({ const notificationStore = useNotificationStore(true) return new Promise((resolve, reject) => { - window.axios + http .put(`/api/m/payments/payment-providers/${data.id}`, data) .then((response) => { notificationStore.showNotification({ @@ -153,7 +157,7 @@ export const usePaymentProviderStore = defineStore({ const notificationStore = useNotificationStore(true) return new Promise((resolve, reject) => { - window.axios + http .delete(`/api/m/payments/payment-providers/${id}`) .then((response) => { let index = this.paymentProviders.findIndex( @@ -188,7 +192,7 @@ export const usePaymentProviderStore = defineStore({ fetchPaymentDrivers() { return new Promise((resolve, reject) => { - axios + http .get(`/api/m/payments/payment-drivers`) .then((response) => { this.paymentDrivers = response.data.payment_drivers @@ -203,7 +207,7 @@ export const usePaymentProviderStore = defineStore({ fetchActiveProviders(company) { return new Promise((resolve, reject) => { - window.axios + http .get(`/api/m/payments/${company}/active-payment-providers`) .then((response) => { this.activeProviders = response.data.data diff --git a/package.json b/package.json index e9b8f10..ab18ac8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "1.1.0", + "version": "1.1.1", "scripts": { "dev": "vite", "build": "vite build", From c43721245df168397334632ebc9b74e4ec1d4a20 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Thu, 24 Sep 2026 12:42:41 +0200 Subject: [PATCH 2/4] fix: stop overriding the app's layout on InvoiceShelf 2.3.0 and later InvoiceShelf 2.3.0 moved to Tailwind 4, which keeps its rules in cascade layers, and CSS outside any layer beats every layered rule. The module's unlayered utilities (.hidden, .flex, ...) overrode the app's responsive ones, hiding the sidebar, the header controls and the settings menu. The built stylesheet now goes into the app's utilities layer, declared in the app's order, so the app's own rule wins wherever both define a class. --- CHANGELOG.md | 1 + vite.config.js | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f380a..a8eb5ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. See [standa ### Bug Fixes * work on InvoiceShelf 2.3.0 and later: the store uses Pinia 3's `defineStore(id, options)` form and the host's HTTP client instead of the removed `window.axios` +* the module's stylesheet no longer breaks the app's layout on InvoiceShelf 2.3.0 and later (missing sidebar and header controls): it now sits in the app's Tailwind 4 `utilities` cascade layer instead of outside any layer * build releases against InvoiceShelf's `2.x` branch with its toolchain (PHP 8.4, Node 24, pnpm) diff --git a/vite.config.js b/vite.config.js index 3c2c53d..dc6dc8a 100644 --- a/vite.config.js +++ b/vite.config.js @@ -4,6 +4,28 @@ const { defineConfig } = require('vite') import vue from '@vitejs/plugin-vue' import { viteExternalsPlugin } from 'vite-plugin-externals' +// InvoiceShelf 2.3.0 and later style the app with Tailwind 4, which keeps its +// rules in cascade layers, and CSS outside any layer beats every layered rule. +// Left unlayered, this module's utilities (.hidden, .flex, ...) overrode the +// app's responsive ones and hid the sidebar. The built stylesheet goes into the +// app's `utilities` layer instead, declared in the app's order first, so the +// app's own rule wins wherever both define a class. Hosts before 2.3.0 have no +// layers, and their rules keep winning there too. +const inHostUtilitiesLayer = () => ({ + name: 'in-host-utilities-layer', + closeBundle() { + const fs = require('fs') + const file = path.resolve(__dirname, 'dist/style.css') + + if (!fs.existsSync(file)) { + return + } + + const css = fs.readFileSync(file, 'utf8').replace(/^@charset "[^"]*";\s*/, '') + fs.writeFileSync(file, `@layer theme, base, components, utilities;\n@layer utilities {\n${css}\n}\n`) + }, +}) + module.exports = defineConfig({ build: { lib: { @@ -24,5 +46,6 @@ module.exports = defineConfig({ viteExternalsPlugin({ vue: 'Vue', }), + inHostUtilitiesLayer(), ], }) From 23fd36f4baf66e1636b598da9eeed8af3430e7e9 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Thu, 24 Sep 2026 12:54:46 +0200 Subject: [PATCH 3/4] style: apply Pint Formatting only: imports for classes named in docblocks, sorted imports and trailing commas. The code has not matched Pint's Laravel preset, which the style check runs, since the module was imported. --- Config/config.php | 2 +- Helpers/VersionHelper.php | 16 +++++++------ .../ActivePaymentProvidersController.php | 6 ++--- Http/Controllers/PaymentController.php | 2 +- Http/Controllers/PaymentDriversController.php | 4 ++-- Http/Controllers/PaymentPdfController.php | 4 ++-- .../PaymentProvidersController.php | 17 ++++++------- Http/Requests/PaymentMethodRequest.php | 10 ++++---- .../ActivePaymentProviderCollection.php | 3 ++- .../ActivePaymentProviderResource.php | 5 ++-- Http/Resources/PaymentProviderCollection.php | 3 ++- Http/Resources/PaymentProviderResource.php | 3 ++- Listeners/ModuleDisabledListener.php | 1 - Providers/PaymentsServiceProvider.php | 7 +++--- Routes/api.php | 6 ++--- Routes/web.php | 1 - Services/PaymentProcessor.php | 8 +++---- Services/Paypal/PaymentProvider.php | 16 ++++++------- Services/Razorpay/PaymentProvider.php | 22 ++++++++--------- Services/Stripe/PaymentProvider.php | 24 +++++++++---------- Traits/AuthorizationTrait.php | 22 ++++++++--------- 21 files changed, 92 insertions(+), 90 deletions(-) diff --git a/Config/config.php b/Config/config.php index 4257a4d..cb04442 100644 --- a/Config/config.php +++ b/Config/config.php @@ -1,5 +1,5 @@ 'Payments' + 'name' => 'Payments', ]; diff --git a/Helpers/VersionHelper.php b/Helpers/VersionHelper.php index 51e1f7f..b772bd4 100644 --- a/Helpers/VersionHelper.php +++ b/Helpers/VersionHelper.php @@ -1,4 +1,5 @@ * @copyright 2024 Rihards Simanovics * @license GNU GPLv3 + * * @version GIT: + * * @link https://invoiceshelf.com */ @@ -33,9 +36,8 @@ class VersionHelper * This method checks the application version against a specified version using a comparison operator. * It temporarily aliases the Setting class to access the version information. * - * @param string $operator The comparison operator (e.g., '<', '>='). - * @param string $version The version to compare against. - * + * @param string $operator The comparison operator (e.g., '<', '>='). + * @param string $version The version to compare against. * @return bool True if the comparison is valid, false otherwise. */ public static function checkAppVersion($operator, $version) @@ -49,12 +51,12 @@ public static function checkAppVersion($operator, $version) /** * Alias old namespace classes to new ones if necessary. * - * @param string $oldClass The old class name with namespace. - * @param string $newClass The new class name with namespace. + * @param string $oldClass The old class name with namespace. + * @param string $newClass The new class name with namespace. */ public static function aliasClass($newClass, $oldClass) { - if (!class_exists($oldClass) && class_exists($newClass)) { + if (! class_exists($oldClass) && class_exists($newClass)) { class_alias($newClass, $oldClass); } } diff --git a/Http/Controllers/ActivePaymentProvidersController.php b/Http/Controllers/ActivePaymentProvidersController.php index 363bdbe..efd4ec4 100644 --- a/Http/Controllers/ActivePaymentProvidersController.php +++ b/Http/Controllers/ActivePaymentProvidersController.php @@ -6,8 +6,9 @@ use App\Models\Company; use App\Models\PaymentMethod; use Illuminate\Http\Request; -use Modules\Payments\Http\Resources\ActivePaymentProviderResource; +use Illuminate\Http\Response; use Modules\Payments\Helpers\VersionHelper; +use Modules\Payments\Http\Resources\ActivePaymentProviderResource; if (VersionHelper::checkAppVersion('<', '2.0.0')) { VersionHelper::aliasClass('InvoiceShelf\Http\Controllers\Controller', 'App\Http\Controllers\Controller'); @@ -20,8 +21,7 @@ class ActivePaymentProvidersController extends Controller /** * Handle the incoming request. * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response + * @return Response */ public function __invoke(Request $request, Company $company) { diff --git a/Http/Controllers/PaymentController.php b/Http/Controllers/PaymentController.php index 83f5009..68fe7af 100644 --- a/Http/Controllers/PaymentController.php +++ b/Http/Controllers/PaymentController.php @@ -6,8 +6,8 @@ use App\Models\Company; use App\Models\Invoice; use Illuminate\Http\Request; -use Modules\Payments\Services\PaymentProcessor; use Modules\Payments\Helpers\VersionHelper; +use Modules\Payments\Services\PaymentProcessor; if (VersionHelper::checkAppVersion('<', '2.0.0')) { VersionHelper::aliasClass('InvoiceShelf\Http\Controllers\Controller', 'App\Http\Controllers\Controller'); diff --git a/Http/Controllers/PaymentDriversController.php b/Http/Controllers/PaymentDriversController.php index ecf8dfc..10a16b0 100644 --- a/Http/Controllers/PaymentDriversController.php +++ b/Http/Controllers/PaymentDriversController.php @@ -4,6 +4,7 @@ use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use Illuminate\Http\Response; use Modules\Payments\Helpers\VersionHelper; if (VersionHelper::checkAppVersion('<', '2.0.0')) { @@ -15,8 +16,7 @@ class PaymentDriversController extends Controller /** * Handle the incoming request. * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response + * @return Response */ public function __invoke(Request $request) { diff --git a/Http/Controllers/PaymentPdfController.php b/Http/Controllers/PaymentPdfController.php index 6b29203..b57f940 100644 --- a/Http/Controllers/PaymentPdfController.php +++ b/Http/Controllers/PaymentPdfController.php @@ -6,6 +6,7 @@ use App\Models\Payment; use App\Models\Transaction; use Illuminate\Http\Request; +use Illuminate\Http\Response; use Modules\Payments\Helpers\VersionHelper; if (VersionHelper::checkAppVersion('<', '2.0.0')) { @@ -19,8 +20,7 @@ class PaymentPdfController extends Controller /** * Handle the incoming request. * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response + * @return Response */ public function __invoke(Transaction $transaction, Request $request) { diff --git a/Http/Controllers/PaymentProvidersController.php b/Http/Controllers/PaymentProvidersController.php index 46e815e..2ffff8d 100644 --- a/Http/Controllers/PaymentProvidersController.php +++ b/Http/Controllers/PaymentProvidersController.php @@ -5,10 +5,11 @@ use App\Http\Controllers\Controller; use App\Models\PaymentMethod; use Illuminate\Http\Request; +use Illuminate\Http\Response; +use Modules\Payments\Helpers\VersionHelper; use Modules\Payments\Http\Requests\PaymentMethodRequest; use Modules\Payments\Http\Resources\PaymentProviderResource; use Modules\Payments\Traits\AuthorizationTrait; -use Modules\Payments\Helpers\VersionHelper; if (VersionHelper::checkAppVersion('<', '2.0.0')) { VersionHelper::aliasClass('InvoiceShelf\Http\Controllers\Controller', 'App\Http\Controllers\Controller'); @@ -22,7 +23,7 @@ class PaymentProvidersController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return Response */ public function index(Request $request) { @@ -42,8 +43,8 @@ public function index(Request $request) /** * Store a newly created resource in storage. * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response + * @param Request $request + * @return Response */ public function store(PaymentMethodRequest $request) { @@ -65,7 +66,7 @@ public function store(PaymentMethodRequest $request) * Display the specified resource. * * @param \InvoiceShelf\Models\PaymentMethod $paymentMethod - * @return \Illuminate\Http\Response + * @return Response */ public function show(PaymentMethod $paymentProvider) { @@ -77,9 +78,9 @@ public function show(PaymentMethod $paymentProvider) /** * Update the specified resource in storage. * - * @param \Illuminate\Http\Request $request + * @param Request $request * @param \InvoiceShelf\Models\PaymentMethod $paymentMethod - * @return \Illuminate\Http\Response + * @return Response */ public function update(PaymentMethodRequest $request, PaymentMethod $paymentProvider) { @@ -101,7 +102,7 @@ public function update(PaymentMethodRequest $request, PaymentMethod $paymentProv * Remove the specified resource from storage. * * @param \InvoiceShelf\Models\PaymentMethod $paymentMethod - * @return \Illuminate\Http\Response + * @return Response */ public function destroy(PaymentMethod $paymentProvider) { diff --git a/Http/Requests/PaymentMethodRequest.php b/Http/Requests/PaymentMethodRequest.php index c5ff751..46a57cd 100644 --- a/Http/Requests/PaymentMethodRequest.php +++ b/Http/Requests/PaymentMethodRequest.php @@ -37,21 +37,21 @@ public function rules() ->where('company_id', $this->header('company')), ], 'driver' => [ - 'required' + 'required', ], 'active' => [ 'required', - 'boolean' + 'boolean', ], 'use_test_env' => [ 'required', - 'boolean' + 'boolean', ], 'settings' => [ - 'required' + 'required', ], 'settings.*' => [ - 'required' + 'required', ], ]; diff --git a/Http/Resources/ActivePaymentProviderCollection.php b/Http/Resources/ActivePaymentProviderCollection.php index b768932..14cf177 100644 --- a/Http/Resources/ActivePaymentProviderCollection.php +++ b/Http/Resources/ActivePaymentProviderCollection.php @@ -2,6 +2,7 @@ namespace Modules\Payments\Http\Resources; +use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; class ActivePaymentProviderCollection extends JsonResource @@ -9,7 +10,7 @@ class ActivePaymentProviderCollection extends JsonResource /** * Transform the resource into an array. * - * @param \Illuminate\Http\Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/Http/Resources/ActivePaymentProviderResource.php b/Http/Resources/ActivePaymentProviderResource.php index a16309b..5e046aa 100644 --- a/Http/Resources/ActivePaymentProviderResource.php +++ b/Http/Resources/ActivePaymentProviderResource.php @@ -2,6 +2,7 @@ namespace Modules\Payments\Http\Resources; +use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; class ActivePaymentProviderResource extends JsonResource @@ -9,7 +10,7 @@ class ActivePaymentProviderResource extends JsonResource /** * Transform the resource into an array. * - * @param \Illuminate\Http\Request $request + * @param Request $request * @return array */ public function toArray($request) @@ -19,7 +20,7 @@ public function toArray($request) 'name' => $this->name, 'type' => $this->type, 'driver' => $this->driver, - 'public_key' => $this->settings['key'] + 'public_key' => $this->settings['key'], ]; } } diff --git a/Http/Resources/PaymentProviderCollection.php b/Http/Resources/PaymentProviderCollection.php index c0b2ed7..845c3fc 100644 --- a/Http/Resources/PaymentProviderCollection.php +++ b/Http/Resources/PaymentProviderCollection.php @@ -2,6 +2,7 @@ namespace Modules\Payments\Http\Resources; +use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; class PaymentProviderCollection extends JsonResource @@ -9,7 +10,7 @@ class PaymentProviderCollection extends JsonResource /** * Transform the resource into an array. * - * @param \Illuminate\Http\Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/Http/Resources/PaymentProviderResource.php b/Http/Resources/PaymentProviderResource.php index dc021c6..a7d2200 100644 --- a/Http/Resources/PaymentProviderResource.php +++ b/Http/Resources/PaymentProviderResource.php @@ -3,6 +3,7 @@ namespace Modules\Payments\Http\Resources; use App\Http\Resources\CompanyResource; +use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; use Modules\Payments\Helpers\VersionHelper; @@ -15,7 +16,7 @@ class PaymentProviderResource extends JsonResource /** * Transform the resource into an array. * - * @param \Illuminate\Http\Request $request + * @param Request $request * @return array */ public function toArray($request) diff --git a/Listeners/ModuleDisabledListener.php b/Listeners/ModuleDisabledListener.php index 8d555f5..ea88108 100644 --- a/Listeners/ModuleDisabledListener.php +++ b/Listeners/ModuleDisabledListener.php @@ -25,7 +25,6 @@ public function __construct() /** * Handle the event. * - * @param ModuleDisabledEvent $event * @return void */ public function handle(ModuleDisabledEvent $event) diff --git a/Providers/PaymentsServiceProvider.php b/Providers/PaymentsServiceProvider.php index 041e908..8e52fb2 100644 --- a/Providers/PaymentsServiceProvider.php +++ b/Providers/PaymentsServiceProvider.php @@ -1,11 +1,12 @@ moduleName, 'Resources/views'); $this->publishes([ - $sourcePath => $viewPath + $sourcePath => $viewPath, ], ['views', $this->moduleNameLower.'-module-views']); $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower); @@ -137,7 +138,7 @@ public function registerMenu() 'icon' => 'CreditCardIcon', 'owner_only' => true, 'ability' => '', - 'model' => '' + 'model' => '', ]; \Menu::make('setting_menu', function ($menu) use ($data) { diff --git a/Routes/api.php b/Routes/api.php index 99a5b34..cd4ee70 100644 --- a/Routes/api.php +++ b/Routes/api.php @@ -16,9 +16,8 @@ | */ - // Admin Routes -//---------------------------------- +// ---------------------------------- Route::middleware(['auth:sanctum', 'company'])->group(function () { Route::get('payment-drivers', PaymentDriversController::class); @@ -26,9 +25,8 @@ Route::apiResource('payment-providers', PaymentProvidersController::class); }); - // Payment Routes -//---------------------------------- +// ---------------------------------- Route::get('/{company:slug}/active-payment-providers', ActivePaymentProvidersController::class); diff --git a/Routes/web.php b/Routes/web.php index 192fff3..52c337a 100644 --- a/Routes/web.php +++ b/Routes/web.php @@ -13,7 +13,6 @@ | */ - // payment pdf // ------------------------------------------------- diff --git a/Services/PaymentProcessor.php b/Services/PaymentProcessor.php index 8ac0fd6..8da804f 100644 --- a/Services/PaymentProcessor.php +++ b/Services/PaymentProcessor.php @@ -3,10 +3,10 @@ namespace Modules\Payments\Services; use App\Models\PaymentMethod; +use Modules\Payments\Helpers\VersionHelper; use Modules\Payments\Services\Paypal\PaymentProvider; use Modules\Payments\Services\Razorpay\PaymentProvider as RazorpayPaymentProvider; use Modules\Payments\Services\Stripe\PaymentProvider as StripePaymentProvider; -use Modules\Payments\Helpers\VersionHelper; if (VersionHelper::checkAppVersion('<', '2.0.0')) { VersionHelper::aliasClass('InvoiceShelf\Models\PaymentMethod', 'App\Models\PaymentMethod'); @@ -25,17 +25,17 @@ public function __construct() switch ($driver) { case 'stripe': - $this->paymentProvider = new StripePaymentProvider(); + $this->paymentProvider = new StripePaymentProvider; break; case 'razorpay': - $this->paymentProvider = new RazorpayPaymentProvider(); + $this->paymentProvider = new RazorpayPaymentProvider; break; case 'paypal': - $this->paymentProvider = new PaymentProvider(); + $this->paymentProvider = new PaymentProvider; break; } diff --git a/Services/Paypal/PaymentProvider.php b/Services/Paypal/PaymentProvider.php index 9ede358..91b2694 100644 --- a/Services/Paypal/PaymentProvider.php +++ b/Services/Paypal/PaymentProvider.php @@ -2,14 +2,14 @@ namespace Modules\Payments\Services\Paypal; -use Carbon\Carbon; use App\Models\Company; use App\Models\Payment; use App\Models\PaymentMethod; use App\Models\Transaction; +use Carbon\Carbon; use Illuminate\Support\Facades\Http; -use Modules\Payments\Services\PaymentInterface; use Modules\Payments\Helpers\VersionHelper; +use Modules\Payments\Services\PaymentInterface; if (VersionHelper::checkAppVersion('<', '2.0.0')) { VersionHelper::aliasClass('InvoiceShelf\Models\Company', 'App\Models\Company'); @@ -30,15 +30,15 @@ public function __construct() { $paymentProvider = PaymentMethod::find(request()->payment_method_id); $this->settings = $paymentProvider->settings; - $this->url = "https://api-m.paypal.com"; + $this->url = 'https://api-m.paypal.com'; if ($paymentProvider->use_test_env) { - $this->url = "https://api-m.sandbox.paypal.com"; + $this->url = 'https://api-m.sandbox.paypal.com'; } $response = Http::withHeaders([ 'Accept' => 'application/json', - 'Accept-Language' => 'en_US' + 'Accept-Language' => 'en_US', ]) ->withBasicAuth($this->settings['key'], $this->settings['secret']) ->withBody('grant_type=client_credentials', 'application/x-www-form-urlencoded') @@ -49,9 +49,7 @@ public function __construct() } } - public function generatePayment(Company $company, $invoice) - { - } + public function generatePayment(Company $company, $invoice) {} public function confirmTransaction(Company $company, $transaction_id, $request) { @@ -61,7 +59,7 @@ public function confirmTransaction(Company $company, $transaction_id, $request) 'status' => Transaction::PENDING, 'transaction_date' => Carbon::now(), 'invoice_id' => $request->invoice_id, - 'company_id' => $request->header('company') + 'company_id' => $request->header('company'), ]; $transaction = Transaction::createTransaction($data); diff --git a/Services/Razorpay/PaymentProvider.php b/Services/Razorpay/PaymentProvider.php index 5148918..74a7b22 100644 --- a/Services/Razorpay/PaymentProvider.php +++ b/Services/Razorpay/PaymentProvider.php @@ -2,15 +2,15 @@ namespace Modules\Payments\Services\Razorpay; -use Carbon\Carbon; use App\Models\Company; use App\Models\Currency; use App\Models\Payment; use App\Models\PaymentMethod; use App\Models\Transaction; +use Carbon\Carbon; use Illuminate\Support\Facades\Http; -use Modules\Payments\Services\PaymentInterface; use Modules\Payments\Helpers\VersionHelper; +use Modules\Payments\Services\PaymentInterface; if (VersionHelper::checkAppVersion('<', '2.0.0')) { VersionHelper::aliasClass('InvoiceShelf\Models\Company', 'App\Models\Company'); @@ -34,11 +34,11 @@ public function generatePayment(Company $company, $invoice) $currency = Currency::find($invoice->currency_id); $response = Http::withHeaders([ - 'Content-Type' => 'application/json', - 'Accept-Language' => 'en_US' - ]) + 'Content-Type' => 'application/json', + 'Accept-Language' => 'en_US', + ]) ->withBasicAuth($this->settings['key'], $this->settings['secret']) - ->post("https://api.razorpay.com/v1/orders", [ + ->post('https://api.razorpay.com/v1/orders', [ 'amount' => $invoice->total, 'currency' => $currency->code, ]); @@ -55,7 +55,7 @@ public function generatePayment(Company $company, $invoice) 'status' => Transaction::PENDING, 'transaction_date' => Carbon::now(), 'invoice_id' => $invoice->id, - 'company_id' => $invoice->company_id + 'company_id' => $invoice->company_id, ]; $transaction = Transaction::createTransaction($data); $response['transaction_unique_hash'] = $transaction->unique_hash; @@ -63,7 +63,7 @@ public function generatePayment(Company $company, $invoice) return [ 'order' => $response, 'key' => $this->settings['key'], - 'currency' => $currency + 'currency' => $currency, ]; } @@ -80,7 +80,7 @@ public function confirmTransaction(Company $company, $transaction_id, $request) return response()->json([ 'transaction' => $transaction, - 'payment' => $payment + 'payment' => $payment, ]); } @@ -94,8 +94,8 @@ public function confirmTransaction(Company $company, $transaction_id, $request) public function getOrder($transaction_id) { $response = Http::withHeaders([ - 'Accept' => 'application/json', - ]) + 'Accept' => 'application/json', + ]) ->withBasicAuth($this->settings['key'], $this->settings['secret']) ->get("https://api.razorpay.com/v1/orders/{$transaction_id}") ->json(); diff --git a/Services/Stripe/PaymentProvider.php b/Services/Stripe/PaymentProvider.php index b80eaa8..d329930 100644 --- a/Services/Stripe/PaymentProvider.php +++ b/Services/Stripe/PaymentProvider.php @@ -2,15 +2,15 @@ namespace Modules\Payments\Services\Stripe; -use Carbon\Carbon; use App\Models\Company; use App\Models\Currency; use App\Models\Payment; use App\Models\PaymentMethod; use App\Models\Transaction; +use Carbon\Carbon; use Illuminate\Support\Facades\Http; -use Modules\Payments\Services\PaymentInterface; use Modules\Payments\Helpers\VersionHelper; +use Modules\Payments\Services\PaymentInterface; if (VersionHelper::checkAppVersion('<', '2.0.0')) { VersionHelper::aliasClass('InvoiceShelf\Models\Company', 'App\Models\Company'); @@ -28,7 +28,7 @@ public function __construct() { $settings = PaymentMethod::getSettings(request()->payment_method_id); - $this->settings = $settings["secret"]; + $this->settings = $settings['secret']; } public function generatePayment(Company $company, $invoice) @@ -37,12 +37,12 @@ public function generatePayment(Company $company, $invoice) $total = $invoice->total; $response = Http::withHeaders([ - 'Accept' => 'application/json', - 'Accept-Language' => 'en_US' - ]) + 'Accept' => 'application/json', + 'Accept-Language' => 'en_US', + ]) ->withToken($this->settings) ->withBody("amount={$total}¤cy={$currency->code}", 'application/x-www-form-urlencoded') - ->post("https://api.stripe.com/v1/payment_intents"); + ->post('https://api.stripe.com/v1/payment_intents'); if ($response->status() !== 200) { return $response->json(); @@ -56,7 +56,7 @@ public function generatePayment(Company $company, $invoice) 'status' => Transaction::PENDING, 'transaction_date' => Carbon::now(), 'invoice_id' => $invoice->id, - 'company_id' => $company->id + 'company_id' => $company->id, ]; $transaction = Transaction::createTransaction($data); @@ -64,7 +64,7 @@ public function generatePayment(Company $company, $invoice) return [ 'order' => $response, - 'currency' => $currency + 'currency' => $currency, ]; } @@ -81,7 +81,7 @@ public function confirmTransaction(Company $company, $transaction_id, $request) return response()->json([ 'transaction' => $transaction, - 'payment' => $payment + 'payment' => $payment, ]); } @@ -101,8 +101,8 @@ public function confirmTransaction(Company $company, $transaction_id, $request) public function getOrder($transaction_id) { $response = Http::withHeaders([ - 'Accept' => 'application/json', - ]) + 'Accept' => 'application/json', + ]) ->withToken($this->settings) ->get("https://api.stripe.com/v1/payment_intents/{$transaction_id}") ->json(); diff --git a/Traits/AuthorizationTrait.php b/Traits/AuthorizationTrait.php index d77e805..6d886de 100644 --- a/Traits/AuthorizationTrait.php +++ b/Traits/AuthorizationTrait.php @@ -8,21 +8,21 @@ trait AuthorizationTrait { public function checkAuthorization($driver, $key, $secret, $useTestEnv = false) { - //paypal authorization + // paypal authorization if ($driver == 'paypal') { - $url = "https://api-m.paypal.com"; + $url = 'https://api-m.paypal.com'; if ($useTestEnv) { - $url = "https://api-m.sandbox.paypal.com"; + $url = 'https://api-m.sandbox.paypal.com'; } $response = Http::withHeaders([ 'Accept' => 'application/json', - 'Accept-Language' => 'en_US' + 'Accept-Language' => 'en_US', ]) - ->withBasicAuth($key, $secret) - ->withBody('grant_type=client_credentials', 'application/x-www-form-urlencoded') - ->post("{$url}/v1/oauth2/token"); + ->withBasicAuth($key, $secret) + ->withBody('grant_type=client_credentials', 'application/x-www-form-urlencoded') + ->post("{$url}/v1/oauth2/token"); if ($response->getStatusCode() == 200) { return true; @@ -31,9 +31,9 @@ public function checkAuthorization($driver, $key, $secret, $useTestEnv = false) return false; } - //stripe authorization + // stripe authorization if ($driver == 'stripe') { - $response = Http::withToken($secret)->get("https://api.stripe.com/v1/orders"); + $response = Http::withToken($secret)->get('https://api.stripe.com/v1/orders'); if ($response->getStatusCode() == 200) { return true; @@ -42,9 +42,9 @@ public function checkAuthorization($driver, $key, $secret, $useTestEnv = false) return false; } - //razorpay authorization + // razorpay authorization if ($driver == 'razorpay') { - $response = Http::withBasicAuth($key, $secret)->get("https://api.razorpay.com/v1/orders"); + $response = Http::withBasicAuth($key, $secret)->get('https://api.razorpay.com/v1/orders'); if ($response->getStatusCode() == 200) { return true; From 3a1632825ac49448f04cc99b8aeac463ee8571a5 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Thu, 24 Sep 2026 12:54:46 +0200 Subject: [PATCH 4/4] ci: run the style check for real, drop the jobs copied from the app The check workflow was InvoiceShelf's own: it ran pint from a vendor directory the module never installs, then php artisan test and a make dist of InvoiceShelf.zip, which a module has none of, so it failed on every push. It now installs Pint 1.29.0 through setup-php and checks the code style; release.yaml builds the module's zip. --- .github/workflows/check.yaml | 108 ++++------------------------------- 1 file changed, 10 insertions(+), 98 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index f0ba489..e4316ad 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -31,113 +31,25 @@ jobs: with: access_token: ${{ github.token }} + # A copy of InvoiceShelf's own workflow used to run here: `pint` from a + # vendor directory the module never installs, `php artisan test` and a + # `make dist` of InvoiceShelf.zip, none of which a module has. It is now the + # style check alone; release.yaml builds the module's zip. php_syntax_errors: name: 1️⃣ PHP Code Style errors runs-on: ubuntu-latest needs: - kill_previous steps: - - name: Set up PHP + - name: Set up PHP with Pint uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.4 + tools: pint:1.29.0 + coverage: none - name: Checkout code uses: actions/checkout@v4 - - name: Install dependencies - uses: ramsey/composer-install@v2 - - - name: Check source code for syntax errors - run: ./vendor/bin/pint --test - - tests: - name: 2️⃣ PHP ${{ matrix.php-version }} Tests - needs: - - php_syntax_errors - runs-on: ubuntu-latest - strategy: - matrix: - php-version: - - 8.2 - - 8.3 - env: - extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup PHP Action - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: ${{ env.extensions }} - coverage: xdebug - tools: pecl, composer - - - name: Install Composer dependencies - uses: ramsey/composer-install@v2 - - - name: Use Node.js 20 - uses: actions/setup-node@v3 - with: - node-version: 20 - - - name: Install - run: npm install - - - name: Compile Front-end - run: npm run build - - - name: Apply tests ${{ matrix.php-version }} - run: php artisan test - - createReleaseFile: - name: 3️⃣ Build / Upload - Release File - if: github.ref_type == 'tag' - needs: - - tests - runs-on: ubuntu-latest - env: - extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.2 - extensions: ${{ env.extensions }} - coverage: none - - - name: Install Composer dependencies - uses: ramsey/composer-install@v2 - with: - composer-options: --no-dev - - - name: Use Node.js 20 - uses: actions/setup-node@v3 - with: - node-version: 20 - - - name: Install - run: npm install - - - name: Compile Front-end - run: npm run build - - - name: Build Dist - run: | - make clean dist - - - name: Upload package - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ github.token }} - file: InvoiceShelf.zip - asset_name: InvoiceShelf.zip - tag: ${{ github.ref }} - overwrite: true + - name: Check code style + run: pint --test