README.md

# Mercadopago

[![Hex.pm](https://img.shields.io/hexpm/v/mercadopago.svg)](https://hex.pm/packages/mercadopago)
[![Documentation](https://img.shields.io/badge/docs-hexdocs-purple.svg)](https://hexdocs.pm/mercadopago)
[![License](https://img.shields.io/gitlab/license/erickueen/mercadopago.svg)](https://gitlab.com/erickueen/mercadopago/-/blob/main/LICENSE)

Elixir client for Mercado Pago API. Provides a comprehensive interface for integrating
payments, customers, subscriptions, and webhooks.

## Features

- **Payments**: Create, search, cancel, and capture payments
- **Customers**: Manage customer accounts and saved cards
- **Card Tokens**: Token management for secure card payments
- **Preferences**: Create checkout preferences
- **Refunds**: Process full and partial refunds
- **Subscriptions**: Handle recurring payments
- **Payment Methods**: List available payment methods
- **Webhooks**: Signature verification and notification parsing

## Installation

Add `mercadopago` to your list of dependencies in `mix.exs`:

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

## Configuration

Add your Mercado Pago credentials to your application config:

```elixir
# config/config.exs
config :mercadopago,
  access_token: "YOUR_ACCESS_TOKEN",
  sandbox: true  # Set to false in production
```

For production, use environment variables:

```elixir
# config/runtime.exs
config :mercadopago,
  access_token: System.get_env("MERCADOPAGO_ACCESS_TOKEN"),
  sandbox: false
```

## Usage

### Creating a Payment

```elixir
# Card payment
{:ok, payment} = Mercadopago.Resources.Payment.create(%{
  transaction_amount: 150.00,
  token: "card_token_from_js_sdk",
  description: "Blue shirt",
  payment_method_id: "visa",
  installments: 1,
  payer: %{
    email: "buyer@email.com",
    identification: %{type: "RFC", number: "ABC123456789"}
  }
})

# Cash payment (OXXO)
{:ok, payment} = Mercadopago.Resources.Payment.create(%{
  transaction_amount: 100.00,
  description: "Product",
  payment_method_id: "oxxo",
  payer: %{email: "buyer@email.com"}
})

# Get the OXXO reference
oxxo_reference = payment.transaction_details.payment_method_reference_id
```

### Using Bang Functions

```elixir
# Raises on error
payment = Mercadopago.Resources.Payment.create!(%{...})
```

### Multi-tenant Applications

```elixir
# Per-request credentials
Mercadopago.Resources.Payment.create(params, access_token: "tenant_token")

# Or create a client explicitly
client = Mercadopago.client(access_token: "tenant_token", sandbox: false)
Mercadopago.Resources.Payment.create(params, client: client)
```

### Managing Customers

```elixir
# Create a customer
{:ok, customer} = Mercadopago.Resources.Customer.create(%{
  email: "customer@email.com",
  first_name: "John",
  last_name: "Doe"
})

# Save a card for the customer
{:ok, card} = Mercadopago.Resources.Card.create(customer.id, %{
  token: "card_token"
})

# Charge a saved card
{:ok, payment} = Mercadopago.Resources.Payment.create(%{
  transaction_amount: 100.00,
  token: card.id,
  description: "Recurring charge",
  payment_method_id: "visa",
  payer: %{id: customer.id}
})
```

### Checkout Preferences

```elixir
{:ok, preference} = Mercadopago.Resources.Preference.create(%{
  items: [
    %{
      title: "Product Name",
      quantity: 1,
      currency_id: "MXN",
      unit_price: 100.00
    }
  ],
  back_urls: %{
    success: "https://example.com/success",
    failure: "https://example.com/failure",
    pending: "https://example.com/pending"
  },
  external_reference: "ORDER-123"
})

# Redirect user to checkout
redirect_url = preference.init_point
```

### Refunds

```elixir
# Full refund
{:ok, refund} = Mercadopago.Resources.Refund.create(payment_id)

# Partial refund
{:ok, refund} = Mercadopago.Resources.Refund.create(payment_id, amount: 50.00)
```

### Webhooks

```elixir
# In your Phoenix controller or LiveView
def handle_webhook(conn, params) do
  body = read_raw_body(conn)
  signature = get_header(conn, "x-signature")
  secret = Application.get_env(:mercadopago, :webhook_secret)

  case Mercadopago.Webhook.parse_and_verify(params, body, signature, secret) do
    {:ok, %{topic: :payment, id: payment_id}} ->
      {:ok, payment} = Mercadopago.Resources.Payment.get(payment_id)
      # Handle payment update...

    {:ok, %{topic: :subscription_preapproval}} ->
      # Handle subscription update...

    {:error, :invalid_signature} ->
      # Reject

    {:error, _} ->
      # Invalid notification format
  end
end
```

## Testing

Run the tests:

```bash
mix test
```

### Using Bypass for Integration Tests

```elixir
setup do
  bypass = Bypass.open()
  Application.put_env(:mercadopago, :base_url, "http://localhost:#{bypass.port}")
  on_exit(fn -> Bypass.down(bypass) end)
  {:ok, bypass: bypass}
end

test "creates a payment", %{bypass: bypass} do
  Bypass.expect_once(bypass, "POST", "/v1/payments", fn conn ->
    Plug.Conn.resp(conn, 200, ~s({"id": 123456, "status": "approved"}))
  end)

  {:ok, payment} = Mercadopago.Resources.Payment.create(%{...})
  assert payment.status == :approved
end
```

## Supported Payment Methods

### Mexico (MLM)

- Credit/Debit Cards (Visa, Mastercard, American Express)
- OXXO
- Paycash
- SPEI (Bank Transfer)
- BBVA Bancomer
- Santander
- Citibanamex

## Documentation

Full documentation is available at [HexDocs](https://hexdocs.pm/mercadopago).

## License

MIT License. See [LICENSE](LICENSE) for details.

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Merge Request