Mercadopago Elixir SDK

Elixir client for the MercadoPago REST API, ported from the official Ruby SDK.

Installation

Add to mix.exs:

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

Usage

client = Mercadopago.new("YOUR_ACCESS_TOKEN")
# Create a payment
{:ok, %{status: 201, response: payment}} =
Mercadopago.Payment.create(client, %{
transaction_amount: 100.0,
description: "Product",
payment_method_id: "pix",
payer: %{email: "buyer@example.com"}
})
# Fetch a payment
{:ok, %{status: 200, response: payment}} =
Mercadopago.Payment.get(client, payment["id"])

Per-call token override:

Mercadopago.Payment.get(client, id, access_token: "OTHER_TOKEN")

Testing

Unit tests (no network, no token)

Use Req.Test stubs to intercept HTTP calls. The SDK exposes a :plug option on the client that routes requests through the stub instead of the network.

A helper is provided in test/support/stub_client.ex (compiled only in the :test env):

# In your test file
import Mercadopago.Test.StubClient, only: [new: 1]
test "creates a payment" do
Req.Test.stub(:payment_stub, fn conn ->
conn
|> Plug.Conn.put_status(201)
|> Req.Test.json(%{"id" => "pay_123", "status" => "approved"})
end)
client = new(:payment_stub)
assert {:ok, %{status: 201, response: %{"id" => "pay_123"}}} =
Mercadopago.Payment.create(client, %{transaction_amount: 100})
end

new/1 builds a client with access_token: "test_token" and plug: {Req.Test, stub_name}. The stub receives a %Plug.Conn{} and must return a response — use Req.Test.json/2 for JSON bodies.

Run unit tests:

mix test

Integration tests (real MercadoPago sandbox)

Tag integration tests with @moduletag :integration. They are excluded from the default mix test run and require a sandbox ACCESS_TOKEN.

defmodule Mercadopago.PaymentIntegrationTest do
@moduletag :integration
use ExUnit.Case
setup do
token = System.fetch_env!("ACCESS_TOKEN")
{:ok, client: Mercadopago.new(token)}
end
test "search payments", %{client: client} do
assert {:ok, %{status: 200, response: %{"results" => _}}} =
Mercadopago.Payment.search(client)
end
end

Run only integration tests:

ACCESS_TOKEN=APP_USR_xxx mix test --include integration

Run all tests (unit + integration):

ACCESS_TOKEN=APP_USR_xxx mix test --include integration --include test

Webhook validation

Mercadopago.Webhook.Validator.validate(
x_signature, # "ts=...;v1=..." header from MercadoPago
x_request_id, # x-request-id header
data_id, # params["data"]["id"] from the webhook body
secret # your webhook secret from the MercadoPago dashboard
)
# => :ok | raises Mercadopago.Webhook.InvalidSignatureError

Timestamp drift tolerance (default: no check):

Mercadopago.Webhook.Validator.validate(x_sig, x_req, data_id, secret,
max_age_seconds: 300
)