SafePays API

Invoices

API endpoints for invoice creation and management

Overview

The Invoice endpoints allow you to create invoices and check their payment status. Invoices can be created with line items or a simple amount, and must include a webhook URL for payment notifications.

Create Invoice

Create a new invoice for payment collection.

Endpoint

POST /api/invoice?webhook=https://your-webhook-url.com/callback

Query Parameters

ParameterTypeRequiredDescription
webhookstringYesURL to receive payment notifications

Request Body

FieldTypeRequiredDescription
api_keystringYesYour API key for authentication
customer_idstringNo*Customer ID (UUID)
emailstringNo*Customer email address
currencystringNoCurrency code (default: USD)
itemsarrayNo**Array of line items
amountnumberNo**Total invoice amount
due_datestringNoDue date (YYYY-MM-DD, default: 90 days)

Required Fields:

  • Either customer_id OR email must be provided
  • Either items array OR amount must be provided

Line Item Structure

When using items array:

FieldTypeRequiredDescription
namestringYesItem name/description
qtynumberYesQuantity
pricenumberYesUnit price

Example Request (With Items)

curl -X POST "https://app.safepays.com/api/invoice?webhook=https://your-webhook-url.com/callback" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "your_api_key_here",
    "customer_id": "550e8400-e29b-41d4-a716-446655440000",
    "currency": "USD",
    "items": [
      {
        "name": "Product A",
        "qty": 2,
        "price": 50.00
      },
      {
        "name": "Product B",
        "qty": 1,
        "price": 25.00
      }
    ],
    "due_date": "2024-12-31"
  }'
const webhookUrl = 'https://your-webhook-url.com/callback';

const response = await fetch(
  `https://app.safepays.com/api/invoice?webhook=${encodeURIComponent(webhookUrl)}`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      api_key: 'your_api_key_here',
      customer_id: '550e8400-e29b-41d4-a716-446655440000',
      currency: 'USD',
      items: [
        {
          name: 'Product A',
          qty: 2,
          price: 50.00
        },
        {
          name: 'Product B',
          qty: 1,
          price: 25.00
        }
      ],
      due_date: '2024-12-31'
    })
  }
);

const result = await response.json();
console.log('Payment Link:', result.invoice.payment_link);
import requests
import json
from urllib.parse import urlencode

webhook_url = 'https://your-webhook-url.com/callback'
url = f'https://app.safepays.com/api/invoice?webhook={webhook_url}'

headers = {'Content-Type': 'application/json'}
data = {
    'api_key': 'your_api_key_here',
    'customer_id': '550e8400-e29b-41d4-a716-446655440000',
    'currency': 'USD',
    'items': [
        {
            'name': 'Product A',
            'qty': 2,
            'price': 50.00
        },
        {
            'name': 'Product B',
            'qty': 1,
            'price': 25.00
        }
    ],
    'due_date': '2024-12-31'
}

response = requests.post(url, headers=headers, data=json.dumps(data))
result = response.json()
print(f"Payment Link: {result['invoice']['payment_link']}")
<?php
$webhook_url = 'https://your-webhook-url.com/callback';
$url = 'https://app.safepays.com/api/invoice?webhook=' . urlencode($webhook_url);

$data = [
    'api_key' => 'your_api_key_here',
    'customer_id' => '550e8400-e29b-41d4-a716-446655440000',
    'currency' => 'USD',
    'items' => [
        [
            'name' => 'Product A',
            'qty' => 2,
            'price' => 50.00
        ],
        [
            'name' => 'Product B',
            'qty' => 1,
            'price' => 25.00
        ]
    ],
    'due_date' => '2024-12-31'
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$result = json_decode($response, true);
echo "Payment Link: " . $result['invoice']['payment_link'];
?>

Example Request (Simple Amount)

For invoices without line items:

curl -X POST "https://app.safepays.com/api/invoice?webhook=https://your-webhook-url.com/callback" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "your_api_key_here",
    "email": "john.doe@example.com",
    "amount": 125.00,
    "currency": "USD",
    "due_date": "2024-12-31"
  }'
const webhookUrl = 'https://your-webhook-url.com/callback';

const response = await fetch(
  `https://app.safepays.com/api/invoice?webhook=${encodeURIComponent(webhookUrl)}`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      api_key: 'your_api_key_here',
      email: 'john.doe@example.com',
      amount: 125.00,
      currency: 'USD',
      due_date: '2024-12-31'
    })
  }
);

const result = await response.json();
import requests
import json

webhook_url = 'https://your-webhook-url.com/callback'
url = f'https://app.safepays.com/api/invoice?webhook={webhook_url}'

data = {
    'api_key': 'your_api_key_here',
    'email': 'john.doe@example.com',
    'amount': 125.00,
    'currency': 'USD',
    'due_date': '2024-12-31'
}

response = requests.post(url, headers={'Content-Type': 'application/json'}, 
                        data=json.dumps(data))
result = response.json()

Success Response

Status Code: 201 Created

{
  "status": "success",
  "message": "Invoice created successfully",
  "invoice": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "amount": 125.00,
    "currency": "USD",
    "email": "john.doe@example.com",
    "provider": "card",
    "status": "Invoice Created",
    "created_on": "15 Jan, 2024",
    "payment_link": "https://app.safepays.com/pay/660e8400-e29b-41d4-a716-446655440001",
    "items": [
      {
        "name": "Product A",
        "qty": 2,
        "price": 50.00
      },
      {
        "name": "Product B",
        "qty": 1,
        "price": 25.00
      }
    ],
    "due_date": "2024-12-31",
    "customer_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}

Error Responses

400 Bad Request - Missing required fields

{
  "error": "webhook parameter is required"
}

401 Unauthorized - Invalid API key

{
  "error": "Invalid API Key"
}

404 Not Found - Customer not found

{
  "error": "Customer not found"
}

The payment_link is the URL your customers should visit to complete payment. Share this link via email, SMS, or redirect them directly.


Check Invoice Status

Retrieve the current status and details of an invoice.

Endpoint

GET /api/invoice/{invoice_id}?api_key=your_api_key_here

Path Parameters

ParameterTypeRequiredDescription
invoice_idstringYesThe unique invoice ID (UUID)

Query Parameters

ParameterTypeRequiredDescription
api_keystringYesYour API key for authentication

Example Request

curl -X GET "https://app.safepays.com/api/invoice/660e8400-e29b-41d4-a716-446655440001?api_key=your_api_key_here"
const invoiceId = '660e8400-e29b-41d4-a716-446655440001';
const apiKey = 'your_api_key_here';

const response = await fetch(
  `https://app.safepays.com/api/invoice/${invoiceId}?api_key=${apiKey}`
);

const result = await response.json();
console.log('Invoice Status:', result.invoice.status);
import requests

invoice_id = '660e8400-e29b-41d4-a716-446655440001'
api_key = 'your_api_key_here'
url = f'https://app.safepays.com/api/invoice/{invoice_id}?api_key={api_key}'

response = requests.get(url)
result = response.json()
print(f"Invoice Status: {result['invoice']['status']}")
<?php
$invoice_id = '660e8400-e29b-41d4-a716-446655440001';
$api_key = 'your_api_key_here';
$url = "https://app.safepays.com/api/invoice/{$invoice_id}?api_key={$api_key}";

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$result = json_decode($response, true);
echo "Invoice Status: " . $result['invoice']['status'];
?>

Success Response

Status Code: 200 OK

{
  "status": "success",
  "invoice": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "amount": 125.00,
    "currency": "USD",
    "email": "john.doe@example.com",
    "provider": "card",
    "status": "Paid",
    "created_on": "15 Jan, 2024",
    "paid_on": "15 Jan, 2024",
    "payment_link": "https://app.safepays.com/pay/660e8400-e29b-41d4-a716-446655440001",
    "items": [
      {
        "name": "Product A",
        "qty": 2,
        "price": 50.00
      },
      {
        "name": "Product B",
        "qty": 1,
        "price": 25.00
      }
    ],
    "due_date": "2024-12-31",
    "customer_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}

Invoice Status Values

StatusDescription
Invoice CreatedInvoice created, awaiting payment
PaidPayment received successfully
UnpaidInvoice is past due
FailedPayment attempt failed

Error Responses

400 Bad Request - Missing API key

{
  "error": "api_key parameter is required"
}

401 Unauthorized - Invalid API key

{
  "error": "Invalid API Key"
}

404 Not Found - Invoice not found

{
  "error": "Invoice not found"
}

Invoice Lifecycle

Invoice Creation

Invoice is created with status Invoice Created

Customer receives the payment link via your chosen method

Payment Processing

Customer completes payment through the secure checkout

Status Update

Invoice status changes to Paid or Failed

Webhook Notification

Your webhook endpoint receives the status update

Best Practices

Invoice Management

  1. Store Invoice IDs: Always save the invoice ID for future reference
  2. Monitor Webhooks: Set up robust webhook handling for real-time updates
  3. Handle Failures: Implement retry logic for failed payments
  4. Track Due Dates: Monitor upcoming and overdue invoices

Currency Handling

When creating invoices:

  • Specify currency explicitly (don't rely on defaults)
  • Use customer's preferred currency when available
  • Handle multi-currency reporting in your system

Line Items vs Amount

Choose the right approach:

Use Line Items when:

  • You need detailed invoicing
  • Customer requires itemized receipts
  • Tracking inventory or services
  • Different tax rates per item

Use Simple Amount when:

  • Single service or subscription
  • Pre-calculated total
  • Simple payment collection
  • No itemization needed

For recurring invoices, consider storing a template of line items in your system to speed up invoice creation.

Testing Invoices

In test mode (using test API keys):

  1. Create invoices normally
  2. Use the dashboard to mark invoices as paid
  3. Webhook will fire with test payment data
  4. No real money is processed

On this page