README.md

# 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`:

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

After adding the dependencies, fetch them:

```bash
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`:

```elixir
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:

```elixir
# 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.

```elixir
# /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.

```elixir
# /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.

```elixir
# /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.

```elixir
# /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.

```elixir
# /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:

*   `%BkashEx.ErrorResponse{}`: When bKash returns a specific error from their API.
*   `String.t()`: For local errors (e.g., JSON encoding/decoding failures, network issues, or unhandled bKash API responses).

## Documentation

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