Overview
Reach will send notifications of the Drop-In session lifecycle by sending HTTP POST requests to the webhook URL you provided during on-boarding.
After successfully receiving a notification, you should respond to Reach with any 200-series HTTP status. If your HTTP status response is not within the 200 range, Reach will attempt to resend the notification.
Notification Structure
Notifications will be sent as an HTTP Post to an endpoint you've defined when setting up your account with reach. The notification body will be JSON, with variations depending on the notification type. They will be formatted with the following fields
Field | Description | Expected when: |
---|---|---|
EventType | Classifies a notification. See: Event Types | Always |
Session | A full session object | EventType is:SESSION_FAILED SESSION_COMPLETED |
Order | An order object containing IDs and state. | EventType is:ORDER_AUTHORIZED ORDER_PROCESSED ORDER_PROCESSING_FAILED ORDER_DECLINED ORDER_CANCELLED ORDER_PROCESSING |
Refund | IDs and state for a Refund. | EventType is:REFUND_SUCCEEDED REFUND_FAILED |
The body of Session, Order or Refund will all be different. Their format is laid out in the following sections.
Session Notifications
Session notifications will include an event type beginning with SESSION
. See the section under Retrieving Sessions for a definition of the fields.
When present in Session notifications, the
Order
field will only contain theOrderId
for Online or Card payments.
Order Notifications
Order notifications will contain a subset of Order information. Clients can expect the following:
Field | Type | Description | Always present? | Notes |
---|---|---|---|---|
OrderId | UUID | Reach-generated identifier for an order | Yes | --- |
SessionId | UUID | Associated Session identifier | No | Present if this order was created using a Session |
State | String | Order state | Yes | See: States and Events |
MerchantReference | String | Merchant-supplied order identifier | Yes | --- |
UnderReview | Boolean | Flag indicating the the order is undergoing a fraud review | No | --- |
Meta | JSON | A free-form JSON object that can be supplied when creating an order | No | Returned if supplied in the initial creation |
ContractId | UUID | The ContractId created with the Order | No | If a ContractId was created with the Order and only for ORDER_AUTHORIZED or ORDER_PROCESSED |
Refund Notifications
Refund Notifications can only be sent for orders in a state of either Processed
or Declined
.Clients can expect the following (all fields will be present in all cases):
Field | Type | Description |
---|---|---|
RefundId | UUID | Unique identifer for an individual refund. Orders may be multiple Refunds with different IDs. |
OrderId | UUID | Identifer corresponding the the Order the refund was issued against |
SessionId | UUID | Unique identifier of the session a refund is associated to. Only present if the original order was created using the Session API, absent otherwise |
Amount | Number | Refund amount in the consumer currency |
State | String | Refund state. See: States and Events |
Responding to Notifications
Upon receipt of a Notification, respond to Reach with any 200-series HTTP status. If any other status is received, Reach will
treat the notification sending attempt as failed and will retry the notification later.
If you receive a duplicate of a notification, respond with a 200-series HTTP status to prevent Reach from retrying.
Event Types
An EventType is at the root of every notification body and can be used to determine what initiated the notification.
Event Type | How to Handle transaction in your system |
---|---|
SESSION_FAILED | Mark as failed and notify the customer you were unable to process payment. A new Session will need to be created if the user tries again. |
SESSION_COMPLETED | Informational notification letting the merchant know that the customer has completed the Drop-In experience. This notification does not mean the payment has been successful. |
ORDER_AUTHORIZED | The Order created by the Session was Authorized. If auto-capture is set to false, you can proceed to capture the Order. If auto-capture is set to true, you can ignore this notification. |
ORDER_PROCESSED | Mark as completed/done. The Order has been successfully captured and funds have been moved. |
ORDER_PROCESSING_FAILED | Mark as failed and notify the customer you were unable to process payment. A new Session will need to be created if the user tries again. |
ORDER_DECLINED | Mark as failed and notify the customer you were unable to process payment. A new Session will need to be created if the user tries again. |
ORDER_CANCELLED | This will only be created if the Order was created directly against the Order API - do not expect it if you created through the Session API. Mark as failed and notify the customer you were unable to process payment |
ORDER_PROCESSING | This will only be created if the Order was created directly against the Order API - do not expect it if you created through the Session API. Informational notification letting the merchant know that the customer's Order has been accepted but not captured.This notification does not mean the payment has been successful. |
REFUND_SUCCEEDED | Mark the identified refund as completed in your system |
REFUND_FAILED | Mark the identified refund as failed in your system. |
Reach does not guarantee the order in which the notifications will arrive. Your server will need to determine the relevancy of the notification depending on the last known state on your side.
Notification retries
In cases where Reach sends a notification but does not receive a response, or a response contains a non-2xx level HTTP status, the notification is queued for a retry. An exponential backoff time will be employed with a maximum of 25 attempts - the first couple of retries will have seconds between each attempt, while the last try will have about 17 hours between attempts (the total retry time will be 5 days).
When a successful HTTP response is received, the retries will halt.
Missed notifications
If individual notifications are missed, please use the session retrieval endpoint (/v1/session/{sessionId}) to retrieve the session information as needed. If a large number of notifications are missed, please coordinate with Reach to attempt to reschedule sending the missed notifications.
Notification Verification
Notifications sent from Reach contain a 'reach-signature' header value that can be used to verify that the notification is authentic and untampered. The signature is a base-64 encoded HMAC-256 hash using the shared secret key provided to the merchant during onboarding. See the Reach Signature calculation
documentation for code examples.
Please refer to the table below, which contains an example of a successful signature calculation in a Reach development environment. You can use this result to confirm your algorithm's accuracy by verifying that you have calculated the same hash as below.
Secret Key (plaintext) | Payload | Base-64 encoded hash |
---|---|---|
e0fRcLWcOi51nTZI4b1fkGt3iJqeZIdc4WFChUNYrGsup4TAvX4GhEJItbVdUhsz | {"EventType":"ORDER_PROCESSED","Order":{"OrderId":"0063ad89-73d7-4c40-98c5-a8313d200938","State":"PROCESSED","SessionId":"40e9eee2-6d49-4268-b763-5b946cca4321","MerchantReference":"294be021-2dce-4054-ac63-512f94a10123"}} | fsaZOgThIygNPMK0qSvW94vEacoTbukaZxlRlJuiVTg= |
012345678901234 | {"Key":"value"} | PpgE4qCJx5VbK38U7PY9+dkE6yuXhxtpVJh7vWSkphk= |
Under Review
Order notifications may contain the boolean flag UnderReview
as part of this body. This flag does not trigger a notification itself, but is intended to inform you that the order is currently undergoing a manual fraud review. If the order is declined due to this review, expect an ORDER_DECLINED
notification on state change.
Notification triggered by UnderReview
When the
UnderReview
flag is added to a notification or changed, it will trigger a notification that will otherwise appear as a duplicate. It is recommended to inspect the notification body for thisUnderReview
flag.
Notification examples
Included below are some sample notifications for the various expected event types.
SESSION_FAILED
This notification indicates that a session has failed and cannot be completed. This can occur if the session was created with data that cannot be accepted by a downstream provider, or if certain fraud rules are triggered. A new Session will need to be created if the user tries again.Example:
{
"EventType": "SESSION_FAILED",
"Session": {
"SessionId": "6ebea5c5-ab2a-4aa1-87a6-d1a3a4976463",
"State": "FAILED",
"MerchantReference": "notification_ex_6",
"Items": [
{
"Name": "initial item",
"Amount": 10,
"Quantity": 2
}
],
"Currency": "EUR",
"TotalAmount": 33.53,
"PaymentMethod": "VISA",
"BillingProfile": {
"BillingProfileId": "06dbe7e7-92f0-43d2-9b9a-e3f18c9ad944",
"Name": "First Last",
"Email": "[email protected]",
"Phone": "4031231234",
"NationalIdentifier": "14.007.288/9999-30",
"Birthdate": "1980-01-02",
"Company": "Umbrella corp",
"Address": {
"Street": "123 Street",
"City": "City",
"Region": "AL",
"Country": "BR",
"Postcode": "12345678"
}
},
"ShippingDetails": {
"Name": "First Last",
"Email": "[email protected]",
"Address": {
"Street": "123 Street",
"City": "City",
"Region": "AB",
"Country": "CA",
"Postcode": "12345678"
},
"Phone": "4031231234",
"ShippingAmount": 10,
"DutyAmount": 2.32
},
"TaxAmount": 1.21,
"AutoCapture": true,
"CompleteUrl": "http://notreal.complete",
"CancelUrl": "http://notreal.cancel",
"ViaAgent": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
}
}
}
SESSION_COMPLETED
This notification indicates that a payment has been successfully submitted. This is sent once the user has completed the payment flow and is done with the Drop-In flow. It's important to note that this does not mean the order is fully authorized or completed - processing may still fail if you have not yet received an ORDER_PROCESSED notification. There are 2 examples provided below - one for Card/Online payments, and one for Offline. Note the difference in the `Order` block in the 2 examples.Example (Card/Online):
{
"EventType": "SESSION_COMPLETED",
"Session": {
"SessionId": "a8dd229f-f76b-4683-bd82-4eb669d3be13",
"State": "COMPLETED",
"MerchantReference": "notification_ex_4",
"Items": [
{
"Name": "initial item",
"Amount": 10,
"Quantity": 2
}
],
"Currency": "EUR",
"TotalAmount": 33.53,
"PaymentMethod": "VISA",
"PaymentDate": "2022-08-31T04:50:59.812922947Z",
"BillingProfile": {
"BillingProfileId": "f2d5fdfa-5536-4979-b4f5-e927b80ad009",
"Name": "First Last",
"Email": "[email protected]",
"Phone": "4031231234",
"Birthdate": "1980-01-02",
"Company": "Umbrella corp",
"Address": {
"Street": "123 Street",
"City": "City",
"Country": "DE"
}
},
"ShippingDetails": {
"Name": "First Last",
"Email": "[email protected]",
"Address": {
"Street": "123 Street",
"City": "City",
"Region": "AB",
"Country": "CA",
"Postcode": "12345678"
},
"Phone": "4031231234",
"ShippingAmount": 10,
"DutyAmount": 2.32
},
"TaxAmount": 1.21,
"AutoCapture": true,
"CompleteUrl": "http://notreal.complete",
"CancelUrl": "http://notreal.cancel",
"Order": {
"OrderId": "57a23c88-21a9-490c-bd61-e225e4bc434d"
},
"ViaAgent": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
}
}
}
Example (Offline):
{
"EventType": "SESSION_COMPLETED",
"Session": {
"SessionId": "a8dd229f-f76b-4683-bd82-4eb669d3be13",
"State": "COMPLETED",
"MerchantReference": "notification_ex_4",
"Items": [
{
"Name": "initial item",
"Amount": 10,
"Quantity": 2
}
],
"Currency": "EUR",
"TotalAmount": 33.53,
"PaymentMethod": "BANK",
"PaymentDate": 1648663588.14708073,
"BillingProfile": {
"BillingProfileId": "f2d5fdfa-5536-4979-b4f5-e927b80ad009",
"Name": "First Last",
"Email": "[email protected]",
"Phone": "4031231234",
"Birthdate": "1980-01-02",
"Company": "Umbrella corp",
"Address": {
"Street": "123 Street",
"City": "City",
"Country": "DE"
}
},
"ShippingDetails": {
"Name": "First Last",
"Email": "[email protected]",
"Address": {
"Street": "123 Street",
"City": "City",
"Region": "AB",
"Country": "CA",
"Postcode": "12345678"
},
"Phone": "4031231234",
"ShippingAmount": 10,
"DutyAmount": 2.32
},
"TaxAmount": 1.21,
"AutoCapture": true,
"CompleteUrl": "http://notreal.complete",
"CancelUrl": "http://notreal.cancel",
"Order": {
"OrderId": "57a23c88-21a9-490c-bd61-e225e4bc434d",
"State": "PROCESSING",
"SessionId": "a8dd229f-f76b-4683-bd82-4eb669d3be13",
"MerchantReference": "notification_ex_4",
"BankDetails": {
"AccountHolder": "Global Collect B.V.",
"AccountNumber": "115241904",
"BankName": "Postbank AG",
"City": "Leipzig",
"Country": "Germany",
"Iban": "DE53860100900115241904",
"PaymentReference": "626300142399",
"SwiftCode": "PBNKDEFF",
"ExtraBankData": "BLZ|86010090"
}
},
"ViaAgent": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
}
}
}
ORDER_AUTHORIZED
This notification indicates that the Order created by the Session was Authorized. If auto-capture is set to false, you can proceed to capture the Order. If auto-capture is set to true, you can ignore this notification.Example:
{
"EventType": "ORDER_AUTHORIZED",
"Order": {
"OrderId": "6b3758d0-75ec-47b6-aed2-f8f99e003c08",
"State": "PAYMENTAUTHORIZED",
"SessionId": "9c16210f-44f9-4b47-803d-418aa4164e85",
"MerchantReference": "a8b90816-3356-4031-94fa-3e15e69e523b",
"UnderReview": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
},
"ContractId": "9eb068ef-ad80-4302-b607-b72469a72e9f"
}
}
ORDER_PROCESSED
This notification serves as a final indication that the order is completed and captured, and may be marked as finished in your system.Example:
{
"EventType": "ORDER_PROCESSED",
"Order": {
"OrderId": "531c1e7b-90bb-4430-89ff-a410acb3d3f5",
"State": "PROCESSED",
"SessionId": "b8fc155b-2e83-4b97-91b6-bc09388d19fe",
"MerchantReference": "beba3643-1c73-4bbf-90ce-e0057e4340f9",
"UnderReview": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
},
"ContractId": "9eb068ef-ad80-4302-b607-b72469a72e9f"
}
}
ORDER_PROCESSING_FAILED
This notification indicates that the order processing has failed at some point after the session was completed. As the user is no longer in the Drop-In flow at this point, they will need to be notified and a new session created to attempt to re-process the transaction if necessary. This is similar to ORDER_DECLINED, however it indicates a technical error or an unprocessable transaction.{
"EventType": "ORDER_PROCESSING_FAILED",
"Order": {
"OrderId": "b88bb6df-20ac-4c63-8091-151e828b2613",
"State": "PROCESSINGFAILED",
"SessionId": "4f7d6b2c-8b36-44e0-8c28-20f7fe4a4c08",
"MerchantReference": "Some unique reference",
"UnderReview": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
}
}
}
ORDER_DECLINED
This notification indicates that an order was declined at some point after the session was completed. As the shopper is no longer in the Drop-In flow at this point, they will need to notified and a new session created to attempt to re-process the transaction if necessary. This is similar to ORDER_PROCESSING_FAILED, however it indicates a transaction was declined because of business rules, such as insufficient funds.{
"EventType": "ORDER_DECLINED",
"Order": {
"OrderId": "c393af25-6966-497d-8d46-20e47b152683",
"State": "DECLINED",
"SessionId": "b473cd78-d27d-47af-a67b-fab8b06835bb",
"MerchantReference": "Some unique reference",
"UnderReview": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
}
}
}
ORDER_CANCELLED
This notification is sent if the order is manually cancelled, either by you or by an agent at some point after the session was completed. This is similar to ORDER_DECLINED, and a new session will need to be created to attemptthis again.{
"EventType": "ORDER_CANCELLED",
"Order": {
"OrderId": "c393af25-6966-497d-8d46-20e47b152683",
"State": "CANCELLED",
"SessionId": "b473cd78-d27d-47af-a67b-fab8b06835bb",
"MerchantReference": "Some unique reference",
"UnderReview": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
}
}
}
ORDER_PROCESSING
Indicates that an order was created and is currently in-flight. For orders created through the Session API, this notification should not be expected. This will only be present if an order is created directly through the Order API.{
"EventType": "ORDER_PROCESSING",
"Order": {
"OrderId": "531c1e7b-90bb-4430-89ff-a410acb3d3f5",
"State": "PROCESSING",
"SessionId": "b8fc155b-2e83-4b97-91b6-bc09388d19fe",
"MerchantReference": "beba3643-1c73-4bbf-90ce-e0057e4340f9",
"UnderReview": false,
"Meta": {
"field": "value",
"AnotherField": "Some other value"
}
}
}
REFUND_SUCCEEDED
A previously submitted refund has completed successfully. Note that SessionId may not be present in all refund notifications.{
"EventType": "REFUND_SUCCEEDED",
"Refund": {
"RefundId": "4da0e6e9-fa0d-4a92-9799-3b75ba846cfd",
"OrderId": "531c1e7b-90bb-4430-89ff-a410acb3d3f5",
"SessionId": "1f6b4c6f-b801-4314-bc7b-cb8db00827c4",
"Amount": 10.12,
"State": "SUCCEEDED"
}
}
REFUND_FAILED
A previously submitted refund has did not complete successfully. Note that SessionId may not be present in all refund notifications.{
"EventType": "REFUND_FAILED",
"Refund": {
"RefundId": "4da0e6e9-fa0d-4a92-9799-3b75ba846cfd",
"OrderId": "531c1e7b-90bb-4430-89ff-a410acb3d3f5",
"SessionId": "1f6b4c6f-b801-4314-bc7b-cb8db00827c4",
"Amount": 10.12,
"State": "FAILED"
}
}