Invoice Ready Webhook

Amberflo.io integrates with Stripe and AWS Marketplace for automatically settling invoices, but you are not limited to these payment providers.

If you have your own payment system or use a different service, you can set up a webhook to be notified of new invoices that are ready to be paid and improve your payment automation.

Invoice Ready Webhook

A webhook is an HTTP POST request that we make to an endpoint you control, with some specific payload.

Every time a new invoice is ready to be paid, Amberflo publishes the ready-product-invoices event. In order to receive the webhook request, you'll need to subscribe to it.

You can do so by making a POST request to the Webhook API. Here is an example:

curl --request POST \
     --url https://app.amberflo.io/webhook \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --header 'x-api-key: <your-amberflo-api-key>' \
     --data '
{
     "authHeader": [
          "X-Auth",
          "g5DC1BDw5BjXDT0RrDhVDqLMuy39fQAI"
     ],
     "topic": "ready-product-invoices",
     "destinationUrl": "https://example.com/webhook-endpoint/"
}
'

Notice the authHeader parameter. This header will be added to the webhook request in order to allow your endpoint to authenticate it.

Now, whenever there is a new invoice ready to be paid, you'll get a POST request (like the one below) on your endpoint.

Sample Webhook Request

This is what a webhook request to your endpoint will look like:

POST https://example.com/webhook-endpoint/
content-type: application/json
user-agent: Amberflo.io Webhook Service
x-auth: g5DC1BDw5BjXDT0RrDhVDqLMuy39fQAI
{
    "topic": "ready-product-invoices",
    "eventTime": 1659711395409,
    "eventId": "1bf92cf0-1d99-11ed-90a2-4fb51c754f3b",
    "data": {
        "invoiceUri": "payments/invoices/account_id=3/customer_id=eda5be25-f145-4448-b85c-6dc6dce1a2ac/product_id=1/product_plan_id=2b08a8f9-f70e-40e2-b595-06b6483c5d91/year=2022/month=02/day=06",
        "invoiceKey": {
            "accountId": "3",
            "customerId": "eda5be25-f145-4448-b85c-6dc6dce1a2ac",
            "productId": "1",
            "productPlanId": "2b08a8f9-f70e-40e2-b595-06b6483c5d91",
            "year": 2022,
            "month": 2,
            "day": 6
        },
        "planBillingPeriod": { "interval": "month", "intervalsCount": 3 },
        "planName": "Starter Plan",
        "invoiceStartTimeInSeconds": 1644105600,
        "invoiceEndTimeInSeconds": 1651795200,
        "gracePeriodInHours": 24,
        "productItemInvoices": [
            {
                "key": {
                    "accountId": "3",
                    "customerId": "eda5be25-f145-4448-b85c-6dc6dce1a2ac",
                    "productId": "1",
                    "productPlanId": "2b08a8f9-f70e-40e2-b595-06b6483c5d91",
                    "year": 2022,
                    "month": 2,
                    "day": 6,
                    "productItemKey": "6c1b443e-8b0a-4182-a640-caeb598eb0a5"
                },
                "productItemId": "6c1b443e-8b0a-4182-a640-caeb598eb0a5",
                "productItemName": "postman calls",
                "meterApiName": "ApiCalls-From-Postman",
                "productPlanName": "Starter Plan",
                "productItemVariants": [
                    {
                        "key": "",
                        "itemDimensions": {},
                        "hourlyBillInfos": null,
                        "totalBill": {
                            "priceInCredits": null,
                            "priceInBaseCurrency": 41010309,
                            "startTimeInSeconds": 1644105600,
                            "endTimeInSeconds": 1651795200,
                            "meterUnits": 41010420,
                            "price": 41010309,
                            "meteredUnitsPerTier": { "0": 111, "1": 41010309 }
                        },
                        "lateArrivalMeters": 0
                    }
                ],
                "totalBill": {
                    "priceInCredits": null,
                    "priceInBaseCurrency": 41010309,
                    "startTimeInSeconds": 1644105600,
                    "endTimeInSeconds": null,
                    "meterUnits": 41010420,
                    "price": 41010309,
                    "meteredUnitsPerTier": null
                }
            }
        ],
        "appliedPromotions": [],
        "productPlanFees": [
            {
                "costInCredits": null,
                "costInBaseCurrency": 200,
                "id": "fee_2",
                "name": "Recurring Rate",
                "description": "recurring fee",
                "cost": 200,
                "isOneTimeFee": false,
                "isProrated": false,
                "prorateToDay": false,
                "discountable": false,
                "prepayable": false
            }
        ],
        "totalBill": {
            "itemPrice": 41010309,
            "fixPrice": 200,
            "prepaid": 0,
            "totalDiscount": 0,
            "totalPriceBeforeDiscount": 41010509,
            "totalPriceBeforePrepaid": 41010509,
            "discountableFixPrice": 0,
            "discountableBasePrice": 41010309,
            "prepaidableFixPrice": 0,
            "prepayableNotDiscountableFees": 0,
            "totalPrepayablePrice": 41010309,
            "startTimeInSeconds": 1644105600,
            "endTimeInSeconds": 1651795200,
            "totalPrice": 41010509
        },
        "invoicePriceStatus": "price_locked",
        "creditUnit": null,
        "paymentStatus": "pre_payment",
        "paymentCreatedInSeconds": null,
        "externalSystemStatus": null,
        "invoiceBillInBaseCurrency": {
            "itemPrice": 41010309,
            "fixPrice": 200,
            "prepaid": 0,
            "totalDiscount": 0,
            "totalPriceBeforeDiscount": 41010509,
            "totalPriceBeforePrepaid": 41010509,
            "discountableFixPrice": 0,
            "discountableBasePrice": 41010309,
            "prepaidableFixPrice": 0,
            "prepayableNotDiscountableFees": 0,
            "totalPrepayablePrice": 41010309,
            "startTimeInSeconds": 1644105600,
            "endTimeInSeconds": 1651795200,
            "totalPrice": 41010509
        },
        "invoiceBillInCredits": null,
        "availablePrepaidLeft": 0,
        "availablePrepaidLeftBaseCurrency": 0,
        "availablePrepaidLeftInCredits": null,
        "availablePayAsYouGoMoney": 0,
        "availablePayAsYouGoMoneyInBaseCurrency": 0,
        "availablePayAsYouGoMoneyInCredits": null,
        "paymentCurrencyInfo": null,
        "paymentMethod": null
    }
}

Note that the content of data is the same that is returned by the Customer Invoice API, so you can always call it to verify the invoice status.

Endpoint Requirements

Amberflo's webhook system expects the endpoint to return a status code 200 upon success. Any other status code will be considered a failure.

The webhook system will retry a few times to send the request whenever there is a failure. For this reason, it is important that the endpoint be idempotent, as the same event may hit it multiple times. For the case of invoices, you can use the invoiceUri as idempotence key.

Because there is a limited number of attempts to send the webhook, your system should have a fallback mechanism to ensure the invoices get settled. You can achieve this by periodically checking the Customer Invoice API and the Account Event API. The first lets you list all invoices for a given customer, while the later lets you check if there have been failed attempts to send the webhook.