Webhooks

Webhooks call a certain website that you register within Áskell when certain events happen. Events that can be registered before:

State identifier

Description

subscription.*

All events that are connected to subscriptions

subscription.created

Subscription created

subscription.changed

Subscription changed

subscription.renewed

Subscription renewed

subscription_contract.*

Allir atburðir sem tengjast samningsáskriftum

subscription_contract.created

Samningsáskrift stofnuð

subscription_contract.changed

Samningsáskrift breytt

subscription_contract.renewed

Samningsáskrift endurnýjuð

billing_run.*

Allir atburðir sem tengjast keyrslum reikningagerðar

billing_run.created

Keyrsla reikningagerðar stofnuð

billing_run.changed

Keyrsla reikningagerðar breytt

billing_run.succeeded

Keyrsla reikningagerðar tókst

billing_run.failed

Keyrsla reikningagerðar mistókst endanlega

billing_run.retry

Fyrirhugað að reyna aftur keyrslu reikningagerðar

customer.*

All events that are connected to customers

customer.created

Customer created

customer.changed

Customer changed

payment.*

All events that are connected to individual payments

payment.created

Individual payment created

payment.changed

Individual payment changed (f.ex. transaction is successful or non successful)

payment.retry

Retry pending for an individual payment

checkout.*

All events that are connected to checkouts

checkout.created

Checkout created

checkout.changed

Checkout changed

Identification

Við mælum með því að allir vefkrókar séu auðkenndir. Við undirritum hvert kall með haus (e. header) sem heitir Hook-HMAC. Gildið er HMAC hakkaður strengur byggður á innihaldi vefkallsins og svo leynilegu gildi sem er aðeins þekkt af okkur og þér. Þú færð þetta leynilega gildi í hendurnar þegar þú stofnar nýjan vefkrók. Tegund atburðar kemur einnig fram í hausnum Hook-Event. Útgáfa API gagna kemur fram í hausnum Hook-API-Version. Eldri plan/áskriftar vefkrókar senda v1, en nýja samningsáskriftarkerfið sendir v2.

Here is a Python example. The process is very similar to what Shopify uses and you can find more code examples in their documentation here.

  • python
  • ruby
  • php
import base64
import hmac
import hashlib

WEBHOOK_SECRET = "Your webhook secret".encode()
WEBHOOK_DIGEST_TYPE = 'sha512'

def verify(hmac_header, digest_method, secret, message):
    digestmod = getattr(hashlib, digest_method)
    signed = base64.b64encode(
        hmac.new(secret, message, digestmod).digest(),
    ).strip()
    return hmac.compare_digest(signed, hmac_header)

# your view function
def handle_webhook(request):
    # The signature
    digest = request.META.get('HTTP_HOOK_HMAC').encode()
    # The name of the webhook event
    event = request.META.get('HTTP_HOOK_EVENT').encode()

    body = request.body
    if verify(digest, WEBHOOK_DIGEST_TYPE, WEBHOOK_SECRET, body):
        payload = json.loads(body)
        # ... the rest of your code here```
require 'rubygems'
require 'base64'
require 'openssl'
require 'sinatra'

WEBHOOK_SECRET = 'Your webhook secret'
WEBHOOK_DIGEST_TYPE = 'sha512'

helpers do
    def verify_webhook(secret, data, hmac_header)
        digested = ::OpenSSL::HMAC.digest(WEBHOOK_DIGEST_TYPE, secret, data)
        calculated_hmac = Base64.encode64(digested).strip
        return calculated_hmac == hmac_header
    end
end

post '/' do
    request.body.rewind
    data = request.body.read
    if verify_webhook(WEBHOOK_SECRET, env["HTTP_HOOK_HMAC"])
        # deserialize data' using json and process webhook
    end
end
<?php

define('WEBHOOK_SECRET', 'Your webhook secret')
define('WEBHOOK_DIGEST_TYPE', 'sha512')

function verify_webhook($data, $hmac_header)
{
    $calculated_hmac = base64_encode(hash_hmac(WEBHOOK_DIGEST_TYPE, $data,
        WEBHOOK_SECRET, true));
    return ($hmac_header == $calculated_hmac);
}

$hmac_header = $_SERVER['HTTP_HOOK_HMAC'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header);

?>

Data in webhooks

Subscriptions (subscription.*)

When a subscription is created, updated or renewed the following events are sent. Here is an example of data that comes with a subscription event:

{
    "id": 12345,
    "plan": {
        "id": 12345,
        "name": "Titill",
        "alternative_name": "Annar titill",
        "reference": "",
        "interval": "month",
        "interval_count": 1,
        "amount": "1.0000",
        "currency": "ISK",
        "trial_period_days": 5,
        "enabled": true,
        "private": false,
        "electronic_only": true,
        "description": "Some description"
    },
    "customer": 12345,
    "customer_reference": "customer-12345",
    "trial_end": "2024-01-01T00:00:00Z",
    "start_date": "2024-01-01T00:00:00Z",
    "ended_at": null,
    "reference": "reference-12345",
    "active": true,
    "meta": "{}",
    "description": "Some subscription description",
    "active_until": "2024-02-01T00:00:00Z",
    "is_on_trial": false,
    "token": "md5sumtokenwith32chars",
    "is_failing": false,
    "last_billing_log": {
        "id": 12345,
        "billing_log_type": "renewal",
        "billing_date": "2024-01-01T00:00:00Z",
        "plan_billed_up_to": "2024-02-01T00:00:00Z",
        "total": null,
        "transaction": {
        "external_reference": null,
        "data": {},
        "state": "settled",
        "uuid": "some-guid-with-numbers-and-letters",
        "fail_code": null,
        "refund_code": null,
        "cancel_code": null,
        "amount": "1.00",
        "currency": "ISK",
        "payment_method": null,
        "created_at": "2024-01-01T00:00:00Z"
        }
    },
    "delivery_address": null,
    "amount": "1.0000"
    }

Samningsáskriftir (subscription_contract.*)

Þegar samningsáskrift er búin til, uppfærist eða endurnýjast eru sendir viðeigandi atburðir. Hér er dæmi um gögn sem koma með atburði um samningsáskrift:

{
    "id": 12345,
    "customer": 33482,
    "state": "active",
    "billing_anchor_at": "2024-01-01T00:00:00Z",
    "next_billing_at": "2024-02-01T00:00:00Z",
    "cancel_at": null,
    "cancel_at_period_end": false,
    "canceled_at": null,
    "ended_at": null,
    "currency": "ISK",
    "recurring": true,
    "legacy_subscription": null,
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-01T00:00:00Z"
}

Keyrslur reikningagerðar (billing_run.*)

Þegar keyrsla reikningagerðar er stofnuð, breytist, tekst, mistekst eða er sett í endurtekningu eru sendir viðeigandi atburðir. Hér er dæmi um gögn sem koma með atburði um keyrslu reikningagerðar:

{
    "id": 12345,
    "contract": 12345,
    "period_start_at": "2024-01-01T00:00:00Z",
    "period_end_at": "2024-02-01T00:00:00Z",
    "state": "succeeded",
    "currency": "ISK",
    "subtotal_amount": "1000.0000",
    "tax_amount": "0.0000",
    "total_amount": "1000.0000",
    "attempt_count": 1,
    "max_attempts": 4,
    "next_retry_at": null,
    "last_attempt_at": "2024-01-01T00:00:00Z",
    "transaction": 54321,
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-01T00:00:00Z"
}

Customer (customer.*)

When a customer is created or updated the following events are sent. Here is an example of data that comes with a customer event:

{
    "id": 33482,
    "first_name": "",
    "last_name": "",
    "delivery_name": "",
    "address_1": "",
    "address_2": "",
    "address_3": "",
    "zip_code": "",
    "city": "",
    "country": "",
    "email": null,
    "customer_reference": "0208912039",
    "payment_method": [],
    "address": null
}

Individual payment (payment.*)

When an individual payment is created, changed or retired the following events are sent. Here is an example of data that comes with a individual payment event:

{
    "uuid": "some-guid-with-numbers-and-letters",
    "amount": "1.0000",
    "currency": "ISK",
    "description": "Description here",
    "reference": "some-reference",
    "state": "settled",
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-01T00:00:00Z",
    "transactions": [
        {
            "external_reference": "410009982476",
            "data": {
                "id": "4100000000",
                "receipt": {}, // receipt contains vendor specific fields, not listed here
                "status": "settled"
            },
            "state": "settled",
            "uuid": "some-guid-with-numbers-and-letters",
            "fail_code": null,
            "refund_code": null,
            "cancel_code": null,
            "amount": "1.00",
            "currency": "ISK",
            "payment_method": {
                "verified": true,
                "canceled": false,
                "valid_until": "2025-03-01T00:00:00Z",
                "display_info": "XXXX-XXXX-XXXX-4324 (Visa)",
                "credit_card": true
            },
            "created_at": "2024-01-01T00:00:00Z"
        }
    ]
}

Checkout (checkout.*)

When a checkout is created or changed:

{
    "token": "3a44383eb19dc9183be4df5ad655094c88159af4",
    "checkout_url": "http://askell.is/checkout/3a44383eb19dc9183be4df5ad655094c88159af4/",
    "status": "tokencreated"
}