# ConektaEx
Conekta API Client for Elixir
## Installation
1. Add `conekta_ex` to deps in `mix.exs`:
```elixir
def deps do
[
{:conekta_ex, "~> 1.0.0"}
]
end
```
2. Add your `private_key` to your config file
```elixir
config :conekta_ex, :private_key, "PRIVATE_KEY"
# Optional Config
## locale, Default "es", ref -> https://developers.conekta.com/api#locale
config :conekta_ex, :locale, "en"
## timeout to establish a connection, in milliseconds, Default 15_000
config :conekta_ex, :timeout, 10_000
## recv_timeout used when receiving a connection. Default is 15_000
config :conekta_ex, :recv_timeout, 10_000
```
## Usage
### Card Payments
Allways check for the Order `payment_status` on :ok responses
Payment with a Customer and a default PaymentSource:
```elixir
customer_attrs =
%{
name: " ",
email: "an@email.com",
payment_sources: [
%{
token_id: "tok_test_visa_4242",
type: "card",
}
]
}
{:ok, customer} = ConektaEx.Customer.create(customer_attrs)
order_attrs =
%{
amount: 2000,
charges: [
%{payment_method: %{type: "default"}}
],
currency: "MXN",
customer_info: %{
customer_id: customer.id
},
line_items: [
%{
name: "some name",
quantity: 2000,
unit_price: 1,
}
]
}
{:ok, order} = ConektaEx.Order.create(order_attrs)
```
Payment without a Customer (this DOES NOT create a Customer):
```elixir
order_attrs =
%{
amount: 2000,
charges: [
%{
payment_method: %{
type: "card",
token_id: "tok_test_visa_4242"
}
}
],
currency: "MXN",
customer_info: %{
name: " ",
phone: "1234567890",
email: "an@email.com"
},
line_items: [
%{
name: "some name",
quantity: 2000,
unit_price: 1,
}
]
}
{:ok, order} = ConektaEx.Order.create(order_attrs)
```
### Customer fn's
#### CRUD
```elixir
customer_attrs = %{name: " ", email: "an@email.com"}
{:ok, c_customer} = ConektaEx.Customer.create(customer_attrs)
{:ok, u_customer} = ConektaEx.Customer.update(c_customer.id, %{name: "name"})
{:ok, %{name: "name"} = customer} = ConektaEx.Customer.retrieve(u_customer.id)
{:ok, %{name: "name"}} = ConektaEx.Customer.delete(customer.id)
```
#### Payment Sources (Cards)
```elixir
{:ok, ps} = ConektaEx.Customer.create_payment_source(customer_id, "card", "tok_test_visa_4242")
{:ok, %{name: "new name"} = ps} = ConektaEx.Customer.update_payment_source(customer_id, ps.id, %{name: "new name"})
{:ok, %{name: "new name"}} = ConektaEx.Customer.delete_payment_source(customer_id, ps.id)
```
### Subscriptions
#### Create
```elixir
plan_attrs =
%{
id: "a-id",
name: "a name",
amount: 2000,
currency: "MXN",
interval: "month"
}
{:ok, plan} = ConektaEx.Plan.create(plan_attrs)
{:ok, sub} = ConektaEx.Customer.create_subscription(customer_id, subscription_id, plan.id)
# wait and handle subscription Webhook
```
#### Pause / Resume / Cancel
```elixir
{:ok, sub} = ConektaEx.Customer.pause_subscription(customer_id, subscription_id)
{:ok, sub} = ConektaEx.Customer.resume_subscription(customer_id, subscription_id)
{:ok, sub} = ConektaEx.Customer.cancel_subscription(customer_id, subscription_id)
```
### Pagination
Conekta uses a Struct to represent List of Objects, which i named StructList :v,
i found some endpoints that the api docs doesn't have, like, `/customers`,
`/orders`, `/plans`, So if you need to list those use ConektaEx.STRUCT.list, and
ConektaEx.STRUCT.next_page and ConektaEx.STRUCT.previous_page.
```elixir
{:ok, %StructList{}} = ConektaEx.Customer.list()
{:ok, %StructList{}} = ConektaEx.Plan.list()
{:ok, %StructList{}} = ConektaEx.Order.list()
```
Other endpoints unlisted in the api docs without list/next/previous function (PR's are welcome):
`/customers/:id/payment_sources`, `/orders/:id/charges`,
`/orders/:id/line_items`, `/orders/:id/shipping_lines`,
`/customers/:id/shipping_contacts`, `/orders/:id/discount_lines`,
`/orders/:id/tax_lines`.
### Webhooks
When using webhooks, you will have to handle different event `type`s.
```elixir
{:ok, event} = ConektaEx.Event.decode(json)
case Map.get(event, :type) do
"charge.paid" ->
do_something(:charge_paid, event)
"charge.refunded" ->
do_something(:charge_refunded, event)
"subscription.paid" ->
do_something(:subscription_paid, event)
"subscription.payment_failed" ->
do_something(:subscription_payment_failed, event)
end
```