Skip to main content
All CollectionsGetting started
Integration instructions
Integration instructions

Quick start guide for how to integrate the cancellation flow modal into your website.

David Wibergh avatar
Written by David Wibergh
Updated today

This guide walks you through the process of integrating Refloat's cancellation flow modal into your website. The modal helps retain customers by offering personalized offers during subscription cancellations.

1. Place the Script Element

The code snippet below imports the Refloat client-side module and assigns it to the window.refloat namespace. This allows you to initialize the Refloat Cancel Flow for your customers later on. Please place this code in the HTML <head> element.

To ensure Failed Payment Recovery works properly upon release, it's recommended to place the snippet on all pages, rather than just the subscription cancellation page.

<!-- Include the Refloat SDK on your page -->
<script>
!function(){
const a = document.createElement('script');
a.src = 'https://assets.refloat.com/snippet.js';
a.async = true;
const b = document.getElementsByTagName('script')[0];
b.parentNode.insertBefore(a, b);
}();
</script>

2. Generate Secure HMAC Hash

To ensure secure access, requests need to be authenticated by generating an HMAC hash using the Stripe Customer ID and your Secret Key.

Below are examples of how to generate an HMAC hash in various backend languages.

NodeJS

import { createHmac } from "node:crypto";
const user_hash = crypto.createHmac(
"sha256",
SECRET_KEY // Replace with Secret Key (keep safe)
)
.update(STRIPE_CUSTOMER_ID) // Replace with actual Stripe Customer ID
.digest("hex"); // Send to front-end

Next.js

import crypto from "node:crypto";
import type { NextApiRequest, NextApiResponse } from "next";

type Data = {
readonly userHash?: string;
readonly error?: string;
};

export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
// Replace with actual Stripe Customer ID
const { STRIPE_CUSTOMER_ID } = req.body;

const authHash = crypto
// Your Secret Key (keep safe)
.createHmac("sha256", SECRET_KEY) // Replace with Secret Key (keep safe)
.update(STRIPE_CUSTOMER_ID)
.digest("hex");

// Send computed auth hash to front-end application
return res.status(200).json({ authHash });
}

Python (Django)

import hmac
import hashlib

auth_hash = hmac.new(
"SECRET_KEY".encode('utf-8'), # Replace SECRET_KEY with Secret Key (keep safe)
"STRIPE_CUSTOMER_ID".encode('utf-8'), # Replace STRIPE_CUSTOMER_ID with actual Stripe Customer ID
digestmod=hashlib.sha256
).hexdigest() # Send to front-end

Ruby (Rails)

OpenSSL::HMAC.hexdigest(
"sha256",
SECRET_KEY, # Replace with Secret Key (keep safe)
STRIPE_CUSTOMER_ID # Replace with actual Stripe Customer ID
) # Send to front-end

PHP

<?php
echo hash_hmac(
'sha256',
STRIPE_CUSTOMER_ID, // Replace with actual Stripe Customer ID
SECRET_KEY // Replace with Secret Key (keep safe)
);
?>

Go

package main

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)

func main() {
hash := hmac.New(
sha256.New,
SECRET_KEY // Replace with Secret Key (keep safe)
)
hash.Write(STRIPE_CUSTOMER_ID) // Replace with actual Stripe Customer ID
hex.EncodeToString(hash.Sum(nil))
}

Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Test {
public static void main(String[] args) {
try {
String clientSecret = SECRET_KEY // Replace with Secret Key (keep safe)
String stripeCustomerId = STRIPE_CUSTOMER_ID; // Replace with actual Stripe Customer ID

Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(clientSecret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);

byte[] hash = (sha256_HMAC.doFinal(stripeCustomerId.getBytes()));
StringBuffer result = new StringBuffer();
for (byte b : hash) {
result.append(String.format("%02x", b));
}

// Send to front-end
System.out.println(result.toString());
} catch (Exception e) {
System.out.println("Error");
}
}
}


3. Trigger the Cancellation Modal (from your web page)

Attach a listener to a button that will trigger the Refloat cancellation flow modal. Below is an example of how to attach a click event listener to a button.

<body>

<!-- ... -->

<button id="refloat-cancel-button">
Cancel subscription
</button>

<!-- ... -->

<script>
document.addEventListener("DOMContentLoaded", () => {
function spawnModal() {
window.refloat?.init && window.refloat.init({
tenantId: "", // Replace with Refloat Tenant ID
apiKey: "", // Replace with Refloat API Key
stripeCustomerId: "", // Replace with actual Stripe Customer ID
authHash: "", // Replace with calculated HMAC hash
})
}

document
.getElementById('refloat-cancel-button')
.addEventListener('click', spawnModal);
})
</script>
</body

4. Done

After adding the necessary script and handlers, when a user clicks the cancellation button, the Refloat SDK will open a modal that presents personalized offers, captures cancellation reasons, and provides insights for reducing churn.


Don’t hesitate to reach out if you have any questions, need assistance, or have any feedback.

Did this answer your question?