shetabit/payment

repository·master·Indexed 21 days ago

https://github.com/shetabit/payment

A Laravel package providing a unified interface for integrating multiple payment gateways. It allows developers to handle different payment drivers, switch gateways easily, and manage the payment lifecycle including invoice creation, purchase requests, user redirection, and payment verification. Supported drivers include Zarinpal, Digipay, PayIR, and many others. It includes an Invoice class for managing payment details and a Payment facade for runtime configuration and driver overrides.

Tokens
8.8K
Snippets
29
Records
35
Agent score
72%

What's inside shetabit/payment

  1. Listen to Payment events

    master

    You can listen to the following events to trigger custom logic during the payment lifecycle:

    • InvoicePurchasedEvent: Dispatched after an invoice is successfully purchased (transaction ID obtained).
    • InvoiceVerifiedEvent: Dispatched after a transaction has been successfully verified.
  2. Payment Events

    master

    You can listen to the following events within your application to trigger logic after specific payment lifecycle stages:

    • InvoicePurchasedEvent: Dispatched when a purchase request is successfully registered.
    • InvoiceVerifiedEvent: Dispatched when a payment has been successfully verified.
  3. Work with Invoices using the Invoice class

    master

    An Invoice represents a single payment request. Before initiating a payment, you must create an invoice and set its amount and metadata. You can use the detail method to attach arbitrary key-value pairs to the invoice.

    Available Invoice Methods:

    • amount($amount): Sets the amount to be paid.
    • getAmount(): Retrieves the invoice amount.
    • detail($key, $value) or detail(['key' => 'value']): Adds metadata/details to the invoice.
    • getDetails(): Retrieves all attached details.
    • uuid(): Sets a unique identifier for the invoice.
    • getUuid(): Retrieves the invoice UUID.
    • transactionId($id): Sets the transaction ID.
    • getTransactionId(): Retrieves the transaction ID.
    • via($driver): Specifies the driver to be used for this invoice.
    • getDriver(): Retrieves the selected driver.
    use Shetabit//
    use Shetabit\Multipay\Invoice;
    
    // Create new invoice.
    $invoice = new Invoice;
    
    // Set invoice amount.
    $invoice->amount(1000);
    
    // Add invoice details (multiple syntax options available)
    $invoice->detail(['detailName' => 'your detail goes here']);
    $invoice->detail('detailName', 'your detail goes here');
    $invoice->detail(['name1' => 'detail1', 'name2' => 'detail2']);
    $invoice->detail('detailName1', 'detail1')->detail('detailName2', 'detail2');
  4. Publish and Configure the payment config file

    master

    After installation, publish the configuration file to your project by running: php artisan vendor:publish.

    This will create config/payment.php. You can set the default driver in this file to specify which gateway to use globally, or provide credentials for various drivers in the drivers array.

    php artisan vendor:publish
  5. Redirect users to the bank gateway

    master

    Once a purchase request is registered and you have a transactionId, you can redirect the user to the bank's payment page. Use the pay() method following a purchase() call.

    • Use render() to get the redirect response (suitable for returning from a controller).
    • Use toJson() to get the redirection data in JSON format if you want to handle the redirection manually via JavaScript.
    use Shetabit\Multipay\Invoice;
    use Shetabit\Payment\Facade\Payment;
    
    $invoice = (new Invoice)->amount(1000);
    
    // Redirect user to the bank page (Standard usage)
    return Payment::purchase($invoice, function($driver, $transactionId) {
        // Store transactionId in database
    })->pay()->render();
    
    // Get JSON format for manual redirection handling
    return Payment::purchase(
        (new Invoice)->amount(1000), 
        function($driver, $transactionId) {
            // Store transactionId in database
        }
    )->pay()->toJson();
  6. Purchasing an Invoice

    master

    To initiate a payment, you first "purchase" the invoice. This step generates a transactionId from the chosen driver. The purchase method accepts a callback that provides the $driver name and the $transactionId. You should store this $transactionId in your database to verify the payment later.

    You can specify a custom callbackUrl using Payment::callbackUrl($url) before calling purchase.

    use Shetabit//
    Multipay//
    Invoice;
    use Shetabit//
    Payment//
    Facade//
    Payment;
    
    $invoice = (new Invoice)->amount(1000);
    
    Payment::purchase($invoice, function($driver, $transactionId) {
        // Store $transactionId in your database
    });
  7. Verifying a Payment

    master

    Once the user completes the payment on the bank's site, they are redirected back to your application. You must verify the payment using the transactionId and the expected amount to ensure the invoice is actually paid.

    If verification fails, the system throws an InvalidPaymentException. You should wrap the verification in a try-catch block.

    use Shetabit//
    Payment//
    Facade//
    Payment;
    use Shetabit//
    Multipay//
    Exceptions//
    InvalidPaymentException;
    
    try {
        $receipt = Payment::amount(1000)->transactionId($transaction_id)->verify();
        echo $receipt->getReferenceId();
    } catch (InvalidPaymentException $exception) {
        echo $exception->getMessage();
    }
  8. Create a custom payment driver

    master

    To add a new payment gateway, follow these steps:

    1. Define Configuration: Add your driver's name and required settings to the drivers array in config/payment.php.
    2. Implement the Driver Class: Create a class that extends Shetabit\Multipay\Abstracts\Driver. You must implement the following methods:
      • purchase(): Request a transaction ID from the gateway and return it.
      • pay(): Handle the redirection to the bank's URL.
      • verify(): Communicate with the gateway to confirm the payment status. If invalid, throw InvalidPaymentException. If valid, return a Receipt object.
    3. Map the Driver: In config/payment.php, add your driver to the map array, ensuring the key matches the name used in the drivers array.
    // 1. config/payment.php
    'drivers' => [
        'my_driver' => ['some_config' => 'value'],
    ],
    'map' => [
        'my_driver' => App\Packages\PaymentDriver\MyDriver::class,
    ]
    
    // 2. Implementation
    namespace App\Packages\PaymentDriver;
    
    use Shetabit\Multipay\Abstracts\Driver;
    use Shetabit\Multipay\Exceptions\InvalidPaymentException;
    use Shetabit\Multipay\{Contracts\ReceiptInterface, Invoice, Receipt};
    
    class MyDriver extends Driver
    {
        protected $invoice;
        protected $settings;
    
        public function __construct(Invoice $invoice, $settings)
        {
            $this->invoice($invoice);
            $this->settings = (object) $settings;
        }
    
        public function purchase() 
        {
            // ... logic to get transaction ID
            $transId = 'generated_id';
            $this->invoice->transactionId($transId);
            return $transId;
        }
        
        public function pay() 
        {
            $bankUrl = $this->settings->bankApiUrl;
            $payUrl = $bankUrl . $this->invoice->getTransactionId();
            return redirect()->to($payUrl);
        }
        
        public function verify(): ReceiptInterface 
        {
            // ... logic to verify with gateway
            $isValid = true; 
    
            if (!$isValid) {
                throw new InvalidPaymentException('Payment failed');
            }
            
            return new Receipt('my_driver', 'receipt_number');
        }
    }
  9. How to Create a Custom Payment Driver

    master

    To add a new payment gateway, follow these three steps:

    1. Register the driver in your config/payment.php file under the drivers array.
    2. Implement the Driver class by extending Shetabit\Multipay\Abstracts\Driver. You must implement:
      • purchase(): Request a transaction ID from the provider and return it.
      • pay(): Handle the redirection to the bank's URL.
      • verify(): Call the provider's verification API. Throw InvalidPaymentException if invalid, or return a Receipt object if successful.
    3. Map the driver in the map section of config/payment.php so the system knows which class to instantiate.

    Note: The key in the map array must be identical to the key in the drivers array.

    namespace App\
    Packages\\\nPaymentDriver;
    
    use Shetabit\//
    Multipay\//
    Abstracts\//
    Driver;
    use Shetabit\//
    Multipay\//
    Exceptions\//
    InvalidPaymentException;
    use Shetabit\//
    Multipay\//
    {Contracts\ReceiptInterface, Invoice, Receipt};
    
    class MyDriver extends Driver
    {
        protected $invoice;
        protected $settings;
    
        public function __construct(Invoice $invoice, $settings)
        {
            $this->invoice($invoice);
            $this->settings = (object) $settings;
        }
    
        public function purchase() {
            // ... logic to get transaction ID
            $this->invoice->transactionId($transId);
            return $transId;
        }
        
        public function pay() {
            $bankUrl = $this->settings->bankApiUrl;
            $payUrl = $bankUrl . $this->invoice->getTransactionId();
            return redirect()->to($payUrl);
        }
        
        public function verify(): ReceiptInterface {
            // ... logic to verify
            // throw new InvalidPaymentException('message') if failed
            return new Receipt('driverName', 'payment_receipt_number');
        }
    }
  10. Configure the Payment Service Provider and Facade

    master

    If you are using Laravel 5.5 or higher, the package should be auto-discovered. For manual configuration in config/app.php:

    1. Add the provider to the providers array: Shetabit\Payment\Provider\PaymentServiceProvider::class
    2. Add the alias to the aliases array: 'Payment' => Shetabit\Payment\Facade\Payment::class
    // In your providers array.
    'providers' => [
        ...
        Shetabit\Payment\Provider\PaymentServiceProvider::class,
    ],
    
    // In your aliases array.
    'aliases' => [
        ...
        'Payment' => Shetabit\Payment\Facade\Payment::class,
    ],
  11. Publish configuration and views

    master

    After installation, you can publish the package's configuration files and views to your application for customization.

    To publish configuration files:

    php artisan vendor:publish --tag=payment-config

    To publish views:

    php artisan vendor:publish --tag=payment-views