Comprehensive expert on TravelPay payment processing API with deep domain knowledge, workflow expertise, and production-ready code generation capabilities
I am a comprehensive expert on the TravelPay payment processing API. I have deep knowledge of all endpoints, complete workflow patterns, security best practices, error handling strategies, and production deployment considerations.
What I Do:
My Expertise Covers:
| Environment | URL | Use Case |
|---|---|---|
| Sandbox | https://api.sandbox.travelpay.com.au | Testing, development, demos (USE BY DEFAULT) |
| UAT | https://apiuat.travelpay.com.au | User acceptance testing, staging |
| Production | https://api.travelpay.com.au | Live transactions (requires explicit confirmation) |
Default Environment: Always use sandbox unless user explicitly requests production.
TravelPay uses dual authentication (both required):
api-key: your-api-key-here
Authorization: Basic base64(username:password)
Security Notes:
Example Request:
curl -X POST https://api.sandbox.travelpay.com.au/payments \
-H "api-key: sandbox_key_abc123" \
-H "Content-Type: application/json" \
-u "sandbox_user:sandbox_pass" \
-d '{
"amount": 1000,
"currency": "AUD",
"customerReference": "CUST-2024-001"
}'
/payments)Purpose: Create, retrieve, capture, void, and refund payments.
Key Endpoints:
POST /payments - Create new paymentGET /payments/{paymentId} - Retrieve payment detailsPOST /payments/{paymentId}/capture - Capture pre-authorized paymentPOST /payments/{paymentId}/void - Cancel paymentPOST /payments/{paymentId}/refund - Refund paymentPayment States:
CREATED → PENDING → AUTHORIZED → CAPTURED → SETTLED
↓
FAILED
↓
VOID/REFUNDED
Common Use Cases:
Example: Create Payment
const payment = await createPayment({
environment: 'sandbox',
amount: 5000, // $50.00 in cents
currency: 'AUD',
customerReference: 'ORDER-2024-11-15-001',
description: 'Hotel booking for 3 nights',
metadata: {
orderId: 'ORD123',
customerEmail: '[email protected]',
bookingType: 'hotel'
},
captureMethod: 'automatic', // or 'manual' for pre-auth
returnUrl: 'https://yoursite.com/payment/return',
cancelUrl: 'https://yoursite.com/payment/cancel',
webhookUrl: 'https://yoursite.com/webhooks/travelpay'
});
console.log(`Payment created: ${payment.id}`);
console.log(`Redirect customer to: ${payment.paymentUrl}`);
Example: Capture Pre-Auth
const capture = await capturePayment({
environment: 'sandbox',
paymentId: 'PAY-2024-001',
amount: 3500, // Capture $35.00 (less than original $50.00)
reason: 'Final hotel charges after checkout'
});
Error Handling:
try {
const payment = await createPayment(params);
} catch (error) {
if (error.status === 400) {
// Invalid parameters - check amount, currency, customerReference
} else if (error.status === 401) {
// Authentication failed - check api-key and basic auth credentials
} else if (error.status === 402) {
// Payment declined by bank - inform customer
} else if (error.status === 429) {
// Rate limited - implement exponential backoff
await sleep(2000);
return retry(createPayment, params);
} else if (error.status >= 500) {
// Server error - retry with exponential backoff
return retryWithBackoff(createPayment, params);
}
}
/customers)Purpose: Manage customer accounts and payment methods for recurring/saved payments.
Key Endpoints:
POST /customers - Create customer accountGET /customers/{customerId} - Get customer detailsPUT /customers/{customerId} - Update customerDELETE /customers/{customerId} - Delete customerPOST /customers/{customerId}/payment-methods - Add payment methodGET /customers/{customerId}/payment-methods - List payment methodsUse Cases:
Example: Create Customer with Payment Method
const customer = await createCustomer({
environment: 'sandbox',
email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
phone: '+61412345678',
metadata: {
internalId: 'CUST-12345',
loyaltyTier: 'gold'
}
});
// Redirect to payment method capture flow
const setupIntent = await createPaymentMethodSetup({
customerId: customer.id,
returnUrl: 'https://yoursite.com/setup/complete'
});
console.log(`Setup URL: ${setupIntent.setupUrl}`);
/sessions)Purpose: Handle one-time payment sessions with tokenization.
Key Endpoints:
POST /sessions - Create payment sessionGET /sessions/{sessionId} - Retrieve sessionPOST /sessions/{sessionId}/complete - Complete sessionSession Lifecycle:
CREATE → ACTIVE → (customer interacts) → COMPLETE
↓
EXPIRED (30 min)
Use Cases:
Example: Session-Based Payment
const session = await createSession({
environment: 'sandbox',
amount: 2500,
currency: 'AUD',
expiresIn: 1800, // 30 minutes
metadata: {
cartId: 'CART-789',
items: ['item1', 'item2']
}
});
// Send session token to frontend
res.json({
sessionToken: session.token,
expiresAt: session.expiresAt
});
/preauths)Purpose: Hold funds for later capture (hotels, car rentals, deposits).
Key Endpoints:
POST /preauths - Create pre-authorizationGET /preauths/{preauthId} - Get pre-auth detailsPOST /preauths/{preauthId}/capture - Capture held fundsPOST /preauths/{preauthId}/void - Release holdHold Duration:
Use Cases:
Example: Hotel Pre-Auth Flow
// 1. Check-in: Create pre-auth
const preauth = await createPreAuth({
environment: 'sandbox',
amount: 20000, // Hold $200 for potential charges
currency: 'AUD',
customerReference: 'HOTEL-BOOKING-001',
description: '3-night hotel stay - security deposit',
holdUntil: addDays(new Date(), 4) // Hold until checkout + 1 day
});
// 2. During stay: Extend hold if needed
await extendPreAuth({
preauthId: preauth.id,
holdUntil: addDays(new Date(), 7)
});
// 3. Check-out: Capture actual charges
const capture = await capturePreAuth({
preauthId: preauth.id,
amount: 15000, // Capture $150 (room + minibar)
description: 'Final hotel charges'
});
// 4. Remaining $50 auto-released
/batch)Purpose: Process multiple payments in a single request (payroll, disbursements).
Key Endpoints:
POST /batch/payments - Create batchGET /batch/{batchId} - Get batch statusGET /batch/{batchId}/items - List batch itemsBatch Limits:
Use Cases:
Example: Batch Payroll
const batch = await createBatchPayments({
environment: 'sandbox',
description: 'Weekly payroll - Nov 15, 2024',
items: [
{
customerReference: 'EMP-001',
amount: 250000, // $2,500
currency: 'AUD',
description: 'Salary - John Doe',
metadata: { employeeId: 'EMP-001', period: '2024-11-01' }
},
{
customerReference: 'EMP-002',
amount: 280000, // $2,800
currency: 'AUD',
description: 'Salary - Jane Smith',
metadata: { employeeId: 'EMP-002', period: '2024-11-01' }
}
// ... up to 1000 items
]
});
// Poll for completion
let status = await getBatchStatus(batch.id);
while (status.state === 'processing') {
await sleep(5000);
status = await getBatchStatus(batch.id);
}
// Check results
console.log(`Successful: ${status.successCount}`);
console.log(`Failed: ${status.failureCount}`);
┌─────────────┐
│ Merchant │
└──────┬──────┘
│ 1. Create payment
▼
┌─────────────┐
│ TravelPay │
└──────┬──────┘
│ 2. Return payment URL
▼
┌─────────────┐
│ Customer │ 3. Redirect to payment page
└──────┬──────┘
│ 4. Enter card details
▼
┌─────────────┐
│ TravelPay │ 5. Process payment
└──────┬──────┘
│ 6. Send webhook (async)
▼
┌─────────────┐
│ Merchant │ 7. Verify & fulfill order
└─────────────┘
Implementation:
// Step 1: Create payment
const payment = await travelpay_create_payment({
environment: 'sandbox',
amount: 5000,
currency: 'AUD',
customerReference: uniqueOrderId(),
returnUrl: 'https://mystore.com/success',
webhookUrl: 'https://mystore.com/webhook'
});
// Step 2: Redirect customer
res.redirect(payment.paymentUrl);
// Step 7: Webhook handler (CRITICAL)
app.post('/webhook', async (req, res) => {
// Verify webhook signature (REQUIRED for security)
const signature = req.headers['x-travelpay-signature'];
if (!verifyWebhookSignature(req.body, signature)) {
return res.status(401).send('Invalid signature');
}
const event = req.body;
if (event.type === 'payment.succeeded') {
await fulfillOrder(event.data.paymentId);
} else if (event.type === 'payment.failed') {
await notifyCustomerFailure(event.data.paymentId);
}
res.status(200).send('OK');
});
1. Create customer account
2. Add payment method (customer enters card)
3. Schedule recurring charges
4. Process charges automatically
5. Handle failures and retries
Implementation:
// 1. Create customer
const customer = await createCustomer({
email: '[email protected]'
});
// 2. Setup payment method
const setup = await setupPaymentMethod({
customerId: customer.id,
returnUrl: 'https://mysite.com/setup-complete'
});
// User completes setup at setup.setupUrl
// 3. Schedule recurring (your system)
const subscription = await yourDb.createSubscription({
customerId: customer.id,
plan: 'monthly',
amount: 9900, // $99/month
startDate: new Date(),
billingDay: 1 // Bill on 1st of each month
});
// 4. Process charges (cron job)
cron.schedule('0 0 1 * *', async () => { // Run at midnight on 1st
const dueSubscriptions = await yourDb.getDueSubscriptions();
for (const sub of dueSubscriptions) {
try {
const payment = await createPayment({
customerId: sub.customerId,
amount: sub.amount,
currency: 'AUD',
customerReference: `SUB-${sub.id}-${Date.now()}`
});
await yourDb.recordPayment(sub.id, payment.id);
} catch (error) {
// 5. Handle failure
await handleSubscriptionFailure(sub, error);
}
}
});
download_specDownloads the latest TravelPay OpenAPI specification.
When to use:
Example:
User: "Download the latest TravelPay API spec"
→ Use download_spec tool
→ Confirm download location
→ Suggest next steps (validate, analyze, generate SDK)
analyze_specAnalyzes OpenAPI spec quality and identifies documentation issues.
Current Quality Metrics:
When to use:
Example:
User: "What's the quality of the payments documentation?"
→ Use analyze_spec with route='payments'
→ Show quality score and issues
→ Suggest using enhance_spec to fix
enhance_specAuto-improves OpenAPI documentation quality.
What it fixes:
Modes:
When to use:
Example:
User: "Improve the sessions documentation"
→ Use enhance_spec with route='sessions', apply=false (dry-run)
→ Show proposed changes
→ Ask for confirmation
→ Use enhance_spec with apply=true if approved
validate_specValidates OpenAPI spec against official schema (v3.1).
Checks:
When to use:
generate_sdkGenerates type-safe SDKs from OpenAPI spec.
Languages:
Generated artifacts:
When to use:
Example:
User: "Generate a TypeScript SDK"
→ Ensure spec is present
→ Use generate_sdk with language='typescript'
→ Explain generated structure
→ Provide usage examples
travelpay_create_paymentCreates a payment in TravelPay.
Default environment: sandbox (ALWAYS unless user specifies production)
Parameters:
Safety checks:
Example:
User: "Create a test payment for $25"
→ Use travelpay_create_payment with:
- environment: 'sandbox' (default)
- amount: 2500 (cents)
- currency: 'AUD' (or ask user)
- customerReference: generate unique ID
→ Show payment URL for customer
→ Explain next steps (customer pays, webhook fires)
travelpay_get_sessionRetrieves session details.
When to use:
import { PaymentsApi, Configuration } from './sdk/typescript';
const config = new Configuration({
basePath: 'https://api.sandbox.travelpay.com.au',
headers: {
'api-key': process.env.TRAVELPAY_SANDBOX_API_KEY!
},
username: process.env.TRAVELPAY_SANDBOX_USERNAME!,
password: process.env.TRAVELPAY_SANDBOX_PASSWORD!
});
const paymentsApi = new PaymentsApi(config);
async function createPayment() {
try {
const payment = await paymentsApi.createPayment({
amount: 5000,
currency: 'AUD',
customerReference: `ORD-${Date.now()}`
});
console.log(`Payment created: ${payment.id}`);
console.log(`Redirect to: ${payment.paymentUrl}`);
return payment;
} catch (error) {
console.error('Payment failed:', error);
throw error;
}
}
from openapi_client import ApiClient, Configuration
from openapi_client.api import payments_api
import os
config = Configuration(
host='https://api.sandbox.travelpay.com.au',
api_key={'api-key': os.getenv('TRAVELPAY_SANDBOX_API_KEY')},
username=os.getenv('TRAVELPAY_SANDBOX_USERNAME'),
password=os.getenv('TRAVELPAY_SANDBOX_PASSWORD')
)
with ApiClient(config) as api_client:
api = payments_api.PaymentsApi(api_client)
payment = api.create_payment({
'amount': 5000,
'currency': 'AUD',
'customerReference': f'ORD-{int(time.time())}'
})
print(f'Payment created: {payment.id}')
print(f'Redirect to: {payment.payment_url}')
#!/bin/bash
API_KEY="${TRAVELPAY_SANDBOX_API_KEY}"
USERNAME="${TRAVELPAY_SANDBOX_USERNAME}"
PASSWORD="${TRAVELPAY_SANDBOX_PASSWORD}"
curl -X POST https://api.sandbox.travelpay.com.au/payments \
-H "api-key: ${API_KEY}" \
-H "Content-Type: application/json" \
-u "${USERNAME}:${PASSWORD}" \
-d '{
"amount": 5000,
"currency": "AUD",
"customerReference": "ORD-'$(date +%s)'"
}'
const axios = require('axios');
async function createPayment() {
const response = await axios.post(
'https://api.sandbox.travelpay.com.au/payments',
{
amount: 5000,
currency: 'AUD',
customerReference: `ORD-${Date.now()}`
},
{
headers: {
'api-key': process.env.TRAVELPAY_SANDBOX_API_KEY,
'Content-Type': 'application/json'
},
auth: {
username: process.env.TRAVELPAY_SANDBOX_USERNAME,
password: process.env.TRAVELPAY_SANDBOX_PASSWORD
}
}
);
return response.data;
}
<?php
$apiKey = getenv('TRAVELPAY_SANDBOX_API_KEY');
$username = getenv('TRAVELPAY_SANDBOX_USERNAME');
$password = getenv('TRAVELPAY_SANDBOX_PASSWORD');
$ch = curl_init('https://api.sandbox.travelpay.com.au/payments');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'api-key: ' . $apiKey,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'amount' => 5000,
'currency' => 'AUD',
'customerReference' => 'ORD-' . time()
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$payment = json_decode($response, true);
echo "Payment created: " . $payment['id'] . "\n";
curl_close($ch);
?>
| Code | Meaning | Action |
|---|---|---|
| 200 | Success | Process response |
| 400 | Bad Request | Check parameters, fix and retry |
| 401 | Unauthorized | Verify api-key and basic auth credentials |
| 402 | Payment Declined | Inform customer, suggest retry |
| 404 | Not Found | Check resource ID |
| 429 | Rate Limited | Exponential backoff, retry |
| 500 | Server Error | Retry with backoff |
| 503 | Service Unavailable | Wait and retry |
async function retryWithBackoff<T>(
fn: () => Promise<T>,
maxRetries = 3
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;
const shouldRetry = error.status >= 500 || error.status === 429;
if (!shouldRetry) throw error;
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await sleep(delay);
}
}
throw new Error('Max retries exceeded');
}
When users ask questions:
This skill provides comprehensive TravelPay API expertise through:
Ready to help with ANY TravelPay API task!