Instant Payments

Process immediate card payments when creating invoices using the schedulePayment=Instant parameter. This section covers instant payment behavior, requirements, and error handling.

Overview

Instant payments allow you to immediately charge a customer's card when creating an invoice, without waiting for manual payment processing. This is useful for immediate service activation or digital product delivery.

Terms and Definitions

TermDefinition
MerchantThe company that has access to FarPay
CustomerThe end user that pays the invoice (Debtor)
Card SubscriptionA card that is registered with the recurring option

Preconditions

For instant payment to work, the following conditions must be met:

Merchant Requirements

  • The merchant must have a card-creditor-agreement in FarPay
  • The agreement must be enabled to handle subscriptions

Customer Requirements

  • The customer must have an active card with recurring/subscription ability
  • The card must be attached in FarPay

Request Requirements

  • The request must include scheduledPayment = instant
  • The card subscription must be valid:
    • Preferably created with 3D-secure
    • Have sufficient funds
    • Not closed due to theft or other reasons

API Usage

Endpoint

POST https://api.farpay.io/v2/invoices?schedulePayment=Instant

Request Example

{
  "CustomerNumber": "12345",
  "InvoiceNumber": "INV-001",
  "Amount": 125.50,
  "Currency": "DKK",
  "DueDate": "2023-02-15",
  "Description": "Premium subscription",
  "EmailAddress": "[email protected]"
}

Response

The response will indicate whether the instant payment was successful or failed.

Error Codes

Instant Payment Specific Errors

Error CodeDefinitionCall to Action
10011Card expired, invoice is not receivedUpdate the card info. Note: This error code is only sent when schedulePayment is instant
10020Payment Rejected, invoice is archivedDue to GDPR, the reason for rejection is not clear. It can be due to card being locked or insufficient funds
10021Timeout, invoice is archivedThe processing did not occur in a timely manner. You are kindly asked to perform the action later (e.g., 10 minutes)

Standard Invoice Errors

In addition to instant payment specific errors, all standard invoice creation errors may also occur.

Error Details

Timeout (10021)

  • Timeout occurs when the time limit of approximately 20-30 seconds is exceeded
  • Subsequent actions are managed by FarPay, which cancels the reservation
  • Reservation cancellation occurs within a few minutes on the customer's bank account

Payment Rejected (10020)

A rejection occurs when the card is not eligible for instant capture of the given amount. Due to GDPR, FarPay is not informed about the specific details of why the card was rejected.

Common rejection reasons:

  • Locked card - Card has been blocked by the bank
  • Missing 3D-Secure authorization - SMS or NEM-ID authorization required
  • Insufficient funds - Card does not have enough available balance

Other technical errors require the debtor to contact their financial institution or bank for details. FarPay and the selected PSP do not have access to further error details.

Implementation Examples

JavaScript Example

async function createInstantPaymentInvoice(invoiceData) {
  try {
    const response = await fetch('https://api.farpay.io/v2/invoices?schedulePayment=Instant', {
      method: 'POST',
      headers: {
        'X-API-KEY': 'your-api-key',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(invoiceData)
    });

    if (response.ok) {
      const result = await response.json();
      console.log('Instant payment successful:', result);
      return result;
    } else {
      const error = await response.json();
      console.error('Instant payment failed:', error);
      
      // Handle specific error codes
      switch (error.errorCode) {
        case 10011:
          console.error('Card expired - update card information');
          break;
        case 10020:
          console.error('Payment rejected - check card status');
          break;
        case 10021:
          console.error('Timeout - try again later');
          break;
        default:
          console.error('Unknown error:', error);
      }
      
      throw new Error(`Instant payment failed: ${error.error}`);
    }
  } catch (error) {
    console.error('Request failed:', error);
    throw error;
  }
}

// Usage
const invoiceData = {
  CustomerNumber: "12345",
  InvoiceNumber: "INV-001",
  Amount: 125.50,
  Currency: "DKK",
  DueDate: "2023-02-15",
  Description: "Premium subscription",
  EmailAddress: "[email protected]"
};

createInstantPaymentInvoice(invoiceData)
  .then(result => {
    console.log('Invoice created with instant payment');
  })
  .catch(error => {
    console.error('Failed to create invoice:', error);
  });

Python Example

import requests
import json

def create_instant_payment_invoice(invoice_data, api_key):
    url = 'https://api.farpay.io/v2/invoices?schedulePayment=Instant'
    
    headers = {
        'X-API-KEY': api_key,
        'Content-Type': 'application/json'
    }
    
    try:
        response = requests.post(url, headers=headers, json=invoice_data)
        
        if response.status_code == 200:
            result = response.json()
            print('Instant payment successful:', result)
            return result
        else:
            error = response.json()
            print('Instant payment failed:', error)
            
            # Handle specific error codes
            error_code = error.get('errorCode')
            if error_code == 10011:
                print('Card expired - update card information')
            elif error_code == 10020:
                print('Payment rejected - check card status')
            elif error_code == 10021:
                print('Timeout - try again later')
            else:
                print('Unknown error:', error)
            
            raise Exception(f'Instant payment failed: {error.get("error")}')
            
    except requests.exceptions.RequestException as e:
        print('Request failed:', e)
        raise e

# Usage
invoice_data = {
    "CustomerNumber": "12345",
    "InvoiceNumber": "INV-001",
    "Amount": 125.50,
    "Currency": "DKK",
    "DueDate": "2023-02-15",
    "Description": "Premium subscription",
    "EmailAddress": "[email protected]"
}

try:
    result = create_instant_payment_invoice(invoice_data, 'your-api-key')
    print('Invoice created with instant payment')
except Exception as e:
    print('Failed to create invoice:', e)

Best Practices

Before Implementation

  1. Verify merchant agreement - Ensure card-creditor-agreement supports subscriptions
  2. Test customer cards - Verify customers have valid recurring cards
  3. Implement 3D-secure - Use 3D-secure for better authorization rates
  4. Handle errors gracefully - Implement proper error handling for all error codes

During Implementation

  1. Monitor timeouts - Implement retry logic for timeout errors
  2. Validate card status - Check card validity before attempting instant payment
  3. Provide user feedback - Give clear feedback about payment status
  4. Log all attempts - Keep detailed logs for troubleshooting

Error Handling

  1. Card expired (10011) - Prompt user to update card information
  2. Payment rejected (10020) - Suggest checking card status or trying different card
  3. Timeout (10021) - Implement retry mechanism with exponential backoff
  4. General errors - Provide fallback to manual payment option

Use Cases

Digital Product Activation

// Activate digital product immediately after payment
const activateProduct = async (customerId, productId) => {
  const invoiceData = {
    CustomerNumber: customerId,
    InvoiceNumber: `PROD-${productId}-${Date.now()}`,
    Amount: 99.00,
    Currency: "DKK",
    DueDate: new Date().toISOString().split('T')[0],
    Description: "Digital product activation",
    EmailAddress: customer.email
  };

  try {
    const result = await createInstantPaymentInvoice(invoiceData);
    if (result) {
      // Activate product immediately
      await activateDigitalProduct(customerId, productId);
      return { success: true, message: 'Product activated' };
    }
  } catch (error) {
    return { success: false, message: 'Payment failed - product not activated' };
  }
};

Service Subscription

// Start service subscription immediately
const startSubscription = async (customerId, serviceId) => {
  const invoiceData = {
    CustomerNumber: customerId,
    InvoiceNumber: `SUB-${serviceId}-${Date.now()}`,
    Amount: 199.00,
    Currency: "DKK",
    DueDate: new Date().toISOString().split('T')[0],
    Description: "Monthly service subscription",
    EmailAddress: customer.email
  };

  try {
    const result = await createInstantPaymentInvoice(invoiceData);
    if (result) {
      // Start subscription service immediately
      await startServiceSubscription(customerId, serviceId);
      return { success: true, message: 'Subscription started' };
    }
  } catch (error) {
    return { success: false, message: 'Payment failed - subscription not started' };
  }
};

Related Endpoints