Webhooks

Super Payments triggers a webhook whenever a significant event occurs within a transaction lifecycle.

Endpoint Configuration

To begin receiving events, you must register your webhook endpoint URL within the Super Payments Portal. This URL is where our server will send POST requests containing event data.

Registering your Endpoint URL

  1. Access the Portal: Log in to your business portal and navigate to the integrations section.
  2. Enter your URL: Locate the webhook configuration field and enter the full destination URL of your server (e.g., https://your-api.com/webhooks/super).
  3. Retrieve your Secret: Once configured, you will see your Confirmation ID (starting with PWH_). Save this securely, as it is required for signature verification.

Securing your Webhook

To ensure that requests are authentic and originated from Super Payments, every webhook includes a super-signature header.

Signature Format

The super-signature header contains a timestamp and a cryptographic signature, separated by a comma.

Verifying the Signature

To verify the signature, you will need your Confirmation ID, which acts as your webhook secret. This ID starts with PWH_ and is located in the Integrations section of your portal, click on the arrow "View this integration".

  1. Extract Data: Split the header by the , character to separate the timestamp and signature.
  2. Parse Pairs: Split the resulting components by the :character to retrieve the actual values.
  3. Prepare Message: Create a single message string by concatenating the timestamp value and the raw request body.
  4. Compute Hash: Generate an HMAC signature using the SHA256 hash function. Use your Confirmation ID as the key and the string from step 3 as the message.
  5. Compare: Ensure the generated hash matches the signature provided in the header.

Example Signature

super-signature: t:1669219987926,v1:bc2719322a26335c486df9dffeb0c555c758b2a7470de6f62421cfb8437e8b5b

Reliability & Retries

If your server is unavailable or returns an error, Super Payments will automatically retry sending the webhook notification using an exponential backoff strategy.

Attempt Resend Interval
1 8 seconds
2 1 minute
3 8 minutes
4 1 hour
5 8 hours
6 12 hours

🚧

Following the sixth attempt, we continue to retry every 12 hours for a maximum of 7 additional attempts.

Event Types

Super Payments sends webhooks for the following event types. Each payload includes an eventType field identifying the event, a unique eventId, an eventDatetime timestamp, and a data object containing the event-specific details.

Event Type Triggered When
payment.success A payment has been successfully authorised and completed.
payment.failed A payment was not completed. Check the status field for the specific reason.
refund.success A refund has been successfully processed.
refund.failed A refund could not be processed.
customer.payment_method.requires_action A saved customer payment method requires further action before it can be used.
customer.payment_method.enabled A saved customer payment method has been successfully enabled.
customer.payment_method.disabled A saved customer payment method has been disabled.

payment.success

Triggered when a payment has been successfully authorised and funds captured. The fundingSummary object details how the transaction was funded.

Example Payload - Checkout Session

{
  "data": {
    "amount": {
      "amount": 15000,
      "currency": "GBP",
      "amountMultiplier": 100
    },
    "source": "checkoutSession",
    "status": "PaymentSuccess",
    "brandId": "123-123-123-123",
    "paymentId": "123-123-123-123",
    "fundingSummary": {
      "superFundedAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "customerFundedAmount": {
        "amount": 15000,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "merchantFundedAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "cashPayableToMerchant": {
        "amount": 15000,
        "currency": "GBP",
        "amountMultiplier": 100
      }
    },
    "surchargeAmount": {
       "amount": 600,
       "currency": "GBP",
       "amountMultiplier": 100
    },
    "paymentReference": "PAYMENT123",
    "externalReference": "TestOrder123",
    "paymentInitiatorId": "123-123-123-123"
  },
  "eventId": "evt_test_123",
  "eventType": "payment.success",
  "eventDatetime": "2026-03-15T11:09:09.000Z"
}

Example Payload - Payment Link

{
  "data": {
    "amount": {
      "amount": 5000,
      "currency": "GBP",
      "amountMultiplier": 100
    },
    "source": "paymentLink",
    "status": "PaymentSuccess",
    "brandId": "123-123-123-123",
    "paymentId": "123-123-123-123",
    "fundingSummary": {
      "superFundedAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "customerFundedAmount": {
        "amount": 5000,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "merchantFundedAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "cashPayableToMerchant": {
        "amount": 5000,
        "currency": "GBP",
        "amountMultiplier": 100
      }
    },
    "surchargeAmount": {
       "amount": 600,
       "currency": "GBP",
       "amountMultiplier": 100
    },
    "paymentReference": "PAYMENT123",
    "externalReference": "TestOrder123",
    "paymentInitiatorId": "123-123-123-123"
  },
  "eventId": "evt_test_123",
  "eventType": "payment.success",
  "eventDatetime": "2026-03-15T10:20:28.000Z"
}

payment.failed

Triggered when a payment was not completed. The status field in the data object indicates the specific reason:

Status Description
PaymentFailed The transaction was declined or could not be processed by the provider.
PaymentCancelled The customer manually cancelled the transaction before completion.
PaymentAbandoned The customer closed the checkout session without taking action.

Note:fundingSummary will be null for all failed payment events.

Example Payload - PaymentCancelled

{
  "data": {
    "amount": {
      "amount": 15000,
      "currency": "GBP",
      "amountMultiplier": 100
    },
    "source": "checkoutSession",
    "status": "PaymentCancelled",
    "brandId": "123-123-123-123",
    "paymentId": "123-123-123-123",
    "fundingSummary": null,
    "paymentReference": "PAYMENT123",
    "externalReference": "TestOrder123",
    "paymentInitiatorId": "123-123-123-123"
  },
  "eventId": "evt_test_123",
  "eventType": "payment.failed",
  "eventDatetime": "2026-03-15T08:54:24.000Z"
}

Example Payload - PaymentAbandoned

{
  "data": {
    "amount": {
      "amount": 15000,
      "currency": "GBP",
      "amountMultiplier": 100
    },
    "source": "checkoutSession",
    "status": "PaymentAbandoned",
    "brandId": "123-123-123-123",
    "paymentId": "123-123-123-123",
    "fundingSummary": null,
    "paymentReference": "PAYMENT123",
    "externalReference": "TestOrder123",
    "paymentInitiatorId": "123-123-123-123"
  },
  "eventId": "evt_test_123",
  "eventType": "payment.failed",
  "eventDatetime": "2026-03-14T13:32:28.000Z"
}

refund.success

Triggered when a refund has been successfully processed against an original transaction.

Example Payload

{
  "data": {
    "amount": {
      "amount": 15000,
      "currency": "GBP",
      "amountMultiplier": 100
    },
    "status": "RefundSuccess",
    "brandId": "123-123-123-123",
    "refundId": "123-123-123-123",
    "refundReference": "REFUND123",
    "refundComponents": {
      "superAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "customerAmount": {
        "amount": 15000,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "merchantAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      }
    },
    "externalReference": "TestOrder123",
    "originatingPaymentId": "123-123-123-123",
    "originatingPaymentSource": "checkoutSession",
    "originatingPaymentExternalReference": "TestOrder123"
  },
  "eventId": "evt_test_123",
  "eventType": "refund.success",
  "eventDatetime": "2026-03-15T10:46:27.000Z"
}

refund.failed

Triggered when a refund could not be processed against an original transaction.

Example Payload

{
  "data": {
    "amount": {
      "amount": 15000,
      "currency": "GBP",
      "amountMultiplier": 100
    },
    "status": "RefundFailed",
    "brandId": "123-123-123-123",
    "refundId": "123-123-123-123",
    "refundReference": "REFUND123",
    "refundComponents": {
      "superAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "customerAmount": {
        "amount": 15000,
        "currency": "GBP",
        "amountMultiplier": 100
      },
      "merchantAmount": {
        "amount": 0,
        "currency": "GBP",
        "amountMultiplier": 100
      }
    },
    "externalReference": "TestOrder123",
    "originatingPaymentId": "123-123-123-123",
    "originatingPaymentSource": "checkoutSession",
    "originatingPaymentExternalReference": "TestOrder123"
  },
  "eventId": "evt_test_123",
  "eventType": "refund.failed",
  "eventDatetime": "2026-03-15T10:46:27.000Z"
}

customer.payment_method.requires_action

Triggered when a saved customer payment method requires further action before it can be used for off-session payments. You should prompt the customer to re-authenticate or update their payment details.

Example Payload

{
  "data": {
    "type": "CARD",
    "usage": "OFF_SESSION",
    "status": "REQUIRES_ACTION",
    "customerId": "cus_123",
    "merchantId": "123-123-123-123",
    "paymentMethodId": "pm_123"
  },
  "eventId": "evt_test_123",
  "eventType": "customer.payment_method.requires_action",
  "eventDatetime": "2026-03-12T16:21:16.000Z"
}

customer.payment_method.enabled

Triggered when a saved customer payment method has been successfully enabled and is ready to be used for off-session payments.

Example Payload

{
  "data": {
    "type": "CARD",
    "usage": "OFF_SESSION",
    "status": "ENABLED",
    "customerId": "cus_123",
    "merchantId": "123-123-123-123",
    "paymentMethodId": "pm_123"
  },
  "eventId": "evt_test_123",
  "eventType": "customer.payment_method.enabled",
  "eventDatetime": "2026-03-10T13:12:40.000Z"
}

customer.payment_method.disabled

Triggered when a saved customer payment method has been disabled and can no longer be used for off-session payments.

Example Payload

{
  "data": {
    "type": "CARD",
    "usage": "OFF_SESSION",
    "status": "DISABLED",
    "customerId": "cus_123",
    "merchantId": "123-123-123-123",
    "paymentMethodId": "pm_123"
  },
  "eventId": "evt_test_123",
  "eventType": "customer.payment_method.disabled",
  "eventDatetime": "2026-03-10T13:16:06.000Z"
}

Payment Identification

Every webhook payload includes a paymentId that uniquely identifies the payment transaction. This is the same value as the paymentIntentId returned in the /proceed endpoint and the id returned in the /payments endpoint response.

Source Field Description
/proceed | /payments response paymentIntentId | id Unique identifier assigned to the payment transaction
Webhook payload paymentId The same identifier, referencing the transaction in status updates

Use this shared identifier to correlate webhook events with the payment transactions initiated from your server.

Matching Webhooks to Orders

The externalReference field in the webhook payload is a pass-through value set by the merchant at payment creation. Super Payments does not use this field to deduplicate or relate transactions.

Because multiple transactions can share the same externalReference, you should use the paymentId as the primary identifier when processing webhook events.

Recommended approach:

  1. When calling /proceed| /payments, store the returned paymentIntentId|id against your order.
  2. If the customer retries the payment, call the relavent endpoint again and update the stored ID with the new value.
  3. When a webhook is received, validate that the incoming paymentId matches the paymentIntentId | idcurrently associated with your order.
  4. Discard any webhook where the transactionId does not match.

Example Approach

ON /proceed response:
    order.paymentIntentId = response.paymentIntentId
    SAVE order

ON webhook received:
    order = FIND order BY webhook.externalReference

IF webhook.paymentId != order.paymentIntentId:
        LOG "Ignoring webhook for outdated transaction"
        RETURN 200 OK
    ELSE:
        UPDATE order status
        RETURN 200 OK

Supported Payment Methods

Webhooks are triggered for the following:

Best Practices

Return a 2xx response

Your endpoint must quickly return a successful status code (2xx) prior to executing any complex logic that could cause a timeout. For example, you should return a 200 response immediately upon receiving the event, before performing tasks like updating your database or triggering order fulfillments. This prevents Super from marking the attempt as a failure and initiating retries.