Looking to hire Laravel developers? Try LaraJobs

laravel-yallapaysudan maintained by yallapaysudan

Description
Laravel package for YallaPaySudan payment gateway
Author
Last update
2026/03/27 11:47 (dev-main)
License
Links
Downloads
1

Comments
comments powered by Disqus

YallaPaySudan Laravel Package

Laravel package for integrating with the YallaPaySudan payment gateway.

Requirements

  • PHP 8.1+
  • Laravel 10, 11, or 12

Installation

composer require yallapaysudan/laravel-yallapaysudan

Publish the config file:

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

Configuration

Add the following to your .env file:

YALLAPAY_AUTHORIZATION_TOKEN=your-authorization-token
YALLAPAY_SECRET_KEY=your-secret-key

# Optional — fallback redirect URLs (can also be set per-transaction)
YALLAPAY_REDIRECT_SUCCESS=https://yoursite.com/payment/success
YALLAPAY_REDIRECT_FAILED=https://yoursite.com/payment/failed

# Optional
YALLAPAY_COMMISSION_BY_CUSTOMER=false
YALLAPAY_WEBHOOK_PATH=yallapay/webhook
YALLAPAY_WEBHOOK_TOLERANCE=5

Both the Authorization Token and Secret Key are found in the Developers section of your YallaPaySudan merchant dashboard.


Usage

One-Time Payment

use YallaPaySudan\Facades\YallaPaySudan;
use YallaPaySudan\Exceptions\PaymentException;

try {
    $response = YallaPaySudan::createPayment(
        amount: 500,
        clientReferenceId: 'order_' . $order->id,
        options: [
            'description'                  => 'Order #' . $order->id,
            'paymentSuccessfulRedirectUrl' => route('payment.success'),
            'paymentFailedRedirectUrl'     => route('payment.failed'),
            'commissionPaidByCustomer'     => false,
        ]
    );

    return redirect($response->paymentUrl);

} catch (PaymentException $e) {
    // API returned a non-success response code
    logger()->error('YallaPaySudan error', ['message' => $e->getMessage(), 'code' => $e->getResponseCode()]);
    abort(500, 'Payment initiation failed.');
}

Subscription Payment

use YallaPaySudan\Facades\YallaPaySudan;

$response = YallaPaySudan::createSubscription(
    amount: 100,
    clientReferenceId: 'sub_' . $subscription->id,
    interval: 'MONTH',      // DAY | MONTH | YEAR
    intervalCycle: 1,        // every 1 month
    options: [
        'totalCycles'  => 12, // 12 months; omit for indefinite
        'description'  => 'Monthly plan',
    ]
);

return redirect($response->paymentUrl);

PaymentResponse Object

$response->isSuccessful();     // bool
$response->paymentUrl;         // string — redirect the user here
$response->responseCode;       // "0" on success
$response->responseMessage;    // "Success"
$response->currentDate;        // "2025-06-22"
$response->currentTime;        // "13:25:20"
$response->raw;                // full raw array from the API

Webhooks

The package automatically registers a webhook endpoint at POST /yallapay/webhook (configurable via YALLAPAY_WEBHOOK_PATH).

Listening to Webhook Events

Register a listener for WebhookReceived in your EventServiceProvider (or using #[AsEventListener]):

use YallaPaySudan\Events\WebhookReceived;

class HandleYallaPayWebhook
{
    public function handle(WebhookReceived $event): void
    {
        if ($event->isSuccessful()) {
            // Mark order as paid
            Order::where('reference', $event->clientReferenceId)
                ->update(['status' => 'paid', 'payment_reference' => $event->paymentReferenceId]);
        }

        if ($event->isFailed() || $event->isCancelled()) {
            // Handle failure
        }
    }
}
// EventServiceProvider
protected $listen = [
    \YallaPaySudan\Events\WebhookReceived::class => [
        \App\Listeners\HandleYallaPayWebhook::class,
    ],
];

Webhook Payload

Field Type Description
clientReferenceId string Your order/transaction ID
paymentReferenceId string YallaPaySudan's internal reference
status string SUCCESSFUL, FAILED, or CANCELLED
timestamp int Unix timestamp in milliseconds

Security

Every incoming webhook is automatically verified:

  • HMAC-SHA-256 signature checked against your secret key using the raw JSON body bytes.
  • Timestamp tolerance (default: 5 minutes) to prevent replay attacks.

Requests failing either check receive a 401 response.

Important: Ensure your webhook endpoint is excluded from Laravel's CSRF middleware. If using routes/web.php, add the path to $except in VerifyCsrfToken. The package registers its route with the api middleware group by default, so CSRF is not applied.

Idempotency

YallaPaySudan may deliver the same webhook more than once. Use clientReferenceId and paymentReferenceId together to deduplicate.


Testing

composer test

License

MIT