payment-webhooks

Payment Webhooks

Payment webhooks provide real-time notifications about payment events that occur between FarPay and payment service providers (card providers, MobilePay, NETS, etc.). These webhooks enable you to track payment status changes and respond immediately to payment events.

Overview

Payment webhooks are triggered by events in the FarPay core system and provide detailed information about:

  • Payment success or failure
  • Customer cancellations
  • Bank rejections and reimbursements
  • Refund processing
  • Payment method changes

Payment Events

EventValueDescription
Succeeded200Payment was successfully executed
Canceled210Customer has cancelled the payment
Failed220Payment failed (insufficient funds, expired card, etc.)
RejectedByCustomer230Customer rejected a scheduled payment (e.g., cancelled in online bank)
ReimbursedByBank240Financial institution cancelled the payment (insufficient funds, etc.)
Refunded245Payment was refunded (transaction rolled back)

Payment Types

TypeDescription
BSBetalingsservice (direct debit for private customers)
LSLeverandørservice (direct debit for businesses)
FIFI-Indbetalingskort (+71)
DanKortDankort (Danish debit card)
VisaVisa credit/debit card
MasterCardMasterCard credit/debit card
MobilePaySubscriptionsMobilePay Subscriptions (recurring payments)
MobilePayPaymentMobilePay ePayment (single payments)

Webhook Payload Structure

JSON Format (POST)

{
  "Type": "Payment",
  "Event": "Succeeded",
  "InvoiceNumber": "1234567BAVV",
  "CustomerNumber": "66776655",
  "PaymentDueDate": "2023-02-15",
  "Currency": "DKK",
  "InvoiceAmount": "1215.0000",
  "Amount": "1125.0000",
  "PaymentType": "LS",
  "PaymentReference": "ABC123-Reference",
  "AgreementId": "1234"
}

XML Format (POST)

<Payment>
  <Type>Payment</Type>
  <Event>Succeeded</Event>
  <InvoiceNumber>1234567BAVV</InvoiceNumber>
  <CustomerNumber>66776655</CustomerNumber>
  <PaymentDueDate>2023-02-15</PaymentDueDate>
  <Currency>DKK</Currency>
  <InvoiceAmount>1215.0000</InvoiceAmount>
  <Amount>1125.0000</Amount>
  <PaymentType>LS</PaymentType>
  <PaymentReference>ABC123-Reference</PaymentReference>
  <AgreementId>1234</AgreementId>
</Payment>

URL Parameters (GET)

https://yourdomain.com/webhook?Type=Payment&Event=Succeeded&PaymentReference=ABC123-Reference&InvoiceNumber=1234567BAVV&CustomerNumber=66776655&PaymentDueDate=2023-02-15&Currency=DKK&InvoiceAmount=1215.000&Amount=1215.000&PaymentType=LS

Payload Properties

PropertyTypeDescriptionFormat
TypestringAlways "Payment"Fixed value
EventstringPayment event typeSee Event table above
InvoiceNumberstringInvoice identifierAlphanumeric, max 15 chars
CustomerNumberstringCustomer identifierAlphanumeric, max 15 chars
PaymentDueDatestringPayment due dateYYYY-MM-DD
CurrencystringPayment currency"DKK", "EUR"
InvoiceAmountdecimalOriginal invoice amount4 decimal places
AmountdecimalActual payment amount4 decimal places
PaymentTypestringPayment method usedSee Payment Types table
PaymentReferencestringPayment referenceOptional
AgreementIdstringAssociated agreement IDOptional

Special Event Types

RejectedByCustomer (230)

Occurs when a customer rejects a scheduled payment through their online bank.

Payload Example

{
  "Type": "Payment",
  "Event": "RejectedByCustomer",
  "InvoiceNumber": "12345678abcnnn",
  "CustomerNumber": "abc123",
  "PaymentDueDate": "2023-07-01",
  "Currency": "DKK",
  "InvoiceAmount": "123.1234",
  "Amount": "123.1234",
  "PaymentType": "BS",
  "PaymentReference": "",
  "AgreementId": ""
}

Payment Type Behavior

TypeAmount BehaviorReason
BSAmount = 0Money not transferred from debtor account
BSAmount > 0Money transferred and will be returned to debtor
MobilePayAmount may differ from InvoiceAmountMobilePay provisioning differences

BS Rejection Examples

Before bank transfer:

{
  "Type": "Payment",
  "Event": "RejectedByCustomer",
  "InvoiceNumber": "234-cvcv-445673",
  "CustomerNumber": "123123123123",
  "PaymentDueDate": "2023-07-01",
  "Currency": "DKK",
  "InvoiceAmount": "750.9900",
  "Amount": "0.0000",
  "PaymentType": "BS",
  "PaymentReference": "",
  "AgreementId": ""
}

After bank transfer:

{
  "Type": "Payment",
  "Event": "RejectedByCustomer",
  "InvoiceNumber": "234-cvcv-445673",
  "CustomerNumber": "123123123123",
  "PaymentDueDate": "2023-07-01",
  "Currency": "DKK",
  "InvoiceAmount": "750.9900",
  "Amount": "750.9900",
  "PaymentType": "BS",
  "PaymentReference": "",
  "AgreementId": ""
}

ReimbursedByBank (240)

Occurs when a financial institution cancels a payment and transfers money back to the customer.

Payload Example

{
  "Type": "Payment",
  "Event": "ReimbursedByBank",
  "InvoiceNumber": "234-cvcv-445673",
  "CustomerNumber": "123123123123",
  "PaymentDueDate": "2023-07-01",
  "Currency": "DKK",
  "InvoiceAmount": "750.9900",
  "Amount": "750.9900",
  "PaymentType": "BS",
  "PaymentReference": "",
  "AgreementId": "12345"
}

Direct Debit Behavior

Payment TypeEventTransCodeDescription
BSReimbursedByBank239Bank initiated reimbursement
BSRejected237No amount available, payment cancelled
BSReimbursedByBank237 w. amountAmount implicated and transferred back
LSReimbursed555Bank initiated reimbursement
LSRejected530 w. amountCustomer initiated reimbursement

Best Practices

1. Event Handling

  • Handle all event types - Don't ignore events you don't expect
  • Log all events - Keep detailed logs for debugging and audit
  • Process asynchronously - Use queues for heavy processing
  • Implement idempotency - Handle duplicate webhooks gracefully

2. Data Validation

  • Validate required fields - Check all required properties
  • Verify data types - Ensure amounts are numeric, dates are valid
  • Check business logic - Validate amounts match expectations
  • Handle edge cases - Account for zero amounts, missing references

3. Error Handling

  • Always return 200 - Acknowledge webhook receipt
  • Log errors - Keep detailed error logs
  • Graceful degradation - Continue processing other events
  • Monitor failures - Set up alerts for processing errors

4. Security

  • Verify webhook origin - Use checksums when available
  • Validate data integrity - Check for tampering
  • Use HTTPS - Secure all webhook endpoints
  • Rate limiting - Prevent abuse of your endpoints

Testing

Test Scenarios

  1. Payment success - Verify correct processing of successful payments
  2. Payment failure - Test handling of failed payments
  3. Customer rejection - Test rejection scenarios
  4. Bank reimbursement - Test reimbursement handling
  5. Refund processing - Test refund event handling
  6. Invalid data - Test error handling with malformed data
  7. Duplicate webhooks - Test idempotency

Test Data Examples

// Successful payment
{
  "Type": "Payment",
  "Event": "Succeeded",
  "InvoiceNumber": "TEST-001",
  "CustomerNumber": "CUST-001",
  "PaymentDueDate": "2023-12-31",
  "Currency": "DKK",
  "InvoiceAmount": "100.0000",
  "Amount": "100.0000",
  "PaymentType": "Visa",
  "PaymentReference": "TEST-REF-001",
  "AgreementId": "AGREE-001"
}

// Failed payment
{
  "Type": "Payment",
  "Event": "Failed",
  "InvoiceNumber": "TEST-002",
  "CustomerNumber": "CUST-002",
  "PaymentDueDate": "2023-12-31",
  "Currency": "DKK",
  "InvoiceAmount": "200.0000",
  "Amount": "0.0000",
  "PaymentType": "Visa",
  "PaymentReference": "TEST-REF-002",
  "AgreementId": "AGREE-002"
}

Related Documentation