byrcsc/laravel-payrex · 1.x
Eloquent customers.
Associate an Eloquent model with a PayRex customer using the HasPayrexCustomer concern and publishable migration.
The HasPayrexCustomer concern ties any Eloquent model to one PayRex customer.
It is commonly added to User, but the package does not require a particular
model.
Publish the migration
php artisan vendor:publish --tag="payrex-migrations"The migration adds a nullable payrex_customer_id column to users by
default. Review the table and column before running it:
php artisan migrateAdd the concern
namespace App\Models;
use ByRcsc\LaravelPayrex\Concerns\HasPayrexCustomer;
use Illuminate\Foundation\Auth\User as Authenticatable;
final class User extends Authenticatable
{
use HasPayrexCustomer;
}By default, the concern reads name and email, stores the ID in
payrex_customer_id, and creates customers in Currency::PHP.
Create and retrieve a customer
$customer = $user->createAsPayrexCustomer();
$user->payrexCustomerId();
$user->hasPayrexCustomerId();
$user->asPayrexCustomer();createAsPayrexCustomer() saves the returned cus_... ID on the model. It
throws CustomerAlreadyCreatedException instead of creating a second remote
customer and orphaning the first.
Use the create-or-read helper when either state is valid:
$customer = $user->createOrGetPayrexCustomer();Update and delete
Push the model's current name and email to PayRex:
$customer = $user->updatePayrexCustomer();Delete the remote customer and clear the local ID:
$deleted = $user->deleteAsPayrexCustomer();Methods that require an ID throw CustomerNotCreatedException when the model
has not been registered yet.
Read saved payment methods
$methods = $user->payrexPaymentMethods(limit: 25);This returns the same Listing<PaymentMethod> as
customers()->listPaymentMethods().
Override model conventions
Every naming decision is a method so models with a different schema can override only what changes:
use ByRcsc\LaravelPayrex\Enums\Currency;
final class Merchant extends Model
{
use HasPayrexCustomer;
public function payrexCustomerIdColumn(): string
{
return 'gateway_customer_id';
}
public function payrexCustomerName(): string
{
return (string) $this->legal_name;
}
public function payrexCustomerEmail(): string
{
return (string) $this->billing_email;
}
public function payrexCustomerCurrency(): Currency
{
return Currency::PHP;
}
}If you override the ID column, update the published migration to match.
Pass additional fields
The create and update helpers accept options merged over their derived name, email, and currency:
$customer = $user->createAsPayrexCustomer([
'billing_details' => [
'phone' => $user->phone,
],
'metadata' => [
'user_id' => (string) $user->getKey(),
],
]);Options also let you override a derived field, so use them deliberately.
Concurrency
The concern prevents a second customer only after the model has an ID. If two
workers call createAsPayrexCustomer() concurrently, both can observe an empty
column before either saves. Serialize customer creation for the same model
with an application lock or database-level workflow when concurrent calls are
possible.