Overview

PaySimple can notify your system or a 3rd party system when an event happens via webhooks. Webhooks are sent with an HTTP post to a publicly accessible url you specify when creating a webhook subscription. You may create as many webhook subscriptions as you wish, and each subscription may subscribe to multiple event types.

Webhook messages are lightweight by design. If you need more context data, call API4 or API5 endpoints using the ids returned in the body.

Delivery

For a webhook message to be delivered successfully, the endpoint must respond with a 2XX status code (eg 200, 201, etc.) within 10 seconds. If a successful response is not received, PaySimple will attempt to resend the webhook once every hour for 72 hours. PaySimple recommends using secure SSL encrypted endpoints hosted on port 443 (https).

Message Consumption Best Practices

It is best to write your consumer in an idempotent manner, as messages may be delivered out of order. Webhook events may be delivered more than once. An event payload will always have a unique event_id, which can be used to prevent duplicates upon message consumption.

Webhook Subscription API

Authorization

All requests to the webhook subscription API must contain the API 5 Authorization header.

Base URL

All requests must be sent using a base URL of https://api.paysimple.com/

Webhook Subscription Object

PropertyTypeDescription
idstringUniquely identifies a webhook subscription
urlstringUrl of the endpoint PaySimple will POST the event message to
event_typesarray of stringsList of event types to be delivered to url
is_activebooleantrue indicates messages should be delivered

Create Webhook Subscription

To create a webhook subscription, call the following endpoint with the url to accept the message and the event types to be sent.

Request:
POST /ps/webhook/subscription
{
    "url" : "https://myserver.mydomain.com/api/webhook",
    "event_types" : [ "payment_created" ],
    "is_active": true
}

Response:
200 OK
{
    "data": {
        "id": "wh_5b45075d253baf7fa0e1b8ee",
        "signature_secret": "3LbX1p2V3w0UDUqh8DWYVVA5tvSosHWWNHutjD3F8nfo3eRzsxbTI97ssGkScqCg"
    }
}

Update Webhook Subscription

Request:
PUT /ps/webhook/subscription/{id}
{
    "url" : "https://myserver.mydomain.com/api/webhook",
    "event_types" : [ "payment_created" ],
    "is_active": true
}

Response:
204 No Content

Get Webhook Subscription

Request:
GET /ps/webhook/subscription/{id}

Response:
200 OK
{
    "data": {
        "id": "wh_5b45075d253baf7fa0e1b8ee",
        "url": "https://myserver.mydomain.com/api/webhook",
        "event_types": [
            "payment_created"
        ],
        "is_active": false,
        "signature_secret": "3LbX1p2V3w0UDUqh8DWYVVA5tvSosHWWNHutjD3F8nfo3eRzsxbTI97ssGkScqCg"
    }
}

Get All Webhook Subscriptions

Request:
GET /ps/webhook/subscriptions

Response:
200 OK
{
    "total_item_count": 4,
    "data": [
        {
            "id": "wh_5be22135d080e311b073d880",
            "url": "https://myserver.mydomain.com/api/webhook",
            "event_types": [
                "payment_created"
            ],
            "is_active": true,
          	"signature_secret": "3LbX1p2V3w0UDUqh8DWYVVA5tvSosHWWNHutjD3F8nfo3eRzsxbTI97ssGkScqCg"
        },
        {
            "id": "wh_5be221ead080e311b073d881",
            "url": "https://myserver.mydomain2.com/api/webhook",
            "event_types": [
                "payment_created"
            ],
            "is_active": true,
          	"signature_secret": "wnQkPomzKpziLNjCtRXdnTXvgNl9fYssLOg6bFsTEzlXsE2AGQwc7ecifpcyixrr"
        }
    ]
}

Delete Webhook Subscription

Request:
/ps/webhook/subscription/{id}

Response:
204 No Content

Manually Resend Webhooks

Request:
PUT /ps/webhook/manually_resend_webhooks
{ 
  "ids": ["id_1", "id_2", "id_n"] 
}

Response:
204 No Content

Webhook Verification

Each webhook request sent from PaySimple contains a "paysimple-hmac-sha256" field in the request header, which can be used to verify the message. To verify the message, a webhook recipient can calculate "paysimple-hmac-sha256" using the C# code below. The code requires two parameters: 1) the signature secret and 2) the webhook event request body. The Signature Secret is provided in the response to the request to create the webhook. If you do not have this saved, the signature secret can be obtained by sending a request to the Get Webhook Subscription endpoint. The webhook event request body is is the raw text of the body of the request message that is sent to your webhook consumer.

new HMACSHA256(Encoding.ASCII.GetBytes(signatureSecret))
	.ComputeHash(Encoding.ASCII.GetBytes(webhookEventRequestBody))
	.Aggregate("", (current, t) => current + t.ToString("X2"))

Once you have calculated the "paysimple-hmac-sha256" using the code above, simply compare it to the value of the "paysimple-hmac-sha256" from the webhook request header. If the values match, then the message has been verified.

πŸ“˜

Troubleshooting Tip

If you consistently fail to verify webhook messages using the code above, be sure to check the webhook event request body for anything that does not match the format of a response as shown above. Occasionally, white space can be added on the consumer end that is different from the original message. In particular check for any white space added in dates before or after a dash ( '-' ) character or any white space before or after special characters.