npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@modcord/paypal-client

v1.0.1

Published

A PayPal client designed to interract with the PayPal API.

Downloads

7

Readme

paypal-client

A PayPal HTTP API client, for internal use in ModCord.

Installing

To install the library, use the command below in your project directory.

npm install @modcord/paypal-client

Library Usage

  • Since PayPal works with basic authentication issuing short-lived tokens, the library requires the user to trigger the token exchange loop before making any requests to the REST API.

  • The paypal.identify() will return a promise that will resolve with true when the client has obtained the authorization and also a ready event will be emitted.

  • It is recommended to check if the paypal.ready property is strictly true before trying to fetch or make any requests.

  • To get your app's client id and secret go to https://developer.paypal.com/developer/applications/.

const PayPalClient = require("@modcord/paypal-client");
const paypal = new PayPalClient({
  client_id: "AT5...3sR", // Your PayPal app client id.
  secret: "EDv...lcj", // Your PayPal app secret.
  environment: "sandbox", // The environment for the run, can be either "live" or "sandbox".
  keep_cache: false // Whether to populate manager's cache with information when you fetch one or more instances.
});

paypal.on("ready", () => {
  console.log("The authorization has been resolved, and the library is ready to make requests..");
});

paypal.identify();

Important!!

  • All of the examples below assume you set up the library the way it is shwon above, if you did it in another way you will need to tweak the examples for your own use case.
  • The examples below show the full list of parameters you can use to call a method or do a specific thing, when the comment next to it says is optional, you may ommit to include that in your code.

1. Catalog Products API

1.1 Products

1.1.1 Creating a product

const { ProductTemplate } = require("@modcord/modcord-client");
...
paypal.on("ready", async () => {
  const newProduct = new ProductTemplate()
    .setName("My New Product")
    .setDescription("A description for my new product.")
    .setType("DIGITAL")
    .setCategory("SOFTWARE")
    .setId("MY-VERY-OWN-ID")
    .setImageUrl("https://image.shutterstock.com/image-vector/new-item-sign-stamp-on-600w-1773071672.jpg")
    .setHomeUrl("https://google.com");

  const myNewProduct = await paypalClient.products.create(newProduct);

  console.log(myNewPorduct);
  // Sample Output:
  //  Product {
  //    client: [Client],
  //    manager: [ProductManager],
  //    id: 'MY-VERY-OWN-ID',
  //    name: 'My New Product',
  //    description: 'A description for my new product.',
  //    type: 'DIGITAL',
  //    category: 'SOFTWARE',
  //    imageUrl: 'https://image.shutterstock.com/image-vector/new-item-sign-stamp-on-600w-1773071672.jpg',
  //    homeUrl: 'https://google.com/',
  //    createTime: 2021-08-02T22:25:24.000Z,
  //    updateTime: 2021-08-02T22:25:24.000Z
  //  }
});

1.1.2 Fetching products in bulk

paypal.on("ready", async () => {
  const myProducts = await paypal.products.fetchBulk({
    page_count: 1, // Optional, maximum amount of pages to fetch, the amount of products returned = 20 * page_count. 
    all: false // Optional, whether to fetch all of the existing products.
  });

  console.log(myProducts);
  // Sample Output: Collection(2) [Map] {
  //   'PROD-6BF74421N29171330' => Product {
  //     client: [Client],
  //     manager: ProductManager { client: [Client], cache: [Collection [Map]] },
  //     id: 'PROD-6BF74421N29171330',
  //     name: 'ModCord Plus',
  //     description: 'Discord bot plus plan service.',
  //     type: 'SERVICE',
  //     category: 'SOFTWARE',
  //     imageUrl: 'https://cdn.discordapp.com/avatars/624617804611452929/4a76c4f5dbf105691f47f0cac3d5756a.png?size=256',
  //     homeUrl: 'https://modcord.xyz/',
  //     createTime: 2021-03-24T07:35:39.000Z,
  //     updateTime: 2021-03-24T07:35:39.000Z
  //   },
  //   'PROD-98551998BW8384520' => Product {
  //     client:[Client],
  //     manager: ProductManager { client: [Client], cache: [Collection [Map]] },
  //     id: 'PROD-98551998BW8384520',
  //     name: 'ModCord',
  //     description: 'Discord bot royalty services.',
  //     type: 'SERVICE',
  //     category: 'SOFTWARE',
  //     imageUrl: 'https://cdn.discordapp.com/avatars/624617804611452929/4a76c4f5dbf105691f47f0cac3d5756a.png?size=256',
  //     homeUrl: 'https://modcord.xyz/',
  //     createTime: 2021-03-24T07:56:01.000Z,
  //     updateTime: 2021-03-24T07:56:01.000Z
  //   }
  // }
});

1.1.3 Fetching product by id

paypal.on("ready", async () => {
  const myProduct = await paypal.products.fetch(
    "PROD-6BF74421N29171330",
    false
  );

  console.log(myProduct);
  // Sample: Product {
  //   client: [Client],
  //   manager: [ProductManager]
  //   id: 'PROD-6BF74421N29171330',
  //   name: 'ModCord Plus',
  //   description: 'Discord bot plus plan service.',
  //   type: 'SERVICE',
  //   category: 'SOFTWARE',
  //   imageUrl: 'https://cdn.discordapp.com/avatars/624617804611452929/4a76c4f5dbf105691f47f0cac3d5756a.png?size=256',
  //   homeUrl: 'https://modcord.xyz/',
  //   createTime: 2021-03-24T07:35:39.000Z,
  //   updateTime: 2021-03-24T07:35:39.000Z
  // }
}
});

1.1.4 Updating a product

  • This method can be applied to any product instance.
paypal.on("ready", async () => {
    const myProduct = await paypal.products.fetch(
    "PROD-6BF74421N29171330",
    false
  );

  console.log(myProduct.name);
  // Output: ModCord Plus

  console.log(myProduct.description);
  // Output: Discord bot plus plan service.

  console.log(myProduct.imageUrl);
  // Output: https://cdn.discordapp.com/avatars/624617804611452929/4a76c4f5dbf105691f47f0cac3d5756a.png?size=256

  console.log(myProduct.homeUrl);
  // Output: https://modcord.xyz/

  const operationResult = await myProduct.update({
    name: "ModCord Pro",
    description: "The re-branded pro plan.",
    imageUrl: "https://image.shutterstock.com/image-vector/new-item-sign-stamp-on-600w-1773071672.jpg",
    homeUrl: "https://modcord.com"
  });

  console.log(operationResult);
  // Output: true if success
  // Output: the http json or false if failed 

  console.log(myProduct.name);
  // Output: ModCord Pro

  console.log(myProduct.description);
  // Output: The re-branded pro plan.

  console.log(myProduct.imageUrl);
  // Output: https://image.shutterstock.com/image-vector/new-item-sign-stamp-on-600w-1773071672.jpg

  console.log(myProduct.homeUrl);
  // Output: https://modcord.com
});

2. Subscriptions API

2.1 Plans

2.1.1 Fetching plans in bulk

paypal.on("ready", async () => {
  const myPlans = await paypal.plans.fetchBulk({
    product_id: "PROD-2435DY8H5G84454455V", // Optional, used to fetch only the plans containing a certain product id.
    page_count: 1, // Optional, maximum amount of pages to fetch, the amount of plans returned = 20 * page_count. 
    all: false // Optional, whether to fetch all of the existing plans.
  });

  console.log(myPlans);
  // Sample Output: 
  //   Collection(2) [Map] {
  //     'P-12T40581WT129034PMBNO4EI' => Plan {
  //       client: [Client],
  //       id: 'P-12T40581WT129034PMBNO4EI',
  //       version: 1,
  //       name: 'ModCord Plus Plan',
  //       description: 'Modcord plus plan',
  //       status: 'ACTIVE',
  //       usage_type: 'LICENSED',
  //       billingCycles: [ [BillingCycle] ],
  //       paymentPreferences: PaymentPreferences {
  //         serviceType: 'PREPAID',
  //         autoBillOutstanding: true,
  //         setupFee: [Price],
  //         setupFeeFailureAction: 'CONTINUE',
  //         paymentFailureThreshold: 3
  //       },
  //       taxes: Taxes { percentage: 8, inclusive: null },
  //       payee: Payee { merchantId: '5CXXY2PXB3AES', displayData: [DisplayData] },
  //       createTime: 2021-03-24T07:45:21.000Z,
  //       updateTime: 2021-03-24T07:45:21.000Z
  //     },
  //     'P-5D525680HN2867820MBNPCQI' => Plan {
  //       client: [Client],
  //       id: 'P-5D525680HN2867820MBNPCQI',
  //       version: 1,
  //       name: 'ModCord Premium Plan',
  //       description: 'TEST!?!?',
  //       status: 'ACTIVE',
  //       usage_type: 'LICENSED',
  //       billingCycles: [ [BillingCycle] ],
  //       paymentPreferences: PaymentPreferences {
  //         serviceType: 'PREPAID',
  //         autoBillOutstanding: true,
  //         setupFee: [Price],
  //         setupFeeFailureAction: 'CANCEL',
  //         paymentFailureThreshold: 4
  //       },
  //       taxes: Taxes { percentage: 7, inclusive: null },
  //       payee: Payee { merchantId: '5CXXY2PXB3AES', displayData: [DisplayData] },
  //       createTime: 2021-03-24T07:58:57.000Z,
  //       updateTime: 2021-08-02T19:52:09.000Z
  //     }
  //   }
});

2.1.2 Fetching plans by id

paypal.on("ready", async () => {
  const plan = await paypal.plans.fetch(
    "P-5D525680HN2867820MBNPCQI", // Required, the plan id you want to fetch. 
    false //  Optional, Whether to bypass the existing cache if paypal.keep_chache is enabled and make a request.
  );

  console.log(plan);

  // Sample Output:
  //   Plan {
  //     client: [Client],
  //     id: 'P-5D525680HN2867820MBNPCQI',
  //     version: 1,
  //     name: 'ModCord Premium Plan',
  //     description: 'TEST!?!?',
  //     status: 'ACTIVE',
  //     usage_type: 'LICENSED',
  //     billingCycles: [ [BillingCycle] ],
  //     paymentPreferences: PaymentPreferences {
  //       serviceType: 'PREPAID',
  //       autoBillOutstanding: true,
  //       setupFee: [Price],
  //       setupFeeFailureAction: 'CANCEL',
  //       paymentFailureThreshold: 4
  //     },
  //     taxes: Taxes { percentage: 7, inclusive: null },
  //     payee: Payee { merchantId: '5CXXY2PXB3AES', displayData: [DisplayData] },
  //     createTime: 2021-03-24T07:58:57.000Z,
  //     updateTime: 2021-08-02T19:52:09.000Z
  //   }
});

2.1.3 Deactivating a plan

  • You can apply this method on every plan instance.
paypal.on("ready", async () => {
  const plan = await paypal.plans.fetch(
    "P-5D525680HN2867820MBNPCQI", // Required, the plan id you want to fetch. 
    false //  Optional, Whether to bypass the existing cache if paypal.keep_chache is enabled and make a request.
  );

  console.log(plan.status);
  // Output: ACTIVE

  const operationResult = await plan.deactivate(); 
  console.log(operationResult); // true if success, false if failed

  console.log(plan.status);
  // Output: INACTIVE

2.1.3 Activating a plan

  • You can activate plans with statuses CREATED and INACTIVE
  • You can apply this method on every plan instance.
paypal.on("ready", async () => {
  const plan = await paypal.plans.fetch(
    "P-5D525680HN2867820MBNPCQI", // Required, the plan id you want to fetch. 
    false //  Optional, Whether to bypass the existing cache if paypal.keep_chache is enabled and make a request.
  );

  console.log(plan.status);
  // Output: INACTIVE or CREATED

  const operationResult = await plan.activate(); 
  console.log(operationResult); // true if success, false if failed

  console.log(plan.status);
  // Output: ACTIVE

3.1.4 Updating a plan

Fetching multiple plans.

paypal.on("ready", async () => {
  const plan = await paypal.plans.fetch(
    "P-5D525680HN2867820MBNPCQI", // Required, the plan id you want to fetch. 
    false //  Optional, Whether to bypass the existing cache if paypal.keep_chache is enabled and make a request.
  );

  console.log(plan.description);
  // Output: Old and boring description.

  console.log(plan.taxes.percentage);
  // Output: 0.7

  console.log(plan.paymentPreferences);
  // Output: PaymentPreferences {
  //    serviceType: 'PREPAID',
  //    autoBillOutstanding: true,
  //    setupFee: {
  //      currencyCode: "USD",
  //      value: 3.52
  //    },
  //    setupFeeFailureAction: 'CONTINUE',
  //    paymentFailureThreshold: 2
  //  }

  const operationResult = await plan.update({
    description: "The shiny new description!",
    taxes: {
      percentage: 10.5
    },
    paymentPreferences: {
      autoBillOutstanding: false,
      paymentFailureThreshold: 4,
      setupFee: {
        currencyCode: "USD",
        value: 4.69
      },
      setupFeeFailureAction: "CANCEL"
    }
  });

  console.log(operationResult);
  // Output: true if success
  // Output: the http json or false if failed 

  console.log(plan.description);
  // Output: The shiny new description!

  console.log(plan.taxes.percentage);
  // Output: 10.5

  console.log(plan.paymentPreferences);
  // Output: PaymentPreferences {
  //    serviceType: 'PREPAID',
  //    autoBillOutstanding: false,
  //    setupFee: {
  //      currencyCode: "USD",
  //      value: 4.69
  //    },
  //    setupFeeFailureAction: 'CANCEL',
  //    paymentFailureThreshold: 4
  //  }
});

3.1.5 Creating a plan

paypal.on("ready", async () => {
  const myProduct = await paypal.products.fetch(
    "PROD-6BF74421N29171330", // The product id to fetch.
    true // Whether to bypass the cache.
  );

  const myNewPlan = new PlanTemplate()
    .setProductId(myProduct.id) // Required, the product id of this plan.
    .setName("My Nice Plan") // Required, the name for this plan.
    .setDescription("A very nice plan to create.") // Optional, the description for this plan.
    .setStatus("ACTIVE") // Optional, the status for this plan - by default the status is "CREATED" - can be "CREATED" or "ACTIVE".
    .setPaymentPreferences({ // Optional, the payment preferences.
      autoBillOutstanding: true, // Whether to bill outstanding balances automatically.
      setupFailureAction: "CANCEL", // What to do when the setup billing fails: "CONTINUE" or "CANCEL".
      paymentFailureThreshold: 3, // The threshold for billing failures until the setupFailureAction is triggered.
      setupFee: { // The setup fee.
        currencyCode: "USD", // The currency code.
        value: 2.44 // The value, amount of currency code.
      }
    })
    .setTaxes(20, true) // 20% taxes that have been included in the plan's price
    .addBillingCycle({ // All of the subscriptions must have 1 billing cycle.
      fixedPrice: { // The price for this cycle.
        currencyCode: "USD", // The currency for this price.
        value: 0 // The value for this price.
      },
      pricingModel: "VOLUME" // The pricing model, can be TIERED or VOLUME: TIERED also reauires you to provide a tiers array to the pricing scheme.
    }, {
      intervalUnit: "WEEK", // How often this billing cycle is billing.
      intervalCount: 2 // The amount of units: for instance this billing cycle will last 2 weeks.
    }, "TRIAL", 1, 1) // The type for this billing cycle is trial, with a sequence of 1: it'll be executed first when subscribed to; and totalCycles of 1: it'll repeat once - for 2 weeks.
    .addBillingCycle({
      fixedPrice: { // The price for this cycle.
        currencyCode: "USD", // The currency.
        value: 4.99 // The value.
      },
      pricingModel: "VOLUME" // Pricing mode - VOLUME or TIERED: TIERED also requires you to provide a tiers array.
    }, {
      intervalUnit: "MONTH", // The interval unit for this cycle.
      intervalCount: 1 // The intercal unit count for this cycle - this will bill every 1 month after subscribing.
    }, "REGULAR", 2, 0) // The type for this billing cycle is "REGULAR", the sequence is 2 so it comes after the trial defined before, and totalCycles: 0 - it'll repeat until the user unsubscribes.
    .setQuantitySupported(false); // Whether the user can input a quentity when checking out subscription, set to false.
  
  const myPlan = await paypal.plans.create(myNewPlan);
  console.log(myPlan);
  // Sample output:
  // Plan {
  //   client: [Client],
  //   id: 'P-6ML94041PT1662406MEFJZJQ',
  //   version: undefined,
  //   name: 'My Nice Plan',
  //   description: 'A very nice plan to create.',
  //   status: 'ACTIVE',
  //   usage_type: 'LICENSED',
  //   billingCycles: [
  //     BillingCycle {
  //       plan: [Circular *2],
  //       pricingScheme: [PricingScheme],
  //       frequency: [Frequency],
  //       tenureType: 'TRIAL',
  //       sequence: 1,
  //       totalCycles: 1
  //     },
  //     BillingCycle {
  //       plan: [Circular *2],
  //       pricingScheme: [PricingScheme],
  //       frequency: [Frequency],
  //       tenureType: 'REGULAR',
  //       sequence: 2,
  //       totalCycles: 0
  //     }
  //   ],
  //   paymentPreferences: PaymentPreferences {
  //     serviceType: 'PREPAID',
  //     autoBillOutstanding: true,
  //     setupFee: Price { currencyCode: 'USD', value: '2.44' },
  //     setupFeeFailureAction: 'CANCEL',
  //     paymentFailureThreshold: 3
  //   },
  //   taxes: null,
  //   payee: null,
  //   createTime: 2021-08-04T13:56:54.000Z,
  //   updateTime: 2021-08-04T13:56:54.000Z
  // }
});