diff --git a/README.md b/README.md index f835886..520038b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ composer require codetech/laravel-eupago Publish the migrations: ```bash -php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=migrations +php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=eupago-migrations ``` Run the migrations: diff --git a/UPGRADE.md b/UPGRADE.md index 6027eb4..6ebc920 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,53 @@ # Upgrading +## From v3.9.x to v3.10.0 + +The publish tags are now prefixed with the package name: `eupago-migrations`, `eupago-config` and `eupago-translations`. The old `migrations`, `config` and `translations` tags keep working. + +On MySQL and MariaDB, the migrations for the `paysafecard_references` and `credit_card_references` tables used to fail with "Identifier name ... is too long", leaving the table created but the migration unrecorded. If that happened to you, drop the table the error names: + +```bash +php artisan tinker --execute="Schema::dropIfExists('paysafecard_references')" +``` + +Delete the published copy of that migration, since publishing never overwrites an existing file: + +```bash +rm database/migrations/2026_06_29_000000_create_paysafecard_references_table.php +``` + +Re-publish the migrations to get the fixed version: + +```bash +php artisan vendor:publish --provider=CodeTech\\EuPago\\Providers\\EuPagoServiceProvider --tag=eupago-migrations +``` + +Run the migrations: + +```bash +php artisan migrate +``` + +If the error named `credit_card_references` instead, repeat the same steps with that table and `2026_09_05_000000_create_credit_card_references_table.php`. + +Translations used to be published to `resources/lang/vendor/eupago`. Creating `resources/lang` makes Laravel use it as the app's lang path, so an app that keeps its translations in `lang/` stopped loading them. If you published the translations, create the new location: + +```bash +mkdir -p lang/vendor +``` + +Move the package's translations there: + +```bash +mv resources/lang/vendor/eupago lang/vendor/eupago +``` + +If `resources/lang` is now empty, remove it so Laravel goes back to `lang/`: + +```bash +rmdir resources/lang/vendor resources/lang +``` + ## From v3.8.x to v3.9.0 Multibanco, MB WAY, PayShop and PaysafeCard references now store the Eupago transaction their callback delivers, so a paid reference can be refunded through `$reference->transaction_id`. A new migration adds the column. Re-publish the migrations, which leaves the existing files untouched: diff --git a/database/migrations/2026_06_29_000000_create_paysafecard_references_table.php b/database/migrations/2026_06_29_000000_create_paysafecard_references_table.php index 855698f..c5180c9 100644 --- a/database/migrations/2026_06_29_000000_create_paysafecard_references_table.php +++ b/database/migrations/2026_06_29_000000_create_paysafecard_references_table.php @@ -20,7 +20,7 @@ public function up() $table->text('url')->nullable(); $table->decimal('value', 10, 2)->default(0); $table->integer('state')->default(0); - $table->morphs('paysafecardable'); + $table->morphs('paysafecardable', 'paysafecard_references_morph_index'); $table->timestamps(); }); } diff --git a/database/migrations/2026_07_15_000000_change_mbway_references_value_to_decimal.php b/database/migrations/2026_07_15_000000_change_mbway_references_value_to_decimal.php index 2c1d1a8..2f94cfc 100644 --- a/database/migrations/2026_07_15_000000_change_mbway_references_value_to_decimal.php +++ b/database/migrations/2026_07_15_000000_change_mbway_references_value_to_decimal.php @@ -13,10 +13,18 @@ * reference with an equality lookup — float rounding could make a * legitimate callback miss the row, leaving a real payment pending. * + * Skipped on SQLite: its column types are only affinities, so FLOAT and + * DECIMAL compare alike, and on Laravel 10 changing a SQLite column + * requires doctrine/dbal, which would abort every later migration. + * * @return void */ public function up() { + if (Schema::getConnection()->getDriverName() === 'sqlite') { + return; + } + Schema::table('mbway_references', function (Blueprint $table) { $table->decimal('value', 10, 2)->default(0)->change(); }); @@ -33,6 +41,10 @@ public function up() */ public function down() { + if (Schema::getConnection()->getDriverName() === 'sqlite') { + return; + } + Schema::table('mbway_references', function (Blueprint $table) { $table->float('value')->default(0)->change(); }); diff --git a/database/migrations/2026_09_05_000000_create_credit_card_references_table.php b/database/migrations/2026_09_05_000000_create_credit_card_references_table.php index 89b28b6..c19a101 100644 --- a/database/migrations/2026_09_05_000000_create_credit_card_references_table.php +++ b/database/migrations/2026_09_05_000000_create_credit_card_references_table.php @@ -25,7 +25,7 @@ public function up() $table->text('url')->nullable(); $table->decimal('value', 10, 2)->default(0); $table->integer('state')->default(0); - $table->morphs('creditcardable'); + $table->morphs('creditcardable', 'credit_card_references_morph_index'); $table->timestamps(); }); } diff --git a/docs/configuration.md b/docs/configuration.md index 7ada458..deecd18 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,7 +43,7 @@ The package supports two levels of usage: - **Full integration** (default): use the traits and models to persist references, and let the package handle Eupago's webhooks — it registers the callback routes (`/eupago/*/callback`) automatically. -- **Thin API client**: use only the payment classes (e.g. `new MB(...)->create()`) and handle +- **Thin API client**: use only the payment classes (e.g. `(new MB(...))->create()`) and handle persistence and webhooks yourself. If you only need the thin client, disable the automatic route registration: diff --git a/docs/credit-card.md b/docs/credit-card.md index 3336762..faaed4e 100644 --- a/docs/credit-card.md +++ b/docs/credit-card.md @@ -11,6 +11,20 @@ own `id` (e.g. the order id), which Eupago echoes back in the callback as `identificador`, the customer's email, and the three URLs the customer is forwarded to when the payment succeeds, fails, or they press back on the form. +References are stored against your own models, so add the `HasCreditCardReferences` trait to each +model that takes Credit Card payments: + +```php +use CodeTech\EuPago\Traits\HasCreditCardReferences; + +class Order extends Model +{ + use HasCreditCardReferences; +} +``` + +Then create the payment and save it through the trait's relationship: + ```php use CodeTech\EuPago\CreditCard\CreditCard; @@ -85,20 +99,9 @@ $creditCard->getErrors(); // ['APIKEY_MISSING' => 'API Key was not available in the request'] ``` -## Using the trait - -Alternatively, use the `HasCreditCardReferences` trait: - -```php -use CodeTech\EuPago\Traits\HasCreditCardReferences; - -class Order extends Model -{ - use HasCreditCardReferences; -} -``` +## Creating and saving in one call -With the trait applied, you can create and persist a reference in a single call. It +The trait can also create and persist a reference in a single call. It returns the persisted reference (whose `url` you redirect to) on success, or the errors on failure: diff --git a/docs/installation.md b/docs/installation.md index e3fede5..e2712c9 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -15,7 +15,7 @@ The service provider is registered automatically via package discovery. Publish the migrations: ```bash -php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=migrations +php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=eupago-migrations ``` Run the migrations: @@ -27,11 +27,11 @@ php artisan migrate Optionally, publish the configuration file: ```bash -php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=config +php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=eupago-config ``` You can also publish the translations: ```bash -php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=translations +php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=eupago-translations ``` diff --git a/docs/mbway.md b/docs/mbway.md index a77b512..9321c3b 100644 --- a/docs/mbway.md +++ b/docs/mbway.md @@ -5,7 +5,21 @@ group: Payment methods --- Create an MB WAY payment request — the customer confirms it on their phone through the -MB WAY app: +MB WAY app. + +References are stored against your own models, so add the `HasMbWayReferences` trait to each +model that takes MB WAY payments: + +```php +use CodeTech\EuPago\Traits\HasMbWayReferences; + +class Order extends Model +{ + use HasMbWayReferences; +} +``` + +Then create the payment and save it through the trait's relationship: ```php use CodeTech\EuPago\MBWay\MBWay; @@ -32,18 +46,10 @@ try { } ``` -## Using the trait - -Alternatively, use the `HasMbWayReferences` trait: - -```php -use CodeTech\EuPago\Traits\HasMbWayReferences; +## Creating and saving in one call -class Order extends Model -{ - use HasMbWayReferences; -} -``` +The trait can also create and persist a reference in a single call. It returns the +persisted reference on success, or the errors on failure: ```php $reference = $order->createMbwayReference($value, $id, $alias); diff --git a/docs/multibanco.md b/docs/multibanco.md index e728af3..e825575 100644 --- a/docs/multibanco.md +++ b/docs/multibanco.md @@ -4,7 +4,19 @@ weight: 5 group: Payment methods --- -Create an MB reference: +References are stored against your own models, so add the `HasMultibancoReferences` trait to each +model that takes MB references: + +```php +use CodeTech\EuPago\Traits\HasMultibancoReferences; + +class Order extends Model +{ + use HasMultibancoReferences; +} +``` + +Then create the payment and save it through the trait's relationship: ```php use CodeTech\EuPago\MB\MB; @@ -44,24 +56,16 @@ try { 'entity' => "82167", 'reference' => "000001236", 'value' => "3.00000", + 'min_value' => "3.00000", + 'max_value' => "3.00000", + 'start_date' => "2026-06-01", + 'end_date' => "2026-06-04", ] ``` -## Using the trait - -Alternatively, use the `HasMultibancoReferences` trait on the models for which you want -to generate MB references: - -```php -use CodeTech\EuPago\Traits\HasMultibancoReferences; - -class Order extends Model -{ - use HasMultibancoReferences; -} -``` +## Creating and saving in one call -With the trait applied, you can create and persist a reference in a single call. It +The trait can also create and persist a reference in a single call. It returns the persisted reference on success, or the errors on failure: ```php diff --git a/docs/paysafecard.md b/docs/paysafecard.md index 8dae30c..5f2c3d3 100644 --- a/docs/paysafecard.md +++ b/docs/paysafecard.md @@ -11,6 +11,20 @@ returns a payment `url` that you must redirect the customer to, along with a and you may optionally pass a `url_retorno` to control where the customer lands after paying. +References are stored against your own models, so add the `HasPaysafeCardReferences` trait to each +model that takes PaysafeCard payments: + +```php +use CodeTech\EuPago\Traits\HasPaysafeCardReferences; + +class Order extends Model +{ + use HasPaysafeCardReferences; +} +``` + +Then create the payment and save it through the trait's relationship: + ```php use CodeTech\EuPago\PaysafeCard\PaysafeCard; @@ -52,20 +66,9 @@ try { ] ``` -## Using the trait - -Alternatively, use the `HasPaysafeCardReferences` trait: - -```php -use CodeTech\EuPago\Traits\HasPaysafeCardReferences; - -class Order extends Model -{ - use HasPaysafeCardReferences; -} -``` +## Creating and saving in one call -With the trait applied, you can create and persist a reference in a single call. It +The trait can also create and persist a reference in a single call. It returns the persisted reference (whose `url` you redirect to) on success, or the errors on failure: diff --git a/docs/payshop.md b/docs/payshop.md index a3d229d..f38b9a1 100644 --- a/docs/payshop.md +++ b/docs/payshop.md @@ -4,7 +4,19 @@ weight: 7 group: Payment methods --- -Create a PayShop reference: +References are stored against your own models, so add the `HasPayShopReferences` trait to each +model that takes PayShop references: + +```php +use CodeTech\EuPago\Traits\HasPayShopReferences; + +class Order extends Model +{ + use HasPayShopReferences; +} +``` + +Then create the payment and save it through the trait's relationship: ```php use CodeTech\EuPago\PayShop\PayShop; @@ -41,18 +53,10 @@ try { ] ``` -## Using the trait +## Creating and saving in one call -Alternatively, use the `HasPayShopReferences` trait: - -```php -use CodeTech\EuPago\Traits\HasPayShopReferences; - -class Order extends Model -{ - use HasPayShopReferences; -} -``` +The trait can also create and persist a reference in a single call. It returns the +persisted reference on success, or the errors on failure: ```php $reference = $order->createPayShopReference($value, $id); diff --git a/src/Providers/EuPagoServiceProvider.php b/src/Providers/EuPagoServiceProvider.php index ad96c54..6af29ac 100644 --- a/src/Providers/EuPagoServiceProvider.php +++ b/src/Providers/EuPagoServiceProvider.php @@ -66,16 +66,20 @@ private function loadRoutes() */ private function setPublishableFiles() { + // The unprefixed tags are kept for backward compatibility; the docs use the prefixed ones. $this->publishes([ __DIR__.'/../../database/migrations/' => database_path('migrations'), - ], 'migrations'); + ], ['eupago-migrations', 'migrations']); + // Publishing into resources/lang would create that directory, and Laravel + // then uses it as the app's lang path instead of lang/, hiding the app's + // own translations. $this->publishes([ - __DIR__.'/../../resources/lang' => resource_path('lang/vendor/eupago'), - ], 'translations'); + __DIR__.'/../../resources/lang' => $this->app->langPath('vendor/eupago'), + ], ['eupago-translations', 'translations']); $this->publishes([ __DIR__.'/../../config/eupago.php' => config_path('eupago.php'), - ], 'config'); + ], ['eupago-config', 'config']); } } diff --git a/tests/Feature/PublishingTest.php b/tests/Feature/PublishingTest.php new file mode 100644 index 0000000..dc0e869 --- /dev/null +++ b/tests/Feature/PublishingTest.php @@ -0,0 +1,30 @@ +not->toBeEmpty() + ->and(ServiceProvider::pathsToPublish(EuPagoServiceProvider::class, $legacy))->toBe($paths); +})->with([ + ['eupago-config', 'config'], + ['eupago-migrations', 'migrations'], + ['eupago-translations', 'translations'], +]); + +it('publishes the translations into the app lang path', function () { + $paths = ServiceProvider::pathsToPublish(EuPagoServiceProvider::class, 'eupago-translations'); + + expect(array_values($paths))->toBe([lang_path('vendor/eupago')]); +}); + +it('keeps every index name within the MySQL 64-character limit', function () { + $names = collect(DB::select("select name from sqlite_master where type = 'index' and name not like 'sqlite_%'")) + ->pluck('name'); + + expect($names)->not->toBeEmpty() + ->and($names->filter(fn (string $name) => strlen($name) > 64)->all())->toBe([]); +});