birkof/netopia-mobilpay
NETOPIA Payments API integration for Laravel/PHP. Composer-ready mirror of the official MobilePay PHP_CARD library with PSR-0 autoloading, helping you work with NETOPIA/MobilPay card payments using a familiar upstream codebase.
Install the package:
composer require birkof/netopia-mobilpay
Configure environment variables in .env:
MOBILPAY_MERCHANT_ID=your_merchant_id
MOBILPAY_SECRET=your_secret_key
MOBILPAY_SANDBOX=true # Set to false for production
MOBILPAY_PUBLIC_CERT_PATH=/path/to/sandbox.YOUR-SIGNATURE.public.cer
MOBILPAY_PRIVATE_KEY_PATH=/path/to/sandbox.YOUR-SIGNATURE.private.key
First use case: Create a payment form
use Mobilpay\Payment\Request\Card;
use Mobilpay\Payment\Invoice;
$request = new Card();
$request->signature = env('MOBILPAY_MERCHANT_ID');
$request->orderId = 'ORDER-' . Str::uuid()->toString();
$request->confirmUrl = route('mobilpay.webhook');
$request->returnUrl = route('checkout.success');
$invoice = new Invoice();
$invoice->currency = 'DKK';
$invoice->amount = '49.99';
$invoice->details = 'Premium Subscription';
$request->invoice = $invoice;
// Encrypt the request
$request->encrypt(env('MOBILPAY_PUBLIC_CERT_PATH'));
// Render the form (Blade example)
return view('checkout.mobilpay', [
'envKey' => $request->getEnvKey(),
'data' => $request->getEncData(),
'cipher' => $request->getCipher(),
'iv' => $request->getIv(),
]);
Create a webhook endpoint (routes/web.php):
Route::post('/mobilpay/webhook', [MobilpayWebhookController::class, 'handle']);
Mobilpay\Payment\Request for payment flows and Mobilpay\Payment\Notify for webhook handling.MOBILPAY_* env vars and certificate paths.// Service class example
class MobilpayService
{
public function createPayment(array $data): array
{
$request = new Card();
$request->signature = env('MOBILPAY_MERCHANT_ID');
$request->orderId = $data['order_id'];
$request->confirmUrl = route('mobilpay.webhook');
$request->returnUrl = $data['return_url'];
$invoice = new Invoice();
$invoice->currency = $data['currency'];
$invoice->amount = $data['amount'];
$invoice->details = $data['description'];
$request->invoice = $invoice;
$request->encrypt(env('MOBILPAY_PUBLIC_CERT_PATH'));
return [
'envKey' => $request->getEnvKey(),
'data' => $request->getEncData(),
'cipher' => $request->getCipher(),
'iv' => $request->getIv(),
];
}
}
// Controller example
class MobilpayWebhookController extends Controller
{
public function handle(Request $request)
{
$privateKey = env('MOBILPAY_PRIVATE_KEY_PATH');
$requestObj = RequestAbstract::factoryFromEncrypted(
$request->input('env_key'),
$request->input('data'),
$privateKey,
null, // No password
$request->input('cipher'),
$request->input('iv')
);
$notify = $requestObj->objPmNotify;
// Process based on action
switch ($notify->action) {
case 'confirmed':
// Update order status
break;
case 'canceled':
// Handle cancellation
break;
}
// Acknowledge
return response()->xml("
<crc error_type=\"0\" error_code=\"0\">{$notify->action}</crc>
");
}
}
use Mobilpay\Payment\Request\Refund;
$refund = new Refund();
$refund->signature = env('MOBILPAY_MERCHANT_ID');
$refund->orderId = 'ORDER-123';
$refund->confirmUrl = route('mobilpay.webhook');
$refund->amount = '20.00';
$refund->currency = 'DKK';
$refund->encrypt(env('MOBILPAY_PUBLIC_CERT_PATH'));
// Post to MobilePay API
Laravel Service Container
Bind the service in AppServiceProvider:
$this->app->bind(MobilpayService::class, function ($app) {
return new MobilpayService();
});
Queues for Async Processing Dispatch a job after receiving a webhook:
ProcessMobilpayWebhook::dispatch($notify)->onQueue('mobilpay');
Eloquent Model for Transactions
class MobilpayTransaction extends Model
{
protected $fillable = [
'order_id', 'amount', 'currency', 'status',
'mobilpay_id', 'webhook_data', 'processed_at'
];
const STATUS_PENDING = 'pending';
const STATUS_COMPLETED = 'completed';
const STATUS_FAILED = 'failed';
}
Middleware for Webhook Validation
class VerifyMobilpaySignature
{
public function handle(Request $request, Closure $next)
{
// Validate HMAC or other MobilePay-specific checks
return $next($request);
}
}
Testing with Factories
// MobilpayTransactionFactory.php
public function definition()
{
return [
'order_id' => 'ORDER-' . Str::uuid(),
'amount' => '49.99',
'currency' => 'DKK',
'status' => 'pending',
'webhook_data' => json_encode(['action' => 'confirmed']),
];
}
OpenSSL 3 Compatibility
aes-256-cbc and requires an IV.iv and cipher in webhook responses will cause decryption failures.iv and cipher in both request and response payloads.Webhook Idempotency
mobilpay_id (or orderId) to deduplicate:
if (!MobilpayTransaction::where('mobilpay_id', $notify->orderId)->exists()) {
// Process
}
Certificate Paths
/path/to/cert.cer) breaks deployments..env and validate they exist at runtime:
if (!file_exists(env('MOBILPAY_PUBLIC_CERT_PATH'))) {
throw new RuntimeException('Public certificate not found');
}
Sandbox vs. Production
.env variables and validate environments:
if (env('MOBILPAY_SANDBOX') && str_contains($endpoint, 'secure.mobilpay.ro')) {
throw new RuntimeException('Production endpoint used in sandbox mode');
}
Error Handling
1001 for invalid merchant), but the library doesn’t throw exceptions by default.$notify->errorCode and log errors:
if ($notify->errorCode !== 0) {
Log::error("MobilePay error {$notify->errorCode}: {$notify->errorMessage}");
throw new MobilpayException($notify->errorMessage, $notify->errorCode);
}
Log::debug('MobilePay Webhook Raw Data', [
'env_key' => $request->input('env_key'),
'data' => $request->input('data'),
'cipher' => $
How can I help you explore Laravel packages today?