Laravel integration
Accept payments in a Laravel application using the official Watenga PHP SDK, Blade views, and signed webhooks.
Installation
Install the Watenga PHP package from Composer. The package name is watenga/watenga-php and it wraps the same REST API as the Node SDK.
composer require watenga/watenga-phpAdd your API credentials to .env. Use sandbox keys while developing; switch to live keys only after KYC approval and a live API app in the dashboard.
WATENGA_SECRET_KEY=sk_test_...
WATENGA_PUBLIC_KEY=pk_test_...
WATENGA_WEBHOOK_SECRET=whsec_...Register the keys in config/services.php so controllers and service providers can resolve them with config().
'watenga' => [
'secret_key' => env('WATENGA_SECRET_KEY'),
'public_key' => env('WATENGA_PUBLIC_KEY'),
'webhook_secret' => env('WATENGA_WEBHOOK_SECRET'),
],Service provider (recommended)
For larger applications, bind Watenga\Watenga as a singleton so you can inject it into controllers instead of instantiating the client in every action.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Watenga\Watenga;
class WatengaServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Watenga::class, function () {
return new Watenga(config('services.watenga.secret_key'));
});
}
}Register the provider in your application configuration.
// config/app.php — add to the providers array:
App\Providers\WatengaServiceProvider::class,After registration, type-hint Watenga in any controller constructor and Laravel will resolve the configured client automatically.
Accepting a payment
Create a checkout session on the server when the customer starts checkout. Return the checkout_id and payment_url to your frontend, or embed Watenga.js with your public key for an on-page widget.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Watenga\Watenga;
class PaymentController extends Controller
{
public function __construct(private Watenga $watenga) {}
public function createCheckout(Request $request): JsonResponse
{
$checkout = $this->watenga->checkout->create([
'amount' => $request->input('amount'),
'currency' => $request->input('currency'),
'merchantTransactionId' => 'INV-' . $request->input('order_id'),
'returnUrl' => route('payment.success'),
'notificationUrl' => route('webhooks.watenga'),
'customerName' => $request->user()?->name,
'customerEmail' => $request->user()?->email,
]);
return response()->json([
'checkout_id' => $checkout['checkoutId'],
'payment_url' => $checkout['paymentUrl'],
]);
}
}In your Blade template, load Watenga.js and mount the widget using the public key from configuration. Never put the secret key in views or JavaScript.
{{-- resources/views/checkout.blade.php --}}
<div id="watenga-payment"></div>
<script src="https://js.watenga.africa/v1/watenga.js"></script>
<script>
const w = Watenga(@json(config('services.watenga.public_key')));
w.mount('#watenga-payment', {
amount: {{ $amount }},
currency: @json($currency),
reference: @json($orderReference),
onSuccess: function (txn) {
window.location.href = @json(route('payment.success'));
},
});
</script>Handling webhooks
Watenga notifies your application when a payment completes or fails. Verify every payload with Watenga::constructEvent() before updating orders or inventory.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Watenga\Watenga;
class WatengaWebhookController extends Controller
{
public function handle(Request $request): JsonResponse
{
$rawBody = $request->getContent();
$signature = $request->header('Watenga-Signature');
$event = Watenga::constructEvent(
$rawBody,
$signature,
config('services.watenga.webhook_secret')
);
if ($event['type'] === 'payment.capture.completed') {
// Mark order paid using $event['data']
}
if ($event['type'] === 'payment.capture.declined') {
// Notify customer or release inventory
}
return response()->json(['received' => true], 200);
}
}Register a POST route for the webhook endpoint.
// routes/api.php
Route::post('/webhooks/watenga', [WatengaWebhookController::class, 'handle'])
->name('webhooks.watenga');CSRF exemption required
$except array in app/Http/Middleware/VerifyCsrfToken.php.// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'api/webhooks/watenga',
];WooCommerce and WHMCS
If your Laravel app uses the Watenga WooCommerce or WHMCS plugin, you do not need this guide — the plugins handle checkout, webhooks, and reconciliation automatically.
Get notified when InnBucks and OneMoney go live.
