Webhooks

Webhooks are events that notify you when a transaction changes its status. For example, they can let you know the moment a payment is authorized, refunded, succeeds or fails. This is particularly useful for asynchronous payment flows, in which a transaction may first return a status of Pending before returning a final status indicating the success or failure of the transaction request.

Webhooks Version

The latest Webhook API version is 1.2.0.

Webhook events returned in version 1.2.0 and higher have a different structure than the events returned in older Webhook versions. Refer to the topic of your choice, depending on the Webhook version you are using:

For an overview of the latest changes, refer to the Webhooks API Changelog.

Setting the API Version

You need to update your webhook configuration if you want to use the latest API version. Simply edit your webhook endpoint and choose the latest version from the Webhook Version list.

Creating Webhooks

To begin receiving Webhook notifications, do the following:

  1. Login to the PaymentsOS Control Center and open the Webhooks configuration page (Accounts > Webhooks).
  2. Select the test or live relevant environment.
  3. Enter an endpoint (the HTTPS URL), that Webhooks notifications should be sent to.
  4. Select the events to track from the Payment Event Alerts list.
  5. Select the business units to associate with the endpoint from the Associated Business Units list.

Receiving Webhook Notifications

PaymentsOS will send Webhook notifications via HTTP POST requests to the URL endpoints that you defined.

If the system doesn't receive a "Request received successfully" status code response (2xx HTTP), then it will continue resending the Webhook notification for 24 hours, using an exponential retry basis.

Modifying an endpoint while a successful response is pending

If you modify the endpoint while PaymentsOS has not yet received a Request received successfully status code, PaymentsOS will still resend the Webhook notification to the previous endpoint URL. The new endpoint will only take effect for subsequent Webhook events.

Webhook Notifications in Versions 1.2.0 and Higher

This section explains the structure of Webhook notifications returned in Webhook API versions 1.2.0 and higher. The topic also outlines the steps you need to follow if you want to validate the integrity of the Webhook data you received.

Webhook Header

A Webhook header includes the following fields.

Header Field Description
signature string This is a Hash-256 (SHA-256) of specific fields contained in the Webhook response. You can use this hash code to validate the integrity of the Webhook data you received. For more information, see Validating the Integrity of the Webhook Data.
event_type string The type of resource that triggered the event.
For example, payment.authorization.create
version string Version of the Webhooks configuration.
x-payments-os-env string PaymentsOS environment header, 'live' or 'test'.
x-zooz-request-id string The ID of the original request that triggered the webhook event.

Here's an example of a Webhook event header:

x-zooz-request-id: 4a86867f-f2bd-4860-a6c8-10a5ab890f03
version: 1.2.0
x-payments-os-env: test
event-type: payment.charge.update
signature: sig1=3bc4d08447e55a704325db8748582eaefd5ebed0157ec1e587cae4df8f5cd74e

Webhook Body

A Webhook body includes the following fields.

Attribute Name Description
id string The Webhook id. This id is unique per Webhook and can be used to validate that the request is unique (idempotency validation). For instance, connectivity issues may cause the same event to be sent multiple times. If you receive the same event multiple times, you can simply ignore the duplicates. Bear in mind that you must still send us a 2xx (success) response so that we will stop resending the webhook event.
created timestamp The date and time the event was created.
payment_id UUID The payment id.
account_id UUID The merchant account related to the event.
app_id string The Business Unit related to the event.
data object The full transaction resource that initiated the event.

Here are examples of Webhook event bodies, for common webhook event types:

Charge Update
Capture Update
Refund Update
Void Update
{
    "id": "13344450-77e9-45b6-9bbe-88fff8c451e5-2018-10-03T04:58:35.385Z-83233f6e-767f-4f55-9d8f-448019e90fbf",
    "created": "2018-10-03T04:58:35.385Z",
    "account_id": "961c3ded-d539-4b5f-8950-3de93570e988",
    "app_id": "com.zooz.docapp",
    "payment_id": "13344450-77e9-45b6-9bbe-88fff8c451e5",
    "data": {
        "id": "cb615c8f-319d-4349-a276-f4ecc7d770d3",
        "created": "1538542712789",
        "payment_method": {
            "type": "tokenized",
            "token": "9c7bc2c6-47fe-4d2a-ac20-23847574ae3e",
            "token_type": "credit_card",
            "holder_name": "John Mark",
            "expiration_date": "10/2029",
            "last_4_digits": "0077",
            "pass_luhn_validation": true,
            "bin_number": "400000",
            "vendor": "VISA",
            "issuer": "",
            "card_type": "CREDIT",
            "level": "",
            "country_code": "USA",
            "created": "1538542703826",
            "billing_address": {
                "country": "USA",
                "state": "NY",
                "city": "NYC",
                "line1": "fifth avenue 10th"
            }
        },
        "result": {
            "status": "Succeed"
        },
        "provider_data": {
            "provider_name": "MockProcessor",
            "response_code": "0",
            "description": "Captured.",
            "raw_response": "{\"OID\":\"13344450-77e9-45b6-9bbe-88fff8c451e5\",\"AUTH_CODE\":\"13344\",\"RETURN_MESSAGE\":\"Captured.\",\"TRANSID\":\"187_961c3ded-d539-4b5f-8950-3de93570e988_Charge-TargetPolicy\",\"STATUS\":\"SUCCESS\",\"AMOUNT\":\"40.97\",\"DATE\":\"1538542715367\",\"RETURN_CODE\":\"0\",\"CURRENCY\":\"EUR\"}",
            "authorization_code": "13344",
            "transaction_id": "187_961c3ded-d539-4b5f-8950-3de93570e988_Charge-TargetPolicy",
            "external_id": "13344450-77e9-45b6-9bbe-88fff8c451e5"
        },
        "amount": 4097
    }
}
{
    "id": "66ebc442-bf8f-42c6-886b-faee8323aad2-2018-10-03T05:14:17.196Z-83233f6e-767f-4f55-9d8f-448019e90fbf",
    "created": "2018-10-03T05:14:17.196Z",
    "account_id": "961c3ded-d539-4b5f-8950-3de93570e988",
    "app_id": "com.zooz.docapp",
    "payment_id": "66ebc442-bf8f-42c6-886b-faee8323aad2",
    "data": {
        "id": "974cfd3e-a461-4efd-804c-9b39104f56f9",
        "created": "1538543654532",
        "result": {
            "status": "Succeed"
        },
        "amount": 2000,
        "provider_data": {
            "provider_name": "MockProcessor",
            "response_code": "0",
            "description": "Captured.",
            "raw_response": "{\"OID\":\"66ebc442-bf8f-42c6-886b-faee8323aad2\",\"AUTH_CODE\":\"66ebc\",\"RETURN_MESSAGE\":\"Captured.\",\"TRANSID\":\"988_961c3ded-d539-4b5f-8950-3de93570e988_Capture\",\"STATUS\":\"SUCCESS\",\"AMOUNT\":\"20\",\"DATE\":\"1538543657182\",\"RETURN_CODE\":\"0\",\"CURRENCY\":\"USD\"}",
            "authorization_code": "66ebc",
            "transaction_id": "988_961c3ded-d539-4b5f-8950-3de93570e988_Capture",
            "external_id": "66ebc442-bf8f-42c6-886b-faee8323aad2"
        }
    }
}
{
    "id": "a3006729-09d7-41e3-9c2f-8fa0cd9d6fdc-2018-10-03T05:22:45.610Z-83233f6e-767f-4f55-9d8f-448019e90fbf",
    "created": "2018-10-03T05:22:45.610Z",
    "account_id": "961c3ded-d539-4b5f-8950-3de93570e988",
    "app_id": "com.zooz.docapp",
    "payment_id": "a3006729-09d7-41e3-9c2f-8fa0cd9d6fdc",
    "data": {
        "id": "df6cfb45-5e03-4815-b777-3124f7a86a43",
        "created": "1538544162818",
        "result": {
            "status": "Succeed"
        },
        "provider_data": {
            "provider_name": "MockProcessor",
            "response_code": "0",
            "description": "Refunded.",
            "raw_response": "{\"OID\":\"a3006729-09d7-41e3-9c2f-8fa0cd9d6fdc\",\"AUTH_CODE\":\"a3006\",\"RETURN_MESSAGE\":\"Refunded.\",\"TRANSID\":\"67_961c3ded-d539-4b5f-8950-3de93570e988_Refund\",\"STATUS\":\"SUCCESS\",\"AMOUNT\":\"20\",\"DATE\":\"1538544165606\",\"RETURN_CODE\":\"0\",\"CURRENCY\":\"USD\"}",
            "authorization_code": "a3006",
            "transaction_id": "67_961c3ded-d539-4b5f-8950-3de93570e988_Refund",
            "external_id": "a3006729-09d7-41e3-9c2f-8fa0cd9d6fdc"
        },
        "amount": 2000
    }
}
{
    "id": "2eea735d-3c37-4f30-ab54-7ccea9a3b1bd-2018-10-03T05:26:03.793Z-83233f6e-767f-4f55-9d8f-448019e90fbf",
    "created": "2018-10-03T05:26:03.793Z",
    "account_id": "961c3ded-d539-4b5f-8950-3de93570e988",
    "app_id": "com.zooz.docapp",
    "payment_id": "2eea735d-3c37-4f30-ab54-7ccea9a3b1bd",
    "data": {
        "id": "7b746d9d-073a-4eb0-a067-b14d952211e2",
        "created": "1538544360751",
        "result": {
            "status": "Succeed"
        },
        "provider_data": {
            "provider_name": "MockProcessor",
            "response_code": "0",
            "description": "Canceled.",
            "raw_response": "{\"OID\":\"2eea735d-3c37-4f30-ab54-7ccea9a3b1bd\",\"AUTH_CODE\":\"2eea7\",\"RETURN_MESSAGE\":\"Canceled.\",\"TRANSID\":\"322_961c3ded-d539-4b5f-8950-3de93570e988_Void\",\"STATUS\":\"SUCCESS\",\"AMOUNT\":\"20\",\"DATE\":\"1538544363785\",\"RETURN_CODE\":\"0\",\"CURRENCY\":\"USD\"}",
            "authorization_code": "2eea7",
            "transaction_id": "322_961c3ded-d539-4b5f-8950-3de93570e988_Void",
            "external_id": "2eea735d-3c37-4f30-ab54-7ccea9a3b1bd"
        }
    }
}

Understanding the Structure of the body.data Object

The structure of the data object is the same as the structure you receive in the response of a GET request made to the specific resource endpoint. For instance, the structure of the data object returned in a payment.charge.update event will be the same as the response body of a GET Charge request. Likewise, the data object returned in a payment.payment.update event will be the same as the response body of a GET Payment request.

Use the event_type value (in the Webhook event header) to ensure you parse the correct data object structure. Refer to the API reference for a sample response.

Validating the Integrity of the Webhook Data

Note

This functionality is available in Webhook API version 1.2.0 and higher.

If you’re worried about the integrity of the Webhook data you received (or want to be reassured that the data was sent to you by PaymentsOS), you can get assurance that your data hasn't been monkeyed with. You just have to compare two hash values:

  • The hash value returned in the signature field of the Webhook header.

  • A SHA256 hash value you generate using part of the fields returned in the Webhook event, as well as your app's private key.

Generating the SHA256 hash value is easy. First concatenate the following fields from the Webhook data into a single string. All fields are returned in the Webhook body, with the exception of theevent_type which is returned in the header. Just make sure to add the fields exactly in the order listed and separate each field in the string with a comma. If the field doesn’t exist, replace it with an empty string.

  • event_type (this field is returned in the Webhook header)

  • id

  • account_id

  • payment_id

  • created

  • app_id

  • data.id

  • data.result.status

  • data.result.category

  • data.result.sub-category

  • data.provider_data.response_code

  • data.reconciliation_id

  • data.amount

  • data.currency

Here's an example of a concatenated string. Notice that empty strings (in the event of a missing field) have been replaced with a ',' (comma). If the missing field is the last one in the sequence, you should include the comma as well.

payment.charge.update,8d3f9e6a-d89b-48bd-9d68-07e1bb582687-2018-09-05T06:44:35.484Z-83233f6e-767f-4f55-9d8f-448019e90fbf,961c3ded-d539-4b5f-8950-3de93570e988,8d3f9e6a-d89b-48bd-9d68-07e1bb582687,2018-09-05T06:44:35.484Z,com.zooz.docapp,557a4e32-d2e9-495a-9a0b-f2a18c39d91b,Succeed,,,0,,4097,

Now use the string to generate the SHA256 hash value, using your app's private key. If the value matches the signature value in the Webhook header, you can rest assured that the data has not been tempered with. For a quick test, you can use an online HMAC Generator / Tester Tool.

Webhook Notifications in Versions 1.0.1 and Lower

This section explains the structure of Webhook notifications returned in Webhook API version 1.0.1.

Webhook Header

A Webhook header includes the following fields.

Header Name Description
digest string This is a Hash-256 (SHA-256) of the body.
version string Version of the Webhooks configuration.
x-payments-os-env string PaymentsOS environment header, 'live' or 'test'.
x-zooz-request-id string The ID of the original request that triggered the webhook event.

Webhook Body

A Webhook body includes the following fields.

Attribute Name Description
event_type string The type of resource that triggered event.
For example, payment.authorization.create
created timestamp The date and time the event was created.
account_id UUID The merchant account related to the event.
app_id string The Business Unit related to the event.
resource object The resource object related to the event.
⇒ id UUID The payment id
⇒ action_id UUID The id of the transaction (such as the refund id, or the charge id.)
⇒ href UUID The href link to the associated resource.
⇒ order_id string Identifier of the order.

Here's an example of a Webhook event body:

{
    "event_type": "payment.charge.create",
    "created": "2018-02-06T10:10:05.466Z",
    "account_id": "961c3ded-d539-4b5f-8950-3de93570e988",
    "app-id": "com.zooz.docapp",
    "resource": {
        "id": "633f5479-7eea-496f-bdc1-629b71d3062a",
        "action_id": "adb3e112-8f35-46f5-8ed1-66dab4f9438c",
        "href": "https://api.paymentsos.com/payments/633f5479-7eea-496f-bdc1-629b71d3062a/charges/adb3e112-8f35-46f5-8ed1-66dab4f9438c",
        "order_id": "myappid"
    }
}

Retrieving the Transaction Status

When receiving the webhook, retrieve the status of the transaction, including any additional details, by invoking a GET request on the resource.href resource. Building on the example above, here's how you can retrieve the status of the charge:

GET https://api.paymentsos.com/payments/6ec2cd4d-9ffb-4ab3-a35a-870f7ec8a803/charges/fe25daca-1149-42e1-8576-d7b52ca9ded4

Where to find the status

The status is returned in the result object of the GET response call.

results matching ""

    No results matching ""