API para integración de pagos con criptomonedas
URL Base: https://cryptopay.lat
Versión: 1.0.0
La API de CryptoPay te permite integrar pagos con criptomonedas en tu aplicación de manera rápida y segura. Nuestra API RESTful sigue los estándares de la industria y proporciona endpoints intuitivos para gestionar pagos, transacciones y billeteras.
Todas las respuestas de la API están en formato JSON y siguen la siguiente estructura:
{
"status": 200,
"error": null,
"data": {
// Datos específicos del endpoint
}
}
Todas las peticiones a la API requieren autenticación mediante una API Key. Para obtener tu API Key:
Incluye tu API Key en el header de todas las peticiones:
X-API-KEY: tu_api_key
Las notificaciones se configuran una sola vez por cliente (menú Webhooks o POST /api/webhook), no por petición. Ver la sección Webhooks.
| Código | Descripción | Schema |
|---|---|---|
| 201 | Creado |
|
| Código | Descripción | Schema |
|---|---|---|
| 200 | Éxito |
|
| Código | Descripción | Schema |
|---|---|---|
| 200 | Éxito |
|
CryptoPay envía notificaciones salientes (webhooks) a tu servidor cuando ocurre un evento de pago. Se entregan de forma asíncrona con reintentos automáticos y firma HMAC, para que no dependas de hacer polling.
Hay dos formas de configurar el destino:
URL de destino y genera el Secreto de firma (HMAC).X-API-KEY):
# Registrar/actualizar la URL
POST /api/webhook { "webhook_url": "https://tu-app.com/webhooks/cryptopay" }
# (Re)generar el secreto (se muestra UNA sola vez)
POST /api/webhook/secret
# Ver la configuración actual (nunca devuelve el secreto)
GET /api/webhook
payment.completed — El pago fue recibido y confirmado on-chain.payment.swept — Los fondos del pago fueron barridos a tu wallet principal.CryptoPay hace un POST con este cuerpo:
{
"event": "payment.completed",
"data": {
"request_id": 140,
"client_id": 3,
"txid": "0x…",
"amount": "97.000000",
"currency": "USDT",
"network": "BSC",
"status": "completed"
}
}
X-CryptoPay-Signature: sha256=<hmac> — HMAC-SHA256 del cuerpo crudo usando tu secreto.X-CryptoPay-Event-Id y X-CryptoPay-Idempotency-Key — úsalos para deduplicar (un evento puede reintentarse).// Node.js / Express (body crudo)
const crypto = require('crypto');
const raw = req.rawBody; // el cuerpo SIN parsear
const expected = 'sha256=' + crypto.createHmac('sha256', WEBHOOK_SECRET)
.update(raw).digest('hex');
const ok = crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(req.get('X-CryptoPay-Signature') || '')
);
if (!ok) return res.status(401).end();
# PHP
$raw = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $raw, $WEBHOOK_SECRET);
if (! hash_equals($expected, $_SERVER['HTTP_X_CRYPTOPAY_SIGNATURE'] ?? '')) {
http_response_code(401); exit;
}
2xx para confirmar la recepción. Cualquier otro código (o timeout) dispara reintentos con backoff exponencial.X-CryptoPay-Idempotency-Key: el mismo evento puede llegar más de una vez.La API utiliza códigos de estado HTTP estándar para indicar el éxito o fallo de las peticiones:
200 - Éxito201 - Recurso creado400 - Solicitud incorrecta401 - No autorizado403 - Prohibido404 - Recurso no encontrado429 - Demasiadas peticiones500 - Error del servidor{
"status": "error_code",
"error": "Mensaje de error descriptivo",
"details": {
"field": "Descripción del error específico"
}
}
<?php
namespace App\Libraries;
class CryptoPay
{
private $apiKey;
private $baseUrl;
private $client;
public function __construct()
{
$this->apiKey = getenv('CRYPTOPAY_API_KEY');
$this->baseUrl = getenv('CRYPTOPAY_API_URL');
$this->client = \Config\Services::curlrequest();
}
public function createPayment($amount, $description = null)
{
try {
$response = $this->client->request('POST', $this->baseUrl . '/api/crypto-payment', [
'headers' => [
'X-API-KEY' => $this->apiKey,
'Content-Type' => 'application/json'
],
'json' => [
'amount' => $amount,
'description' => $description
]
]);
return json_decode($response->getBody(), true);
} catch (\Exception $e) {
log_message('error', '[CryptoPay::createPayment] Error: ' . $e->getMessage());
throw new \RuntimeException('Error creating payment: ' . $e->getMessage());
}
}
public function checkPaymentStatus($requestId)
{
try {
$response = $this->client->request('GET', $this->baseUrl . '/api/crypto-payment/status/' . $requestId, [
'headers' => [
'X-API-KEY' => $this->apiKey
]
]);
return json_decode($response->getBody(), true);
} catch (\Exception $e) {
log_message('error', '[CryptoPay::checkPaymentStatus] Error: ' . $e->getMessage());
throw new \RuntimeException('Error checking payment status: ' . $e->getMessage());
}
}
}
const axios = require('axios');
class CryptoPayClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://cryptopay.lat';
this.client = axios.create({
baseURL: this.baseUrl,
headers: {
'X-API-KEY': this.apiKey,
'Content-Type': 'application/json'
}
});
}
async createPayment(amount, description = null) {
try {
const response = await this.client.post('/api/crypto-payment', {
amount,
description
});
return response.data;
} catch (error) {
throw new Error(error.response?.data?.error || 'Error creating payment');
}
}
async checkPaymentStatus(requestId) {
try {
const response = await this.client.get(`/api/crypto-payment/status/${requestId}`);
return response.data;
} catch (error) {
throw new Error(error.response?.data?.error || 'Error checking payment status');
}
}
}
import requests
class CryptoPayAPI:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://cryptopay.lat'
self.headers = {
'X-API-KEY': self.api_key,
'Content-Type': 'application/json'
}
def create_payment(self, amount, description=None):
try:
response = requests.post(
f'{self.base_url}/api/crypto-payment',
headers=self.headers,
json={
'amount': amount,
'description': description
}
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
raise Exception(f'Error creating payment: {str(e)}')
def check_payment_status(self, request_id):
try:
response = requests.get(
f'{self.base_url}/api/crypto-payment/status/{request_id}',
headers=self.headers
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
raise Exception(f'Error checking payment status: {str(e)}')