This repo contains the Elixir client for Craftgate API.
- Elixir
1.12
or newer
- HTTPoison to execute requests
- Jason for JSON serialization/deserialization
- Construct to provide a concise interface for representing request/response payloads as Elixir structs while also having them converted automatically by Jason
- Decimal to represent monetary values
- Recase to convert between Craftgate API's
camelCase
and Elixir'ssnake_case
Note: To keep the correct precision without losing any information, all decimals are serialized into strings. Since Craftgate API uses Java's
BigDecimal
to process these values it has no trouble parsing them, and likewise, by using Construct, Jason and Decimal in conjunction we're able to parse both numerical and string representations of decimals.
Add the :craftgate
dependency to your mix.exs
file
def deps do
...
{:craftgate, "~> 1.0.42"}
...
end
To access the Craftgate API you'll first need to obtain a set of API credentials. If you don't already have a Craftgate account, you can signup at https://craftgate.io, and after the onboarding process you will be able to access your API credentials from the merchant panel.
Once you've obtained your API credentials, you can configure Craftgate through the :craftgate
on your config.exs
file.
config :craftgate,
api_key: "<YOUR API KEY>",
secret_key: "<YOUR SECRET KEY>"
By default, Craftgate will run in sandbox mode and connect to the sandbox API at https://sandbox-api.craftgate.io.
Once you're confident with your implementation you can swap out the base_url
parameter with the live production URL at https://api.craftgate.io
config :craftgate,
api_key: "<YOUR API KEY>",
secret_key: "<YOUR SECRET KEY>",
base_url: "https://api.craftgate.io"
Additionally, Craftgate will use English as the default locale ("en"
) when contacting the Craftgate API, and also set a few request options to disable redirections and set particular request and receive timeouts. You can override these configurations by changing the lang
and request_options
keys respectively.
Do note, however, that by overriding request_options
, you will be losing the default request options, so don't forget to include them if you only wish to add more parameters. For a list of all available options, see the documentation for HTTPoison.Request
Below is the list of default request options:
[
timeout: 10_000,
recv_timeout: 150_000,
max_redirect: 0,
follow_redirect: false
]
Note: You can also override these values by passing them to any Craftgate API call (e.g.
Craftgate.Adapter.PaymentReportingAdapter.retrieve_payment(1, request_options: [timeout: 100_000]
)
So with that, a fully customized Craftgate configuration can look something like below:
config :craftgate,
api_key: "<YOUR API KEY>",
secret_key: "<YOUR SECRET KEY>",
base_url: "https://api.craftgate.io",
lang: "tr",
request_options: [
timeout: 60_000,
recv_timeout: 120_000,
max_redirect: 1,
follow_redirect: true
]
As with any Phoenix app you can also make use of the environment-specific files to configure Craftgate for your development and production environments. In fact, we highly recommend inferring the production API credentials from environment variables in production and not have them written out plainly in your codebase.
config/config.exs
...
config :craftgate,
base_url: "https://sandbox-api.craftgate.io",
api_key: "<YOUR SANDBOX API KEY>",
secret_key: "<YOUR SANDBOX SECRET KEY>"
...
config/prod.exs
...
config :craftgate,
base_url: "https://api.craftgate.io",
api_key: System.get_env("CRAFTGATE__API_KEY"),
secret_key: System.get_env("CRAFTGATE__SECRET_KEY")"
...
If you're not using Phoenix, or if you can't/don't want to use the Config
module you can also configure Craftgate by injecting the same properties into the :craftgate
key using Application.put_env/3
Application.put_env(:craftgate, :api_key, "<YOUR API KEY>")
Application.put_env(:craftgate, :secret_key, "<YOUR SECRET KEY>")
Application.put_env(:craftgate, :base_url, "https://sandbox-api.craftgate.io")
The Craftgate Elixir client is stateless, so unlike its counterparts in other programming languages, you do not have to instantiate any Craftgate client. Instead, you can access specificy adapters directly, either through the adapter module itself, or through the convenience accessors on the Craftgate
module itself.
Below is a list of all the adapters that are available:
Module | Accessor | Responsibilities |
---|---|---|
Craftgate.Adapter.FileReportingAdapter |
Craftgate.file_reporting/0 |
File-based reporting activities like obtaining daily transaction reports |
Craftgate.Adapter.FraudAdapter |
Craftgate.fraud/0 |
Fraud operations like retrieving potentially fraudulent transactions, marking them as safe, managing fraud values |
Craftgate.Adapter.HookAdapter |
Craftgate.hook/0 |
Hook-related utility functions like verifying incoming webhooks |
Craftgate.Adapter.InstallmentAdapter |
Craftgate.installment/0 |
Retrieving per-installment pricing information based on installment count or BIN number |
Craftgate.Adapter.OnboardingAdapter |
Craftgate.onboarding/0 |
Conducting CRUD operations on buyers and submerchants |
Craftgate.Adapter.PayByLinkAdapter |
Craftgate.pay_by_link/0 |
Managing and listing products available for the pay-by-link feature |
Craftgate.Adapter.PaymentAdapter |
Craftgate.payment/0 |
Conducting payments, managing stored cards |
Craftgate.Adapter.PaymentReportingAdapter |
Craftgate.payment_reporting/0 |
Searching payments, retrieving payment details, retrieving payment transaction records |
Craftgate.Adapter.SettlementReportingAdapter |
Craftgate.settlement_reporting/0 |
Settlement operations like search payout completed transactions, search bounced payout transactions |
Craftgate.Adapter.SettlementAdapter |
Craftgate.settlement/0 |
Settlement operations like create instant wallet settlement |
Craftgate.Adapter.WalletAdapter |
Craftgate.wallet/0 |
Wallet operations like sending and receiving remittance, searching walletes and wallet transactions of members |
Once Craftgate is configured, you can use one of these adapters to interact with Craftgate API.
defmodule Orders do
def refund_order(order_id) do
with {:ok, order} <- Order.get(order_id),
{:ok, refund_result} <- Craftgate.Adapter.PaymentAdapter.refund_payment(%Craftgate.Request.RefundPaymentRequest{
payment_id: order.craftgate_payment_id,
refund_destination_type: Craftgate.Model.RefundDestinationType.card(),
}),
...
do
...
else
...
end
end
end
This project has a set of samples that you can run to interact with the Craftgate API, located at lib/mix/tasks/sample.
These samples are constructed as Mix tasks so you can even run them after adding craftgate-elixir
as a dependency to your project.
$ mix sample.payment.create
[lib/mix/tasks/sample/payment/create.ex:45: Mix.Tasks.Sample.Payment.Create.run/1]
result #=> %Craftgate.Response.PaymentResponse{
...
}
Note that by default these samples use the public API keypairs found at https://developer.craftgate.io and target the sandbox environment of Craftgate API at https://sandbox-api.craftgate.io, but they will also try to use any existing configuration you might have. As such, if you run these samples from your own project with Craftgate already configured, you will be access the Craftgate API with your own credentials.
In addition to the Mix tasks, you can also jump into a Mix-enabled interactive Elixir session, put your credentials into the :api_key
and :secret_key
keys of the :craftgate
configuration and run any adapter method.
$ iex -S mix
iex(1)> Application.put_env(:craftgate, :api_key, "<YOUR API KEY>")
:ok
iex(2)> Application.put_env(:craftgate, :secret_key, "<YOUR SECRET KEY>")
:ok
iex(3)> Application.put_env(:craftgate, :base_url, "https://sandbox-api.craftgate.io")
:ok
iex(4)> Craftgate.Adapter.PaymentReportingAdapter.retrieve_payment(1)
{:ok,
%Craftgate.Response.ReportingPaymentResponse{
retry_count: 0,
refundable_price: Decimal.new("100.0"),
refund_status: :NOT_REFUNDED,
...
}
}
For instructions on how to contribute to the project please see CONTRIBUTING.md
MIT