shubo / module-bog-payment
Bank of Georgia (BOG) iPay payment integration for Duka marketplace
Package info
github.com/nshubitidze/module-bog-payment
Type:magento2-module
pkg:composer/shubo/module-bog-payment
Requires
- php: >=8.4
- magento/framework: ^103.0
- magento/module-backend: ^102.0
- magento/module-checkout: ^100.4
- magento/module-payment: ^100.4
- magento/module-sales: ^103.0
- magento/module-store: ^101.1
README
Bank of Georgia payment integration for Magento 2 using the BOG Payments REST API. Customers are redirected to the BOG-hosted payment page to complete their payment and returned to your store afterward.
IMPORTANT DISCLAIMER: This module has NOT been tested in production with real transactions. It has been developed and tested against sandbox/test environments only. Thorough testing with real payment credentials and real cards is required before going live.
Table of Contents
- Overview
- Requirements
- Installation
- Configuration
- Supported Features
- Unsupported Features
- Payment Flow
- Order Status Flow
- Split Payments (Marketplace)
- Admin Actions
- Technical Architecture
- API Endpoints
- Logging
- Cron Jobs
- Internationalization
- Troubleshooting
- License
Overview
Shubo_BogPayment integrates Bank of Georgia payments into Magento 2 via the BOG Payments API (also known as iPay). The module uses a redirect-based flow: the customer clicks "Place Order", is redirected to the BOG-hosted payment page, and returns to the store after payment completes.
Key highlights:
- Redirect to BOG-hosted payment page
- OAuth2 client credentials authentication
- Pre-authorization (manual capture) and automatic capture modes
- Full and partial refunds via Magento credit memos
- Multiple payment methods: Card, Google Pay, Apple Pay, BOG P2P, BOG Loyalty
- Split payments for marketplace/multi-vendor scenarios (via IBAN-based distribution)
- SHA256withRSA callback signature verification
- Server-to-server callback + cron reconciler for reliable order processing
- Country restriction support
- Light/Dark payment page themes
Key design decision: The Magento order is created after the customer returns from the BOG payment page with a successful payment, not before. This prevents ghost orders from abandoned payment flows.
Requirements
| Requirement | Version |
|---|---|
| Magento | 2.4.8+ |
| PHP | 8.4+ |
magento/framework |
* |
magento/module-payment |
* |
magento/module-sales |
* |
magento/module-checkout |
* |
magento/module-store |
* |
magento/module-backend |
* |
You need a BOG Payments API account with a Client ID and Client Secret. These are obtained from the Bank of Georgia merchant portal.
No external PHP SDK dependency is required -- the module communicates directly with the BOG REST API using cURL.
Installation
Via Composer (recommended)
composer require shubo/module-bog-payment bin/magento module:enable Shubo_BogPayment bin/magento setup:upgrade bin/magento cache:flush
Manual Installation
- Copy the module files to
app/code/Shubo/BogPayment/. - Enable and install:
bin/magento module:enable Shubo_BogPayment bin/magento setup:upgrade bin/magento cache:flush
Configuration
Navigate to Stores > Configuration > Sales > Payment Methods > BOG Payments (Bank of Georgia).
Credentials
| Field | Description |
|---|---|
| Enabled | Enable or disable the payment method. |
| Title | Display name shown to customers at checkout. Default: BOG Payments. |
| Environment | Test or Live. Controls which credentials and environment are active. |
| Client ID | Your BOG Payments API client ID. |
| Client Secret | Your BOG Payments API client secret. Stored encrypted. |
Payment Settings
| Field | Description |
|---|---|
| Payment Action | Automatic Capture (default) -- charges immediately and creates an invoice. Manual Capture -- pre-authorizes funds, requiring manual capture from admin. |
| API URL | Base URL for the BOG Payments API. Default: https://api.bog.ge/payments/v1. |
| OAuth URL | OAuth2 token endpoint URL. Default: https://oauth2.bog.ge/auth/realms/bog/protocol/openid-connect/token. |
| Payment Lifetime (minutes) | How long the payment session stays valid. Default: 15 minutes. Range: 2 to 1440 (24 hours). |
| Payment Page Theme | Light or Dark theme for the BOG-hosted payment page. |
| Allowed Payment Methods | Multi-select: Card, Google Pay, Apple Pay, BOG P2P, BOG Loyalty. |
| Debug | When enabled, logs all API requests and responses to the dedicated log file. |
| New Order Status | Initial order status. Default: pending_payment. |
| Sort Order | Controls the display order of the payment method at checkout. |
Country Restrictions
| Field | Description |
|---|---|
| Payment from Applicable Countries | All Allowed Countries or Specific Countries. |
| Payment from Specific Countries | If "Specific Countries" is selected, only these countries can use this payment method. |
Split Payments
| Field | Description |
|---|---|
| Enable Split Payments | Enable fund distribution to multiple BOG merchants. |
| Auto-Settle After Approval | Automatically distribute funds when payment is approved. |
| Split Receivers | Dynamic rows table. Each row has: IBAN, Amount Type (Percentage or Fixed), Amount, Description. |
Config paths (for programmatic access):
payment/shubo_bog/active
payment/shubo_bog/title
payment/shubo_bog/environment
payment/shubo_bog/client_id
payment/shubo_bog/client_secret
payment/shubo_bog/api_url
payment/shubo_bog/oauth_url
payment/shubo_bog/payment_action_mode
payment/shubo_bog/payment_lifetime
payment/shubo_bog/payment_theme
payment/shubo_bog/payment_methods
payment/shubo_bog/split_enabled
payment/shubo_bog/split_auto_settle
payment/shubo_bog/split_receivers
payment/shubo_bog/debug
payment/shubo_bog/order_status
payment/shubo_bog/sort_order
payment/shubo_bog/allowspecific
payment/shubo_bog/specificcountry
Supported Features
| Feature | Status | Details |
|---|---|---|
| Redirect-based payment | Supported | Customer redirected to BOG-hosted payment page |
| Card payments | Supported | Visa, Mastercard, etc. via BOG |
| Google Pay | Supported | Configurable in Allowed Payment Methods |
| Apple Pay | Supported | Configurable in Allowed Payment Methods |
| BOG P2P | Supported | Configurable in Allowed Payment Methods |
| BOG Loyalty | Supported | Configurable in Allowed Payment Methods |
| Automatic Capture (auto-invoice) | Supported | Payment charged on approval, invoice created automatically |
| Manual Capture (pre-authorization) | Supported | Funds held, manual capture via admin button |
| Manual capture from admin | Supported | "Capture Payment" button on order view |
| Void pre-authorized payment | Supported | "Void Payment" button cancels the order |
| Full refund | Supported | Via Magento credit memo |
| Partial refund | Supported | Via Magento credit memo with partial amount |
| Server-to-server callbacks | Supported | BOG POSTs to /shubo_bog/payment/callback |
| SHA256withRSA signature verification | Supported | Verifies callback authenticity using BOG's RSA public key |
| Status API fallback verification | Supported | Falls back to checking BOG Receipt API if signature verification fails |
| Cron reconciler | Supported | Checks stuck orders every 5 minutes |
| Manual status check from admin | Supported | "Check BOG Status" button queries API and syncs order |
| Split payments (IBAN-based) | Supported | Fund distribution to sub-merchants via IBAN + percentage |
| OAuth2 authentication | Supported | Client credentials grant with automatic token refresh |
| Multi-currency | Supported | Sends quote currency code to BOG |
| Multi-store / multi-website | Supported | All config fields are website-scoped |
| Country restrictions | Supported | Allow all or specific countries |
| Payment info in admin | Supported | Shows BOG Order ID, status, card type, PAN, payment method |
| Localization (EN/KA) | Supported | Payment page and API requests use store locale |
| Payment page theme | Supported | Light or Dark theme for the BOG payment page |
| Sensitive data protection | Supported | Client secret encrypted in config |
| Order confirmation emails | Supported | Sent after payment is confirmed |
| Idempotency | Supported | UUID v4 Idempotency-Key header on create-order requests |
Unsupported Features
| Feature | Status |
|---|---|
| Embedded payment form (no redirect) | Not implemented (redirect only) |
| Recurring / subscription payments | Not implemented |
| Saved card / tokenization | Not implemented |
| Installment payments | Not implemented |
| Partial capture of pre-authorized amount | Supported but untested -- the capture API call sends the full amount |
| Admin order creation (phone orders) | Not supported (can_use_internal = 0) |
| Settlement API for split distribution | The split data is sent at order creation time via the config.split payload, not as a separate post-payment settlement call (unlike the TBC module) |
| Multiple address checkout | Disabled in payment.xml |
Payment Flow
Customer selects BOG payment at checkout
|
v
Customer clicks "Place Order"
-> JS calls POST /shubo_bog/payment/initiate
-> Backend authenticates via OAuth2 (client_credentials)
-> Backend calls BOG API: POST /ecommerce/orders
-> BOG returns order ID + redirect URL
-> Frontend redirects to BOG payment page
|
v
Customer completes payment on BOG page
(Card entry, 3DS, Google Pay, etc.)
|
+-----+-----+
| |
Success Failure
| |
v v
Redirect to Redirect to
/shubo_bog/ checkout/
payment/return onepage/failure
|
v
ReturnAction controller:
-> Checks BOG Status API (GET /receipt/{id})
-> If completed: creates Magento order, captures, invoices
-> If pending: creates order in pending_payment state
-> Redirects to success page
|
v
(Meanwhile) BOG sends POST callback to
/shubo_bog/payment/callback
-> Verifies SHA256withRSA signature (or falls back to Status API)
-> Updates order if not already processed
-> Sends order confirmation email
|
v
(Every 5 min) Cron reconciler checks stuck orders
-> Queries BOG Status API
-> Processes completed / cancels failed or expired
Key design decision: No Magento order exists until the customer returns from BOG. The Initiate controller works with the quote only. The ReturnAction controller creates the actual Magento order via CartManagementInterface::placeOrder(). This prevents ghost orders.
Order Status Flow
Customer returns from BOG
|
+---+---+
| |
Success Pending
| |
v v
processing pending_payment
(invoice) |
+----+----+
| | |
Approved Failed Expired
| | |
v v v
processing canceled canceled
(invoice)
If Payment Action = "Manual Capture":
Success ──> processing (funds held, no invoice)
|
+------+------+
| |
Capture Void
| |
v v
processing canceled
(invoice)
Split Payments (Marketplace)
Split payments allow distributing order funds to multiple BOG merchants. This is designed for marketplace scenarios.
How It Works (BOG)
Unlike the TBC/Flitt module which uses a post-payment settlement API, the BOG module sends split payment data at order creation time as part of the create-order API request:
{
"config": {
"split": {
"split_payments": [
{
"iban": "GE12TB1234567890123456",
"percent": 60.0,
"description": "Vendor payment"
}
]
}
}
}
Configuration Methods
Admin-configured receivers (static): Set fixed receivers in the admin panel using IBANs.
Event-based receivers (dynamic): Other modules can listen to the shubo_bog_payment_split_before event and call addSplitPayment() on the SplitPaymentDataInterface object.
Key Differences from TBC Module
| Aspect | TBC (Flitt) | BOG |
|---|---|---|
| Split identifier | Merchant ID (Flitt) | IBAN (bank account) |
| Split timing | Post-payment settlement API | At order creation time |
| Amount types | Fixed + Percentage | Percentage only (in API payload) |
| Settlement button | Yes (manual trigger) | No (sent with order) |
Admin Actions
The following buttons appear on the order view page for BOG-paid orders:
| Button | Appears When | Action |
|---|---|---|
| Check BOG Status | Any BOG order with a BOG order ID | Queries BOG Status API, displays status, auto-processes if completed |
| Capture Payment | Pre-authorized order (not yet captured) | Sends capture request to BOG API, creates invoice |
| Void Payment | Pre-authorized order (not yet captured) | Cancels the Magento order; hold expires on bank side |
Technical Architecture
Key Classes
| Class | Purpose |
|---|---|
Gateway\Config\Config |
Configuration reader; URL builders for all API endpoints |
Gateway\Http\Client\CreatePaymentClient |
Creates orders via BOG /ecommerce/orders with OAuth2 bearer token |
Gateway\Http\Client\RefundClient |
Sends refunds via BOG /checkout/refund |
Gateway\Http\Client\CaptureClient |
Captures pre-authorized payments via /payment/authorization/approve/{id} |
Gateway\Http\Client\StatusClient |
Checks status via /receipt/{id} |
Gateway\Request\InitializeRequestBuilder |
Builds the create-order request with basket, URLs, capture mode, TTL |
Gateway\Request\RefundRequestBuilder |
Builds the refund request with BOG order ID and amount |
Gateway\Request\SplitDataBuilder |
Adds split payment config to the create-order request |
Gateway\Response\InitializeHandler |
Stores BOG order ID, redirect URL, details URL on payment |
Gateway\Response\RefundHandler |
Stores refund status and transaction ID |
Gateway\Validator\ResponseValidator |
Validates HTTP status codes from BOG API |
Gateway\Validator\CallbackValidator |
SHA256withRSA signature verification + Status API fallback |
Model\OAuthTokenProvider |
OAuth2 client_credentials token management with in-memory caching |
Controller\Payment\Initiate |
AJAX endpoint: creates BOG order from quote, returns redirect URL |
Controller\Payment\ReturnAction |
Handles customer return: creates Magento order, processes payment |
Controller\Payment\Callback |
Server-to-server callback from BOG |
Controller\Payment\Confirm |
Safety net confirmation endpoint |
Cron\PendingOrderReconciler |
Reconciles stuck pending orders |
Observer\SetPendingPaymentState |
Sets order to pending_payment on placement |
Plugin\AddOrderButtons |
Adds admin toolbar buttons |
Model\Ui\ConfigProvider |
Provides checkout JS configuration |
Block\Payment\Info |
Renders payment details in admin |
Magento Payment Gateway Pattern
The module uses Magento's Payment Gateway framework with virtual types:
- Facade:
ShuboBogPaymentFacade(virtual type ofMagento\Payment\Model\Method\Adapter) - Command Pool:
initializeandrefundcommands - Request Builders: Composite builder with
InitializeRequestBuilder+SplitDataBuilder - HTTP Clients: Direct cURL calls with OAuth2 bearer token
- Response Handlers: Store BOG order IDs, redirect URLs, refund status
- Validators:
ResponseValidatorfor HTTP status,CallbackValidatorfor signatures,CountryValidatorfor country restrictions
OAuth2 Authentication
The BOG Payments API uses OAuth2 client credentials grant:
- Token endpoint:
https://oauth2.bog.ge/auth/realms/bog/protocol/openid-connect/token - Grant type:
client_credentials - Auth: HTTP Basic (Client ID : Client Secret)
- Token is cached in memory with a 60-second buffer before expiry
Callback Signature Verification
BOG callbacks include a Callback-Signature header containing a base64-encoded SHA256withRSA signature. The module verifies this signature using BOG's RSA public key (embedded in the CallbackValidator class). If signature verification fails, the module falls back to checking the payment status via the BOG Receipt/Status API.
Events Dispatched
| Event | Purpose |
|---|---|
shubo_bog_payment_split_before |
Allows modules to populate split payment data via SplitPaymentDataInterface |
API Endpoints
BOG Payments API Endpoints Used
| Endpoint | Method | Purpose |
|---|---|---|
/ecommerce/orders |
POST | Create payment order |
/receipt/{order_id} |
GET | Check payment status |
/checkout/refund |
POST | Refund payment |
/payment/authorization/approve/{order_id} |
POST | Capture pre-authorized payment |
Base URL: https://api.bog.ge/payments/v1
OAuth token endpoint: https://oauth2.bog.ge/auth/realms/bog/protocol/openid-connect/token
Module Frontend Routes
| URL | Method | Controller | Purpose |
|---|---|---|---|
/shubo_bog/payment/initiate |
POST | Initiate |
Create BOG order and get redirect URL (AJAX) |
/shubo_bog/payment/return |
GET | ReturnAction |
Handle customer return from BOG |
/shubo_bog/payment/callback |
POST | Callback |
Server-to-server callback (CSRF exempt) |
/shubo_bog/payment/confirm |
POST | Confirm |
Safety net payment confirmation (AJAX) |
Module Admin Routes
| URL | Controller | Purpose |
|---|---|---|
/shubo_bog/order/checkStatus |
CheckStatus |
Query BOG API and sync order status |
/shubo_bog/order/capture |
Capture |
Capture a pre-authorized payment |
/shubo_bog/order/voidPayment |
VoidPayment |
Void payment and cancel order |
Logging
All module logs are written to a dedicated file:
var/log/shubo_bog_payment.log
Enable Debug mode in configuration to log full API request/response bodies including OAuth token requests, create-order calls, status checks, and callback processing.
Cron Jobs
| Job | Schedule | Purpose |
|---|---|---|
shubo_bog_pending_order_reconciler |
Every 5 minutes | Checks orders in pending_payment state older than 15 minutes. Queries BOG Status API and processes completed/failed/expired orders. Max 50 orders per run. |
Internationalization
The module includes translations for:
- English (
en_US) - Georgian (
ka_GE)
The BOG payment page language is automatically set based on the Magento store locale via the Accept-Language header on API requests. Supported languages: en, ka.
Troubleshooting
Customer redirected but order not created
- This is by design. The Magento order is only created when the customer returns from BOG.
- If the customer closes the browser on the BOG page, the callback and cron reconciler will not create an order since the quote has not been converted.
- Check
var/log/shubo_bog_payment.logfor details.
Order stuck in "pending_payment"
- Use the "Check BOG Status" button in admin to manually query and sync.
- The cron reconciler should automatically process stuck orders after 15 minutes.
- Verify the callback URL (
/shubo_bog/payment/callback) is accessible from the internet (HTTPS required). - Check that your OAuth2 credentials are valid and not expired.
OAuth2 authentication fails
- Verify Client ID and Client Secret are correctly set.
- Ensure the OAuth URL is correct:
https://oauth2.bog.ge/auth/realms/bog/protocol/openid-connect/token. - Check if the credentials are for the correct environment (test vs. live).
- Check
var/log/shubo_bog_payment.logfor the HTTP response from the token endpoint.
Callback signature verification fails
- The module has BOG's RSA public key embedded. If BOG rotates their key, the
CallbackValidatorclass needs to be updated. - The module falls back to the Status API when signature verification fails, so orders should still process correctly.
- Check logs for "signature verification failed" messages.
Refund fails
- Ensure the BOG order ID is stored on the payment (
bog_order_idin additional info). - Check
var/log/shubo_bog_payment.logfor the BOG API error response. - Verify your OAuth2 credentials have refund permissions.
Payment page shows wrong language
- The language is derived from the Magento store locale. Set the store locale to
ka_GEfor Georgian or any English locale for English.
Split payments not working
- BOG split payments use IBANs, not merchant IDs.
- Verify the IBANs are valid Georgian bank accounts.
- The split data is sent at order creation time. If the create-order call fails, check the API response in debug logs.
- The
shubo_bog_payment_split_beforeevent must be observed by your module to provide dynamic split data.
License
Apache License 2.0. See LICENSE for details.
Copyright 2026 Nikoloz Shubitidze (Shubo).