Skip to content

Bohudur Laravel SDK

Developer-first Laravel SDK for the Bohudur Payment Automation Platform.

This package is a Laravel wrapper around the Bohudur Payment API, providing a clean service-based architecture, Facade access, and fluent request builders.

Requirements

RequirementValue
PHP^8.0
Laravel10.x, 11.x, 12.x, 13.x
Extensionscurl, json

Installation

Step 1: Install Package

bash
composer require bohudur/laravel-sdk:^1.1.1

Step 2: Add Your API Key

The SDK supports two ways to provide your API key. Both work independently — you don't need to set up both, just pick whichever fits your use case.

  • Option 1 — From .env (recommended for most projects)

This is the standard approach. Add your Bohudur API key to your Laravel .env file:

env
BOHUDUR_API_KEY=your_api_key_here

That's all. The SDK automatically reads this value every time you make a request — no extra code, no configuration needed. This is the best choice when your entire application uses a single API key.

  • Option 2 — At runtime via Bohudur::init() (for dynamic keys)

Sometimes you can't hardcode the API key in .env — for example, if you are building a multi-merchant platform where each merchant has their own Bohudur account and their own API key. In that case, use Bohudur::init() to pass the key at runtime before making any request.

php
use App\Modules\Bohudur\Facades\Bohudur;
use App\Modules\Bohudur\Exceptions\BohudurException;

try {
    Bohudur::init('your_api_key_here'); // Set the key first
} catch (BohudurException $e) {
    echo $e->getMessage();
}

Important

Always call Bohudur::init() before calling request(), execute(), or query(). If you call init(), it takes priority over whatever is set in .env for that request. If you do not call init(), the SDK falls back to BOHUDUR_API_KEY from .env automatically.

Keep your API key secret

Never expose your API key in frontend JavaScript, mobile apps, or public repositories. Your API key gives full access to your Bohudur account. Always use this SDK on a secure backend server only.

API Flow Overview (Laravel)

  1. Create payment
  2. Redirect customer to hosted checkout
  3. Customer completes or cancels payment
  4. Execute payment
  5. Receive webhook (optional)
  6. Query payment anytime

This flow is identical to the PHP SDK and cURL API.

Create Payment (Laravel)

Creates a new payment session and returns a hosted checkout URL.

Example

php
use App\Modules\Bohudur\Facades\Bohudur;
use App\Modules\Bohudur\Exceptions\BohudurException;

try {
    $response = Bohudur::request()
        ->fullName('Jane Doe')
        ->email('janedoe@gmail.com')
        ->amount(10)
        ->returnType('GET')
        ->redirectUrl('https://example.com/redirect')
        ->cancelUrl('https://example.com/cancel')
        ->metadata([
            'order_id' => 'ORD-1001',
            'user_id'  => 55
        ])
        ->webhook([
            'success' => 'https://example.com/success',
            'cancel'  => 'https://example.com/cancel'
        ])
        ->send();
} catch (BohudurException $e) {
    echo $e->getMessage();
}

Create Payment Parameters

MethodRequiredTypeDescription
fullName()YESstringCustomer full name
email()YESstringCustomer email
amount()YESfloatPayment amount
returnType()YESstringGET or POST
redirectUrl()YESstringRedirect URL after success
cancelUrl()YESstringRedirect URL after cancellation
metadata()NOarrayCustom key-value data
webhook()NOarrayWebhook URLs

Success Response

json
{
  "responseCode": 200,
  "message": "Payment created successfully",
  "status": "success",
  "paymentkey": "5RWS4w2w1R5nFAvoP5U0JS4O74UrMXGt",
  "payment_url": "https://checkout.bohudur.one/payment/5RWS4w2w1R5nFAvoP5U0JS4O74UrMXGt"
}
FieldTypeDescription
responseCodenumber200 on success
messagestringHuman-readable result message
statusstringAlways "success" on success
paymentkeystringUnique 32-character key for this payment — store this
payment_urlstringHosted checkout URL — redirect your customer here

Failed Response

json
{
  "responseCode": 3018,
  "message": "Oops! Internal error. Try again",
  "status": "failed"
}

Create Payment Error Codes

CodeMessageDescription
3000API key not foundAH-BOHUDUR-API-KEY header is missing
3001Required parameters not foundOne or more required fields are missing
3002--- parameter is emptySpecific field value is empty
3003Invalid Full Name Formatfull_name must be a valid non-empty string
3004Invalid Email FormatEmail address is not valid
3005Invalid Amount FormatAmount must be a positive numeric value
3006Invalid Return Type FormatOnly GET or POST allowed
3007Invalid Return URL Formatredirect_url is not a valid URL
3008Invalid Cancel URL Formatcancel_url is not a valid URL
3009Invalid JSON format in metadatametadata must be a valid JSON object
3010Invalid JSON format in webhookwebhook must be a valid JSON object
3011Invalid webhook actionsOnly success and cancel keys allowed in webhook
3012Invalid JSON format in metadata or webhookOne or both JSON objects are malformed
3013Invalid API keyAPI key is incorrect or inactive
3014Oops! internal error. Try again.Temporary server-side issue — retry
3015Unknown amount providedAmount value is not acceptable
3016You don't have accessRequest blocked due to IP restriction
3017Oops! Internal error. Try again.Unexpected internal server error
3018Unable to create paymentPayment session could not be created

Response objects are returned as stdClass, allowing direct access like:

php
$response->responseCode;
$response->payment_url;

Redirecting Customer

php
if ($response->status === 'success') {
    return redirect()->away($response->payment_url);
}

Execute Payment (Laravel)

Finalizes a completed payment.

Example

php
$execute = Bohudur::execute('PAYMENT_KEY');

Rules

  • Can be executed only once
  • Payment must be COMPLETED
  • Executed payments are final

Execute Response (Success)

json
{
  "full_name": "Gabriel Adams",
  "email": "janedoe@gmail.com",
  "amount": 40,
  "converted_amount": 4878,
  "total_amount": 40,
  "transaction_fee": 0,
  "default_currency": "USD",
  "payment_currency": "BDT",
  "currency_value": 121.951,
  "metadata": [],
  "created_time": "2026-01-04 16:04:35",
  "payment_time": "2026-01-04 16:12:37",
  "paymentkey": "fnPwIkdIsMjN4FJxYxw6DF75GuW9qStn",
  "webhook": [],
  "payment_info": {
    "m0": "SSLCommerz",
    more....
  },
  "status": "EXECUTED"
}

Execute Response Parameters

FieldTypeDescription
full_namestringCustomer full name
emailstringCustomer email address
amountnumberOriginal payment amount in your default currency
converted_amountnumberAmount converted to the payment currency
total_amountnumberTotal amount charged including any fees
transaction_feenumberTransaction fee applied (0 if none)
default_currencystringYour account's default currency code
payment_currencystringCurrency the customer actually paid in
currency_valuenumberExchange rate used (default → payment currency)
metadataarray/objectCustom data attached during payment creation
created_timestringTimestamp when payment session was created
payment_timestringTimestamp when customer completed payment
paymentkeystringUnique 32-character payment identifier
receiptstringURL to download the PDF receipt for this payment
webhookarray/objectWebhook URLs configured for this payment
payment_infoobjectGateway-specific transaction details
payment_info.m0stringPayment gateway used (e.g. "Stripe", "SSLCommerz")
statusstringAlways "EXECUTED" on success

Execute Error Response

json
{
  "responseCode": 3108,
  "message": "Payment already executed!",
  "status": "failed"
}

Execute Error Codes

CodeMessageDescription
3100API key not foundAH-BOHUDUR-API-KEY header missing
3101API key not validAPI key is invalid or inactive
3102Invalid Payment Keypaymentkey is malformed or does not exist
3103Invalid api keyAPI key does not match any active account
3104You don't have access! Your IP: ...Your server IP is not authorized
3105Payment Data Not FoundNo payment exists for this paymentkey
3106Payment is pending!Customer has not completed payment yet
3107Payment is cancelled!Payment was cancelled — cannot be executed
3108Payment already executed!This payment was already executed once
3109Failed to execute paymentServer or processing error

Response objects are returned as stdClass, allowing direct access like:

php
$response->responseCode;
$response->status;
$response->amount;

Execute is One-Time Only

A payment can be executed exactly once. Any second attempt returns 3108. This is intentional — it prevents duplicate charges. Always store the execute response in your database immediately after a successful execution.

Query Payment (Laravel)

Retrieve payment information at any time.

Example

php
$query = Bohudur::query('PAYMENT_KEY');

Query Response Types

The Query API returns one of four responses based on the current payment status.

1. PENDING

Payment session created but the user has not yet completed payment.

json
{
  "full_name": "Chloe Morales",
  "email": "chloe@gmail.com",
  "amount": 1,
  "converted_amount": 1,
  "total_amount": 1,
  "transaction_fee": 0,
  "default_currency": "USD",
  "payment_currency": "USD",
  "currency_value": 1,
  "metadata": [],
  "created_time": "2026-01-07 10:02:20",
  "payment_time": "NONE",
  "paymentkey": "7QWQsOhg9X7dgQlfRO4EPxWKK9qaCWka",
  "receipt": "NONE",
  "webhook": [],
  "payment_info": [],
  "status": "PENDING"
}

2. COMPLETED

User has paid. Payment is ready to be executed by your server.

json
{
  "full_name": "Jane Doe",
  "email": "jane@gmail.com",
  "amount": 150,
  "converted_amount": 150,
  "total_amount": 150,
  "transaction_fee": 0,
  "default_currency": "USD",
  "payment_currency": "USD",
  "currency_value": 1,
  "metadata": [],
  "created_time": "2025-12-11 21:47:11",
  "payment_time": "2025-12-11 23:11:25",
  "paymentkey": "TYtsYll15iqsDqsR4h8EJrMfou9NavE2",
  "receipt": "https://pay.bohudur.one/receipt/download/102f89389f9e",
  "webhook": [],
  "payment_info": {
    "m0": "Stripe",
    more....
  },
  "status": "COMPLETED"
}

Note

status: "COMPLETED" means the customer has paid. You must now call /execute/v2/ to finalize and deliver your product or service.

3. EXECUTED

Payment has been finalized by your server via the Execute API.

json
{
  "full_name": "Gabriel Adams",
  "email": "gabriel@gmail.com",
  "amount": 40,
  "converted_amount": 4878,
  "total_amount": 40,
  "transaction_fee": 0,
  "default_currency": "USD",
  "payment_currency": "BDT",
  "currency_value": 121.951,
  "metadata": [],
  "created_time": "2026-01-04 16:04:35",
  "payment_time": "2026-01-04 16:12:37",
  "paymentkey": "fnPwIkdIsMjN4FJxYxw6DF0I92W9qStn",
  "receipt": "https://pay.bohudur.one/receipt/download/102f89389f9e",
  "webhook": [],
  "payment_info": {
    "m0": "SSLCommerz",
    more....
  },
  "status": "EXECUTED"
}

4. CANCELLED

Payment was cancelled by the user or system. Cannot be executed.

json
{
  "full_name": "Jane Doe",
  "email": "jane@gmail.com",
  "amount": 1,
  "converted_amount": 1,
  "total_amount": 1,
  "transaction_fee": 0,
  "default_currency": "USD",
  "payment_currency": "USD",
  "currency_value": 1,
  "metadata": {
    "order_id": "ORD-1001",
    "user_id": 55
  },
  "created_time": "2026-01-18 19:30:56",
  "payment_time": "NONE",
  "paymentkey": "P4m1OEiopqPy4cFx9QO0mARuzqxx7bsf",
  "receipt": "NONE",
  "webhook": {
    "success": "https://example.com/success.php",
    "cancel": "https://example.com/cancel.php"
  },
  "payment_info": [],
  "status": "CANCELLED"
}

The Query API may return one of the following statuses:

StatusDescription
PENDINGPayment created but not completed
COMPLETEDPayment completed, ready for execute
EXECUTEDPayment finalized
CANCELLEDPayment cancelled

Payment Info By Gateways

json
{
    "payment_info": {
        "id": 1,
        "gateway": "bkash",
        "method": "Send Money",
        "number": "01XXXXXXXXX",
        "amount": 100,
        "trx": "TRX123ABC456",
        "time": "01/01/2026 12:00",
        "m0": "Bkash Send Money"
    }
}
json
{
    "payment_info": {
        "id": 1,
        "gateway": "nagad",
        "method": "Send Money",
        "number": "01XXXXXXXXX",
        "amount": 100,
        "trx": "TRX123ABC456",
        "time": "01/01/2026 12:00",
        "m0": "Nagad Send Money"
    }
}
json
{
    "payment_info": {
        "id": 1,
        "gateway": "rocket",
        "method": "Send Money",
        "number": "01XXXXXXXXX",
        "amount": 100,
        "trx": "TRX123ABC456",
        "time": "01/01/2026 12:00",
        "m0": "Rocket Send Money"
    }
}
json
{
    "payment_info": {
        "id": 1,
        "gateway": "upay",
        "method": "Send Money",
        "number": "01XXXXXXXXX",
        "amount": 100,
        "trx": "TRX123ABC456",
        "time": "01/01/2026 12:00",
        "m0": "Upay Send Money"
    }
}
json
{
    "payment_info": {
        "id": 1,
        "gateway": "mcash",
        "method": "Send Money",
        "number": "01XXXXXXXXX",
        "amount": 100,
        "trx": "TRX123ABC456",
        "time": "01/01/2026 12:00",
        "m0": "mCash Send Money"
    }
}
json
{
    "paymentID": "TRX_PAYMENT_ID_EXAMPLE",
    "trxID": "TRX123ABC456",
    "transactionStatus": "Completed",
    "amount": "100",
    "currency": "BDT",
    "intent": "sale",
    "paymentExecuteTime": "2026-01-01T12:00:00 GMT+0600",
    "merchantInvoiceNumber": "invoice_demo_12345",
    "payerType": "Customer",
    "payerReference": "CUSTOMER_REF",
    "customerMsisdn": "01XXXXXXXXX",
    "payerAccount": "01XXXXXXXXX",
    "maxRefundableAmount": "100",
    "statusCode": "0000",
    "statusMessage": "Successful",
    "m0": "Bkash Merchant"
}
json
{
    "status": "VALID",
    "tran_date": "2026-01-01 12:00:00",
    "tran_id": "SSLCZ_DEMO_TRANSACTION",
    "val_id": "VALIDATION_ID_EXAMPLE",
    "amount": "100.00",
    "store_amount": "97.50",
    "currency": "BDT",
    "bank_tran_id": "BANK_TRANSACTION_ID",
    "card_type": "NAGAD-Nagad",
    "card_no": "",
    "card_issuer": "Nagad",
    "card_brand": "MOBILEBANKING",
    "card_category": "MOBILE",
    "card_sub_brand": "",
    "card_issuer_country": "Bangladesh",
    "card_issuer_country_code": "BD",
    "currency_type": "BDT",
    "currency_amount": "100.00",
    "currency_rate": "1.0000",
    "base_fair": "0.00",
    "value_a": "",
    "value_b": "",
    "value_c": "",
    "value_d": "",
    "emi_instalment": "0",
    "emi_amount": "0.00",
    "emi_description": "",
    "emi_issuer": "Nagad",
    "account_details": "",
    "risk_title": "Safe",
    "risk_level": "0",
    "discount_percentage": "0",
    "discount_amount": "0.00",
    "discount_remarks": "",
    "APIConnect": "DONE",
    "validated_on": "2026-01-01 12:00:10",
    "gw_version": "",
    "offer_avail": 1,
    "card_ref_id": "CARD_REFERENCE_ID_EXAMPLE",
    "isTokeizeSuccess": 0,
    "campaign_code": "",
    "m0": "SSLCommerz"
}
json
{
    "id": "pi_demo_payment_intent",
    "object": "payment_intent",
    "amount": 10000,
    "amount_capturable": 0,
    "amount_details": {
        "tip": []
    },
    "amount_received": 10000,
    "application": null,
    "application_fee_amount": null,
    "automatic_payment_methods": null,
    "canceled_at": null,
    "cancellation_reason": null,
    "capture_method": "automatic_async",
    "client_secret": "pi_demo_payment_intent_secret_example",
    "confirmation_method": "automatic",
    "created": 1767225600,
    "currency": "usd",
    "customer": null,
    "customer_account": null,
    "description": "Demo Payment",
    "excluded_payment_method_types": null,
    "last_payment_error": null,
    "latest_charge": "ch_demo_charge_id",
    "livemode": false,
    "managed_payments": {
        "enabled": false
    },
    "metadata": [],
    "next_action": null,
    "on_behalf_of": null,
    "payment_details": {
        "customer_reference": null,
        "order_reference": "ORDER_REFERENCE_EXAMPLE"
    },
    "payment_method": "pm_demo_payment_method",
    "payment_method_configuration_details": null,
    "payment_method_options": {
        "card": {
            "installments": null,
            "mandate_options": null,
            "network": null,
            "request_three_d_secure": "automatic"
        }
    },
    "payment_method_types": [
        "card"
    ],
    "presentment_details": {
        "presentment_amount": 12000,
        "presentment_currency": "bdt"
    },
    "processing": null,
    "receipt_email": "customer@example.com",
    "review": null,
    "setup_future_usage": null,
    "shared_payment_granted_token": null,
    "shipping": null,
    "source": null,
    "statement_descriptor": null,
    "statement_descriptor_suffix": null,
    "status": "succeeded",
    "transfer_data": null,
    "transfer_group": null,
    "m0": "Stripe"
}
json
{
    "uid": 123456789,
    "counterpartyId": 987654321,
    "orderId": "ORDER_ID_EXAMPLE",
    "orderType": "CRYPTO_BOX",
    "transactionId": "TRANSACTION_ID_EXAMPLE",
    "transactionTime": 1767225600000,
    "amount": "10.00",
    "currency": "USDT",
    "walletType": 1,
    "walletTypes": [
        "1"
    ],
    "fundsDetail": [
        {
            "currency": "USDT",
            "amount": "10.00"
            "walletAssetCost": {
                "1": "10.00"
            }
        }
    ],
    "payerInfo": {
        "name": "John Doe",
        "type": "USER",
        "email": "customer@example.com",
        "countryCode": 880,
        "phoneNumber": "01XXXXXXXXX",
        "mobileCode": "BD",
        "unmaskData": false
    },
    "receiverInfo": {
        "binanceId": 123456789,
        "accountId": 987654321,
        "unmaskData": false
    },
    "totalPaymentFee": "0",
    "m0": "Binance Personal"
}

Query Response Fields

FieldTypeDescription
full_namestringCustomer full name
emailstringCustomer email
amountnumberOriginal payment amount
converted_amountnumberAmount in the payment currency
total_amountnumberTotal charged including fees
transaction_feenumberFee applied (0 if none)
default_currencystringYour account default currency
payment_currencystringCurrency customer paid in
currency_valuenumberExchange rate applied
metadataarray/objectCustom data from payment creation
created_timestringPayment creation timestamp
payment_timestringWhen customer completed payment ("NONE" if not yet)
paymentkeystringUnique payment identifier
receiptstringPDF receipt download URL ("NONE" if not yet available)
webhookarray/objectConfigured webhook URLs
payment_infoarray/objectGateway transaction data (empty if pending)
statusstringPENDING / COMPLETED / EXECUTED / CANCELLED

Note

m0 indicates gateway name. It's available in all payments. To get payment method developers can use this.

Query Error Codes

CodeMessageDescription
3050API key not foundAH-BOHUDUR-API-KEY header missing
3051API key not validAPI key invalid or inactive
3052Invalid Payment Keypaymentkey does not exist or is malformed
3053Invalid api keyAPI key does not match any active account
3054You don't have access! Your IP: ...IP not authorized
3055Payment Data Not FoundNo payment found for this key

Response objects are returned as stdClass, allowing direct access like:

php
$query->full_name;
$query->status;

Webhooks (Laravel)

Bohudur sends webhook notifications using POST JSON.

Success Payload

json
{
  "full_name": "Jane Doe",
  "email": "janedoe@gmail.com",
  "amount": 1,
  "paymentkey": "CrD85r3ibMK6ip38reUcuECvVhaF0xOT",
  "status": "COMPLETED"
}

Cancel Payload

json
{
  "full_name": "Jane Doe",
  "email": "janedoe@gmail.com",
  "amount": 1,
  "paymentkey": "CrD85r3ibMK6ip38reUcuECvVhaF0xOT",
  "status": "CANCELLED"
}

Webhook Handler Example

php
Route::post('/bohudur/webhook', function () {
    $data = request()->all();

    // Always verify
    Bohudur::query($data['paymentkey']);
});

Best Practices

  • Always verify payments using Query API
  • Never execute payments from frontend
  • Webhooks are not final truth
  • Execute payments only once

Support

Bohudur is free and open to everyone. No trade license required.