# Super Payments Documentation > Super powers free payments forever for businesses, and more rewarding shopping for our members, so everyone wins. We want businesses and shoppers to keep more of their money. We’re making it possible by eliminating the high fees on the internet charged by payments and digital advertising companies so that businesses can pass on these extra savings as cashback. Unlike other payment solution providers that charge between 1-5% for every transaction they process, Super is completely free to use, forever. ## Guides - [Getting Started](https://docs.superpayments.com/docs/getting-started.md): An overview of the steps to start accepting payments using Super Payments. - [Integration Methods](https://docs.superpayments.com/docs/manual-overview.md): A simple guide to manually integrate with Super Payments API. - [Embedded](https://docs.superpayments.com/docs/embedded-payments.md): A comprehensive guide to integrating our multi-payment method embedded checkout on your website. This solution allows you to offer Card (Apple Pay & Google Pay), Open Banking, and Credit (Pay Later) options within a single secure component. - [Hosted Page](https://docs.superpayments.com/docs/hosted-payment-page.md): A streamlined guide to integrating our secure, hosted payment page solution. - [Payment Links](https://docs.superpayments.com/docs/payments-payment-links.md): A streamlined guide to our no-code payment solution. - [Refund a Payment](https://docs.superpayments.com/docs/refund-a-payment.md): Easily manage and process customer refunds directly through our Portal or API. We provide full and partial refund capabilities to give you complete control over your post-purchase experience. - [Cash Rewards](https://docs.superpayments.com/docs/reward-calculation.md): Manage and calculate reward configurations to incentivize your customers. - [Saved Card Payments](https://docs.superpayments.com/docs/saved-card-payments.md): Saved card payments let you charge a customer's card at a later date without them needing to be present. Use this when you need to charge a customer and save their card details all in one session. - [Save a Card & Take Payment](https://docs.superpayments.com/docs/save-a-card-and-take-a-payment.md): Customers can request to store their card details during a payment, which you can then use for future payments without customers having to re-enter the details. - [Charge a Saved Card](https://docs.superpayments.com/docs/charge-a-saved-card.md): This guide explains how to charge a customer's saved card without them being present. This is a **merchant-initiated transaction (MIT)** - the customer has already consented to future charges during the initial payment, so no checkout flow or redirect is required. - [E-commerce Platforms](https://docs.superpayments.com/docs/e-commerce-platforms.md) - [Super for Shopify](https://docs.superpayments.com/docs/shopify.md): A seamless integration with Shopify. - [Super for Magento 2](https://docs.superpayments.com/docs/magento.md): A seamless integration with Magento. - [Super for BigCommerce](https://docs.superpayments.com/docs/bigcommerce.md): A seamless integration with BigCommerce. - [Super for WooCommerce](https://docs.superpayments.com/docs/woo-commerce.md): A seamless integration with WooCommerce. - [Integration security guide](https://docs.superpayments.com/docs/integration-security-guide.md): A reference for securing your Super Payments integration in production. - [Testing Your Integration ](https://docs.superpayments.com/docs/testing-your-super-integration.md): Use our sandbox environment for testing your integration before going live. Payments created in the sandbox are never processed by real banks or card networks, so you can test freely without affecting real customers or funds. - [Test with Cards](https://docs.superpayments.com/docs/test-with-cards.md): In the sandbox environment, you can use Adyen's standard test card numbers to simulate a range of payment scenarios - no real card details are needed. - [Test with Super Credit](https://docs.superpayments.com/docs/test-with-super-credit.md) - [Test with Open Banking](https://docs.superpayments.com/docs/test-with-open-banking.md): Use **Yapily Mock** to simulate the full Open Banking payment journey in your sandbox environment. No real bank account or credentials are needed. - [Go Live](https://docs.superpayments.com/docs/go-live.md): Before switching to your production credentials, run through the checklist below to make sure your integration is ready to accept live payments. - [Stored Credentials](https://docs.superpayments.com/docs/stored-credentials.md) - [Customers](https://docs.superpayments.com/docs/customers.md) - [Tokens](https://docs.superpayments.com/docs/tokens.md) - [Migrate to Super](https://docs.superpayments.com/docs/migrate-to-super.md) - [Custom Sites](https://docs.superpayments.com/docs/advertising-custom.md): Integrate advertisers component into your website - [Super messaging](https://docs.superpayments.com/docs/super-checkout-messaging.md): Let your customers know early on in their shopping journey that Super is available as a checkout option. Help their purchase decision and increase their likelihood to purchase from you, knowing that they’ll get money off. - [Super messaging guide](https://docs.superpayments.com/docs/understand-super-checkout-messaging.md): A best practice guide to highlight the ideal methods to let your customers know about Super, long before they decide to make a purchase. - [Super on your storefront](https://docs.superpayments.com/docs/marketing-assets.md): Get your customers thinking about Super at the beginning of their shopping journey. ## API Reference - [Authentication](https://docs.superpayments.com/reference/authentication.md) - [Errors](https://docs.superpayments.com/reference/errors.md) - [Pagination](https://docs.superpayments.com/reference/pagination.md) - [Versioning](https://docs.superpayments.com/reference/versioning.md) - [Webhooks](https://docs.superpayments.com/reference/webhooks.md): Stay in sync with real-time event notifications delivered directly to your server. - [External IPs](https://docs.superpayments.com/reference/external-ips.md): Super Payment Public IP Addresses - [Marketing Assets](https://docs.superpayments.com/reference/marketing-assets-1.md) - [Rate Limiting](https://docs.superpayments.com/reference/rate-limiting.md) - [Upgrading](https://docs.superpayments.com/reference/upgrading.md) - [Sandbox Environment](https://docs.superpayments.com/reference/sandbox-environment.md) - [Create Payment Intent](https://docs.superpayments.com/reference/create-payment-intent.md): This endpoint is used to create a payment intent for e-commerce transactions. It requires the merchant integration to be set up and will return a payment intent object upon successful creation. - [Search payment transactions](https://docs.superpayments.com/reference/search-payment-transactions-2025-11-01.md): Retrieve a list of payment transactions with filtering options. Results are paginated and can be filtered by various criteria including status, reference, and date range. Payment transactions are returned in reverse chronological order (newest first). If no filters are specified, all available payment transactions will be returned subject to pagination limits. Note that funding details and card metadata are not included in search results for performance reasons - use the individual payment transaction endpoint to access these details. - [Get payment transaction](https://docs.superpayments.com/reference/get-payment-transaction.md): Poll for an individual payment transaction status to check its current state. Returns detailed information about the payment including its status, amount, and funding details with associated card metadata. This endpoint includes detailed information about payment intent funding attempts and their associated card metadata. Use this endpoint if your integration has not been configured to use webhooks. Payment transactions are returned in real-time as they update in our system. - [Create Refund](https://docs.superpayments.com/reference/create-refund.md): This endpoint is used to initiate a refund for a payment transaction. - [Create Payout Refund (Restricted)](https://docs.superpayments.com/reference/create-payout-refund.md): This endpoint is used to initiate a payout refund to a provided payment method. This is a restricted endpoint, contact customer support to request access. - [Search refund transactions](https://docs.superpayments.com/reference/search-refund-transactions-2025-11-01.md): Retrieve a list of refund transactions with filtering options. Results are paginated and can be filtered by various criteria including status, payment ID, and date range. Refund transactions are returned in reverse chronological order (newest first). If no filters are specified, all available refund transactions will be returned subject to pagination limits. - [Get refund transaction](https://docs.superpayments.com/reference/get-refund-transaction-2025-11-01.md): Poll for an individual refund transaction status to check its current state. Returns detailed information about the refund transaction including its status and payment details. - [List settlements](https://docs.superpayments.com/reference/list-settlements-2025-11-01.md): Retrieve paginated settlement batches for the current merchant. Provide Accept - [Get settlement detail](https://docs.superpayments.com/reference/get-settlement-detail-2025-11-01.md): Fetch a single settlement and its payments/statistics. Provide Accept - [Get settlement reconciliation rows](https://docs.superpayments.com/reference/get-settlement-reconciliation-2025-11-01.md): Return ledger reconciliation items for a settlement, with pagination. Provide Accept - [Create a new checkout session](https://docs.superpayments.com/reference/create-checkout-session.md): Creates a new checkout session for a payment initiator. - [Retrieve a checkout session by ID](https://docs.superpayments.com/reference/get-checkout-session.md): Fetches the details of a checkout session using its ID. - [Proceed with payment via checkout session](https://docs.superpayments.com/reference/proceed-payment-via-checkout-session.md): Processes a payment using an existing checkout session. Requires the payment initiator ID and session details. - [Upsert order details for a checkout session](https://docs.superpayments.com/reference/upsert-order-details.md): Updates or inserts order details (shipping address, billing address, and/or line items) for an existing checkout session. At least one of the three fields must be provided. - [Get Payment Link by ID](https://docs.superpayments.com/reference/get-link.md): Retrieves a payment link by its ID. - [Update a link](https://docs.superpayments.com/reference/update-link.md): Updates an existing link with the provided data. - [Delete Payment Link](https://docs.superpayments.com/reference/delete-link.md): Deletes a payment link by its ID. - [List Payment Links](https://docs.superpayments.com/reference/list-links.md): Retrieves a list of payment links with optional filters, sorting, and pagination. - [Create Payment Link](https://docs.superpayments.com/reference/create-link.md): Creates a new payment link - [Generate a reward calculation for a given amount and brand](https://docs.superpayments.com/reference/generate-reward-calculation.md): This endpoint calculates the reward percentage and issuable rewards based on the provided amount and brand ID. - [Get the reward configuration for a brand](https://docs.superpayments.com/reference/get-reward-configuration.md): This endpoint retrieves the reward configuration for a specific brand, including the reward percentage, minimum spend, and rewards expiration time. - [Upsert the reward configuration for a brand](https://docs.superpayments.com/reference/upsert-brand-reward-configuration.md): This endpoint allows you to create or update the reward configuration for a specific brand, including the reward percentage, minimum spend, and rewards expiration time. - [Create Customer](https://docs.superpayments.com/reference/create-customer.md): This endpoint is used to create a representation of a known customer. You may supply your own identifier for a given customer, and will return a Super customer ID upon successful creation. - [List Customers](https://docs.superpayments.com/reference/list-customers.md): This endpoint lists your previously created customers in a paged list. Additional filters and sorting criteria may be provided as query parameters. - [Update Customer](https://docs.superpayments.com/reference/patch-customer.md): This endpoint is used to update the information of an existing customer. It requires the Super customer ID that was provided upon successful creation of the customer. - [Get Customer](https://docs.superpayments.com/reference/get-customer.md): This endpoint returns a previously created customer. It requires the Super customer ID that was provided upon successful creation of the customer. - [Create Payment Method](https://docs.superpayments.com/reference/create-payment-method.md): This endpoint creates a new payment method that will be associated with a particular customer. This payment method, once set up, can be used to create off-session payments against a given customer. - [List Payment Methods](https://docs.superpayments.com/reference/list-payment-methods.md): This endpoint lists your previously created payment methods in a paged list. Additional filters and sorting criteria may be provided as query parameters. - [Get Payment Method](https://docs.superpayments.com/reference/get-payment-method.md): This endpoint returns a previously created payment method, including its current status. It requires the Super payment method ID that was provided upon successful creation of the payment method. - [Create Setup Intent](https://docs.superpayments.com/reference/create-setup-intent.md): This endpoint creates a setup intent against a previously created payment method. The setup intent is used to orchestrate the process that allows a customer to set up their payment method (e.g. debit card) for future usage in off-session payments. It returns a session token that may be passed to the Web Component to begin the setup process. - [List Setup Intents](https://docs.superpayments.com/reference/list-setup-intents.md): This endpoint lists all existing setup intents. - [Refund Status Update Webhook](https://docs.superpayments.com/reference/refundstatusupdatewebhook.md): Configure this webhook against a specific Integration in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Payment Status Update Webhook](https://docs.superpayments.com/reference/paymentstatusupdatewebhook.md): Configure this webhook against a specific Integration in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Sent when a payment is successfully completed](https://docs.superpayments.com/reference/webhookpaymentsuccess.md): Configure this webhook in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Sent when a payment fails](https://docs.superpayments.com/reference/webhookpaymentfailed.md): Configure this webhook in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Sent when a refund is successfully completed](https://docs.superpayments.com/reference/webhookrefundsuccess.md): Configure this webhook in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Sent when a refund fails](https://docs.superpayments.com/reference/webhookrefundfailed.md): Configure this webhook in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Sent when a customer payment method is created and requires action to complete setup](https://docs.superpayments.com/reference/webhookcustomerpaymentmethodrequiresaction.md): Configure this webhook in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Sent when a customer payment method becomes enabled and ready for use](https://docs.superpayments.com/reference/webhookcustomerpaymentmethodenabled.md): Configure this webhook in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Sent when a customer payment method is disabled](https://docs.superpayments.com/reference/webhookcustomerpaymentmethoddisabled.md): Configure this webhook in your Business Portal.
HMAC signature verification Every webhook request includes a super-signature header so you can verify it came from Super and hasn't been tampered with. ## Header format The header contains a timestamp and a signature, separated by a comma: ```super-signature: t:1669219987926,v1:vCcZMqom...base64...``` - `t:` — Unix timestamp in milliseconds, generated when the request was signed - `v1:` — HMAC-SHA256 signature, base64-encoded ## Verifying a request 1. Parse the header. Split on "," to get the timestamp and signature parts, then split each on ":" to extract the values. 2. Build the signed message. Concatenate the timestamp and the raw request body, with no separator: "message = timestamp + raw_body" 2. Use the raw bytes of the request body — do not re-serialize parsed JSON, as whitespace or key ordering changes will invalidate the signature. 3. Compute the expected signature. Generate an HMAC-SHA256 of message using your webhook secret as the key, and base64-encode the result. 4. Compare signatures. Use a constant-time comparison (e.g. crypto.timingSafeEqual in Node, hmac.compare_digest in Python) to avoid timing attacks. Reject the request if they don't match. 5. Check the timestamp. Reject requests whose timestamp is more than 5 minutes old to prevent replay attacks. ## Example (Node.js) ```js const crypto = require('crypto'); function verifySuperSignature(rawBody, header, secret) { const parts = Object.fromEntries( header.split(',').map((p) => { return p.split(':'); }) ); const timestamp = parts.t; const signature = parts.v1; if (Math.abs(Date.now() - Number(timestamp)) > 5 * 60 * 1000) { return false; } const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}${rawBody}`) .digest('base64'); const expectedBuf = Buffer.from(expected, 'base64'); const actualBuf = Buffer.from(signature, 'base64'); if (expectedBuf.length !== actualBuf.length) { return false; } return crypto.timingSafeEqual(expectedBuf, actualBuf); } ```
- [Super Payments SDK for ReactNative](https://docs.superpayments.com/reference/getting-started-with-your-api.md) ## Recipes - [Accept a Payment](https://docs.superpayments.com/recipes/accept-a-payment.md) - [Accept an Embedded Payment on Your Website](https://docs.superpayments.com/recipes/accept-an-embedded-payment-on-your-website.md) - [Accept an Off-Session Payment](https://docs.superpayments.com/recipes/accept-an-off-session-payment.md) - [Handle Post Payment Events](https://docs.superpayments.com/recipes/handle-post-payment-events.md) - [Handle Post Refund Events](https://docs.superpayments.com/recipes/handle-post-refund-events.md) - [Refunds](https://docs.superpayments.com/recipes/refunds.md) ## Pages - [Super checkout messaging](https://docs.superpayments.com/super-checkout-messaging.md) ## Changelog - [Version 2026-04-01](https://docs.superpayments.com/changelog/version-2026-04-01.md) - [Version 2025-11-01](https://docs.superpayments.com/changelog/version-2025-11-01.md) - [Version 2025-06-01](https://docs.superpayments.com/changelog/version-2025-06-01.md) - [Version 2025-02-01](https://docs.superpayments.com/changelog/version-2025-02-01.md) - [Version 2024-10-01](https://docs.superpayments.com/changelog/version-2024-10-01.md)