Skip to content

Creating a Payment Gateway

This guide walks you through building a payment gateway adapter to integrate providers like Stripe, PayPal, or any payment processor into FOSSBilling.

  1. Payment Initiation — Client clicks "Pay", FOSSBilling calls getHtml() to display the payment form
  2. Payment Processing — Gateway processes the payment
  3. Verification — Gateway calls ipn.php, which triggers processTransaction() to verify and record the payment

Place your adapter in:

src/library/Payment/Adapter/
├── MyGateway.php # Single file
└── MyGateway/
└── MyGateway.php # Or subdirectory for complex gateways
  • File: MyGateway.php (PascalCase)
  • Class: Payment_Adapter_MyGateway
<?php
class Payment_Adapter_MyGateway implements FOSSBilling\InjectionAwareInterface
{
protected ?Pimple\Container $di = null;
public function __construct(private $config)
{
if (!isset($this->config['api_key'])) {
throw new Payment_Exception(
'The ":pay_gateway" payment gateway is not fully configured. Please configure the :missing',
[':pay_gateway' => 'MyGateway', ':missing' => 'API Key'],
4001
);
}
}
public function setDi(Pimple\Container $di): void
{
$this->di = $di;
}
public function getDi(): ?Pimple\Container
{
return $this->di;
}
public static function getConfig(): array
{
return [
'supports_one_time_payments' => true,
'supports_subscriptions' => false,
'description' => 'Accept payments via MyGateway.',
'logo' => [
'logo' => 'mygateway.png',
'height' => '30px',
'width' => '65px',
],
'form' => [
'api_key' => ['text', ['label' => 'API Key:']],
'api_secret' => ['password', ['label' => 'API Secret:']],
],
];
}
public function getHtml($api_admin, $invoice_id, $subscription): string
{
$invoice = $api_admin->invoice_get(['id' => $invoice_id]);
$fields = [
'merchant_id' => $this->config['api_key'],
'amount' => number_format($invoice['total'], 2, '.', ''),
'currency' => $invoice['currency'],
'callback_url' => $this->config['notify_url'],
'success_url' => $this->config['thankyou_url'],
];
$form = '<form action="https://api.mygateway.com/checkout" method="post">';
foreach ($fields as $key => $value) {
$form .= sprintf(
'<input type="hidden" name="%s" value="%s" />',
htmlspecialchars($key),
htmlspecialchars($value)
);
}
$form .= '<input type="submit" value="Pay Now" class="btn btn-primary" />';
$form .= '</form>';
return $form;
}
public function processTransaction($api_admin, $id, $data, $gateway_id): void
{
$tx = $this->di['db']->getExistingModelById('Transaction', $id);
$invoiceId = $data['get']['invoice_id'] ?? $data['post']['invoice_id'];
$invoice = $this->di['db']->getExistingModelById('Invoice', $invoiceId);
$paymentId = $data['post']['payment_id'];
$payment = $this->verifyPaymentWithGateway($paymentId);
if ($payment['status'] === 'completed') {
$clientService = $this->di['mod_service']('Client');
$invoiceService = $this->di['mod_service']('Invoice');
$client = $this->di['db']->getExistingModelById('Client', $invoice->client_id);
$clientService->addFunds($client, $payment['amount'], 'MyGateway payment');
if (!$invoiceService->isInvoiceTypeDeposit($invoice)) {
$invoiceService->payInvoiceWithCredits($invoice);
}
$tx->status = 'processed';
} else {
$tx->status = 'error';
$tx->error = 'Payment failed';
}
$this->di['db']->store($tx);
}
}

FOSSBilling injects these into $this->config:

KeyPurpose
notify_urlIPN/webhook callback URL
return_urlRedirect after successful payment
cancel_urlRedirect if client cancels
thankyou_urlThank you page URL
test_modeWhether in sandbox mode
  • Always verify server-side — Never trust client-side data
  • Check amounts and currency — Ensure they match the invoice
  • Handle errors gracefully — Record errors on the transaction
  • Prevent duplicates — Check $tx->status before processing
  • Log for debugging — Use $this->di['logger'] when needed
  1. Enable test mode in the admin panel
  2. Create a test invoice
  3. Check Invoicing → Transactions for results
  4. Test the full flow: payment → verification → invoice marking

See existing adapters in the source code for real-world implementations like Stripe and PayPal.