1. Go to this page and download the library: Download shwary/php-sdk library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
shwary / php-sdk example snippets
hwary\Enums\Country;
// If this code runs without error, the installation is successful
echo "✅ Shwary SDK installed successfully!\n";
echo "Supported countries: " . implode(', ', array_column(Country::cases(), 'name')) . "\n";
using vlucas/phpdotenv (composer (__DIR__);
$dotenv->load();
// Or load manually
// putenv('SHWARY_MERCHANT_ID=your-merchant-id');
// putenv('SHWARY_MERCHANT_KEY=your-merchant-key');
use Shwary\Shwary;
// The SDK automatically reads environment variables
Shwary::initFromEnvironment();
// Ready! You can now use Shwary::
hwary\Config;
use Shwary\ShwaryClient;
// Create a configuration object
$config = new Config(
merchantId: 'your-merchant-id-here',
merchantKey: 'your-merchant-key-here',
baseUrl: 'https://api.shwary.com', // optional
timeout: 30, // optional
sandbox: false // true for testing
);
// Create the client
$client = new ShwaryClient($config);
// Use $client->payDRC(), $client->payKenya(), etc.
/**
* My first Shwary payment
*
* This script initiates a Mobile Money payment of 5000 CDF
* to a phone number in DRC.
*/
-merchant-id',
'merchant_key' => 'your-merchant-key',
'sandbox' => true, // Test mode to start
]);
// 2. Initiate a payment
try {
$transaction = Shwary::payDRC(
amount: 5000, // Amount in CDF
phone: '+243812345678', // Customer's phone number
callbackUrl: 'https://your-site.com/webhook' // Optional
);
// 3. Display the result
echo "✅ Payment initiated successfully!\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "Transaction ID : {$transaction->id}\n";
echo "Amount : {$transaction->amount} {$transaction->currency}\n";
echo "Status : {$transaction->status->value}\n";
echo "Phone : {$transaction->recipientPhoneNumber}\n";
echo "Reference : {$transaction->referenceId}\n";
echo "Sandbox Mode : " . ($transaction->isSandbox ? 'Yes' : 'No') . "\n";
} catch (ShwaryException $e) {
// 4. Handle errors
echo "❌ Error: {$e->getMessage()}\n";
echo "Code: {$e->getCode()}\n";
}
use Shwary\Shwary;
// Simplified method
$transaction = Shwary::payDRC(
amount: 5000, // Minimum: 2901 CDF
phone: '+243812345678', // Must start with +243
callbackUrl: 'https://...' // Optional but recommended
);
// Check status
if ($transaction->isPending()) {
echo "Waiting for customer confirmation...";
}
use Shwary\Shwary;
$transaction = Shwary::payKenya(
amount: 1000, // Amount in KES
phone: '+254712345678', // Must start with +254
callbackUrl: 'https://...'
);
use Shwary\Shwary;
$transaction = Shwary::payUganda(
amount: 5000, // Amount in UGX
phone: '+256712345678', // Must start with +256
callbackUrl: 'https://...'
);
use Shwary\Shwary;
use Shwary\Enums\Country;
// Determine the country (from a form, database, etc.)
$countryCode = 'DRC'; // or 'KE', 'UG'
$country = Country::from($countryCode);
// Generic payment
$transaction = Shwary::pay(
amount: 5000,
phone: '+243812345678',
country: $country,
callbackUrl: 'https://your-site.com/webhook'
);
use Shwary\Shwary;
use Shwary\DTOs\PaymentRequest;
use Shwary\Enums\Country;
// Create a payment request
$request = new PaymentRequest(
amount: 5000,
clientPhoneNumber: '+243812345678',
country: Country::DRC,
callbackUrl: 'https://your-site.com/webhook'
);
// Or use the factory method
$request = PaymentRequest::create(
amount: 5000,
phone: '+243812345678',
country: Country::DRC,
callbackUrl: 'https://your-site.com/webhook'
);
// Send the request
$transaction = Shwary::createPayment($request);
/**
* File: webhook.php
* URL: https://your-site.com/webhook.php
*
* This file receives notifications from Shwary
*/
vironment();
// Set the response header
header('Content-Type: application/json');
try {
// Automatically parse the webhook
$transaction = Shwary::webhook()->parseFromGlobals();
// Process based on status
processTransaction($transaction);
// Respond to Shwary with success
http_response_code(200);
echo json_encode([
'success' => true,
'message' => 'Webhook processed successfully'
]);
} catch (ShwaryException $e) {
// On error, respond with an error code
http_response_code(400);
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
/**
* Process the transaction based on its status
*/
function processTransaction(Transaction $transaction): void
{
// Log the transaction (recommended)
error_log("Webhook received - Transaction: {$transaction->id}, Status: {$transaction->status->value}");
switch (true) {
case $transaction->isCompleted():
// ✅ Payment successful!
handleSuccessfulPayment($transaction);
break;
case $transaction->isFailed():
// ❌ Payment failed
handleFailedPayment($transaction);
break;
case $transaction->isPending():
// ⏳ Still pending
handlePendingPayment($transaction);
break;
}
}
function handleSuccessfulPayment(Transaction $transaction): void
{
// Example: Update your database
// UPDATE orders SET status = 'paid' WHERE reference = ?
error_log("✅ Payment confirmed: {$transaction->amount} {$transaction->currency}");
// Example: Send a confirmation email
// mail($customer_email, "Payment confirmed", "...");
}
function handleFailedPayment(Transaction $transaction): void
{
error_log("❌ Payment failed: {$transaction->failureReason}");
// Example: Notify the customer
// Example: Offer another payment method
}
function handlePendingPayment(Transaction $transaction): void
{
error_log("⏳ Payment pending: {$transaction->id}");
}
// From a JSON string
$jsonPayload = file_get_contents('php://input');
$transaction = Shwary::parseWebhook($jsonPayload);
// Or via the handler
$transaction = Shwary::webhook()->parsePayload($jsonPayload);
// Via configuration
Shwary::initFromArray([
'merchant_id' => 'your-merchant-id',
'merchant_key' => 'your-merchant-key',
'sandbox' => true, // ← Enable test mode
]);
use Shwary\Shwary;
use Shwary\Enums\Country;
// Method 1: Via sandboxPay
$transaction = Shwary::sandboxPay(
amount: 5000,
phone: '+243812345678',
country: Country::DRC
);
// Method 2: Via createSandboxPayment
$request = PaymentRequest::create(5000, '+243812345678', Country::DRC);
$transaction = Shwary::createSandboxPayment($request);
// Sandbox transactions are immediately "completed"
var_dump($transaction->isSandbox); // true
var_dump($transaction->isCompleted()); // true
use Shwary\Exceptions\ShwaryException; // Base exception
use Shwary\Exceptions\AuthenticationException; // Authentication error (401)
use Shwary\Exceptions\ValidationException; // Validation error
use Shwary\Exceptions\ApiException; // Other API errors
use Shwary\Shwary;
use Shwary\Exceptions\AuthenticationException;
use Shwary\Exceptions\ValidationException;
use Shwary\Exceptions\ApiException;
use Shwary\Exceptions\ShwaryException;
try {
$transaction = Shwary::payDRC(5000, '+243812345678');
echo "✅ Payment initiated: {$transaction->id}";
} catch (AuthenticationException $e) {
// ❌ Error 401: Invalid credentials
echo "Authentication error: {$e->getMessage()}\n";
echo "Check your MERCHANT_ID and MERCHANT_KEY\n";
} catch (ValidationException $e) {
// ❌ Validation error (amount, phone, etc.)
echo "Validation error: {$e->getMessage()}\n";
// Get the details
$details = $e->getContext();
print_r($details);
// Examples of validation errors:
// - "Amount must be greater than 2900 CDF for DRC"
// - "Phone number must start with +243 for DRC"
// - "Callback URL must use HTTPS"
} catch (ApiException $e) {
// ❌ Other API errors
$code = $e->getCode();
switch ($code) {
case 404:
echo "Customer not found in the Mobile Money system\n";
break;
case 502:
echo "Temporary provider error. Try again later.\n";
break;
case 500:
echo "Shwary server error. Contact support.\n";
break;
default:
echo "API error ({$code}): {$e->getMessage()}\n";
}
// Get the original HTTP response if available
$response = $e->getResponse();
} catch (ShwaryException $e) {
// ❌ Any other Shwary error
echo "Shwary error: {$e->getMessage()}\n";
} catch (\Exception $e) {
// ❌ Unexpected error (network, etc.)
echo "Unexpected error: {$e->getMessage()}\n";
}
// config/shwary.php
return [
/*
|--------------------------------------------------------------------------
| Shwary Credentials
|--------------------------------------------------------------------------
|
| Your Shwary merchant credentials. Keep them secret!
|
*/
'merchant_id' => env('SHWARY_MERCHANT_ID'),
'merchant_key' => env('SHWARY_MERCHANT_KEY'),
/*
|--------------------------------------------------------------------------
| Sandbox Mode
|--------------------------------------------------------------------------
|
| In sandbox mode, no real payment is made.
| Ideal for testing and development.
|
*/
'sandbox' => env('SHWARY_SANDBOX', false),
/*
|--------------------------------------------------------------------------
| Timeout
|--------------------------------------------------------------------------
|
| Maximum timeout for API requests (in seconds).
|
*/
'timeout' => env('SHWARY_TIMEOUT', 30),
];
// app/Providers/ShwaryServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Shwary\Config;
use Shwary\ShwaryClient;
class ShwaryServiceProvider extends ServiceProvider
{
/**
* Register the Shwary client as a singleton.
*/
public function register(): void
{
$this->app->singleton(ShwaryClient::class, function ($app) {
return new ShwaryClient(
Config::fromArray(config('shwary'))
);
});
// Convenient alias
$this->app->alias(ShwaryClient::class, 'shwary');
}
/**
* Bootstrap services.
*/
public function boot(): void
{
// Publish configuration
$this->publishes([
__DIR__.'/../../config/shwary.php' => config_path('shwary.php'),
], 'shwary-config');
}
}
// app/Http/Controllers/PaymentController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Shwary\ShwaryClient;
use Shwary\Enums\Country;
use Shwary\Exceptions\ShwaryException;
class PaymentController extends Controller
{
/**
* Inject the Shwary client via constructor.
*/
public function __construct(
private ShwaryClient $shwary
) {}
/**
* Initiate a Mobile Money payment.
*/
public function initiatePayment(Request $request): JsonResponse
{
// Validate data
$validated = $request->validate([
'amount' => 'erence' => $transaction->referenceId,
// 'amount' => $transaction->amount,
// 'status' => $transaction->status->value,
// ]);
return response()->json([
'success' => true,
'message' => 'Payment initiated successfully',
'data' => [
'transaction_id' => $transaction->id,
'reference' => $transaction->referenceId,
'status' => $transaction->status->value,
'amount' => $transaction->amount,
'currency' => $transaction->currency,
],
]);
} catch (ShwaryException $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage(),
'code' => $e->getCode(),
], 422);
}
}
/**
* Shortcut for DRC payment.
*/
public function payDRC(Request $request): JsonResponse
{
$validated = $request->validate([
'amount' => '
// app/Http/Controllers/WebhookController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Shwary\ShwaryClient;
use Shwary\DTOs\Transaction;
use Shwary\Exceptions\ShwaryException;
class WebhookController extends Controller
{
public function __construct(
private ShwaryClient $shwary
) {}
/**
* Receive webhooks from Shwary.
*/
public function handleShwary(Request $request): JsonResponse
{
try {
// Parse the webhook
$transaction = $this->shwary->parseWebhook(
$request->getContent()
);
// Log for debugging
Log::info('Shwary webhook received', [
'transaction_id' => $transaction->id,
'status' => $transaction->status->value,
'amount' => $transaction->amount,
]);
// Process based on status
$this->processTransaction($transaction);
return response()->json(['success' => true]);
} catch (ShwaryException $e) {
Log::error('Shwary webhook error', [
'error' => $e->getMessage(),
'payload' => $request->getContent(),
]);
return response()->json([
'success' => false,
'message' => $e->getMessage(),
], 400);
}
}
/**
* Process the transaction based on its status.
*/
private function processTransaction(Transaction $transaction): void
{
// Find the payment in database
// $payment = Payment::where('transaction_id', $transaction->id)->first();
if ($transaction->isCompleted()) {
// Payment successful
Log::info("✅ Payment confirmed: {$transaction->id}");
// $payment->update(['status' => 'completed']);
// event(new PaymentCompleted($payment));
} elseif ($transaction->isFailed()) {
// Payment failed
Log::warning("❌ Payment failed: {$transaction->id}", [
'reason' => $transaction->failureReason,
]);
// $payment->update([
// 'status' => 'failed',
// 'failure_reason' => $transaction->failureReason,
// ]);
}
}
}
// routes/web.php or routes/api.php
use App\Http\Controllers\PaymentController;
use App\Http\Controllers\WebhookController;
// Payment routes
Route::post('/payments/initiate', [PaymentController::class, 'initiatePayment']);
Route::post('/payments/drc', [PaymentController::class, 'payDRC']);
// Webhook route (exclude from CSRF if needed)
Route::post('/webhooks/shwary', [WebhookController::class, 'handleShwary'])
->name('webhooks.shwary')
->withoutMiddleware(['csrf']); // Important for webhooks