Integration Examples
Complete integration examples and use case scenarios for the FarPay API. These examples demonstrate real-world implementations and best practices for common payment workflows.
Quick Start Examples
Basic API Setup
// Configure API client
const FARPAY_API_BASE = 'https://api.farpay.io/v2';
const API_KEY = 'your-api-key-here';
const farpayClient = {
async request(endpoint, options = {}) {
const url = `${FARPAY_API_BASE}${endpoint}`;
const response = await fetch(url, {
headers: {
'X-API-KEY': API_KEY,
'Accept': 'application/json',
'Content-Type': 'application/json',
...options.headers
},
...options
});
if (!response.ok) {
throw new Error(`API Error: ${response.status} ${response.statusText}`);
}
return response.json();
}
};Test API Connection
// Test your API connection
async function testConnection() {
try {
const customers = await farpayClient.request('/customers');
console.log('API connection successful!');
console.log(`Found ${customers.length} customers`);
} catch (error) {
console.error('API connection failed:', error.message);
}
}Customer Management Examples
Create Customer with Complete Information
async function createCustomer() {
const customerData = {
CustomerNumber: "CUST-001",
Name: "John Smith",
Email: "[email protected]",
Street: "Main Street 123",
City: "Copenhagen",
PostCode: "1000",
Country: "Denmark",
AttachPdfInvoice: false,
Language: "English"
};
try {
const customer = await farpayClient.request('/customers', {
method: 'POST',
body: JSON.stringify(customerData)
});
console.log('Customer created:', customer);
return customer;
} catch (error) {
console.error('Failed to create customer:', error);
}
}Update Customer Information
async function updateCustomer(customerNumber, updates) {
try {
const customer = await farpayClient.request(`/customers/${customerNumber}`, {
method: 'PUT',
body: JSON.stringify({
CustomerNumber: customerNumber,
...updates
})
});
console.log('Customer updated:', customer);
return customer;
} catch (error) {
console.error('Failed to update customer:', error);
}
}
// Usage
updateCustomer("CUST-001", {
Name: "John Smith Updated",
Email: "[email protected]",
City: "Aarhus"
});Send Agreement Invitation
async function sendAgreementInvitation(customerNumber, email, paymentType) {
try {
const response = await farpayClient.request(
`/customers/${customerNumber}/agreementRequest?type=${paymentType}&email=${email}`
);
console.log('Agreement invitation sent');
return response;
} catch (error) {
console.error('Failed to send invitation:', error);
}
}
// Send card agreement invitation
sendAgreementInvitation("CUST-001", "[email protected]", "card");Order and Payment Flow Examples
Create Payment Order
async function createPaymentOrder(customerData, paymentData) {
const orderData = {
ExternalID: `ORDER-${Date.now()}`,
AcceptUrl: "https://yourcompany.com/payment/success",
CancelUrl: "https://yourcompany.com/payment/cancel",
CallbackUrl: "https://yourcompany.com/payment/callback",
Lang: "da",
Agreement: 0, // No agreement required
Customer: customerData,
Payment: paymentData
};
try {
const order = await farpayClient.request('/orders', {
method: 'POST',
body: JSON.stringify(orderData)
});
console.log('Order created:', order);
console.log('Redirect customer to:', order.UserInputUrl);
return order;
} catch (error) {
console.error('Failed to create order:', error);
}
}
// Usage
const customer = {
CustomerNumber: "CUST-001",
CustomerName: "John Smith",
CustomerEmail: "[email protected]"
};
const payment = {
Amount: 99.95,
Currency: "DKK",
Description: "Monthly subscription",
Reference: "SUB-001"
};
createPaymentOrder(customer, payment);Create Order with Agreement
async function createAgreementOrder(customerData) {
const orderData = {
ExternalID: `AGREEMENT-${Date.now()}`,
AcceptUrl: "https://yourcompany.com/agreement/success",
CancelUrl: "https://yourcompany.com/agreement/cancel",
CallbackUrl: "https://yourcompany.com/agreement/callback",
Lang: "da",
Agreement: 1, // Agreement required
PaymentTypes: "card,mp", // Only cards and MobilePay
Customer: customerData
};
try {
const order = await farpayClient.request('/orders', {
method: 'POST',
body: JSON.stringify(orderData)
});
console.log('Agreement order created:', order);
return order;
} catch (error) {
console.error('Failed to create agreement order:', error);
}
}Monitor Order Status
async function monitorOrder(token) {
try {
const order = await farpayClient.request(`/orders/${token}`);
switch (order.Status) {
case "New":
console.log("Order created, waiting for customer action");
break;
case "PendingPayment":
console.log("Payment received, processing...");
break;
case "Ok":
console.log("Order completed successfully");
break;
case "Error":
console.log("Order failed:", order.ErrorDescription);
break;
case "Canceled":
console.log("Order was canceled");
break;
default:
console.log("Order status:", order.Status);
}
return order;
} catch (error) {
console.error('Failed to get order status:', error);
}
}Invoice Management Examples
Create Invoice
async function createInvoice(customerNumber, invoiceData) {
const invoice = {
CustomerNumber: customerNumber,
InvoiceNumber: invoiceData.invoiceNumber,
PaymentDueDate: invoiceData.dueDate,
PaymentType: "MobilePayInvoice",
InvoiceLines: invoiceData.lines
};
try {
const result = await farpayClient.request('/invoices', {
method: 'POST',
body: JSON.stringify(invoice)
});
console.log('Invoice created:', result);
return result;
} catch (error) {
console.error('Failed to create invoice:', error);
}
}
// Usage
const invoiceData = {
invoiceNumber: "INV-001",
dueDate: "2023-02-15",
lines: [
{
Description: "Basic subscription",
Quantity: 1,
UnitPrice: 99.00,
TotalPrice: 99.00
},
{
Description: "Premium add-on",
Quantity: 1,
UnitPrice: 26.00,
TotalPrice: 26.00
}
]
};
createInvoice("CUST-001", invoiceData);Get Invoices with Filtering
async function getInvoices(filters = {}) {
const params = new URLSearchParams();
if (filters.fromDueDate) params.append('fromDueDate', filters.fromDueDate);
if (filters.toDueDate) params.append('toDueDate', filters.toDueDate);
if (filters.paymentStatus) params.append('paymentStatus', filters.paymentStatus);
const queryString = params.toString();
const endpoint = queryString ? `/invoices?${queryString}` : '/invoices';
try {
const invoices = await farpayClient.request(endpoint);
console.log(`Found ${invoices.length} invoices`);
return invoices;
} catch (error) {
console.error('Failed to get invoices:', error);
}
}
// Get unpaid invoices from last month
const lastMonth = new Date();
lastMonth.setMonth(lastMonth.getMonth() - 1);
getInvoices({
fromDueDate: lastMonth.toISOString().split('T')[0],
paymentStatus: 100 // Not Paid
});Payment Tracking Examples
Get Payment History
async function getPaymentHistory(filters = {}) {
const params = new URLSearchParams();
if (filters.paymentDateFrom) params.append('paymentDateFrom', filters.paymentDateFrom);
if (filters.paymentDateTo) params.append('paymentDateTo', filters.paymentDateTo);
if (filters.invoiceID) params.append('invoiceID', filters.invoiceID);
const queryString = params.toString();
const endpoint = queryString ? `/payments?${queryString}` : '/payments';
try {
const payments = await farpayClient.request(endpoint);
console.log(`Found ${payments.length} payments`);
return payments;
} catch (error) {
console.error('Failed to get payments:', error);
}
}
// Get payments from last 30 days
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
getPaymentHistory({
paymentDateFrom: thirtyDaysAgo.toISOString().split('T')[0]
});Process Refund
async function processRefund(paymentId, amount) {
// Convert amount to minor units (cents)
const minorUnits = Math.round(amount * 100);
try {
const refund = await farpayClient.request(`/payments/${paymentId}/refund/${minorUnits}`, {
method: 'POST'
});
console.log('Refund processed:', refund);
return refund;
} catch (error) {
console.error('Failed to process refund:', error);
}
}
// Refund 50 DKK
processRefund(456, 50.00);Agreement Management Examples
Create Bank Agreement
async function createBankAgreement(customerNumber, bankData, agreementType) {
const agreement = {
BankRegNumber: bankData.regNumber,
BankAccountNumber: bankData.accountNumber,
Type: agreementType, // "BS" or "LS"
CustomerNumber: customerNumber,
PayerID: bankData.payerId
};
try {
const result = await farpayClient.request('/agreements', {
method: 'POST',
body: JSON.stringify(agreement)
});
console.log('Agreement created:', result);
return result;
} catch (error) {
console.error('Failed to create agreement:', error);
}
}
// Create Betalingsservice agreement
const bankData = {
regNumber: "1234",
accountNumber: "12345678",
payerId: "1234567890" // CPR number
};
createBankAgreement("CUST-001", bankData, "BS");Monitor Agreement Status
async function monitorAgreements() {
try {
const agreements = await farpayClient.request('/agreements');
const statusCounts = {
Pending: 0,
Ok: 0,
Cancel: 0,
Error: 0
};
agreements.forEach(agreement => {
statusCounts[agreement.Status]++;
});
console.log('Agreement status summary:', statusCounts);
// Check for pending agreements
const pendingAgreements = agreements.filter(a => a.Status === 'Pending');
if (pendingAgreements.length > 0) {
console.log('Pending agreements:', pendingAgreements);
}
return agreements;
} catch (error) {
console.error('Failed to get agreements:', error);
}
}File Upload Examples
Upload Invoice File
async function uploadInvoiceFile(filename, fileContent) {
// Convert file to base64
const base64Data = Buffer.from(fileContent).toString('base64');
const delivery = {
DeliveryType: "TransmissionReceipt",
File: {
Filename: filename,
Data: base64Data
}
};
try {
const result = await farpayClient.request('/deliveries', {
method: 'POST',
body: JSON.stringify(delivery)
});
console.log('File uploaded:', result);
return result;
} catch (error) {
console.error('Failed to upload file:', error);
}
}
// Usage with file system
const fs = require('fs');
const fileContent = fs.readFileSync('invoices.xml');
uploadInvoiceFile('invoices.xml', fileContent);Monitor File Processing
async function monitorFileProcessing(deliveryId) {
try {
const delivery = await farpayClient.request(`/deliveries/${deliveryId}`);
switch (delivery.DeliveryStatus) {
case "New":
console.log("File uploaded, awaiting processing");
break;
case "Processing":
console.log("File is being processed");
break;
case "Ok":
console.log("File processed successfully");
break;
case "Error":
console.log("Processing failed:", delivery.ErrorMessage);
break;
}
return delivery;
} catch (error) {
console.error('Failed to get delivery status:', error);
}
}Complete Integration Example
Subscription Management System
class SubscriptionManager {
constructor() {
this.apiClient = farpayClient;
}
async createSubscription(customerData, planData) {
// 1. Create or update customer
let customer = await this.ensureCustomer(customerData);
// 2. Create agreement order
const order = await this.createAgreementOrder(customer);
// 3. Create initial invoice
const invoice = await this.createInvoice(customer.CustomerNumber, {
invoiceNumber: `INV-${Date.now()}`,
dueDate: this.getNextMonthDate(),
lines: [{
Description: planData.name,
Quantity: 1,
UnitPrice: planData.price,
TotalPrice: planData.price
}]
});
return { customer, order, invoice };
}
async ensureCustomer(customerData) {
try {
// Try to get existing customer
const customer = await this.apiClient.request(`/customers/${customerData.CustomerNumber}`);
return customer;
} catch (error) {
// Customer doesn't exist, create new one
return await this.apiClient.request('/customers', {
method: 'POST',
body: JSON.stringify(customerData)
});
}
}
async createAgreementOrder(customer) {
const orderData = {
ExternalID: `AGREEMENT-${Date.now()}`,
AcceptUrl: "https://yourcompany.com/subscription/success",
CancelUrl: "https://yourcompany.com/subscription/cancel",
CallbackUrl: "https://yourcompany.com/subscription/callback",
Lang: "da",
Agreement: 1,
PaymentTypes: "card,mp,bs",
Customer: {
CustomerNumber: customer.CustomerNumber,
CustomerName: customer.Name,
CustomerEmail: customer.Email
}
};
return await this.apiClient.request('/orders', {
method: 'POST',
body: JSON.stringify(orderData)
});
}
async createInvoice(customerNumber, invoiceData) {
const invoice = {
CustomerNumber: customerNumber,
InvoiceNumber: invoiceData.invoiceNumber,
PaymentDueDate: invoiceData.dueDate,
PaymentType: "MobilePayInvoice",
InvoiceLines: invoiceData.lines
};
return await this.apiClient.request('/invoices', {
method: 'POST',
body: JSON.stringify(invoice)
});
}
getNextMonthDate() {
const date = new Date();
date.setMonth(date.getMonth() + 1);
return date.toISOString().split('T')[0];
}
async monitorSubscription(customerNumber) {
// Get customer with agreements
const customer = await this.apiClient.request(`/customers/${customerNumber}`);
// Get recent invoices
const invoices = await this.apiClient.request(`/invoices?fromDueDate=${this.getLastMonthDate()}`);
// Get recent payments
const payments = await this.apiClient.request(`/payments?paymentDateFrom=${this.getLastMonthDate()}`);
return {
customer,
agreements: customer.Agreements || [],
invoices: invoices.filter(inv => inv.CustomerNumber === customerNumber),
payments: payments.filter(pay => pay.CustomerNumber === customerNumber)
};
}
getLastMonthDate() {
const date = new Date();
date.setMonth(date.getMonth() - 1);
return date.toISOString().split('T')[0];
}
}
// Usage
const subscriptionManager = new SubscriptionManager();
const customerData = {
CustomerNumber: "CUST-001",
Name: "John Smith",
Email: "[email protected]",
Street: "Main Street 123",
City: "Copenhagen",
PostCode: "1000",
Country: "Denmark"
};
const planData = {
name: "Premium Subscription",
price: 99.95
};
subscriptionManager.createSubscription(customerData, planData)
.then(result => {
console.log('Subscription created:', result);
})
.catch(error => {
console.error('Failed to create subscription:', error);
});Error Handling Best Practices
Comprehensive Error Handler
class FarPayError extends Error {
constructor(message, statusCode, details) {
super(message);
this.name = 'FarPayError';
this.statusCode = statusCode;
this.details = details;
}
}
async function handleApiRequest(requestFn) {
try {
return await requestFn();
} catch (error) {
if (error.name === 'FarPayError') {
// Handle known API errors
switch (error.statusCode) {
case 401:
console.error('Authentication failed. Check your API key.');
break;
case 404:
console.error('Resource not found:', error.details);
break;
case 400:
console.error('Bad request:', error.details);
break;
default:
console.error('API error:', error.message);
}
} else {
// Handle network or other errors
console.error('Request failed:', error.message);
}
throw error;
}
}
// Usage
handleApiRequest(() => farpayClient.request('/customers'))
.then(customers => {
console.log('Success:', customers);
})
.catch(error => {
// Error already handled above
});Testing Examples
Unit Tests
// Using Jest for testing
describe('FarPay API Integration', () => {
test('should create customer successfully', async () => {
const customerData = {
CustomerNumber: "TEST-001",
Name: "Test Customer",
Email: "[email protected]"
};
const customer = await farpayClient.request('/customers', {
method: 'POST',
body: JSON.stringify(customerData)
});
expect(customer.CustomerNumber).toBe("TEST-001");
expect(customer.Name).toBe("Test Customer");
});
test('should handle duplicate customer error', async () => {
const customerData = {
CustomerNumber: "TEST-001",
Name: "Test Customer",
Email: "[email protected]"
};
await expect(
farpayClient.request('/customers', {
method: 'POST',
body: JSON.stringify(customerData)
})
).rejects.toThrow();
});
});Related Resources
- Authentication - API setup and authentication
- Customers - Customer management
- Orders - Payment flows and orders
- Invoices - Invoice management
- Payments - Payment tracking and refunds
- Agreements - Payment agreements
- Deliveries - File uploads and batch processing