# Webhook Integration Guide

### Notification content and structure

The notification body contains the type of notification and its payload.

```
{
  "type": [notification_type],
  "action": [status],
  "payload": [content]
}
```

| Parameter | Description                                                                                                                                                                                                                                                                                                                                                                                       | Format                        | Required    |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ----------- |
| type      | <p>Type of the notification</p><ul><li><strong>PAYMENT</strong> This type of notification is sent when a payment is created or updated in the system.</li><li><strong>REGISTRATION</strong> This type of notification is sent when a registration is created or deleted.</li><li><strong>RISK</strong> This type of notification is sent when a risk transaction is created or deleted.</li></ul> | (PAYMENT\|REGISTRATION\|RISK) | required    |
| action    | <p>Indicator of status change. This field is available only if the type is REGISTRATION.</p><ul><li><strong>CREATED</strong> when registration has been created.</li><li><strong>UPDATED</strong> when registration has been updated.</li><li><strong>DELETED</strong> when registration has been deleted.</li></ul>                                                                              | (CREATED\|UPDATED\|DELETED)   | conditional |
| payload   | Content of the notification. If the notification type is payment or registration, the payload's content will be identical to the response you received on the payment or registration.                                                                                                                                                                                                            | JSON                          | required    |

#### Example - payment

```
{
   "type":"PAYMENT",
   "payload":{
      "id":"8a829449515d198b01517d5601df5584",
      "paymentType":"PA",
      "paymentBrand":"VISA",
      "amount":"92.00",
      "currency":"EUR",
      "presentationAmount":"92.00",
      "presentationCurrency":"EUR",
      "descriptor":"3017.7139.1650 OPP_Channel ",
      "result":{
         "code":"000.100.110",
         "description":"Request successfully processed in 'Merchant in Integrator Test Mode'"
      },
      "authentication":{
         "entityId":"8a8294185282b95b01528382b4940245"
      },
      "card":{
         "bin":"420000",
         "last4Digits":"0000",
         "holder":"Jane Jones",
         "expiryMonth":"05",
         "expiryYear":"2018"
      },
      "customer":{
         "givenName":"Jones",
         "surname":"Jane",
         "merchantCustomerId":"jjones",
         "sex":"F",
         "email":"jane@jones.com"
      },
      "customParameters":{
         "SHOPPER_promoCode":"AT052"
      },
      "risk":{
         "score":"0"
      },
      "buildNumber":"ec3c704170e54f6d7cf86c6f1969b20f6d855ce5@2015-12-01 12:20:39 +0000",
      "timestamp":"2015-12-07 16:46:07+0000",
      "ndc":"8a8294174b7ecb28014b9699220015ca_66b12f658442479c8ca66166c4999e78"
   }
}
```

#### Example - registration

```
{
   "type":"REGISTRATION",
   "action": "CREATED",
   "payload":{
      "id":"8a82944a53e6a0150153eaf693584262",
      "paymentBrand":"VISA",
      "result":{
         "code":"000.100.110",
         "description":"Request successfully processed in 'Merchant in Integrator Test Mode'",
         "randomField1315125026":"Please allow for new unexpected fields to be added"
      },
      "card":{
         "bin":"420000",
         "last4Digits":"0000",
         "holder":"Jane Jones"
      },
      "authentication":{
         "entityId":"8a8294174b7ecb28014b9699220015ca"
      },
      "redirect":{
         "parameters":[

         ]
      },
      "risk":{
         "score":""
      },
      "timestamp":"2016-04-06 09:45:41+0000",
      "ndc":"8a8294174b7ecb28014b9699220015ca_b1539494024c411684b544574716e608"
   }
}
```

#### Example - risk

```
{
 "type": "RISK",
  "payload": {
    "id": "8ac9a4a86461239601646522acb26523",
    "referencedId": "8ac9a4a86461239601646522aaf96510",
    "paymentType": "RI",
    "paymentBrand": "VISA",
    "presentationAmount": "0.0",
    "result": {
      "code": "000.000.000",
      "description": "Transaction succeeded"
    },
    "card": {
      "bin": "420000",
      "last4Digits": "0000",
      "holder": "Jane Jones",
      "expiryMonth": "03",
      "expiryYear": "2025"
    },
    "authentication": {
      "entityId": "8a8294174b7ecb28014b9699220015ca"
    },
    "redirect": {
      "parameters": []
    },
    "risk": {
      "score": ""
    },
    "timestamp": "2018-07-04 11:52:08+0000",
    "ndc": "8a8294174b7ecb28014b9699220015ca_b1539494024c411684b544574716e608"
  }
}
```

#### [Encryption](https://primeiropay.docs.oppwa.com/tutorials/webhooks/integration-guide#encryption)

The content of notification is encrypted to protect data from fraud attempts. When converting human-readable string to hexadecimal format, we use UTF-8.

| Parameter             | Description                                                                   |
| --------------------- | ----------------------------------------------------------------------------- |
| Encryption algorithm  | AES                                                                           |
| Key                   | \[secret of listener] (64-character-long hexadecimal string in configuration) |
| Key length            | 256 bits (32 bytes)                                                           |
| Block mode            | GCM                                                                           |
| Padding               | None                                                                          |
| Initialization vector | In HTTP header (X-Initialization-Vector)                                      |
| Authentication tag    | In HTTP header (X-Authentication-Tag)                                         |

Format of body: Hexadecimal\
Format of Initialization Vector: Hexadecimal

**Example**

```
Payload
{"type": "PAYMENT"}

Payload in Hexadecimal (after getting bytes in UTF-8)
7B2274797065223A20225041594D454E54227D

Key in Hexadecimal
000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F

Initialization-Vector (Hexadecimal)
3D575574536D450F71AC76D8

Authentication-Tag (Hexadecimal)
19FDD068C6F383C173D3A906F7BD1D83

Encrypted value in Hexadecimal
F8E2F759E528CB69375E51DB2AF9B53734E393
```

### Responding to Notifications

When your service receives a webhook notification, it must return a **2xx** HTTP status code. Otherwise, the webhook service considers the notification delivery as failed, and will retry to send the notification later.

### Protocol Details

| Protocol     | HTTPS (HTTP is allowed on test systems only) |
| ------------ | -------------------------------------------- |
| HTTP method  | POST                                         |
| Content type | text(text/plain)                             |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.primeiropay.com/webhook-1/webhook-integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
