Invoices
API V2 endpoints for invoice creation and status checking
Overview
The Invoice endpoints allow you to create invoices and check their payment status. Invoices can be created with line items or a simple total amount. Returns a payment_link the customer can use to pay.
Create Invoice
Create a Fanbasis payment invoice. Returns a payment_link the customer can use to pay.
Endpoint
POST /api/v2/invoiceRequest Headers
Content-Type: application/jsonRequest Body
{
"api_key": "your_api_key",
"customer_id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john@example.com",
"amount": 200.00,
"currency": "USD",
"items": [
{ "title": "Monthly Plan", "qty": 1, "price": 200.00 }
],
"due_date": "2026-04-17",
"redirect_url": "https://yoursite.com/thank-you",
"webhook_url": "https://yoursite.com/webhooks/safepays"
}| Field | Required | Default | Description |
|---|---|---|---|
api_key | Yes | — | Your vendor API key |
customer_id | No* | — | Existing customer ID |
email | No* | — | Customer email |
amount | No** | — | Total invoice amount |
items | No** | — | Array of line items |
currency | No | "USD" | Currency code |
due_date | No | 30 days | Due date (YYYY-MM-DD) |
redirect_url | No | — | URL to redirect buyer after payment |
webhook_url | No | — | URL to POST payment details to |
* Either customer_id or email is required. If customer_id is provided, the email is pulled from the customer record.
** Either amount or items is required. If items is provided, the total is calculated automatically. If only amount is provided, a single item "Payment" is created.
Line Item Structure
When using the items array, each item must include:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Item name/description |
qty | number | Yes | Quantity |
price | number | Yes | Unit price |
Addon Keys
redirect_url
After the customer completes payment, they are redirected to this URL with the transaction ID appended:
https://yoursite.com/thank-you?transaction_id=49ae344a-3f30-4675-b7bb-a95a92e03545If not provided, the customer sees the default SafePays "Thank you" page.
webhook_url
After payment is confirmed and all fees are calculated, SafePays sends a POST request to this URL with the full transaction details as JSON. See Webhook Notifications for the payload format.
Example: Simple Amount
curl -X POST https://app.safepays.com/api/v2/invoice \
-H "Content-Type: application/json" \
-d '{
"api_key": "your_api_key",
"email": "john@example.com",
"amount": 200,
"redirect_url": "https://yoursite.com/thank-you",
"webhook_url": "https://yoursite.com/webhooks/safepays"
}'const response = await fetch('https://app.safepays.com/api/v2/invoice', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
api_key: 'your_api_key',
email: 'john@example.com',
amount: 200,
redirect_url: 'https://yoursite.com/thank-you',
webhook_url: 'https://yoursite.com/webhooks/safepays'
})
});
const result = await response.json();
console.log('Payment Link:', result.invoice.payment_link);import requests
import json
url = 'https://app.safepays.com/api/v2/invoice'
headers = {'Content-Type': 'application/json'}
data = {
'api_key': 'your_api_key',
'email': 'john@example.com',
'amount': 200,
'redirect_url': 'https://yoursite.com/thank-you',
'webhook_url': 'https://yoursite.com/webhooks/safepays'
}
response = requests.post(url, headers=headers, data=json.dumps(data))
result = response.json()
print(f"Payment Link: {result['invoice']['payment_link']}")Example: With Line Items
curl -X POST https://app.safepays.com/api/v2/invoice \
-H "Content-Type: application/json" \
-d '{
"api_key": "your_api_key",
"customer_id": "550e8400-e29b-41d4-a716-446655440000",
"currency": "USD",
"items": [
{ "title": "Pro Plan", "qty": 1, "price": 150.00 },
{ "title": "Setup Fee", "qty": 1, "price": 50.00 }
],
"due_date": "2026-04-30",
"redirect_url": "https://yoursite.com/thank-you",
"webhook_url": "https://yoursite.com/webhooks/safepays"
}'const response = await fetch('https://app.safepays.com/api/v2/invoice', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
api_key: 'your_api_key',
customer_id: '550e8400-e29b-41d4-a716-446655440000',
currency: 'USD',
items: [
{ title: 'Pro Plan', qty: 1, price: 150.00 },
{ title: 'Setup Fee', qty: 1, price: 50.00 }
],
due_date: '2026-04-30',
redirect_url: 'https://yoursite.com/thank-you',
webhook_url: 'https://yoursite.com/webhooks/safepays'
})
});
const result = await response.json();
console.log('Payment Link:', result.invoice.payment_link);import requests
import json
url = 'https://app.safepays.com/api/v2/invoice'
headers = {'Content-Type': 'application/json'}
data = {
'api_key': 'your_api_key',
'customer_id': '550e8400-e29b-41d4-a716-446655440000',
'currency': 'USD',
'items': [
{'title': 'Pro Plan', 'qty': 1, 'price': 150.00},
{'title': 'Setup Fee', 'qty': 1, 'price': 50.00}
],
'due_date': '2026-04-30',
'redirect_url': 'https://yoursite.com/thank-you',
'webhook_url': 'https://yoursite.com/webhooks/safepays'
}
response = requests.post(url, headers=headers, data=json.dumps(data))
result = response.json()
print(f"Payment Link: {result['invoice']['payment_link']}")Success Response
Status Code: 201 Created
{
"status": "success",
"message": "Invoice created successfully",
"invoice": {
"id": "49ae344a-3f30-4675-b7bb-a95a92e03545",
"amount": 212.00,
"base_amount": 200.00,
"currency": "USD",
"payment_link": "https://www.fanbasis.com/agency-checkout/ibubble/V7V1O",
"fanbasis_checkout_session_id": 559373,
"status": "Invoice Created",
"email": "john@example.com",
"customer_id": "550e8400-e29b-41d4-a716-446655440000",
"items": [
{ "title": "Payment", "qty": 1, "price": 200.00 }
],
"due_date": "2026-04-17",
"created_on": "17 Mar, 2026"
}
}amount is the total charged (base + customer fee). base_amount is the original amount before fees. Share the payment_link with your customer to collect payment.
Error Responses
| Status | Error |
|---|---|
| 400 | "email or customer_id is required" |
| 400 | "amount or items are required" |
| 400 | "Invoice amount must be greater than 0" |
| 400 | "Invalid redirect_url" / "Invalid webhook_url" |
| 400 | "Invalid due_date format. Use YYYY-MM-DD" |
| 401 | "api_key is required" / "Invalid API Key" |
| 403 | "This vendor account has been banned." |
| 404 | "Customer not found" |
| 502 | "Payment provider error (status)" |
Check Invoice Status
Get the current status of an invoice by its ID.
Endpoint
GET /api/v2/invoice/{invoice_id}?api_key=your_api_key_herePath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
invoice_id | string | Yes | The unique invoice ID (UUID) |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key | string | Yes | Your API key for authentication |
Example Request
curl -X GET "https://app.safepays.com/api/v2/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/v2/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/v2/invoice/{invoice_id}?api_key={api_key}'
response = requests.get(url)
result = response.json()
print(f"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
| Status | Description |
|---|---|
Invoice Created | Invoice has been created but not yet paid |
Paid | Invoice has been paid |
Unpaid | Invoice is unpaid and past due |
Failed | Payment 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"
}