Payavel Documentation

website·Indexed 29 days ago

https://payavel.com

A modular commerce ecosystem providing a core Orchestration layer for integrating third-party services and a Checkout package for processing and managing payments. The platform features a unified API, multi-driver support, and tools for routing payments and managing service configurations within Laravel applications.

Tokens
6.1K
Snippets
33
Records
45
Agent score
50%

What's inside Payavel

  1. Overview of the Payavel modular commerce ecosystem

    Payavel is a suite of independent, decoupled packages for Laravel developers designed to build custom End-to-End (E2E) revenue workflows. Instead of a rigid solution, it provides an orchestration layer that allows developers to write business logic against a unified API, enabling the hot-swapping of payment gateways and providers without modifying core application code.
  2. Install Payavel Orchestration in Laravel

    The Payavel Orchestration package provides a standardized architecture for integrating third-party services into Laravel, allowing developers to swap providers and mock APIs without modifying core business logic.

    Prerequisites:

    • PHP 8.1+
    • Laravel 10.0+
    composer require payavel/orchestration
  3. Integrate payment processing with Payavel Checkout

    Payavel Checkout is a dedicated package for Laravel applications used to integrate, process, and manage payments. It provides an abstraction layer over various payment providers (such as Stripe, Adyen, and Braintree), allowing developers to capture one-time payments, authorize funds, and handle multi-gateway flows without tying application logic to a specific vendor. It is built on top of the Payavel Orchestration layer to decouple payment workflows from the underlying gateway implementation details.
  4. Implement Multi-Provider Architecture in Payavel

    Payavel's Multi-Provider Architecture decouples provider credentials and configurations from business logic. This allows developers to switch between different service providers or tenant accounts at runtime by updating a configuration file or passing a new context, without needing to modify the core application logic.
  5. Understand the Orchestration service file structure

    The Orchestration package organizes service-related files within the app/Services directory. Each service (e.g., Checkout) has its own subdirectory containing contracts, provider-specific request/response classes, and fake implementations for testing.
    app
     └─ Services
        └─ Checkout
           ├─ Contracts
           │  ├─ CheckoutRequester.php
           │  └─ CheckoutResponder.php
           ├─ AdyenCheckoutRequest.php
           ├─ AdyenCheckoutResponse.php
           ├─ FakeCheckoutRequest.php
           └─ FakeCheckoutResponse.php
  6. Understand the Payavel Unified Service API

    Payavel provides a Unified Service API that abstracts the differences between various commerce providers (such as Stripe, Braintree, or Adyen). Developers define standard Request and Response contracts aligned with their application's domain logic and interact with them via a single fluent interface. The Orchestration layer handles the translation of these commands into provider-specific logic.
  7. Update provider stubs for custom Checkout contracts

    To ensure that new providers generated via php artisan checkout:provider include your custom contract modifications, you must update the provider stubs. First, publish the stubs to your application, then edit the checkout-request.stub file in the stubs directory to align with your local contract.
    php artisan checkout:stubs
  8. Create and configure a new orchestrated service

    To start a new service in a Laravel application, use the provided artisan command to generate the service structure. Once created, configure the service in your configuration files by defining default providers and accounts, as well as the specific gateway classes and API credentials for each provider.
    php artisan orchestrate:service
    return [
        'defaults' => [
            'provider' => 'stripe',
            'account' => 'payavel',
        ],
        'providers' => [
            'stripe' => [
                'gateway' => \App\Services\Checkout\StripeCheckoutRequest::class,
                'base_url' => 'https://api.stripe.com', 
            ],
        ],
        'accounts' => [
            'payavel' => [
                'providers' => [
                    'stripe' => [
                        'api_key' => env('STRIPE_PAYAVEL_API_KEY'),
                        'account_id' => env('STRIPE_PAYAVEL_ACCOUNT_ID'),
                    ],
                ],
            ],
        ],
    ];
  9. Route payments dynamically by provider or account

    You can override the default payment routing at runtime using the provider() and account() methods on the Checkout facade. This is useful for routing payments based on user region, tenant type, or specific business logic without changing the payment data structure.
    use Payavel\Checkout\Facades\Checkout;
    
    // Example 1: Route by provider based on IP/Region
    $provider = $request->isUsIp() ? 'stripe' : 'adyen';
    $response = Checkout::provider($provider)->authorize([
        // standardized payment data
    ]);
    
    // Example 2: Route by specific account based on user context
    $account = $user->company->isEnterprise() ? 'us_b2b' : 'us_b2c';
    $response = Checkout::provider('stripe')->account($account)->authorize([
        // standardized payment data
    ]);
  10. Perform payment actions using automatic origin resolution

    Payavel Checkout payment models natively track their origin. When calling methods like capture(), void(), or refund() directly on a payment model, the system automatically routes the request to the same provider and account used during the original authorization, eliminating the need to repeat routing logic.
    // The model automatically resolves the correct provider and account
    $response = $payment->capture();
    $response = $payment->void();
    $response = $payment->refund();
  11. Implement a Service Request Gateway

    A service gateway acts as the bridge between the application and the provider's API. It must extend ServiceRequest and implement the service's request contract. Use the setUp() method to initialize the HTTP client with the base URL and authentication credentials retrieved from the configuration based on the current account ID.
    namespace App\Services\Checkout;
    
    use App\Services\Checkout\Contracts\CheckoutRequester;
    use Illuminate\Support\Facades\Config;
    use Illuminate\Support\Facades\Http;
    use Payavel\Orchestration\ServiceRequest;
    
    class StripeCheckoutRequest extends ServiceRequest implements CheckoutRequester
    {
        private $http;
    
        protected function setUp(): void
        {
            $this->http = Http::asForm()
                ->baseUrl(Config::get('checkout.providers.stripe.base_url'))
                ->withToken(
                    Config::get("checkout.accounts.{$this->account->getId()}.providers.stripe.api_key")
                )
                ->withHeader(
                    'Stripe-Account',
                    Config::get("checkout.accounts.{$this->account->getId()}.providers.stripe.account_id")
                );
        }
    
        public function charge(array $data): StripeCheckoutResponse
        {
            $response = $this->http->post('v1/payment_intents', [
                'amount' => $data['amount'],
                'currency' => $data['currency'] ?? 'usd',
                'payment_method' => $data['paymentMethod']['nonce'],
                'confirm' => 'true',
                'automatic_payment_methods' => [
                    'enabled' => 'true',
                    'allow_redirects' => 'never',
                ],
            ]);
    
            return new StripeCheckoutResponse($response);
        }
    }
  12. Define Service Request and Response Contracts

    Service contracts serve as blueprints to ensure consistent interaction across different providers. Define a Request contract (Requester) for the actions the service should perform and a Response contract (Responder) to standardize the data returned to the application.
    // Request Contract
    namespace App\Services\Checkout\Contracts;
    
    interface CheckoutRequester
    {
        public function charge(array $data): CheckoutResponder;
    }
    
    // Response Contract
    namespace App\Services\Checkout\Contracts;
    
    interface CheckoutResponder
    {
        public function chargeResponse(): array;
    }