Notifications

Once a webhook has been configured it will immediately begin to receive notifications. Notifications are sent for most events; each notification has a well defined format. Notifications are all sent in the HTTP body of the request.

Notification API documentation 

Notification Format

Each event contains a number of core properties:

Property Description Example
id ID of the notification NOT-3D46-E0EB-47E5-AC7A-10A53C03BF31
domain Resource upon which the event occurred Invoice
action Event which occurred on the resource Pending
destinationURL URL webhook is being sent to
entityID ID of the BillForward resource JSON-encoded value at time notification is created.
This JSON does not include any nested data.
entityID ID of the BillForward resource JSON-encoded value at time notification is created.
This JSON does not include any nested data.
changes The fields that changed on this objet JSON-encoded values at time notification is created.
totalSendAttempts Number of times the notification was sent
state State of notification

The event is uniquely identified by its domain/action pair.


Use case:

A notification is sent upon an invoice's being created in the pending state. You can listen for this notification, then apply business logic in response to it.

Example Notification

{
   "id" : "NOT-3D46-E0EB-47E5-AC7A-10A53C03BF31",
   "domain" : "Invoice",
   "action" : "Paid",
   "entityID" : "INV-6AE4-2256-4B7A-8C25-650048D15269",
   "destinationURL" : "https://app.acme.inc/handle/billforward/webhook",
   "format" : "JSON",
   "entity" : "{\"id\":\"INV-6AE4-2256-4B7A-8C25-650048D15269\", \"subscriptionID\":\"160EF8D8-916A-48C5-AB86-4726862CEE53\",\"state\":\"Paid\", ... }"
   "changes" : "{\"auditFieldChanges\":[{\"attributeName\":\"state\",\"previousValue\":\"Unpaid\",\"newValue\":\"Paid\"}]}",
   "totalSendAttempts" : 1, 
   "state" : "Sent"
}

For example: you could edit the invoice cost, then issue that invoice to the customer.


List of Events

New webhooks are constantly being added to the BillForward API. Because of this, any webhook handling code needs to be made robust, to handle unknown/new events.

Your webhook will automatically respond to state changes on resources. These include (but are not limited to) the following:

`
Domain Action Description  
Subscription Provisioned Subscription in this state has not been activated and no invoices will be raised.
Trial Subscription has entered a free trial period.  
AwaitingPayment Subscription has an issued invoice which has not been paid.  
Paid Subscription's outstanding invoices have all been paid.  
Cancelled Subscription was manually cancelled for example by a customer. The 'subscriptionEnd' property indicates the end time.
Expired Subscription has come a natural end. The 'subscriptionEnd' property indicates the end time. For example: end of a non-recurring subscription or fixed-term subscription.
Failed Subscription has failed to pay an invoice during the dunning period. The 'subscriptionEnd' property indicates the end time.
Invoice Pending Invoice has not been issued. The invoice can be re-generated and costs changed.
Unpaid Invoice has outstanding cost that has not been paid.  
Paid Invoice has been fully paid with no outstanding cost.  
PaymentFailed Invoice payment from gateway was attempted but failed.  
Voided Invoice has been voided, this usually occurs when re-calculating an invoice. As invoices are versioned, the old invoice is voided and the new invoice is issued in the desired state.
Receipt Accept The payment gateway allowed the payment request. Generally represents a successful payment
Reject The payment gateway declined the payment request. Generally represents a failed payment
Error An error occurred submitting payment request to the payment gateway. Refer to reasonCode, rawReasonCode and rawData for further information.
Unknown The current state of the payment is unknown. Refer to reasonCode, rawReasonCode and rawData for further information.
Refund AwaitingRefund Refund has been created but the payment gateway has not been contacted to perform the refund.
Refunded The payment gateway allowed the refund request. This means the payment was refunded.
Cancelled Refund was manually cancelled. For example: an account may cancel refund before execution.
Failed The payment gateway declined the refund request.  
FixedTerm NeedsAmendments Initial state of fixed term
Active Fixed term is currently running  
Expired The fixed term has ended  
SubscriptionCancellation Pending Subscription has not been cancelled yet
Completed Subscription has been cancelled  
Cancelled The subscription cancellation has been revoked and the subscription will no longer be cancelled  
PaymentMethod Expiring Card associated with payment method will expire in 1 months time.
Expired Card associated with payment method has expired.  

Other notification types

'Created' and 'Updated' notifications are issued for the following resources:

List of Notification Domains:

Account,
Address,
AdhocSubscription,
Alias,
Amendment,
AmendmentCompoundConstituent,
AmendmentPriceNTime,
APIConfiguration,
AuditLog,
Authority,
AuthorizeNetToken,
BalancedToken,
BraintreeToken,
Card,
Client,
CouponBook,
CouponBookDefinition,
CouponDefinition,
CouponInstance,
CouponInstanceExistingValue,
CouponModifier,
CouponRule,
CreditNote,
CybersourceToken,
DunningLine,
FixedTermDefinition,
FreePaymentReconciliation,
GatewayRevenue,
InvoiceLine,
InvoicePayment,
LocustworldPaymentReconciliation,
Migration,
Notification,
NotificationSnapshot,
Organization,
OrganizationGateway,
Password,
Payment,
PaymentMethod,
PaymentMethodSubscriptionLink,
PaypalSimplePaymentReconciliation,
PaypalToken,
PricingCalculation,
PricingComponent,
PricingComponentTier,
PricingComponentValue,
PricingComponentValueChange,
Product,
ProductRatePlan,
Profile,
Receipt,
Refund,
SearchResult,
StripeToken,
SubscriptionCharge,
TaxationLink,
TaxationStrategy,
TaxLine,
UnitOfMeasure,
Unknown
UsageRoundingStrategies,
User
Username,
Verification,
Webhook

Library Support for Webhook Notifications

SDK support is available for parsing incoming webhooks.

Java

String httpPostBody = ... // get from POST BODY of Notification

Notification notification = NotificationHelper.parse(httpPostBody.toString());

if(notification.getDomain() == NotificationDomain.Invoice &&
   notification.getAction() == NotificationAction.Pending) {
  InvoiceNotification invoiceNotification = (InvoiceNotification)notification;

  Invoice invoice = invoiceNotification.getInvoice();
  invoice.issue();
}

Worked Java Notification Handler Example

PHP

$entityBody = file_get_contents('php://input');
print_r($entityBody);

Ruby

// Dependent on library used. For example in a rails controller.
def receives_data
   log(request.body.read)
end