Laravel package for Moka Payment integration with 3D Secure support

dev-main 2025-03-13 06:36 UTC

README

This package provides an easy way to integrate Moka Payment system into your Laravel application.

Installation

You can install the package via composer:

composer require tarfin/moka

Configuration

Publish the config file:

php artisan vendor:publish --tag="moka-config"

Add your Moka credentials to your .env file:

MOKA_DEALER_CODE=your-dealer-code
MOKA_USERNAME=your-username
MOKA_PASSWORD=your-password
MOKA_SANDBOX_MODE=true

# Optional: Configure redirect URLs
MOKA_PAYMENT_SUCCESS_URL=/moka-payment/success
MOKA_PAYMENT_FAILURE_URL=/moka-payment/failed

Usage

Creating a 3D Payment

use Tarfin\Moka\Facades\Moka;

// With minimal parameters
public function checkoutMinimal()
{
    $result = Moka::threeDPayment()->create(
        amount: 100.00,
        cardHolderName: 'John Doe',
        cardNumber: '5555555555555555',
        expMonth: '12',
        expYear: '2025',
        cvc: '123'
    );

    return $result; // Returns RedirectResponse
}

// With all parameters
public function checkout()
{
    $result = Moka::threeDPayment()->create(
        amount: 100.00,
        cardHolderName: 'John Doe',
        cardNumber: '5555555555555555',
        expMonth: '12',
        expYear: '2025',
        cvc: '123',
        software: 'Tarfin',
        // Optional parameters
        returnUrl: 'https://your-site.com/moka-callback', // Defaults to route('callback.handle3D')
        installment: 1,
        otherTrxCode: 'your-unique-id', // If not provided, a UUID will be generated
        isPoolPayment: 0,
        isTokenized: 0,
        currency: 'TL',
        redirectType: 1,
        language: 'TR',
        description: 'Payment description'
    );

    // The user will be redirected to Moka's 3D secure page
    return $result; // Returns RedirectResponse
}

// With buyer information using method chaining
public function checkoutWithBuyerInfo()
{
    $result = Moka::threeDPayment()
        ->buyerInformation(
            fullName: 'John Doe',
            gsmNumber: '5551234567',
            email: 'john@example.com',
            address: '123 Main St, City'
        )
        ->create(
            amount: 100.00,
            cardHolderName: 'John Doe',
            cardNumber: '5555555555555555',
            expMonth: '12',
            expYear: '2025',
            cvc: '123'
        );

    return $result; // Returns RedirectResponse
}

Handling the 3D Callback

The package automatically sets up a callback route at POST /moka-callback (named moka-callback.handle3D) to handle the 3D payment result. The callback will:

  1. Validate the payment
  2. Update the payment status
  3. Redirect to your success/failure URL with the payment result

You can configure the success and failure URLs in your .env file:

MOKA_PAYMENT_SUCCESS_URL=/moka-payment/success
MOKA_PAYMENT_FAILURE_URL=/moka-payment/failure

The callback will redirect to these URLs with the following session data:

[
    'other_trx_code' => 'other_transaction_id',
    'status' => 'success|failed',
    'message' => 'Payment result message'
]

Events Fired After Payment

The package includes an event system to help you manage payment outcomes. When a 3D Secure payment is processed, one of the following events will be dispatched:

// For successful payments
Tarfin\Moka\Events\MokaPaymentSucceededEvent::dispatch($payment);

// For failed payments
Tarfin\Moka\Events\MokaPaymentFailedEvent::dispatch($payment);

Listening for Payment Events

To react to these events, you can create listeners in your application. There are multiple ways to register event listeners in Laravel.

Then create your listener classes:

// app/Listeners/HandleSuccessfulMokaPayment.php

namespace App\Listeners;

use Tarfin\Moka\Events\MokaPaymentSucceededEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class HandleSuccessfulMokaPayment implements ShouldQueue
{
    use InteractsWithQueue;
    
    /**
     * Handle the event.
     */
    public function handle(MokaPaymentSucceededEvent $event): void
    {
        $payment = $event->mokaPayment;
        
        // Access payment details
        $transactionId = $payment->other_trx_code;
        $amount = $payment->amount;
        
        // Implement your business logic
        // - Complete the order
        // - Generate invoice
        // - Send confirmation email
        // - Update inventory
    }
}
// app/Listeners/HandleFailedMokaPayment.php

namespace App\Listeners;

use Tarfin\Moka\Events\MokaPaymentFailedEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class HandleFailedMokaPayment implements ShouldQueue
{
    use InteractsWithQueue;
    
    /**
     * Handle the event.
     */
    public function handle(MokaPaymentFailedEvent $event): void
    {
        $payment = $event->mokaPayment;
        
        // Access payment details
        $transactionId = $payment->other_trx_code;
        $failureCode = $payment->result_code;
        $failureMessage = $payment->result_message;
        
        // Implement your business logic
        // - Update order status
        // - Notify customer
        // - Log payment failure
    }
}

Dynamic Redirect URLs

You can specify custom success and failure URLs for each payment by adding them as query parameters to the return URL:

$result = Moka::threeDPayment()->create(
    amount: 100.00,
    cardHolderName: 'John Doe',
    cardNumber: '5555555555555555',
    expMonth: '12',
    expYear: '2025',
    cvc: '123',
    returnUrl: route('moka-callback.handle3D', [
        'success_url' => 'https://your-site.com/orders/123/payment-success',
        'failure_url' => 'https://your-site.com/orders/123/payment-failed',
    ]),
    installment: 1,
);

With this approach, you can dynamically specify different URLs for each payment transaction. The callback handler will:

  1. Check for success_url or failure_url parameters in the request
  2. Redirect to these URLs if present
  3. Fall back to the configured MOKA_PAYMENT_SUCCESS_URL or MOKA_PAYMENT_FAILURE_URL if not specified

This is useful for applications that require different redirect destinations based on the payment context, such as returning users to specific order pages or application sections.

Calculating Payment Amount

You can calculate the payment amount including commission rates and bank card details using the MokaPaymentAmount service:

use TarfinMokaServicesInformationMokaPaymentAmount;

// With minimal parameters
$paymentAmount = app(MokaPaymentAmount::class);
$result = $paymentAmount->calculate(
    binNumber: '526911',
    amount: 100.00
);

// With all parameters
$result = $paymentAmount->calculate(
    binNumber: '526911',
    amount: 100.00,
    installment: 3,
    isThreeD: 0,
    currency: 'USD'
);

The service will return an array containing detailed payment information:

[
    'PaymentAmount' => 101.56,
    'DealerDepositAmount' => 95.0,
    'DealerCommissionRate' => 6.46,
    'DealerCommissionAmount' => 6.56,
    'DealerCommissionFixedAmount' => 0.0,
    'DealerGroupCommissionRate' => 1.54,
    'DealerGroupCommissionAmount' => 1.56,
    'DealerGroupCommissionFixedAmount' => 0.0,
    'GroupRevenueRate' => 5.0,
    'GroupRevenueAmount' => 5.0,
    'BankCard' => [
        'BankName' => 'FINANSBANK',
        'BankCode' => '111',
        'BinNumber' => '526911',
        'CardType' => 'MASTER',
        'CreditType' => 'CreditCard',
        'ProductCategory' => 'Bireysel'
    ]
]

If there's an error with the calculation, the service will throw a MokaException with the error code and message.

Storing Failed Payments

By default, failed payments are not stored in the database. If you want to store them, set this in your .env:

MOKA_STORE_FAILED_PAYMENTS=true

BIN Inquiry

You can use the BIN inquiry service to get information about a credit card based on its BIN number (first 6 digits):

use Tarfin\Moka\Facades\Moka;

$binInfo = Moka::binInquiry()->get('526911');

// Response structure
[
    'BankName' => 'FÄ°NANSBANK',
    'BankCode' => '111',
    'BinNumber' => '526911',
    'CardName' => '',
    'CardType' => 'MASTER',
    'CreditType' => 'CreditCard',
    'CardLogo' => 'https://cdn.moka.com/Content/BankLogo/CARDFINANS.png',
    'CardTemplate' => 'https://cdn.moka.com/Content/BankCardTemplate/FINANS-MASTER-CREDIT.png',
    'ProductCategory' => 'Bireysel',
    'GroupName' => 'CARDFINANS'
]

The BIN inquiry service provides information about:

  • Bank details (name and code)
  • Card type (MASTER/VISA)
  • Credit type (CreditCard/DebitCard)
  • Card logos and templates
  • Product category and group name

If the BIN inquiry fails, a MokaException will be thrown with the error message and code from Moka.

Payment Table

You can get payment table information including installment options and commission rates using the MokaPaymentTable service:

use Tarfin\Moka\Facades\Moka;

// With minimal parameters
$result = Moka::paymentTable()->calculate(
    amount: 100.00
);

// With BIN number
$result = Moka::paymentTable()->calculate(
    amount: 100.00,
    binNumber: '526911'
);

// With all parameters
$result = Moka::paymentTable()->calculate(
    amount: 100.00,
    binNumber: '526911',
    isThreeD: 0,
    isIncludedCommissionAmount: 0,
    currency: 'TL',
);

The service will return an array containing available installment options and commission rates:

'BankPaymentInstallmentInfoList' => [
    [
        'BankInfoName' => 'GENEL',
        'PaymentInstallmentInfoList' => [
            [
                'CommissionType' => 'CreditCard',
                'InstallmentNumber' => 1,
                'DealerCommissionRate' => 2.2,
                'DealerCommissionFixedAmount' => 0,
                'DealerCommissionAmount' => 2.2,
                'PerInstallmentAmount' => 100,
                'Amount' => 100,
            ],
            // ... more installment options
        ],
    ],
    [
        'BankInfoName' => 'AXESS',
        'PaymentInstallmentInfoList' => [
            [
                'CommissionType' => 'CreditCard',
                'InstallmentNumber' => 1,
                'DealerCommissionRate' => 3,
                'DealerCommissionFixedAmount' => 0,
                'DealerCommissionAmount' => 3,
                'PerInstallmentAmount' => 100,
                'Amount' => 100,
            ],
            // ... more installment options
        ],
    ],
],

Testing

composer test

License

The MIT License (MIT). Please see License File for more information.