BkashEx

BkashEx is an Elixir library for interacting with the bKash API, providing a convenient and structured way to handle payments, refunds, and transaction inquiries. It abstracts away the complexities of API authentication and request/response parsing, offering a clean Elixir interface.

Installation

The package can be installed by adding bkash_ex to your list of dependencies in mix.exs:

def deps do
  [
    {:bkash_ex, "~> 0.1.0"},
  ]
end

After adding the dependencies, fetch them:

mix deps.get

Configuration

BkashEx requires several configuration values to be set in your application's environment, typically in config/config.exs or config/runtime.exs:

config :bkash_ex,
  base_url: "https://tokenized.pay.bka.sh/v1.2.0-beta", # Or your specific bKash API base URL
  username: "your_username",
  password: "your_password",
  app_key: "your_app_key",
  app_secret: "your_app_secret"

Note: Ensure you replace "your_username", "your_password", "your_app_key", and "your_app_secret" with your actual bKash API credentials. The base_url should also be set to the correct bKash API endpoint you are targeting (e.g., sandbox or production).

BkashEx automatically starts Finch and manages token storage via ETS — no manual setup required.

However, you can optionally tune Finch’s HTTP pool configuration:

# config/runtime.exs
config :finch, BkashEx.Finch,
  pools: %{
    default: [size: 10, count: 5] # Adjust as needed
  }

Usage

Here's how you can use the BkashEx functions:

1. Create Payment

Initiates a payment request.

# /dev/null/usage.ex#L1-12
case BkashEx.create_payment("INV-001", "01XXXXXXXXX", "http://example.com/callback", 100.50) do
  {:ok, %BkashEx.CreatePaymentResponse{bkash_url: url, payment_id: payment_id}} ->
    Logger.info("Payment initiated. Redirect customer to: #{url}")
    Logger.info("Payment ID: #{payment_id}")
    # Store payment_id and redirect user to url
  {:error, %BkashEx.ErrorResponse{status_code: code, status_message: msg}} ->
    Logger.info("bKash Error during payment creation: #{code} - #{msg}")
  {:error, reason} ->
    Logger.info("Local error during payment creation: #{reason}")
end

2. Execute Payment

Executes a payment that was previously created.

# /dev/null/usage.ex#L1-11
payment_id = "TR000139pVZqh169096716XXXX" # Get this from the callback url's query string

case BkashEx.execute_payment(payment_id) do
  {:ok, %BkashEx.ExecutePaymentResponse{transaction_status: status, trx_id: trx_id}} ->
    Logger.info("Payment executed successfully. Status: #{status}, Transaction ID: #{trx_id}")
  {:error, %BkashEx.ErrorResponse{status_code: code, status_message: msg}} ->
    Logger.info("bKash Error during payment execution: #{code} - #{msg}")
  {:error, reason} ->
    Logger.info("Local error during payment execution: #{reason}")
end

3. Query Payment

Queries the status of a specific payment.

# /dev/null/usage.ex#L1-11
payment_id = "TR0001IV1565085942653" # The payment ID you want to query

case BkashEx.query_payment(payment_id) do
  {:ok, %BkashEx.QueryPaymentResponse{transaction_status: status, amount: amount}} ->
    Logger.info("Payment ID: #{payment_id}, Status: #{status}, Amount: #{amount}")
  {:error, %BkashEx.ErrorResponse{status_code: code, status_message: msg}} ->
    Logger.info("bKash Error during payment query: #{code} - #{msg}")
  {:error, reason} ->
    Logger.info("Local error during payment query: #{reason}")
end

4. Search Transaction

Searches for a transaction by its transaction ID.

# /dev/null/usage.ex#L1-11
trx_id = "6H7XXXXTCT" # The transaction ID you want to search

case BkashEx.search_transaction(trx_id) do
  {:ok, %BkashEx.SearchTransactionResponse{transaction_status: status, amount: amount}} ->
    Logger.info("Transaction ID: #{trx_id}, Status: #{status}, Amount: #{amount}")
  {:error, %BkashEx.ErrorResponse{status_code: code, status_message: msg}} ->
    Logger.info("bKash Error during transaction search: #{code} - #{msg}")
  {:error, reason} ->
    Logger.info("Local error during transaction search: #{reason}")
end

5. Refund Payment

Initiates a refund for a previously completed payment.

# /dev/null/usage.ex#L1-12
payment_id = "TR00111I8aKdL17619XXXXXXXX" # Original payment ID
original_trx_id = "CK14XXXXXX" # Original transaction ID
sku = "ITEM001" # SKU of the item (if applicable)
reason = "Customer changed mind"
amount = 10.00 # Amount to refund

case BkashEx.refund(payment_id, original_trx_id, sku, reason, amount) do
  {:ok, %BkashEx.PaymentRefundResponse{refund_trx_id: refund_id, transaction_status: status}} ->
    Logger.info("Refund initiated. Refund Transaction ID: #{refund_id}, Status: #{status}")
  {:error, %BkashEx.ErrorResponse{status_code: code, status_message: msg}} ->
    Logger.info("bKash Error during refund: #{code} - #{msg}")
  {:error, reason} ->
    Logger.info("Local error during refund: #{reason}")
end

Error Handling

All public functions in BkashEx return a tuple in the format {:ok, result} for successful operations or {:error, reason} for failures. The reason can be:

Documentation

The docs can be found at https://hexdocs.pm/bkash_ex.