Documentation
Everything you need to integrate Quetzal
Getting Started
1. Get Your API Keys
Contact our sales team to get your Quetzal API keys. You'll receive:
- •
pk_test_xxx- Publishable key for frontend - •
sk_test_xxx- Secret key for backend - •
pk_live_xxx- Live publishable key - •
sk_live_xxx- Live secret key
2. Choose Your Integration
Checkout JS
Best for quick integration with pre-built UI
Checkout API
Best for custom checkout experiences
3. Configure Your Redsys Credentials
Provide your Redsys TPV credentials in the Quetzal dashboard. We'll handle the complex Redsys integration for you.
Frontend SDK
Checkout JS
Installation
Add the Quetzal script to your HTML:
<script src="https://js.quetzal-api.com/v1/checkout.js"></script>
Initialize
Initialize Quetzal with your publishable key:
Quetzal.init({
publishableKey: 'pk_test_xxx',
locale: 'es' // Optional: 'es', 'en', 'ca', 'eu', 'gl'
});
Create a Payment
Open the checkout modal to collect payment:
Quetzal.checkout({
amount: 2999, // Amount in cents (29.99)
currency: 'EUR', // Currency code
description: 'Order #1234',
mode: 'modal', // 'modal' or 'redirect'
// Callbacks
onSuccess: function(result) {
console.log('Payment successful!', result.paymentId);
// Redirect to success page
window.location.href = '/order/success?id=' + result.paymentId;
},
onError: function(error) {
console.error('Payment failed:', error.message);
// Show error to user
},
onCancel: function() {
console.log('Payment cancelled');
}
});
Configuration Options
| Option | Type | Description |
|---|---|---|
amount |
number | Amount in cents (required) |
currency |
string | ISO currency code (default: 'EUR') |
description |
string | Payment description |
mode |
string | 'modal' or 'redirect' |
metadata |
object | Custom metadata to attach |
REST API
Checkout API
Authentication
Use your secret key in the Authorization header:
curl -H "Authorization: Bearer sk_test_xxx" \
https://pay.quetzal-api.com/v1/payments
Create a Payment
Create a new payment intent:
POST /v1/payments
{
"amount": 2999,
"currency": "EUR",
"payment_method": "card",
"description": "Order #1234",
"return_url": "https://yoursite.com/payment/complete",
"metadata": {
"order_id": "1234"
}
}
Response
{
"id": "pay_1234567890",
"object": "payment",
"status": "requires_action",
"amount": 2999,
"currency": "EUR",
"checkout_url": "https://checkout.quetzal-api.com/pay_1234567890",
"created": 1699876543
}
Get Payment Status
Retrieve the current status of a payment:
GET /v1/payments/{payment_id}
# Response
{
"id": "pay_1234567890",
"status": "succeeded",
"amount": 2999,
"currency": "EUR",
"paid_at": 1699876600
}
Webhooks
Configure webhooks to receive real-time notifications:
# Webhook payload example
{
"event": "payment.succeeded",
"data": {
"id": "pay_1234567890",
"status": "succeeded",
"amount": 2999,
"currency": "EUR"
},
"timestamp": 1699876600
}
Available Events
payment.created- Payment intent createdpayment.succeeded- Payment completed successfullypayment.failed- Payment failedpayment.refunded- Payment was refunded
Payment Statuses
| Status | Description |
|---|---|
requires_action |
Customer must complete checkout |
processing |
Payment is being processed |
succeeded |
Payment completed successfully |
failed |
Payment failed |
canceled |
Payment was canceled |
refunded |
Payment was refunded |
Error Codes
| Code | Description |
|---|---|
invalid_request |
The request was malformed or missing required fields |
authentication_error |
Invalid or missing API key |
card_declined |
The card was declined by the bank |
insufficient_funds |
The card has insufficient funds |
expired_card |
The card has expired |
processing_error |
An error occurred while processing |