承接 istorebox/omnipay-benefitgateway 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

istorebox/omnipay-benefitgateway

最新稳定版本:v2.0.0

Composer 安装命令:

composer require istorebox/omnipay-benefitgateway

包简介

Benefit Payment Gateway driver for the Omnipay payment processing library

README 文档

README

PHP License CI

A Benefit Payment Gateway driver for the Omnipay PHP payment processing library.

Benefit is the leading payment network in Bahrain, enabling merchants to accept payments in Bahraini Dinar (BHD).

Requirements

Requirement Version
PHP ^8.2
ext-openssl any
omnipay/common ^3.1

Installation

composer require istorebox/omnipay-benefitgateway

Configuration

Obtain the following credentials from your Benefit merchant account:

Parameter Type Description
id string Merchant / Portal ID issued by Benefit
password string Gateway password issued by Benefit
resource_key string Exactly 32-byte AES-256 encryption key issued by Benefit
currency string ISO 4217 alpha code — must be BHD
langid string Payment page language: USA (English, default) or ARA (Arabic)
testMode bool true → sandbox, false (default) → production
use Omnipay\Omnipay;

$gateway = Omnipay::create('BenefitGateway');

$gateway->setId('YOUR_MERCHANT_ID');
$gateway->setPassword('YOUR_GATEWAY_PASSWORD');
$gateway->setResourceKey('YOUR_EXACTLY_32_BYTE_KEY_HERE!!'); // must be 32 bytes
$gateway->setCurrency('BHD');
$gateway->setLangId('USA');    // or 'ARA' for Arabic
$gateway->setTestMode(false);  // true for sandbox

⚠️ Security: The resource_key must be exactly 32 bytes. The driver will throw an \InvalidArgumentException immediately if the key length is wrong — this prevents silent encryption failures.

Usage

1 — Initiate a Purchase

Redirects the customer to the Benefit-hosted payment page.

$response = $gateway->purchase([
    'amount'        => '1.000',              // 3 decimal places for BHD
    'transactionId' => 'ORDER-' . time(),   // your unique order/track ID
    'returnUrl'     => 'https://yoursite.com/payment/return',
    'cancelUrl'     => 'https://yoursite.com/payment/cancel',
])->send();

if ($response->isRedirect()) {
    $response->redirect();
    // or: header('Location: ' . $response->getRedirectUrl());
}

Note: The gateway password is included inside the AES-encrypted trandata blob only. It is never exposed as a plain query string parameter in the redirect URL.

2 — Complete a Purchase (Callback)

Benefit POSTs the encrypted result back to your returnUrl. Handle it:

$response = $gateway->completePurchase()->send();
// trandata is decrypted automatically using your resource_key

if ($response->isSuccessful()) {
    $paymentId = $response->getTransactionReference(); // Benefit payment ID
    $orderId   = $response->getTransactionId();        // your order/track ID
    $authCode  = $response->getAuthCode();             // authorisation code
    $refId     = $response->getReferenceId();          // reference number

    // Mark order as paid ...

} elseif ($response->isCancelled()) {
    // Customer clicked Cancel on the Benefit page

} elseif ($response->isTimedOut()) {
    // Bank host communication timed out — advise customer to retry

} else {
    $error = $response->getMessage(); // e.g. 'NOT CAPTURED'
    // Handle failure ...
}

Passing Callback Data Manually

Useful in controllers or tests where you want to pass POST data explicitly:

$response = $gateway->completePurchase([
    'request_data' => $request->post(),
])->send();

Response Methods

completePurchase Response

Method Returns Description
isSuccessful() bool true only when result === 'CAPTURED'
isCancelled() bool true when result === 'CANCELED'
isTimedOut() bool true when result === 'HOSTIMEOUT'
getCode() string|null Raw result from Benefit (CAPTURED, NOT CAPTURED, CANCELED, HOSTIMEOUT)
getMessage() string|null Result string or ErrorText on failure
getTransactionReference() string|null Benefit-assigned paymentid
getTransactionId() string|null Your merchant trackid echoed back
getAuthCode() string|null Authorization code (auth)
getReferenceId() string|null Reference number (ref)

How Encryption Works

The Benefit gateway uses AES-256-CBC with a fixed IV (PGKEYENCDECIVSPC) and PKCS#5 padding, as required by the Benefit integration specification.

  • Purchase: request parameters (including id and password) are encrypted into a hex string and sent as trandata in the redirect URL.
  • completePurchase: the trandata POST field is URL-decoded, then hex-decoded, then AES-decrypted and parsed back into key-value pairs.
  • All encryption/decryption is handled by Omnipay\BenefitGateway\Crypto\AesEncryptor — you never call it directly.

Error Handling

Exception Trigger
InvalidRequestException Required parameter missing (id, amount, resource_key, paymentid, etc.)
InvalidRequestException Unsupported or missing currency code
InvalidRequestException AES decryption failure on callback (wraps RuntimeException)
\InvalidArgumentException resource_key is not exactly 32 bytes
\InvalidArgumentException setLangId() called with value other than USA or ARA
\InvalidArgumentException Unknown currency passed to CurrencyCodeResolver
\RuntimeException OpenSSL failure, invalid hex, or corrupted cipher data

Testing

composer install
composer test

Enable sandbox mode to route requests to the Benefit test environment:

https://www.test.benefit-gateway.bh/payment/PaymentHTTP.htm

Supported Currencies

The driver includes a full ISO 4217 currency map used internally for numeric code resolution. Pass BHD for all live Bahrain transactions.

You can also use CurrencyCodeResolver directly:

use Omnipay\BenefitGateway\Currency\CurrencyCodeResolver;

CurrencyCodeResolver::numericCode('BHD'); // '048'
CurrencyCodeResolver::getName('BHD');     // 'Bahraini Dinar'
CurrencyCodeResolver::isSupported('XYZ'); // false

Changelog

v2.1.0

  • Security: Validate AES key is exactly 32 bytes before any encrypt/decrypt operation
  • Security: Strip password from plaintext redirect URL — password only travels inside AES-encrypted trandata
  • Security: URL-decode trandata before hex2bin to handle Benefit POST encoding correctly
  • Security: Guard base64_decode and hex2bin false returns with explicit RuntimeException
  • Robustness: Add resource_key validation in CompletePurchaseRequest
  • Robustness: Wrap decryption RuntimeException as InvalidRequestException with context
  • Robustness: Add empty-string guard in pkcs5Unpad after successful decrypt
  • Feature: langid is now configurable (USA / ARA) via setLangId() on Gateway and PurchaseRequest
  • Feature: Add isCancelled() and isTimedOut() to CompletePurchaseResponse
  • Feature: Add CurrencyCodeResolver::getName() and ::all() methods
  • DX: Add suggest section to composer.json
  • Tests: Add AesEncryptorTest — 9 test cases covering round-trip, key length, encoding, errors
  • Tests: Add CurrencyCodeResolverTest — 12 test cases covering codes, names, case-insensitivity, duplicates
  • Tests: Expand GatewayTest — add isCancelled, isTimedOut, password-not-in-URL, resource_key missing tests
  • CI: Add GitHub Actions workflow for PHP 8.2 and 8.3 matrix

v2.0.0

  • Require PHP ^8.2, drop PHP 7.x
  • Strict types and full return-type declarations
  • Replace global helpers with Crypto\AesEncryptor and Currency\CurrencyCodeResolver
  • Fix duplicate currency keys in ISO 4217 map
  • Add getAuthCode(), getReferenceId(), getCode() to response
  • Fluent setter interface
  • PHPUnit v11 config
  • MIT LICENSE

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-09

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固