PHP code example of glueful / payvia

1. Go to this page and download the library: Download glueful/payvia library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

glueful / payvia example snippets


// config/extensions.php
return [
    'enabled' => [
        'Glueful\\Extensions\\Payvia\\PayviaServiceProvider',
        // other providers...
    ],
];

return [
    'default_gateway' => env('PAYVIA_DEFAULT_GATEWAY', 'paystack'),

    // How long a PROVIDER-CONFIRMED "this hosted session is still live" answer is trusted
    // before ensure-live asks the provider again. Only a confirmed-live probe refreshes the
    // stamp; dead/unknown answers never do, and a brand-new attempt is never suppressed.
    // Set to 0 to always probe.
    'session_liveness_cooldown_seconds' => (int) env('PAYVIA_SESSION_LIVENESS_COOLDOWN_SECONDS', 30),

    'intents' => [
        // How long an `initializing`/`open` payment_intents row may sit UNTOUCHED before
        // `payvia:intents:sweep-stale` retires it to `failed`, freeing its payable's active
        // idempotency port. Age is the only criterion. Clamped to 1..365 days at read time.
        'stale_after_days' => (int) env('PAYVIA_INTENTS_STALE_AFTER_DAYS', 30),
    ],

    'gateways' => [
        'paystack' => [
            'enabled' => (bool) env('PAYVIA_PAYSTACK_ENABLED', true),
            'driver' => 'paystack',
            'secret_key' => env('PAYVIA_PAYSTACK_SECRET_KEY', env('PAYSTACK_SECRET_KEY', null)),
            'webhook_secret' => env('PAYVIA_PAYSTACK_WEBHOOK_SECRET', env('PAYVIA_PAYSTACK_SECRET_KEY', env('PAYSTACK_SECRET_KEY', null))),
            'base_url' => env('PAYVIA_PAYSTACK_BASE_URL', 'https://api.paystack.co'),
            'timeout' => (int) env('PAYVIA_PAYSTACK_TIMEOUT', 15),
            // Hosted-redirect trust boundary: the ONLY hosts a returned `authorization_url`
            // may live on. File-config only -- not overridable via PayviaSettings.
            'checkout_hosts' => ['checkout.paystack.com'],
        ],
        'stripe' => [
            'enabled' => (bool) env('PAYVIA_STRIPE_ENABLED', false),
            'driver' => 'stripe',
            'secret_key' => env('PAYVIA_STRIPE_SECRET_KEY', null),
            'webhook_secret' => env('PAYVIA_STRIPE_WEBHOOK_SECRET', null),
            'webhook_tolerance' => (int) env('PAYVIA_STRIPE_WEBHOOK_TOLERANCE', 300),
            'base_url' => env('PAYVIA_STRIPE_BASE_URL', 'https://api.stripe.com'),
            'timeout' => (int) env('PAYVIA_STRIPE_TIMEOUT', 15),
            // Same trust boundary as paystack above, applied to the Checkout Session `url`
            // for both one-time and subscription sessions.
            'checkout_hosts' => ['checkout.stripe.com'],
        ],
    ],

    'features' => [
        'store_raw_payload' => (bool) env('PAYVIA_STORE_RAW_PAYLOAD', true),
    ],

    'security' => [
        // Three ordered profiles composed onto every /payvia/* route except the webhook
        // route (which stays signature-authenticated/tenantless). See "Middleware profiles
        // and tenancy" below.
        'auth_middleware' => ['auth'],
        'tenant_context_middleware' => [],
        'manage_middleware' => ['admin'],
    ],

    'webhooks' => [
        'queue' => (bool) env('PAYVIA_WEBHOOKS_QUEUE', false),
        'queue_name' => env('PAYVIA_WEBHOOKS_QUEUE_NAME', 'default'),
        'relay_stale_seconds' => (int) env('PAYVIA_WEBHOOKS_RELAY_STALE_SECONDS', 300),
    ],
];

namespace Glueful\Extensions\Payvia\Contracts;

interface StrictPaymentEventListener
{
    public const CONTAINER_TAG = 'payvia.strict_payment_event_listeners';

    public function supports(PaymentProviderEventInterface $event): bool;

    public function handle(PaymentProviderEventInterface $event): void;
}

use Glueful\Extensions\Payvia\Contracts\StrictPaymentEventListener;

public static function services(): array
{
    return [
        // ... other services ...
        MyStrictEventListener::class => [
            'class' => MyStrictEventListener::class,
            'shared' => true,
            'autowire' => true,
            'tags' => [StrictPaymentEventListener::CONTAINER_TAG],
        ],
    ];
}

$manager->supports('stripe', 'subscription_checkout');  // true
$manager->supports('stripe', 'cancellation_modes');     // true

$acknowledger->acknowledge(
    originationUuid: $originationUuid,
    consumer: 'subscriptions',
    logicalEventKey: $event->logicalEventKey(),
    outcome: 'accepted',   // or 'rejected'
    reason: null,          // 

// config/payvia.php (application override — neutral defaults shown; single-store
// installs can leave this block out entirely)
return [
    'security' => [
        // Profile 1 — authentication.
        'auth_middleware' => ['auth'],

        // Profile 2 — tenant context. Empty by default; a tenancy-enabled host sets
        // this to whatever establishes request-scoped tenant context before Payvia's
        // repositories run (Payvia never names or hardcodes host-specific aliases here).
        'tenant_context_middleware' => [],

        // Profile 3 — authorization for the management (write) routes only.
        'manage_middleware' => ['admin'],
    ],
];

use Glueful\Extensions\Payvia\Services\PaymentService;

/** @var PaymentService $payments */
$payments = container()->get(PaymentService::class);

$result = $payments->confirmAndRecord(
    reference: 'PSK_tx_ref_123456',
    gatewayName: 'paystack', // or null to use default
    context: [
        'user_uuid' => $userUuid,
        'payable_type' => 'subscription',
        'payable_id' => $subscriptionId,
        'metadata' => [
            'source' => 'web_checkout',
            'campaign' => 'black_friday',
        ],
    ]
);

if (($result['payment_status'] ?? '') === 'success') {
    // Start subscription, mark invoice paid, etc.
}

use Glueful\Extensions\Payvia\Services\BillingPlanService;

/** @var BillingPlanService $plans */
$plans = container()->get(BillingPlanService::class);

// Create a plan
$planUuid = $plans->create([
    'name' => 'Pro Monthly',
    'description' => 'Pro plan billed monthly',
    'amount' => 9900, // minor units of `currency` (cents); $99.00 = 9900
    'currency' => 'USD',
    'interval' => 'monthly',
    'trial_days' => 14,
    'gateway' => 'stripe',
    'gateway_product_id' => 'prod_123',
    'gateway_price_id' => 'price_123',
]);

// List active monthly plans
$activePlans = $plans->list([
    'status' => 'active',
    'interval' => 'monthly',
]);

use Glueful\Extensions\Payvia\Services\InvoiceService;

/** @var InvoiceService $invoices */
$invoices = container()->get(InvoiceService::class);

// Create an invoice linked to a plan and payable entity
$invoiceUuid = $invoices->create([
    'user_uuid' => $userUuid,
    'billing_plan_uuid' => $planUuid,
    'payable_type' => 'location_subscription',
    'payable_id' => $locationUuid,
    'amount' => 9900, // minor units of `currency` (cents); $99.00 = 9900
    'currency' => 'USD',
    'status' => 'pending',
    'metadata' => [
        'period' => '2025-01',
        'source' => 'subscription_renewal',
    ],
]);

// After a successful payment, mark the invoice as paid
$invoices->markPaid($invoiceUuid);

// List paid invoices for a user for a given period
$userInvoices = $invoices->list([
    'user_uuid' => $userUuid,
    'status' => 'paid',
    'metadata_contains' => [
        'key' => 'period',
        'value' => '2025-01',
    ],
]);
bash
php glueful extensions:enable payvia
# disable with: php glueful extensions:disable payvia
bash
php glueful extensions:list
php glueful extensions:info payvia
php glueful extensions:diagnose
bash
php glueful migrate run
bash
php glueful payvia:intents:sweep-stale [--limit=200] [--stale-after-days=30] [--tenant=UUID]
text
POST /payvia/webhooks/paystack
POST /payvia/webhooks/stripe
bash
curl -s "$API_BASE/payvia/invoices?user_uuid=$USER_UUID&metadata_key=period&metadata_value=2025-01" \
  -H "Authorization: Bearer $TOKEN"