Getting started

Quick start

This guide walks you through the complete flow of creating and collecting a payment with the Qualy API — from authentication to checkout. By the end, you'll have a working integration that creates a payment intent and collects funds.


Overview

A typical payment flow follows these steps:

  1. Authenticate — set up your API key and tenant ID.
  2. Create a contact — the person who will pay.
  3. Create a payment intent — define the amount, currency, and line items.
  4. Collect the payment — redirect to Qualy's portal or use the API directly.
  5. Monitor with webhooks — track when the payment succeeds or fails.

Step 1: Set up authentication

All requests require an API key and a tenant ID. If you haven't created an API key yet, follow the API keys guide. To find your tenant ID, see the tenants guide.

Every example below uses these headers:

const headers = {
  'Content-Type': 'application/json',
  'Authorization': 'ApiKey your-api-key-here',
  'X-TENANT-ID': 'your-tenant-id-here',
};

See: Authentication


Step 2: Create a contact

A contact is the person who will receive the payment intent and make the payment. You only need to create them once.

const contactResponse = await fetch('https://api.qualyhq.com/v1/contacts/create', {
  method: 'POST',
  headers,
  body: JSON.stringify({
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+61412345678"
  }),
});

const contact = await contactResponse.json();
console.log('Contact ID:', contact._id); // e.g. "656b9ef1a3258074a705433b"

See: Contacts API Reference


Step 3: Create a payment intent

Now create a payment intent with the contact, amount, currency, and line items:

const paymentResponse = await fetch('https://api.qualyhq.com/v1/payment-intents/create', {
  method: 'POST',
  headers,
  body: JSON.stringify({
    "intentType": "ad-hoc",
    "contact": "656b9ef1a3258074a705433b",
    "dueAt": "2026-05-10T14:26:07.369Z",
    "currency": "AUD",
    "items": [
      {
        "name": "Tuition fee",
        "description": "",
        "category": "Course",
        "amount": 100000
      }
    ]
  }),
});

const paymentIntent = await paymentResponse.json();
console.log('Payment Intent ID:', paymentIntent._id);
console.log('Payment link:', paymentIntent.links.short);

Amounts are in cents

All amounts in Qualy are in minor currency units (cents). So 100000 means $1,000.00 AUD.

See: Creating payment intents


Step 4: Collect the payment

You have two options to collect the payment:

The simplest approach. Redirect your contact to Qualy's hosted payment page using the links URL returned in the payment intent response:

// Redirect the contact to this URL
const paymentUrl = paymentIntent.links.short;
// e.g. "https://qualyhqpay.com/abc123"

Qualy handles method selection, payer verification, and processing. This is required for card payments.

Option B: Direct API

For non-card methods (PIX, Boleto, PayID, bank transfers), call the sign endpoint to get payment details and display them in your own UI:

const signResponse = await fetch('https://api.qualyhq.com/v1/payment-gateways/sign', {
  method: 'POST',
  headers,
  body: JSON.stringify({
    gateway: 'zai',
    signatureType: 'ZAI_PAYID',
    entity: 'payment-intent',
    paymentIntentId: paymentIntent._id,
    contact: {
      contactId: contact._id,
    },
    payer: {
      type: 'myself',
      email: 'john.doe@example.com',
      profile: {
        firstName: 'John',
        lastName: 'Doe',
        phone: '+61412345678',
      },
    },
  }),
});

const paymentDetails = await signResponse.json();
console.log('PayID address:', paymentDetails.email);

See: Collecting payments


Step 5: Monitor with webhooks

Set up webhooks to get notified when a payment succeeds or fails. After a contact completes the payment, Qualy sends a webhook event to your server.

You can also check the payment status via the API:

const statusResponse = await fetch(
  `https://api.qualyhq.com/v1/payment-intents/${paymentIntent._id}`,
  {
    method: 'GET',
    headers,
  }
);

const status = await statusResponse.json();
console.log('Payment status:', status.status);

See: Setting up webhooks


Complete example

Here's the entire flow in one script:

const API = 'https://api.qualyhq.com/v1';
const headers = {
  'Content-Type': 'application/json',
  'Authorization': 'ApiKey your-api-key-here',
  'X-TENANT-ID': 'your-tenant-id-here',
};

// 1. Create a contact
const contact = await fetch(`${API}/contacts/create`, {
  method: 'POST', headers,
  body: JSON.stringify({
    firstName: 'John', lastName: 'Doe',
    email: 'john.doe@example.com', phone: '+61412345678',
  }),
}).then(r => r.json());

// 2. Create a payment intent
const paymentIntent = await fetch(`${API}/payment-intents/create`, {
  method: 'POST', headers,
  body: JSON.stringify({
    intentType: 'ad-hoc',
    contact: contact._id,
    dueAt: '2026-05-10T14:26:07.369Z',
    currency: 'AUD',
    items: [
      { name: 'Tuition fee', description: '', category: 'Course', amount: 100000 },
    ],
  }),
}).then(r => r.json());

// 3. Send the payment link to your contact
console.log('Payment link:', paymentIntent.links.short);

// 4. Check payment status
const status = await fetch(`${API}/payment-intents/${paymentIntent._id}`, {
  method: 'GET', headers,
}).then(r => r.json());

console.log('Status:', status.status);

Next steps

Previous
Getting started