Stripe Card Collections

๐Ÿ“˜

Stripe Collection Module template on Github

Root offers a preconfigured Stripe Collection Module Template to help you get started quickly with your build. Clone it from Github to get started.

Creating a new Stripe webhook

Get a collection module token

In order to create the webhook on Stripe, we need an endpoint on Root that Stripe can hit.
To create this, we first need a token for the collection module.

curl -XPOST -H 'Authorization: Basic {{authToken}}' -d '{
  "description": "Collection module webhook for Stripe to hit",
  }' '{{host}}/v1/apps/{{org_id}}/insurance/collection-modules/{{collection_module_key}}/tokens'

Use your login token from the Root platform as the username. This can be retrieved from your cookies in the browser, or by hitting the login endpoint on Root.

If this is successful, you should receive a response like this:

Copy the secret for later.

{  
  "collection_module_token_id": "00000000-c164-4d0f-af25-7485c41b29fc",  
  "collection_module_id": "00000000-2ec3-4034-a9e3-93ade71a4907",  
  "description": "Collection module webhook for Stripe to hit",  
  "created_at": "2024-05-28T13:48:00.580Z",  
  "created_by": {  
    "type": "user",  
    "id": "be30701a-b0fa-43d2-a261-9ced8239191e"  
  },  
  "secret": "cm_sandbox_ODdm..."  
}

Create the webhook on Stripe

  1. Login to Stripe
  2. Select the "Developers" button on the top right.
  3. Ensure you are in the correct mode. "Test mode" is probably where you want to be.
  4. Go to webhooks and add a new endpoint

The endpoint URL is {{host}}/v1/insurance/collection-modules/{{secret}}/webhook
e.g: https://sandbox.uk.rootplatform.com/v1/insurance/collection-modules/cm_sandbox_xxx/webhook

  1. Select the events you would like to listen to

  1. Once you have selected all the events, take note of them, because we will need the event keys when handling them in our collection module.
  2. Be sure to click "Add events".
  3. Once you are done - click "Add endpoint".

Handling events in collection module

All of these events need to be handled in our collection module.
When the events are triggered, Stripe will hit our webhook endpoint with a payload. We need to handle that payload appropriately.

In your collection module, navigate to the webhook-hooks file.
Here you should have a processWebhookRequest function. This is where the webhook request will be handled.
Each event should be handled here.

Example:

const payload = parsedBody.data.object;  
    switch (parsedBody.type) {  
      case StripeEvents.InvoiceCreated: {  
        await new ProcessInvoiceCreatedEventController(  
          environment as Environment, // TODO: Remove all instances of environment - replace with global  
        ).process(payload as Stripe.Invoice);  
        break;  
      } 
	case StripeEvents.InvoicePaid: {
    await new ProcessInvoicePaidEventController(
      environment as Environment,
    ).process(payload as Stripe.Invoice);
    break;
  }

  case StripeEvents.InvoicePaymentFailed: {
    await new ProcessInvoicePaymentFailedEventController(
      environment as Environment,
    ).process(payload as Stripe.Invoice);
  }

  case StripeEvents.SubscriptionScheduleUpdated: {
    await new ProcessSubscriptionScheduleUpdatedEventController(
      environment as Environment,
    ).process(payload as Stripe.SubscriptionSchedule);
  }

  case StripeEvents.InvoiceVoided:
  case StripeEvents.InvoiceMarkedUncollectible: {
    await new ProcessInvoiceMarkedUncollectableEventController().process(
      payload as Stripe.Invoice,
    );
  }

  case StripeEvents.ChargeRefunded: {
    await new ProcessInvoiceChargeRefundedEventController(
      environment as Environment,
    ).process(payload as Stripe.Charge);
    break;
  }

  case StripeEvents.PaymentIntentSucceeded: {
    await new ProcessPaymentIntentSucceededEventController(
      environment as Environment,
    ).process(payload as Stripe.PaymentIntent);
  }

  default:
    // Unexpected event type
    throw new Error(
      `[${environment}] Collection module does not handle event type '${parsedBody.type}'.`,
    );
}
return {
  response: {
    status: 200,
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({}),
  },
};

Setting environment variables in collection modules and where to find them

In order for the collection module to work with Stripe, we need to update a couple of environment variables which will be used in your code. These variables can all be set in the config.ts file.

KeyDescriptionExample
STRIPE_API_KEYFound under the API keys tab. Used to authenticate with the Stripe SDK.
https://docs.stripe.com/api/authentication
sk_live_.....
STRIPE_PRODUCT_IDFound under the products tab.
https://docs.stripe.com/api/products
prod_.....
STRIPE_WEBHOOK_SIGNING_SECRETThe Stripe webhook signing secret. Used to authorize requests from Stripe. See authWebhookRequestfunction in webhook-hooks.tswhsec_.....
STRIPE_PUBLISHABLE_KEY_LIVEThe Stripe publishable key. This is used when rendering the Stripe card details form.
See renderCreatePaymentMethod in lifecycle-hooks.ts
pk_live_.....

Push and Publish the collection module

Once the environment variables have been configured, be sure to rp push and publish your collection module.