Search by

10corp / shurjopay-blesta

10corp

Official ShurjoPay payment gateway module for Blesta, developed and maintained by 10Corp.

Package info

github.com/10corp/shurjopay-blesta

Type:blesta-gateway-nonmerchant

pkg:composer/10corp/shurjopay-blesta

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

2.0.0 2025-04-27 19:50 UTC

This package is not auto-updated.

Last update: 2026-11-12 01:42:29 UTC


README

Accept BDT and USD invoice payments using ShurjoPay inside Blesta billing.
Compatible with Blesta 5.x / 6.0+ · Verified with Blesta Extension Dev Kit · Supports ShurjoPay API v2

Table of Contents

Overview

This module integrates ShurjoPay (Bangladesh's pioneer online payment gateway operated by shurjoMukhi Ltd.) into Blesta as a Non-Merchant Gateway. Customers pay invoices without entering sensitive card details, mobile banking PINs, or OTP credentials on your server — they are redirected to ShurjoPay's official hosted payment portal, authorize the transaction via their chosen channel, and are securely returned to Blesta.

Merchant vs. Non-Merchant Gateway Architecture

In Blesta's payment architecture:

  • Merchant Gateways collect payment credentials directly on the billing server, requiring higher PCI-DSS compliance and server security overhead.
  • Non-Merchant Gateways (NonmerchantGateway) offload all sensitive authentication (card numbers, CVVs, mobile wallet PINs, and OTPs) to the processor's secure hosted environment. By extending NonmerchantGateway, this module eliminates sensitive credential handling on your server while maintaining cryptographic server-to-server payment verification.

Hosted Secret-Pay Flow (/api/secret-pay)

The module implements ShurjoPay's secure Tokenized Secret-Pay workflow:

  1. Obtains a scoped Bearer token from ShurjoPay (/api/get_token).
  2. Initiates the payment session with customer billing metadata, invoice allocations, and signed callback parameters (/api/secret-pay).
  3. Redirects the client to the verified ShurjoPay checkout page (checkout_url).
  4. Upon payment completion, ShurjoPay redirects to Blesta's callback router, which verifies the payment directly with ShurjoPay's ledger (/api/verification/) before crediting the invoice.

Features

Feature Description
Multi-Channel Payments Supports Visa, Mastercard, American Express, bKash, Nagad, Rocket, Upay, and major Bangladeshi bank internet banking portals
Blesta 6.0 Dev Kit Compliant Fully compliant with official Blesta 6.0 Extension Dev Kit standards and specifications
Theme-Aware Paradigm UI Native Bootstrap 5 admin settings interface supporting both Light Mode and Dark Mode seamlessly
Dual Currency Support Native support for both BDT and USD invoice transactions
Sandbox / Test Mode Seamless toggle switch in admin settings connecting to ShurjoPay Sandbox (sandbox.shurjopayment.com)
Strict SSRF & Open Redirect Guard Validates checkout_url hostnames via isAllowedCheckoutUrl() to ensure redirects only point to verified ShurjoPay domains
Cryptographic Order Entropy Unguessable order identifiers generated using random_bytes() with custom merchant prefix
Amount & Currency Validation Deep verification comparing ledger amount and currency against expected invoice allocations to prevent financial tampering
Safe Callback Routing Eliminates loopback cURL deadlocks; natively leverages Blesta's Callback::gw and ClientPay::received architecture
Log Credential Masking Passwords, tokens, customer phone numbers, emails, and physical addresses are scrubbed before logging
Encrypted Credential Storage API password is automatically encrypted at rest using AES-256 by Blesta's encryption engine
Invoice Breakdown Tracking Serializes and unserializes multiple invoice payments within single transactions

Requirements

Requirement Minimum Version Notes
Blesta 5.0+ / 6.0+ Fully verified against Blesta 6.0 Extension Dev Kit
PHP 8.2+ Uses modern PHP typing, random_bytes(), and secure JSON decoding
PHP Extensions curl, json, openssl Standard on modern PHP web servers
SSL / TLS HTTPS required for Live ShurjoPay requires public HTTPS callback URLs for live production transactions
ShurjoPay Account Merchant Account Active merchant credentials from shurjoMukhi Ltd.

File Structure

shurjopay/
├── composer.json                 # Composer package definition (blesta-gateway-nonmerchant)
├── config.json                   # Gateway metadata, supported currencies, and Bootstrap icon
├── CHANGELOG.md                  # Version release history and migration notes
├── LICENSE                       # MIT License
├── README.md                     # Comprehensive developer & operator documentation
├── shurjopay.php                 # Main gateway class — implements NonmerchantGateway
├── language/
│   └── en_us/
│       └── shurjopay.php         # English language definitions, error strings, & i18n
└── views/
    └── default/
        ├── images/
        │   └── logo.png          # Official ShurjoPay gateway logo
        ├── process.pdt           # Client checkout payment view (Bootstrap 4 + FontAwesome)
        └── settings.pdt          # Admin configuration view (Bootstrap 5 Paradigm + Dark Mode)

Blesta 6.0 Dev Kit Compliance

This module adheres strictly to the specifications established in the official Blesta Extension Dev Kit:

Admin UI (Paradigm / Bootstrap 5) vs. Client Portal (Bootstrap 4)

Per Dev Kit Section 2 & reference/common/conversion-ui.md:

  • Admin Settings (views/default/settings.pdt):
    • Built specifically for the Blesta 6.0 Paradigm admin theme using native Bootstrap 5 classes (mb-3, form-control, form-label, form-check, card).
    • Uses Bootstrap Icons (bi bi-info-circle).
    • Zero Hardcoded Colors: Uses semantic utility classes and variables so the settings interface renders flawlessly in both Light and Dark mode.
    • Passwords rendered via $this->Form->fieldPassword() for screen security.
  • Client Portal View (views/default/process.pdt):
    • The Blesta 6.0 client portal runs on Bootstrap 4 + FontAwesome 5 + jQuery.
    • Client-facing views intentionally retain Bootstrap 4 structures and FontAwesome icons (fas fa-credit-card) to prevent visual breakage across custom client themes.
    • Action URLs are escaped with $this->Html->safe() to prevent XSS.

Universal Transaction Return Shape

Per Dev Kit Section 3.2 & Section 9.3, all processing methods (validate() and success()) return the exact standardized transaction array:

return [
    'client_id'             => $transaction['value2'],      // Blesta Client ID
    'amount'                => (float) $transaction['amount'], // Ledger amount
    'currency'              => $transaction['currency'],    // e.g. 'BDT' or 'USD'
    'status'                => 'approved',                  // Standard status enum
    'reference_id'          => $transaction['bank_trx_id'], // Bank transaction ID
    'transaction_id'        => $transaction['order_id'],    // ShurjoPay Order ID
    'parent_transaction_id' => null,                        // Standard shape requirement
    'invoices'              => $invoices                    // [['id' => 1, 'amount' => '100.00'], ...]
];

Metadata & Icon Configuration

Per Dev Kit Section 3.1:

  • In config.json, the "icon" field contains only the Bootstrap Icon name without any prefixes:
    "icon": "bi-wallet2"
  • Package type in composer.json is set to:
    "type": "blesta-gateway-nonmerchant"

Installation

Method 1: Manual Installation (Recommended)

  1. Upload or copy the shurjopay/ directory into your Blesta installation under:
    /path/to/blesta/components/gateways/nonmerchant/shurjopay/
  2. Ensure directory and file permissions allow the web server to read the files:
    chmod -R 755 /path/to/blesta/components/gateways/nonmerchant/shurjopay/
  3. Log in to your Blesta Admin area.
  4. Navigate to Settings → Payment Gateways.
  5. Click on the Available tab, locate ShurjoPay, and click Install.
  6. Enter your credentials, toggle Test Mode if appropriate, and click Update Settings.

Method 2: Composer Installation

Run composer inside your Blesta root directory:

composer require 10corp/shurjopay-blesta

Configuration

Admin Settings Parameters

In Blesta Admin, navigate to Settings → Payment Gateways → Installed → ShurjoPay → Manage.

Setting Field Purpose Source / Value
API Username (store_id) Merchant username assigned by ShurjoPay ShurjoPay Merchant Dashboard
API Password (store_password) Merchant API secret password ShurjoPay Merchant Dashboard (encrypted at rest by Blesta)
Merchant Prefix (store_prefix) 2 to 6 character unique prefix used in order IDs Assigned by ShurjoPay (e.g. sp, BL, corp)
Test Mode (dev_mode) When checked, connects to the ShurjoPay Sandbox API. When unchecked, connects to live production Toggle checkbox in gateway settings

Important

Because store_password is declared in encryptableFields(), it is encrypted at rest using AES-256. It is rendered using a secure password field (fieldPassword) to protect credentials from screen exposure.

Configuring the IPN / Callback URL in ShurjoPay

To ensure payments are verified automatically even if a customer closes their browser window after paying:

  1. Log into your ShurjoPay Merchant Dashboard.
  2. Navigate to your Project / IPN Settings.
  3. Set the IPN / Return URL to your Blesta callback URL:
    https://[your-blesta-domain]/callback/gw/[company_id]/shurjopay/
    
    (Your exact company-specific URL is displayed inside a copyable box at the bottom of the ShurjoPay settings page in Blesta).
  4. Save your ShurjoPay configuration.

ShurjoPay Sandbox Testing Guide & Credentials

The ShurjoPay sandbox allows developers to simulate live transactions across multiple channels without debiting real funds.

Official API Base URLs

Environment Base URL Verification / API Base
Production https://engine.shurjopayment.com/ https://engine.shurjopayment.com/api
Sandbox https://sandbox.shurjopayment.com/ https://sandbox.shurjopayment.com/api
Documentation ShurjoPay Direct Integration API Guide API Reference & Field Specs

Sandbox Testing Walkthrough

  1. Navigate to Settings → Payment Gateways → Installed → ShurjoPay in Blesta Admin.
  2. Check the Test Mode checkbox and enter your ShurjoPay Sandbox credentials.
  3. Open or create an invoice in the Blesta Client Portal (in BDT or USD).
  4. Click Pay with ShurjoPay.
  5. You will be redirected to sandbox.shurjopayment.com.
  6. Select any simulated payment channel (Cards, bKash, Nagad, etc.):
    • Simulated Cards: Enter standard sandbox card numbers and test OTP (123456).
    • Simulated MFS: Enter a test mobile number and complete the simulated PIN confirmation.
  7. Upon approval, ShurjoPay redirects to Blesta's callback URL, where validate() queries /api/verification/, confirms the ledger status, marks the invoice paid, and returns the client to the payment received screen.

Architectural Lifecycles & Sequence Flow

High-Level Payment & Return Flow

sequenceDiagram
    autonumber
    actor Customer as Customer (Browser)
    participant Blesta as Blesta Client Portal
    participant GW as ShurjoPay Gateway (Module)
    participant SP_API as ShurjoPay API Engine
    participant SP_UI as ShurjoPay Hosted Checkout

    Customer->>Blesta: Clicks "Pay with ShurjoPay" on Invoice
    Blesta->>GW: buildProcess($contact, $amount, $invoices)
    GW->>SP_API: POST /api/get_token (username, password)
    SP_API-->>GW: Returns Bearer Token
    GW->>GW: Generate order_id (prefix + timestamp + random_bytes)
    GW->>SP_API: POST /api/secret-pay (params + token)
    SP_API-->>GW: Returns checkout_url
    GW->>GW: Validate checkout_url host (SSRF guard)
    GW-->>Blesta: Render views/default/process.pdt
    Blesta-->>Customer: Display "Pay with ShurjoPay" button
    Customer->>SP_UI: Redirect to ShurjoPay Hosted Portal
    SP_UI->>Customer: Customer authorizes payment (Card/MFS)
    SP_UI->>Blesta: Browser Redirect to /callback/gw/[id]/shurjopay/?order_id=...
    Blesta->>GW: validate($get, $post)
    GW->>SP_API: POST /api/verification/ (order_id + token)
    SP_API-->>GW: Returns transaction ledger data (sp_code: 1000)
    GW->>GW: Verify order_id, amount & currency match
    GW-->>Blesta: Return universal transaction array (status: approved)
    Blesta->>Blesta: Record transaction & credit invoice
    Blesta->>Customer: Redirect to /client/pay/received/shurjopay/?order_id=...
    Blesta->>GW: success($get, $post)
    GW-->>Blesta: Return verified transaction receipt data
    Blesta-->>Customer: Display Payment Confirmation Receipt
Loading

1. Payment Initiation Lifecycle (buildProcess()) — 8 Steps

  1. Amount Normalization: Formats payment amount as two-decimal string and resolves client billing details (name, email, phone, address).
  2. Callback URL Generation: Formats Blesta's non-merchant callback URL:
    $callback_url = Configure::get('Blesta.gw_callback_url') . Configure::get('Blesta.company_id') . '/shurjopay/';
  3. Authentication: Acquires a Bearer authentication token from ShurjoPay /api/get_token.
  4. Order ID Generation: Constructs a unique, non-enumerable order identifier using the merchant prefix, timestamp, and cryptographically secure random bytes:
    $order_id = $prefix . date('ymdHis') . bin2hex(random_bytes(4));
  5. Payload Assembly: Builds the complete /api/secret-pay payload including customer metadata, serialized invoice IDs in value1, client ID in value2, expected amount in value3, and currency in value4.
  6. Log Credential Scrubbing: Masks tokens, phone numbers, and customer addresses before writing to Blesta Gateway Logs.
  7. SSRF & Open Redirect Validation: Validates the returned checkout_url against isAllowedCheckoutUrl() to ensure the redirect destination strictly belongs to verified ShurjoPay hosts.
  8. UI Rendering: Renders views/default/process.pdt with the verified checkout URL.

2. Callback Validation Lifecycle (validate()) — 6 Steps

When ShurjoPay sends an IPN or redirects the client to the callback URL:

  1. Parameter Resolution: Extracts order_id safely from $get or $post.
  2. Ledger Query: Calls /api/verification/ with Bearer token authentication to fetch authoritative transaction status directly from ShurjoPay.
  3. Order ID Match: Asserts that order_id in the API response matches the requested order identifier.
  4. Status Code Check: Verifies that sp_code === '1000' (Success).
  5. Amount & Currency Validation: Asserts that the ledger amount is strictly positive and matches the expected amount within floating-point tolerance, and validates the currency.
  6. Universal Return: Decodes the serialized invoices from value1 and returns the standard approved transaction data array to Blesta.

3. Client Return Security (success())

success() is executed when the customer arrives back at ClientPay::received:

  • Serves as a read-only confirmation display handler.
  • Queries ShurjoPay /api/verification/ to retrieve the transaction receipt number (bank_trx_id) and invoice allocations.
  • Zero Loopback Calls: Unlike earlier legacy implementations, success() never performs recursive cURL requests to the server itself, completely preventing server deadlocks and duplicate payments.

Cancellation & Error Handling

  • If the customer cancels payment on ShurjoPay, the gateway receives sp_code: '1002' or '1068'.
  • The gateway registers a friendly cancellation notice (Shurjopay.!error.payment.canceled).
  • Invoices remain open and unpaid, allowing the customer to retry payment immediately.

Code Architecture & Key Methods

All gateway logic resides in shurjopay.php.

Public Blesta Contract Methods

Method Visibility Purpose
__construct() public Initializes config.json, the Input component, and loads language strings
setCurrency($currency) public Stashes the active transaction currency code
setMeta(array $meta) public Receives saved gateway settings from Blesta
encryptableFields() public Declares ['store_password'] for automatic AES-256 encryption at rest
getSettings(array $meta) public Renders the Paradigm Bootstrap 5 admin view (views/default/settings.pdt)
editSettings(array $meta) public Validates settings inputs and normalizes sandbox checkbox
upgrade($current_version) public Handles company-scoped version migrations per Blesta 6.0 Dev Kit standards
buildProcess(...) public Executes the 8-step payment initialization and renders process.pdt
validate(array $get, array $post) public Authoritative IPN/callback handler; queries /api/verification/
success(array $get, array $post) public Read-only return handler for invoice payment receipt display
capture(...) / void(...) / refund(...) public Non-merchant stubs returning unsupported errors per Blesta specifications

Private Internal Engine Methods

Method Visibility Purpose
getApiUrl() private Returns sandbox or production base URL depending on dev_mode
getToken($api_url) private Obtains Bearer authentication token from /api/get_token with log masking
makeApiRequest(...) private Hardened cURL executor with TLS verification, timeouts, and JSON decoding
verifyPayment($order_id) private Queries /api/verification/ directly with Bearer token authentication
processPaymentResponse(...) private Validates response status codes, amounts, currencies, and invoice maps
isAllowedCheckoutUrl($url) private Enforces HTTPS and whitelists authorized ShurjoPay hostnames against SSRF
serializeInvoices(...) private Encodes multi-invoice allocations into `id=amt
unserializeInvoices(...) private Safely decodes invoice string back into structured associative array
getClientPhone($client) private Extracts and sanitizes primary phone number from client contacts
buildForm($post_to) private Renders the checkout action view (views/default/process.pdt)

View Templates (.pdt)

  • views/default/settings.pdt: Renders the admin settings form using native Bootstrap 5 classes, password masking, responsive form controls, and an informative IPN callback display box. Works seamlessly across Light and Dark admin themes.
  • views/default/process.pdt: Renders the customer-facing checkout button using Bootstrap 4 and FontAwesome (fas fa-credit-card). Output URLs are escaped via $this->Html->safe().

Security Architecture & Verification

The integration has been hardened against common payment integration risks:

┌────────────────────────────────────────────────────────────────────────┐
│                        Security Defense Layers                         │
├──────────────────────────────┬─────────────────────────────────────────┤
│ PCI-DSS Offloading           │ NonmerchantGateway delegates all card/  │
│                              │ MFS authentication to ShurjoPay hosted  │
│                              │ portal.                                 │
├──────────────────────────────┼─────────────────────────────────────────┤
│ SSRF & Open Redirect Guard   │ isAllowedCheckoutUrl() strictly verifies│
│                              │ HTTPS and whitelists official ShurjoPay │
│                              │ domain hostnames.                       │
├──────────────────────────────┼─────────────────────────────────────────┤
│ Amount & Currency Tampering  │ Rejects transactions where ledger amount│
│                              │ or currency differs from expected values│
├──────────────────────────────┼─────────────────────────────────────────┤
│ Cryptographic Order IDs      │ random_bytes() eliminates predictable   │
│                              │ sequential order enumeration.           │
├──────────────────────────────┼─────────────────────────────────────────┤
│ Concurrency & Deadlock Fix   │ Eliminates loopback cURL calls; uses    │
│                              │ Blesta's native callback architecture.  │
├──────────────────────────────┼─────────────────────────────────────────┤
│ Credential & PII Scrubbing   │ maskData() strips secrets, tokens, and  │
│                              │ customer details before writing logs.   │
├──────────────────────────────┼─────────────────────────────────────────┤
│ AES-256 Storage Encryption   │ store_password is encrypted at rest by  │
│                              │ Blesta's encryption engine.             │
├──────────────────────────────┼─────────────────────────────────────────┤
│ XSS Prevention               │ Html->safe() escapes output URLs in     │
│                              │ client checkout views.                  │
└──────────────────────────────┴─────────────────────────────────────────┘

Step-by-Step Developer Guide

How to Modify Settings or Add a Field

If you need to add an additional configuration option (e.g. custom_fee):

  1. Add Form Input in views/default/settings.pdt:
    <div class="mb-3">
        <?php
        $this->Form->label($this->_('Shurjopay.custom_fee', true), 'custom_fee', ['class' => 'form-label']);
        $this->Form->fieldText('custom_fee', ($meta['custom_fee'] ?? null), ['id' => 'custom_fee', 'class' => 'form-control']);
        ?>
    </div>
  2. Add Validation Rule in shurjopay.php (editSettings()):
    $rules['custom_fee'] = [
        'valid' => [
            'if_set' => true,
            'rule' => 'isNumeric',
            'message' => Language::_('Shurjopay.!error.custom_fee.valid', true)
        ]
    ];
  3. Add Language Strings in language/en_us/shurjopay.php:
    $lang['Shurjopay.custom_fee'] = 'Custom Processing Fee';
    $lang['Shurjopay.!error.custom_fee.valid'] = 'Please enter a valid numeric fee.';

How to Add a New Language Translation (e.g., bn_bd)

  1. Create a new directory under language/ matching Blesta's locale code (Bengali - Bangladesh):
    mkdir -p language/bn_bd/
  2. Copy language/en_us/shurjopay.php into the new directory:
    cp language/en_us/shurjopay.php language/bn_bd/shurjopay.php
  3. Translate the string values on the right-hand side of each $lang[...] = '...'; assignment.
  4. Blesta will automatically load language/bn_bd/shurjopay.php whenever an administrator or client selects Bengali (bn_bd).

Error Reference & Status Code Mapping

ShurjoPay Response Codes (sp_code)

SP Code Status Meaning Module Action
1000 Success Approves payment, records transaction ID, and marks invoice as paid
1001 Failed Rejects payment; registers Shurjopay.!error.payment.failed
1002 Canceled Customer canceled payment; registers Shurjopay.!error.payment.canceled
1005 Authentication Error Token request rejected; registers Shurjopay.!error.token.failed
1068 User Abandoned Customer closed gateway session; registers cancellation notice

Blesta Input Error Keys

Error Key Message Displayed Typical Cause
Shurjopay.!error.username.valid Please enter a valid API Username. Username missing in gateway settings
Shurjopay.!error.password.valid Please enter a valid API Password. Password missing in gateway settings
Shurjopay.!error.prefix.valid Please enter a valid Merchant Prefix. Prefix missing in gateway settings
Shurjopay.!error.token.failed Failed to obtain an authentication token... Invalid API credentials or server IP not whitelisted
Shurjopay.!error.api.response Invalid or unexpected response received... Network timeout or malformed ShurjoPay response
Shurjopay.!error.order.missing Order ID is missing from the gateway response. ShurjoPay callback received without order_id
Shurjopay.!error.order.mismatch Order ID mismatch detected... Verified order ID does not match session order ID
Shurjopay.!error.amount.mismatch Transaction amount verification failed... Paid amount differs from expected invoice amount
Shurjopay.!error.currency.mismatch Currency mismatch detected... Paid currency differs from expected currency
Shurjopay.!error.checkout_url.invalid Security error: The returned checkout URL is untrusted. ShurjoPay returned a non-HTTPS or unauthorized URL
Shurjopay.!error.payment.canceled The payment was canceled by the customer... Customer clicked Cancel or closed payment screen
Shurjopay.!error.payment.failed The payment failed or was declined... Insufficient funds, bad PIN, or card decline

Troubleshooting Guide

Issue Typical Cause Resolution
"Failed to obtain an authentication token" Invalid API username/password or IP not whitelisted Verify credentials in settings. In production, ShurjoPay may require your web server's outbound IP to be whitelisted in their firewall.
Payment redirects to blank page or fails to load button cURL request failed or network timeout Check Tools → Logs → Gateway Log in Blesta Admin for the raw HTTP request/response to /api/secret-pay.
Invoice remains unpaid after customer completes transaction ShurjoPay IPN not configured or firewall blocking callbacks Set the Callback URL in your ShurjoPay merchant portal. Ensure outbound/inbound port 443 is open on your web server.
"Transaction amount verification failed" Amount paid on ShurjoPay differs from invoice total Check if customer applied discounts directly on ShurjoPay or partial payments were submitted.
Test Mode not switching to Sandbox Admin setting was not saved Ensure Test Mode is checked and click Update Settings in the ShurjoPay gateway settings page.

ShurjoPay API Quick Reference

Endpoint Method Headers Description
/api/get_token POST Content-Type: application/json Obtains Bearer authentication token using username and password
/api/secret-pay POST Authorization: Bearer <token> Initiates checkout session with order, amount, and customer details
/api/verification/ POST Authorization: Bearer <token> Queries transaction ledger state using order_id to verify payment

Maintained by 10Corp · Developed with shurjoMukhi Ltd. · Fully verified with Blesta Extension Dev Kit.