BINKDocs
HelpDashboard

Magento 2 Integration

/docs/global/integrations/magentoGlobal

The BINKPAY Magento 2 module adds a certified payment gateway to your Magento store, enabling credit and debit card payments, Apple Pay, and Google Pay across USD, AED, EUR, GBP, and SAR. It supports multi-store and multi-website configurations, full and partial refunds via credit memos, webhook-driven order state updates, and is compatible with Magento 2.4.5 through the latest 2.4.x release.

Hosted Checkout

Cards · Apple Pay · Google Pay

Refunds sync

No code changes

Prerequisites

Confirm your server and Magento environment meet the following requirements before installing the BINKPAY module.

RequirementMinimum versionNotes
PHP8.1+PHP 8.2 recommended; required extensions: curl, json, openssl
Magento2.4.5+Open Source and Commerce editions are both supported
Composer2.xComposer 1.x is not supported
BINKPAY accountSign up at dashboard.binkpay.net

and retrieve your API keys from

Developers → API Keys
SSL certificateRequired for Apple Pay domain verification and PCI compliance

Installation

The BINKPAY module is installed via Composer and registered through the standard Magento module management CLI. Run each command from the root of your Magento installation as a user who has write access to the codebase.

Require the module via Composer

Pull the latest stable release of the BINKPAY Magento 2 module from Packagist. Composer will resolve the module's dependencies (including the BINKPAY PHP SDK) and add entries to your composer.json.

bash
composer require binkpay/magento2-module

Enable the BinkPay_Checkout module

Register the module with Magento's module registry. This adds BinkPay_Checkout to app/etc/config.php.

bash
php bin/magento module:enable BinkPay_Checkout

Run setup upgrade and compile the dependency injection container

Apply the module's database schema and data patches, then regenerate the DI container. On large stores, setup:di:compile may take several minutes.

bash
php bin/magento setup:upgrade && php bin/magento setup:di:compile

Flush all caches

Clear and flush the Magento full-page cache and configuration cache so that the newly registered module is visible in the Admin.

bash
php bin/magento cache:clean && php bin/magento cache:flush

Reindex all indexers

Reindex to ensure product and catalog data is consistent after the schema changes introduced by the module.

bash
php bin/magento indexer:reindex

Admin Configuration

After installation, configure BINKPAY in the Magento Admin by navigating to Stores → Configuration → Sales → Payment Methods → BINKPAY. Expand the BINKPAY section and fill in the fields below.

FieldDescription
EnabledToggle the gateway on or off for this store view
TitleLabel shown to customers at checkout (e.g., "Pay by Card")
Secret KeyYour sk_live_... or sk_test_... key
Publishable KeyYour pk_live_... or pk_test_... key
Webhook SecretThe whsec_... value from your BINKPAY webhook endpoint
Payment ActionAuthorize Only or Authorize and Capture. Use Authorize Only if you fulfill before charging.
Enable Apple PayShows the Apple Pay button on supported browsers. Domain verification must be complete.
Enable Google PayShows the Google Pay button on supported browsers
Statement DescriptorUp to 22 characters shown on the customer's bank statement

These settings correspond to the following XML node in the module's etc/config.xml. This file ships with safe defaults and is the source of truth for the Admin form. You do not need to edit it directly — use the Admin UI or override values per store (see Multi-Store below).

app/code/BinkPay/Checkout/etc/config.xml

text
<?xml version= "1.0"?>
<config xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation= "urn:magento:module:Magento_Store:etc/config.xsd">
 < default>
 <payment>
 <binkpay_checkout>
 <active> 0</active>
 <title>Credit / Debit Card</title>
 <model>BinkPayCheckoutModelMethodBinkPayCheckout</model>
 <order_status>pending</order_status>
 <payment_action>authorize_capture</payment_action>

 <!-- API credentials — override these in Admin or via env variables -->
 <secret_key backend_model= "MagentoConfigModelConfigBackendEncrypted"/>
 <publishable_key backend_model= "MagentoConfigModelConfigBackendEncrypted"/>
 <webhook_secret backend_model= "MagentoConfigModelConfigBackendEncrypted"/>

 <!-- Wallet methods -->
 <enable_apple_pay> 1</enable_apple_pay>
 <enable_google_pay> 1</enable_google_pay>

 <!-- Statement descriptor shown on customer bank statements (max 22chars) -->
 <statement_descriptor>BINKPAY</statement_descriptor>

 <!-- Test mode: set to 1to use sk_test_... keys; routes calls to sandbox -->
 <test_mode> 1</test_mode>

 <!-- Accepted currencies for this gateway (comma-separated ISO 4217codes) -->
 <allowspecific> 0</allowspecific>
 <specificcountry/>
 <sort_order> 10</sort_order>
 </binkpay_checkout>
 </payment>
 </ default>
</config>

Multi-Store Configuration

Magento's configuration scoping lets you set different BINKPAY API keys per website or store view. This is useful if you operate multiple brands or regional stores from a single Magento instance, each with separate BINKPAY accounts or separate live/test environments.

In the Admin, select the target website or store view in the scope switcher at the top of the Configuration page before saving credentials. To set credentials programmatically (for example, via a deployment script), use the Magento config:set CLI command or inject values via the Magento\Framework\App\Config\Storage\WriterInterface. The snippet below demonstrates the programmatic approach with scoped configuration:

app/code/MyStore/Setup/Patch/Data/ConfigureBinkPay.php

text
<?php
declare(strict_types= 1);

namespace MyStoreSetupPatchData;

use MagentoFrameworkAppConfigStorageWriterInterface;
use MagentoFrameworkEncryptionEncryptorInterface;
use MagentoFrameworkSetupPatchDataPatchInterface;
use MagentoStoreModelScopeInterface;

/**
 * Sets per-website BINKPAY credentials during deployment.
 * Replace the website IDs and key values with your own.
 */ classConfigureBinkPay implements DataPatchInterface
{ // Magento config paths for BinkPay_Checkout settings
 private const PATH_SECRET_KEY = 'payment/binkpay_checkout/secret_key';
 private const PATH_PUB_KEY = 'payment/binkpay_checkout/publishable_key';
 private const PATH_WEBHOOK_SECRET = 'payment/binkpay_checkout/webhook_secret';
 private const PATH_TEST_MODE = 'payment/binkpay_checkout/test_mode';
 private const PATH_ACTIVE = 'payment/binkpay_checkout/active';

 public function__construct(
 private readonly WriterInterface $configWriter,
 private readonly EncryptorInterface $encryptor,
 ) {}

 public function apply(): self
 {
 // --- Website 1: main storefront (live keys) ---$this->setWebsiteConfig( 1, [
 self::PATH_SECRET_KEY => $this->encryptor->encrypt( 'sk_live_WEBSITE_1_SECRET'),
 self::PATH_PUB_KEY => 'pk_live_WEBSITE_1_PUBLISHABLE',
 self::PATH_WEBHOOK_SECRET => $this->encryptor->encrypt( 'whsec_WEBSITE_1_WEBHOOK_SECRET'),
 self::PATH_TEST_MODE => '0',
 self::PATH_ACTIVE => '1',
 ]);

 // --- Website 2: secondary brand storefront (separate BINKPAY account) ---$this->setWebsiteConfig( 2, [
 self::PATH_SECRET_KEY => $this->encryptor->encrypt( 'sk_live_WEBSITE_2_SECRET'),
 self::PATH_PUB_KEY => 'pk_live_WEBSITE_2_PUBLISHABLE',
 self::PATH_WEBHOOK_SECRET => $this->encryptor->encrypt( 'whsec_WEBSITE_2_WEBHOOK_SECRET'),
 self::PATH_TEST_MODE => '0',
 self::PATH_ACTIVE => '1',
 ]);

 return $this;
 }

 private functionsetWebsiteConfig(int $websiteId, array $values): void
 {
 foreach ($values as $path => $value) {
 $this->configWriter->save($path, $value, ScopeInterface::SCOPE_WEBSITES, $websiteId);
 }
 }

 public static functiongetDependencies(): array
 { return [];
 }

 public functiongetAliases(): array
 { return [];
 }
}

Encrypted fields

Always encrypt secret keys and webhook secrets using

EncryptorInterface::encrypt()

backend_model="Magento\Config\Model\Config\Backend\Encrypted"

config.xml

Webhook Setup

BINKPAY sends signed webhook events to your Magento store to update order state after payments, refunds, and disputes. The module registers a built-in webhook endpoint at:

bash
https://your-store.com/binkpay/webhook/receive

Register this URL in the BINKPAY Dashboard under Developers → Webhooks → Add endpoint. Enable at minimum the following event types: payment.succeeded, payment.failed, refund.created, and dispute.created. Copy the whsec_... signing secret into the Webhook Secret field in Magento Admin (Stores → Configuration → Sales → Payment Methods → BINKPAY).

The module ships with an observer class that handles signature verification and dispatches Magento events for each BINKPAY webhook type. You can listen to these events in your own module. Below is the full observer implementation for reference:

app/code/BinkPay/Checkout/Observer/WebhookObserver.php

text
<?php
declare(strict_types= 1);

namespace BinkPayCheckoutObserver;

use BinkPayCheckoutModelWebhookSignatureValidator;
use BinkPayCheckoutModelOrderStateUpdater;
use MagentoFrameworkEventObserver;
use MagentoFrameworkEventObserverInterface;
use MagentoFrameworkExceptionLocalizedException;
use PsrLogLoggerInterface;

/**
 * Dispatched by BinkPayCheckoutControllerWebhookReceive after
 * the raw HTTP request is validated.
 *
 * Listens to: binkpay_webhook_received
 */ classWebhookObserver implements ObserverInterface
{
 public function__construct(
 private readonly WebhookSignatureValidator $signatureValidator,
 private readonly OrderStateUpdater $orderStateUpdater,
 private readonly LoggerInterface $logger,
 ) {}

 public functionexecute(Observer $observer): void
 {
 /** @ varMagentoFrameworkDataObject $transport */
 $transport = $observer->getData( 'transport');

 $rawBody = (string) $transport->getData( 'raw_body');
 $signature = (string) $transport->getData( 'signature_header');
 $storeId = (int) $transport->getData( 'store_id');

 // 1. Verify HMAC-SHA256 signature before trusting payload contenttry {
 $this->signatureValidator->verify($rawBody, $signature, $storeId);
 } catch (LocalizedException $e) {
 $this->logger->error( '[BINKPAY] Webhook signature invalid', [
 'error'=> $e->getMessage(), 'store_id' => $storeId,
 ]);
 // Return early — controller returns HTTP 401$transport->setData( 'rejected', true);
 return;
 }

 $payload = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
 $type = $payload[ 'type'] ?? 'unknown';
 $data = $payload[ 'data'] ?? [];

 $this->logger->info( '[BINKPAY] Webhook received', [
 'event_id' => $payload[ 'id'] ?? null,
 'type' => $type,
 'livemode' => $payload[ 'livemode'] ?? false,
 ]);

 match ($type) { 'payment.succeeded'=> $this->orderStateUpdater->markPaid($data), 'payment.failed'=> $this->orderStateUpdater->markFailed($data), 'refund.created'=> $this->orderStateUpdater->applyRefund($data), 'dispute.created'=> $this->orderStateUpdater->openDispute($data), 'dispute.resolved'=> $this->orderStateUpdater->closeDispute($data), default=> $this->logger->debug( "[BINKPAY] Unhandled event type: {$type}"),
 };
 }
}

Never disable signature verification

The WebhookSignatureValidator uses a timing-safe HMAC-SHA256 comparison. Disabling or bypassing it allows any party to forge webhook events and fraudulently mark orders as paid. Do not skip this step, even in development.

Refund and Dispute Flow

BINKPAY refunds are initiated from Magento Admin by creating a credit memo on the order. The module intercepts the credit memo submission event, calls the BINKPAY Refunds API, and stores the resulting BINKPAY refund ID on the credit memo for reconciliation.

Issuing a Refund via Credit Memo

Open the order in Magento Admin

Navigate to Sales → Orders and open the order you want to refund. The order must have status Processing or Complete and payment method BINKPAY.

Click "Credit Memo"

In the order detail page, click the Credit Memo button in the top-right action bar. If the button is absent, the order is either not invoiced yet or the payment method does not support refunds.

Enter refund amounts

Adjust the Qty to Refund per line item for a partial refund, or leave defaults for a full refund. You can also adjust the Refund Shipping amount. The Refund Totals section shows the calculated refund amount in the order's currency.

Click "Refund" to submit to BINKPAY

Click Refund (not "Refund Offline"). This triggers the module to call the BINKPAY Refunds API. On success, the credit memo is saved with the BINKPAY refund ID, and the order status updates to Closed (full refund) or Processing (partial refund). Refunds typically appear on the customer's statement within 5–10 business days.

Dispute Handling

When a customer files a chargeback, BINKPAY sends a dispute.created webhook event. The module automatically adds an order comment with the dispute ID and evidence due date, and changes the order status to Payment Review. To respond to a dispute:

  1. Log in to the BINKPAY Dashboard → Disputesand open the dispute by its ID (shown in the Magento order comment).
  2. Upload your evidence (shipping confirmation, customer correspondence, etc.) before the evidence due date shown on the dispute detail page.
  3. Click Submit Evidence. BINKPAY forwards your evidence to the card network. Resolution typically takes 60–90 days depending on the issuer.
  4. When the dispute is resolved, BINKPAY sends a dispute.resolved event. The module updates the Magento order status accordingly — back to Complete if the dispute was decided in your favour, or Closed if the chargeback was upheld.

Production Deployment

Switch Magento to production mode and flush all generated files before going live. Use the following deployment sequence in your CI/CD pipeline or deployment script.

text
#!/usr/bin/env bash
set -euo pipefail

# 1. Put the store in maintenance mode to block customer traffic during deploymentphp bin/magento maintenance:enable # 2. Pull the latest code (adjust to your VCS workflow)
git pull origin main

# 3. Install/update Composer dependencies without dev packagescomposer install --no-dev --optimize-autoloader --no-interaction # 4. Run any pending schema upgrades and data patchesphp bin/magento setup:upgrade --keep-generated # 5. Compile the dependency injection container (required in production mode)php bin/magento setup:di:compile # 6. Deploy static content for all locales used by your stores
# Add -f to force regeneration; adjust locales as neededphp bin/magento setup:static-content:deploy en_US ar_EG fr_FR -f # 7. Switch to production mode (disables Magento's developer error pages)php bin/magento deploy:mode:set production # 8. Reindex all indexers to reflect any data changesphp bin/magento indexer:reindex # 9. Flush all cachesphp bin/magento cache:flush # 10. Bring the store back onlinephp bin/magento maintenance:disable

echo "Deployment complete. Store is live."

Pre-Launch Checklist

  • Set Test Mode to No in Stores → Configuration → Sales → Payment Methods → BINKPAY.
  • Replace all sk_test_ / pk_test_ credentials with live keys from the BINKPAY Dashboard.
  • Confirm the webhook endpoint (https://your-store.com/binkpay/webhook/receive) returns HTTP 200 when tested from Dashboard → Developers → Webhooks → Send test event.
  • Register your live domain for Apple Pay via the BINKPAY API if you have enabled Apple Pay.
  • Place one live test transaction with a real card and verify it appears as Succeeded in the BINKPAY Dashboard and as Processing in Magento Admin.
  • Issue a full refund on that test transaction and confirm the credit memo is created and the BINKPAY Dashboard shows the refund.

Test Mode

Enable test mode before running any test transactions

In Magento Admin, go to Stores → Configuration → Sales → Payment Methods → BINKPAY and set Test Mode to Yes. The module will automatically use your sk_test_ and pk_test_ keys and route all API calls to the BINKPAY sandbox. No real charges are processed in test mode.

Use the following test card at checkout to simulate a successful payment. Use any future expiry date and any three-digit CVV.

Card numberExpiryCVVOutcome
4242 4242 4242 4242Any future dateAny 3 digitsSucceeded
4000 0000 0000 0002Any future dateAny 3 digitsCard declined
4000 0000 0000 9995Any future dateAny 3 digitsInsufficient funds
4000 0027 6000 3184Any future dateAny 3 digits3DS authentication required

Troubleshooting

BINKPAY does not appear under Payment Methods in Magento Admin

This almost always means the module registration step was skipped or failed. From the Magento root, run php bin/magento module:status BinkPay_Checkout. If the output shows disabled, run php bin/magento module:enable BinkPay_Checkout followed by php bin/magento setup:upgrade and a cache flush. If the module does not appear in the status output at all, the Composer install did not complete — re-run composer require binkpay/magento2-module and confirm there are no version constraint conflicts with your other modules.

Webhook events are not being received — orders stay in "Pending Payment"

First, verify the endpoint URL is publicly reachable: from outside your server, curl -X POST https://your-store.com/binkpay/webhook/receive should return HTTP 200 (or 401 for a missing signature — both mean the endpoint is reachable). Next, check the BINKPAY Dashboard under Developers → Webhooks for delivery failure logs. Common causes: (1) the Magento web server blocks POST requests from external IPs — whitelist BINKPAY's IP ranges in your firewall or WAF; (2) Magento is in maintenance mode; (3) the webhook URL was registered with http:// instead of https:// and your server redirects, which causes the POST body to be lost.

Credit memo refund fails with "BINKPAY API error: charge already fully refunded"

This error means the underlying BINKPAY charge has already been fully refunded — either via a previous credit memo, from the BINKPAY Dashboard directly, or because the original authorization was voided before capture. Open the BINKPAY Dashboard, search for the charge using the BINKPAY Payment ID stored in the Magento order's payment additional information, and confirm its refund state. If the charge is fully refunded, manually set the Magento order status to Closed via Order → Comments History → Submit Comment with a status change.

Multi-store currency mismatch: "Currency EGP is not supported in the Global environment"

The BINKPAY Global environment (api.binkpay.net) does not process EGP. If you are operating a store with EGP as the base currency, you must use a separate BINKPAY account configured for the Egypt environment and enter the Egypt API keys (pointing to api.binkpay.eg) in the website-scope configuration for that store. Confirm the correct website scope is selected in the Admin scope switcher when saving BINKPAY credentials — saving at the Default Config scope overwrites all website-level overrides.

Was this page helpful?