Monika Vaghasiya


Here we will learn, how to export annotation drawn using PDFTron.

Events for export annotation

When we draw any annotation "annotationChanged" event will be fired, then we cache that event and we can export that annotation using "exportAnnotations".
When we draw annotation we'll save them in the database and when we reload the same document we can retrieve saved annotations from database and can again show them, we will learn that in my next blog post.
Here is example of how to save and annotation in database.


    path: 'path_to_the_PDFTron_'lib'_folder_on_your_server',
    css: 'webviewer_css',
    licenseKey: 'YOUR_PDF_TRON_LICENSE_KEY',
    initialDoc: 'YOUR_FILE URL' //url of a file to load
}, document.getElementById('viewer'))
    .then(function (instance) {
        let docViewer = instance.docViewer;
        let annotManager = instance.annotManager;
        annotManager.on('annotationChanged', (annots, action, e) => {
            if (e.imported) return;

                links: false,
                widgets: false,
                annotList: annots
            }).then(function (xfdfStrings) {

                annots.forEach(function (annot) {
                    if (action === "delete") {
                    } else {
                        saveAnnotation(, xfdfStrings);

                if (action === "add") {

                    if (annots[0]['Subject'] !== 'Comment') {
                        // to open comment box

let saveAnnotation = function (annotationId, annotationXfdf) {
    let saveAnnotationUrl = '';
    if (fromExtension) {
        saveAnnotationUrl = `YOUR_PROJECT_URL/annotations/${annotationId}`;
    } else {
        saveAnnotationUrl = `YOUR_PROJECT_URL/annotations/${annotationId}`;

        url: saveAnnotationUrl,
        type: 'POST',
        data: {annotation: annotationXfdf},
        success: function (result) {
        error: function (result) {

let deleteAnnotation = function (annotationId) {

    let deleteAnnotationUrl = '';
    if (fromExtension) {
        deleteAnnotationUrl = `YOUR_PROJECT_URL/annotations/${annotationId}`;
    } else {
        deleteAnnotationUrl = `YOUR_PROJECT_URL/annotations/${annotationId}`;

        url: deleteAnnotationUrl,
        type: 'DELETE',
        success: function (result) {
        error: function (result) {
December 21, 20201 minuteauthorMonika Vaghasiya

You must be thinking what is a webhook? Where it is used? What is the usage of it? And the most important why it’s used?

Webhooks are automated services, it is a way that the app can send automated messages or information to our system.

When something happens in the system then this service is fire and our system caches those services and can do according to changes in our system.

Let’s take an example of a stripe webhook

We have integrated Stripe payment gateway, we have according to payment fields in our system’s database. When our system user do the payment in stripe at that time payment is done in stripe, but now how will our system get to know about the customer has do payment or not?

When customer complete payment in stripe, it will send service(webhook) to our system which has information about customer payment detail, our system will cache this service, then our system will find that user in our system and if found then we can do payment changes in our customer detail.

November 28, 20201 MinutesauthorMonika Vaghasiya

The Stripe Customer Portal is very useful for managing customer subscriptions like Upgrade, Downgrade, and Renew.

Customers can review their invoices directly and also check their history.

Portal billing setting

Do login into your stripe account

Navigate to the portal settings to configure the portal, and do below billing settings


Create Product

First of all, we need to create products. Follow the below process for creating products.

Click on the “Products” menu from the sidebar and click on the “Add Product” button on the top right corner of the products page and create a product.

Here is an example of how to create a product.

Create two or three products as shown below.


Select product In portal settings

If you want to allow your customer to change their subscription by an upgrade, downgrade, cancel or renew you need to set products in your portal setting.

Now navigate to customer portal settings again, in the Products section, you will find a dropdown “Find or add a product..”, click on it you will find the plan you have added, select the price of this product.

portal settings

Don’t forget to save all these settings.

Then do the setup of your business information, also do branding settings in the “Appearance” section, and save it.

Once you are done with settings, you can preview the customer portal by clicking the Preview button beside the save button.

This will launch a preview of the portal so you can see how customers will use it for managing their subscriptions and billing details.

Integrate into Laravel

  • Get you API keys
    • Go to “Developers > API keys” here you will find your “Publishable key” and “Secret key

api keys

  • Create customer using stripe dashboard or by API
    • Create customer by Stripe API.
    • First of all, you’ll need to set your stripe secret key. For development mode, you can use test mode keys, but for production, you need to use your live mode keys

$customer = \Stripe\Customer::create([
    'name' => 'jenny rosen'
    'email' => ''
  • Once you create a customer using stripe API, now you can create a billing session for that customer using stripe API.
    • Create a billing session of the customer by API
   'customer' => 'cus_HnKDAQNjBniyFh',
   'return_url' => '',

You’ll get a response, like the below object:

  "id": "pts_c5cfgf8gjfgf73m5748g6",
  "object": "billing_portal.session",
  "created": 453543534,
  "customer": "cus_bGFsnjJDcSiJu",
  "livemode": false,
  "return_url": "'",

In the response body, there is a URL attribute:

Now redirect your customer to this URL immediately. For security purposes, this URL will expire in a few minutes.

After redirecting the customer to this URL, the portal will open and customers can manage their subscriptions and billing details in the portal. customers can return to the app by clicking the Return link on your company’s name or logo within the portal on the left side. They’ll redirect to the return_url you have provided at the time of creating the session or redirect URL set in your portal settings.

Listen to Webhooks

You must have a question, what is this Webhook!!!

It’s just an event, which will fire when a customer does any changes in his/her subscription in the portal, we can listen to this event in our app and make appropriate changes.

For example,

If a customer cancels his/her subscription in the portal, then how we will know about it!!

For it, when customers do any changes in his/her subscription

“customer.subscription.updated” event will be fired and we can listen for this event and, get to know the customer has changed subscription so we need to do appropriate changes in our app also.

Set webhook in your app

In the webhooks.php (in routes folder) file set up a route for handle webhook.

You can use the [Laravel Cashier Package ( to handle webhooks.

To set up a webhook for your portal navigate to the “Developers > Webhooks” menu you will find the below screen, here I have added a webhook to handle subscription cancel and update events, it will fire when customers update subscription, and you will receive it.


Click on the “Add endpoint” button and the below pop up will open. In Endpoint URL set the route you have created in the webhooks.php file. Select subscription updated and deleted events.

webhook endpoint

All done.

For more details, you can use stripe customer portal integration

November 19, 20203 MinutesauthorMonika Vaghasiya