Maison  >  Article  >  développement back-end  >  Sélection dynamique du processeur de paiement dans Laravel à l'aide du modèle d'usine

Sélection dynamique du processeur de paiement dans Laravel à l'aide du modèle d'usine

Susan Sarandon
Susan Sarandonoriginal
2024-10-03 18:07:02244parcourir

Dynamic Payment Processor Selection in Laravel  Using the Factory Pattern

In the previous posts, we explored two different methods for handling payment processing in Laravel:

  • hardcoded service bindings
  • contextual binding.

While both methods are effective, they have their limitations when it comes to selecting payment processors dynamically based on runtime conditions (e.g., user input, configuration settings).

In this third and final part, we’ll look at a more flexible approach: using the Factory Pattern. This design pattern allows us to choose the appropriate implementation of PaymentProcessorInterface based on the context (e.g., selecting between Stripe or PayPal depending on the request).

Implementing the Factory Pattern

The Factory Pattern provides a scalable solution to dynamically resolve different implementations at runtime. Here's how to set it up step by step.

Step 1: Create a Factory Interface

First, let's define a PaymentProcessorFactoryInterface that outlines how to resolve different payment processors.

<?php

namespace App\Contracts;

interface PaymentProcessorFactoryInterface
{
    public function getProcessor(string $provider): PaymentProcessorInterface;
}

This interface ensures that any factory we create will have a getProcessor method, responsible for returning the appropriate payment processor based on the provided argument (e.g., 'stripe' or 'paypal').

Step 2: Create the Factory Implementation

Next, we'll implement the factory that resolves the appropriate payment processor based on the provider input.

<?php

namespace App\Services;

use App\Contracts\PaymentProcessorInterface;
use App\Contracts\PaymentProcessorFactoryInterface;
use App\Services\StripePaymentProcessor;
use App\Services\PayPalPaymentProcessor;

class PaymentProcessorFactory implements PaymentProcessorFactoryInterface
{
    public function getProcessor(string $provider): PaymentProcessorInterface
    {
        switch ($provider) {
            case 'stripe':
                return new StripePaymentProcessor(); // Can be resolved via the container if needed
            case 'paypal':
                return new PayPalPaymentProcessor(); // Can also be resolved via the container
            default:
                throw new \Exception("Unsupported payment provider: $provider");
        }
    }
}

This factory dynamically selects the correct payment processor based on the input provided at runtime. In this example, we directly return new instances of StripePaymentProcessor and PayPalPaymentProcessor. If needed, these classes can also be resolved from Laravel's service container for better management.

Step 3: Implement Stripe and PayPal Processors

Make sure you have both the StripePaymentProcessor and PayPalPaymentProcessor classes that implement the PaymentProcessorInterface.

Example: StripePaymentProcessor

<?php

namespace App\Services;

use App\Contracts\PaymentProcessorInterface;

class StripePaymentProcessor implements PaymentProcessorInterface
{
    public function createPayment(float $amount, string $currency, array $paymentDetails): array
    {
        // Stripe-specific implementation
    }

    public function processPayment(array $paymentData): array
    {
        // Stripe-specific implementation
    }

    public function refundPayment(string $transactionId, float $amount): bool
    {
        // Stripe-specific implementation
    }
}

Example: PayPalPaymentProcessor

Similarly, implement the PayPalPaymentProcessor class, following the same pattern as the StripePaymentProcessor.

Step 4: Bind the Factory in the Service Container

To ensure that the factory is available throughout your Laravel application, you need to bind the PaymentProcessorFactory to Laravel’s service container. You can do this in the AppServiceProvider.

In App\Providers\AppServiceProvider.php, add the following inside the register method:

public function register()
{
    $this->app->singleton(\App\Contracts\PaymentProcessorFactoryInterface::class, \App\Services\PaymentProcessorFactory::class);
}

This binding tells Laravel to use the PaymentProcessorFactory whenever the PaymentProcessorFactoryInterface is requested, ensuring that there's only one instance of the factory throughout the application.

Step 5: Using the Factory in a Controller

Now that the factory is set up, you can inject it into your controllers to dynamically select the appropriate payment processor based on runtime data, such as the request input.

Example: PaymentController

<?php

namespace App\Http\Controllers;

use App\Contracts\PaymentProcessorFactoryInterface;
use Illuminate\Http\Request;

class PaymentController extends Controller
{
    protected $paymentProcessorFactory;

    public function __construct(PaymentProcessorFactoryInterface $paymentProcessorFactory)
    {
        $this->paymentProcessorFactory = $paymentProcessorFactory;
    }

    public function makePayment(Request $request)
    {
        $provider = $request->input('provider'); // E.g., 'stripe' or 'paypal'
        $amount = $request->input('amount');
        $currency = $request->input('currency');
        $paymentDetails = $request->input('details');

        // Get the appropriate payment processor based on the provider
        $paymentProcessor = $this->paymentProcessorFactory->getProcessor($provider);

        // Use the selected payment processor to create a payment
        $response = $paymentProcessor->createPayment($amount, $currency, $paymentDetails);

        return response()->json($response);
    }
}

In this controller, we inject the PaymentProcessorFactoryInterface via dependency injection. When a payment is requested, we determine the payment provider (e.g., Stripe or PayPal) from the request, pass it to the factory, and dynamically resolve the appropriate payment processor.

Step 6: Handling Different Payment Providers

In this setup, the controller can now dynamically handle different payment providers by simply switching the provider name in the request. This method is particularly powerful when you need to handle multiple payment gateways without duplicating logic or tightly coupling your code to specific implementations.

Conclusion

Using the Factory Pattern in Laravel 11 offers a highly flexible approach to selecting different payment processors at runtime. Here’s a summary of the steps we covered:

  • Interface et implémentation d'usine : création d'une usine qui résout dynamiquement le processeur de paiement correct en fonction d'une entrée de chaîne.
  • Implémentations du processeur : garantie que les classes StripePaymentProcessor et PayPalPaymentProcessor implémentent PaymentProcessorInterface.
  • Liaison du conteneur de service : reliez l'usine dans le conteneur de service pour permettre une injection facile tout au long de l'application. Sélection dynamique dans les contrôleurs : utilisation de l'usine à l'intérieur d'un contrôleur pour sélectionner et utiliser dynamiquement le processeur de paiement approprié en fonction des données d'exécution.

Principes de conception de logiciels et modèles de conception

Nous avons commencé ce tutoriel en 3 parties en utilisant un seul processeur de paiement, avec une sélection codée en dur, puis nous avons utilisé une configuration dans le code ("temps de compilation") en utilisant Laravel Service Container Binding, puis dans cette partie nous avons continué à refactoriser avec le design principes et modèles de conception à l'esprit, ce qui nous a permis de refactoriser le code, obtenant :

  • Flexibilité dynamique : le modèle d'usine permet la sélection de différents processeurs de paiement au moment de l'exécution, ce qui rend votre application plus flexible et évolutive.
  • Couplage lâche : en injectant l'usine, vos contrôleurs sont faiblement couplés aux processeurs de paiement, ce qui facilite l'ajout ou le remplacement de passerelles de paiement à l'avenir.
  • Maintenabilité : cette approche fournit une base de code plus propre et plus maintenable, en particulier lorsqu'il s'agit de plusieurs options de paiement.

Avec cette configuration, nous disposons désormais d'un système puissant et flexible pour gérer les paiements dans Laravel. Si nous avons besoin de prendre en charge des processeurs supplémentaires, nous pouvons facilement étendre l'usine pour prendre en charge et modifier la logique de sélection des fournisseurs, et gérer différents scénarios de logique métier.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn