# Webhooks

# Overview

The purpose of webhooks are to provide more realtime updates versus performing query requests. Currently webhooks can be triggered as transactions are processed within the gateway platform.

# How to enable

Webhooks can be enabled within the merchant control panel under "Manage" -> "Settings" -> "Webhooks".

# Security

Webhook post requests are sent with a header "Signature" that is HMAC SHA 256 signed and then base64 url encoded.

To verify webhook post signatures, retrieve "Signature" from header. Base64 url decode and use HMAC SHA 256 to check using your signature UUID located in the control panel under the webhook previously created.

    # Acknowledge and Retry

    Webhook notifications are processed within a few seconds of a transaction being processed as long as the response code is within the Approved or Declined range. Webhooks have a 5 second timeout and should be acknowledged with a HTTP 200 response. If a webhook is not acknowledged it will be rescheduled using a 5 minute exponential backoff and will be retried for 24 hours.

    # Core Webhook Response Format

    {
        "transaction_id": "", 
        "account_type": "merchant",
        "account_type_id": "testmerchant12345678",
        "action_at": "2020-10-08T18:45:39.053107-05:00",
        "data": {},
        "msg": "success",
        "status": "success",
        "type": "transaction"
    }
    

    # Example Automatic Account Updater Webhook

    {
        "account_type": "merchant",
        "account_type_id": "testmerchant12345678",
        "transaction_id": "", 
        "action_at": "2020-10-08T18:45:39.053107-05:00",
        "data": {
            "card_id": "btvq916vvhfmlmgnfdh0",
            "digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            "expiration_date": "02/25",
            "flags": null,
            "generic_card_level": "",
            "instrument_type": "credit",
            "masked_number": "411111******1111",
            "processor_id": "",
            "record_id": "btvq916vvhfmlmgnfdhg",
            "status": "updated_card"
        },
        "msg": "success",
        "status": "success",
        "type": "transaction_automatic_account_updater_vault_update"
    }
    

    # Example Settlement Batch Webhook

    {
        "account_type": "merchant",
        "account_type_id": "testmerchant12345678",
        "action_at": "2024-06-05T15:45:17.788695-05:00",
        "data": {
            "amount_captured": 1630,
            "amount_credit": 0,
            "base_amount": 1630,
            "batch_date": "2024-06-05T15:45:17.728045-05:00",
            "batch_number": 1,
            "id": "cpgcsnbug2jm1i6kv4vg",
            "merchant_id": "testmerchant12345678",
            "net_amount": 1630,
            "net_deposit": 1630,
            "num_transactions": 2,
            "payment_adj_amount": 0,
            "processor_id": "cpg94brug2jhhon86rsg",
            "processor_name": "TSYS default",
            "processor_type": "tsys_sierra",
            "response_code": 100,
            "response_message": "ACCEPT",
            "surcharge_amount": 0
        },
        "msg": "success",
        "status": "success",
        "type": "settlement_batch"
    }
    

    The type field can change depending on the main webhook type, which is either transaction, settlement, or cardsync.

    For transaction, the type can be - test, transaction_create, transaction_update, transaction_void, transaction_capture, transaction_settlement.
    For cardsync, the type can be - transaction_automatic_account_updater_vault_update, transaction_automatic_account_updater_vault_iw.
    For settlement, the type can be - settlement_batch.

    Then, inside of the data object, the status field will change depending on what type of webhook is being sent.

    For transaction webhook types, data.status can be - unknown, declined, authorized, pending_settlement, settled, voided, refunded, returned, late_return, pending, partially_refunded, flagged, flagged_partner.
    For cardsync webhook types, data.status can be - updated_card.
    For settlement webhook types, there is no data.status field.

    # Example Transaction Webhook Post

    TIP

    The "Signature" header is rfc4648 encoded as to be url safe.

    POST / HTTP/1.1
    Host: localhost:9000
    User-Agent: Go-http-client/1.1
    Content-Length: 2372
    Content-Type: application/json
    Signature: Fs62H-ZaZH80Ccf-Ii9V4xC9AJLf8dQym7BFAbApJwc
    Accept-Encoding: gzip
    
    {"data":{"amount":450,"amount_authorized":450,"amount_captured":450,"amount_settled":0,"billing_address":{"address_line_1":"","address_line_2":"","city":"","company":"","country":"US","email":"","fax":"","first_name":"","last_name":"","phone":"","postal_code":"","state":""},"captured_at":"2019-09-25T19:47:14.031268117Z","created_at":"2019-09-25T19:47:14.001901427Z","currency":"usd","custom_fields":{"bm5s7im9ku6el2qvh0c0":["placeat"],"bm5s7im9ku6el2qvh0cg":["maxime"],"bm5s7im9ku6el2qvh0d0":["est"],"bm5s7im9ku6el2qvh0f0":["dolorum"],"bm5s7im9ku6el2qvh0g0":["corporis"]},"customer_id":"","customer_payment_ID":"","customer_payment_type":"","customer_vat_registration_number":"","description":"","discount_amount":0,"duty_amount":0,"email_address":"","email_receipt":false,"id":"bm5s8gm9ku6ejcu15t9g","idempotency_key":"","idempotency_time":0,"ip_address":"127.0.0.1","line_items":null,"merchant_vat_registration_number":"","national_tax_amount":0,"order_id":"","payment_adjustment":350,"payment_method":"card","payment_type":"card","po_number":"","processor_id":"bm5s7im9ku6el2qvgsrg","processor_name":"TSYS true","processor_type":"tsys_sierra","referenced_transaction_id":"","response":"approved","response_body":{"card":{"auth_code":"TAS000","avs_response_code":"","card_type":"visa","created_at":"2019-09-25T19:47:14.007998277Z","cvv_response_code":"","expiration_date":"12/20","first_six":"411111","id":"bm5s8gm9ku6ejcu15ta0","last_four":"1111","masked_card":"411111******1111","processor_id":"bm5s7im9ku6el2qvgsrg","processor_response_code":"00","processor_response_text":"APPROVAL TAS000 ","processor_specific":null,"processor_type":"tsys_sierra","response":"approved","response_code":100,"updated_at":"2019-09-25T19:47:14.027775736Z"}},"response_code":100,"settled_at":null,"settlement_batch_id":"","ship_from_postal_code":"","shipping_address":{"address_line_1":"","address_line_2":"","city":"","company":"","country":"US","email":"","fax":"","first_name":"","last_name":"","phone":"","postal_code":"","state":""},"shipping_amount":0,"status":"pending_settlement","subscription_id":"","summary_commodity_code":"","surcharge":0,"tax_amount":0,"tax_exempt":false,"tip_amount":0,"transaction_source":"api","type":"sale","updated_at":"2019-09-25T19:47:14.031268348Z","user_id":"testmerchant12345678","user_name":"test_merchant"},"msg":"success","status":"success"}