defmodule Knet do @moduledoc """ Documentation for `Knet`. """ @doc """ Takes a map of payment details and returns a KNET payment link. The `payment_details` map should contain the following required keys: - `knet_username` - `knet_password` - `knet_key` - `amount` - `response_url` - `error_url` - `track_id` The following keys are optional: - `knet_url` (defaults to https://kpay.com.kw/kpg/PaymentHTTP.htm) - `currency_code` (defaults to 414) - `lang`. Could be ENG or AR (defaults to ENG) - `udf1` to `udf5` (user defined fields). These are optional and will be returned back to you in the response. """ @spec get_payment_link(map()) :: String.t() def get_payment_link(payment_details) do payment_details |> get_payment_params() |> encrypt_params(payment_details) |> get_payment_url(payment_details) end defp get_payment_params(payment_details) do %{ "id" => Map.get(payment_details, "knet_username"), "password" => Map.get(payment_details, "knet_password"), "amt" => Map.get(payment_details, "amount"), "currencycode" => Map.get(payment_details, "currency_code", "414"), "action" => "1", "langid" => Map.get(payment_details, "lang", "ENG"), "responseURL" => Map.get(payment_details, "response_url"), "errorURL" => Map.get(payment_details, "error_url"), "trackid" => Map.get(payment_details, "track_id"), "udf1" => Map.get(payment_details, "udf1"), "udf2" => Map.get(payment_details, "udf2"), "udf3" => Map.get(payment_details, "udf3"), "udf4" => Map.get(payment_details, "udf4"), "udf5" => Map.get(payment_details, "udf5") } end defp encrypt_params(params, payment_details) do params = params |> Enum.map(fn {k, v} -> "#{k}=#{v}" end) |> Enum.join("&") block_size = 16 pad = block_size - rem(String.length(params), block_size) padded_params = params <> String.duplicate(List.to_string([pad]), pad) api_key = Map.get(payment_details, "knet_key") :crypto.crypto_one_time(:aes_128_cbc, api_key, api_key, padded_params, true) |> Base.encode16(case: :lower) end defp get_payment_url(encrypted_data, payment_details) do knet_url = Map.get(payment_details, "knet_url", "https://kpay.com.kw/kpg/PaymentHTTP.htm") knet_username = Map.get(payment_details, "knet_username") response_url = Map.get(payment_details, "response_url") error_url = Map.get(payment_details, "error_url") "#{knet_url}?param=paymentInit&trandata=#{encrypted_data}&tranportalId=#{knet_username}&responseURL=#{response_url}&errorURL=#{error_url}" end end