pay2my.app
TypeScript icon, indicating that this package has built-in type declarations

1.4.19 • Public • Published

pay2my.app by overhide.io

A free and fully open-sourced ecosystem of widgets, a front-end library, and back-end services — to make addition of "logins" and "in-app-purchases" (IAP) to your app as banal as possible.


# pay2my.app widgets

Customizable web-components enabling login and in-app purchases (IAP, paid up-sells) for any Web application to be as simple as possible.

The web-components are backed by the legers.js library in the browser and renumeration APIs to allow IAP in US dollars, ethers, and bitcoins (easily extensible to other cryptos).

Everything is open-source.

The authentication and authorization mechanism used herein is the Ledger-Based Authorizations: crypto authorization concepts abstracted out for use with US dollars and any ledger based currency.

👉 jump to the demos

👉 read the tutorial

👉 read the remote-storage app tutorial

👉 reach out on r/overhide.

It's simple to add IAPs to your Web application — check out the "simplest" demo — it's essentially:

<html>

    ...

    <script>
      window.addEventListener('pay2myapp-appsell-sku-clicked',(e) => { /* react to feature being used, only if, auth'ed */ });
    </script>

    <pay2myapp-hub id="hub" apiKey="0x___API_KEY_ONLY_FOR_DEMOS_AND_TESTS___" isTest></pay2myapp-hub>      

    <pay2myapp-login hubId="hub"
                    overhideSocialMicrosoftEnabled
                    overhideSocialGoogleEnabled
                    overhideWeb3Enabled
                    ethereumWeb3Enabled
                    bitcoinEnabled
                    overhideSecretTokenEnabled>
    </pay2myapp-login>

    <pay2myapp-appsell hubId="hub" 
                      sku="2-dollar-feature"
                      priceDollars="2"
                      authorizedMessage="Use Feature"
                      unauthorizedTemplate="Add Feature ($${topup})"
                      bitcoinAddress="tb1qr9d7z0es86sps5f2kefx5grpj4a5yvp4evj80z"
                      ethereumAddress="0x046c88317b23dc57F6945Bf4140140f73c8FC80F"
                      overhideAddress="0x046c88317b23dc57F6945Bf4140140f73c8FC80F"
                      alwaysLogin>
    </pay2myapp-appsell>
    
    ...
    
</html>

The above three web-components in an HTML page are all that's needed for the simplest authentication and authorization scenarios — allowing you to get paid ($2 in the above sample). The components use the legers.js library library and renumeration APIs to provide all functionality.

Now, of course, the simplest example above is limited, it doesn't use a back-end and all code sits fully decompilable in the browser. It's useful for some scenarios, but for other scenarios you will want to re-check authorizations in your back-end code and have feature-flows run through a back-end.

Most demos in this repo have business flows incorporating one of two simple back-ends:

You can use the overhide.io hosted back-end to authorize IAP data via the help of lucchetto.js or simply base your own back-end off of /demo-back-end it's very little code.

The below infographic conveys at-a-glance what you get with these widgets:

The top-left shows a sample Web app with a nav-bar housing the [pay2myapp-status](#pay2myapp-status-) component. It also shows three purchase buttons. Clicking any of these will open up the [pay2myapp-login](#pay2myapp-login-) component which serves as our "login widget".

When a user wants to authorize for a feature; different UI experiences will present themselves depending on whether the feature is free, the user wants to pay in dollars, or the user wants to pay using a wallet, e.g., above, see:

  • anti-bot authentication
  • purchase for dollars
  • puchase with crypto wallet

A logged in user can check their previous payments in new browser tabs — UI experiences vary by currency/wallet.

Framework Users -- React.js, Angular, Vue.js, ...

These are standard Web components written using FAST.

They can be incorporated into any framework.

An example/demo of these components used in a React.js app is provided in its own repository: pay2my.app React.js Demo app.

Quick Start

To use these widgets in your Web app follow the steps below (or read through the tutorial).

Don't just read these steps, follow along copying/looking-at the demos.

The first three steps are gathering metadata necessary to setup how you, the developer, get paid.

The remainder of the steps are actual code changes in your Web application.

  1. onboard onto the dollar-ledger to get your US-dollar-ledger address (production | testnet)

    • optional, you don't need this if you just want to accept cryptos or don't want in-app purchases at all (just authentication)
  • but, keep in mind, it's too early to just accept cryptos — most people online won't have any just yet and it's prudent to give them the option to pay in dollars
  • you will create a new Stripe account or connect your existing Stripe account
  • you will provide the above address as the overhideAddress attribute in all your pay2myapp-appsell components (the feature buttons)
  1. onboard onto Ethereum (optional, recommended)

    • use a wallet such as MetaMask to generate your credentials
    • you will provide your Ethereum public address as the ethereumAddress attribute in all your pay2myapp-appsell components
  2. onboard onto Bitcoin (optional)

    • use a wallet such as Electrum to generate your credentials
    • you will provide your Bitcoin public address as the bitcoinAddress attribute in all your pay2myapp-appsell components
  3. pull in the pay2my.app.js component into your app, see CDN.

  4. add an pay2myapp-hub component to your DOM or initialize programatically

    • assign an id attribute to the hub if other components will de-reference this hub via their hubId attribtues; otherwise, call the setHub(..) explicitly on each of those components from script
    • configure the token attribute or apiKey (see Enabling with Token)
    • specify the isTest attribute if this is a testnet application, otherwise leave it out
  5. add an pay2myapp-login component to your DOM

    • configure the id of the pay2myapp-hub element via the hubId, or call this elements's setHub(..) setter to set the hub element programatically
    • list all the desired authentication/authorization methods for this application, the various overhide..Enabled attributes in pay2myapp-login
      • overhideSocialMicrosoftEnabled if you want Microsoft social-login against the US dollar ledger — must onboard step [1] above and specify overhideAddress in your pay2myapp-appsell elements
      • overhideSocialGoogleEnabled if you want Google social-login against the US dollar ledger — must onboard step [1] above and specify overhideAddress in your pay2myapp-appsell elements
      • overhideWeb3Enabled if you want customers to manage their US dollar ledger credentials with their Ethereum wallet such as MetaMask — must onboard step [1] above and specify overhideAddress in your pay2myapp-appsell elements
      • ethereumWeb3Enabled if you want to allow payments in ethers for customers with their Ethereum wallet such as MetaMask — must onboard step [2] above and specify ethereumAddress in your pay2myapp-appsell elements
      • bitcoinEnabled if you want to allow payments in bitcoins for customers with their Bitcoin wallet such as Electrum — must onboard step [3] above and specify bitcoinAddress in your pay2myapp-appsell elements
      • overhideSecretTokenEnabled if you want user-managed secret-token access against the US dollar ledger — must onboard step [1] above and specify overhideAddress in your pay2myapp-appsell elements
  6. add an pay2myapp-appsell component as an explicit "login" button (non-feature) to your DOM

    1. optional, as the feature buttons — when clicked — will login your users if they're not yet logged in
    2. configure the id of the pay2myapp-hub element via the hubId, or call this elements's setHub(..) setter to set the hub element programatically
    3. do not provide any pay2myapp-appsell attributesexcept for the hubId (above) and the loginMessage
  7. add pay2myapp-appsell components to your DOM for each feature

    1. configure the id of the pay2myapp-hub element via the hubId, or call this elements's setHub(..) setter to set the hub element programatically
    2. provide a unique sku attribute per button
    3. provide the desired priceDollars attribute, or 0 if setting up a for-free feature
    4. provide the authorizedMessage attribute to be displayed when user is already authorized and just needs to click on the feature to enable / use
    5. provide the unauthorizedTemplate attribute to be displayed when the user is not yet authorized to use the feature (insufficient funds, not auth'ed)
    6. provide the overhideAddress attribute if onboarded for US dollar payments in step [1] above
    7. provide the ethereumAddress attribute if onboarded for ethers payments in step [2] above
    8. provide the bitcoinAddress attribute if onboarded for bitcoin payments in step [3] above

Demos

We have several component demo files in /demo-front-end:

Demo Name Link Code Type of Back-End Notes
basic demo code overhide.io hosted the basic demo — pay2myapp-status in the nav-bar, a login button, 3 feature buttons.
no back-end demo code none a no back-end demo, everything just in-browser — same as basic otherwise
custom buttons demo code ./demo-back-end as Azure Function same as basic demo but the login button has different colors and the feature buttons are ice cream desserts — see slots section of the pay2myapp-appsell component below
javascript-hub demo code overhide.io hosted same as basic demo but the pay2myapp-hub component is not in the DOM, it's wired in via script
simplest demo code none bare bones single button demo — the simplest demo, no back-end


pay2my.app React.js Demo app
demo code ./demo-back-end as Azure Function React.js version of these demos.

Most demos show:

  • a nav-bar at the top with an pay2myapp-status web-component flush to the right.
  • a login button (which is just an pay2myapp-appsell component with a loginMessage attribute instead of a sku)
  • 3 feature buttons (pay2myapp-appsell components):
    • free
    • $2 up-sell
    • $3 subscription for 30 minutes

Everything is optional except for the non-visible pay2myapp-hub web-component that can be wired via DOM or JavaScript (see the javascript-hub demo for JS wiring).

You could just have a single up-sell / in-app purchase button, no status, no explicit login, and it will allow all the functionality (see "simplest" demo (code).

The /demo-front-end/no-back-end.html shows the use of these widgets without any back-end — shows use of widgets with just an API key, the back-end setup can be ignored for this one. This is OK for some projects, but is less bad-actor proof. All other demos leverage a back-end.

Back-End

Most of the above demos run their feature-flows via one of two back-ends:

Regardless of back-end choice, when a user clicks a feature, the back-end is interrogated to complete the feature flow.

Either back-end verifies authentication and authorization as per credentials provided and monies paid on a ledger of choice.

Notes on the overhide.io hosted back-end

The demos that leverage the overhide.io hosted back-end also leverage the lucchetto.js module. This module has a nice convenience getSku(..) function that connects the pay2myapp-appsell-sku-clicked event data to the back-ends.

The back-ends are:

See lucchetto.js for details on how to onboard in-app purchase SKUs for use with the Lucchetto back-ends.

Note that the overhide.io hosted back-ends are remote-storage servers supporting remote-storage applications. But you absolutly do not have to be writing a remote-storage application to leverage them: as the here-in demos demonstrate.

But if you are interested in writing a remote-storage application with in-app purchases, check out the remote-storage tutorial.

Notes on the /demo-back-end

The /demo-back-end serves a couple purposes on behalf of our front-ends:

  • retrieves an overhide token for use with overhide APIs — browser front-end code calls this to get the token and provide to the pay2myapp-hub component.
  • retrieves the fees-schedule (not actually leveraged in demos for simplicity, but provided for completness)
    • usually you'll want a single source of truth for your feature fees schedule
  • runs the feature-flow business logic on the back-end when corresponding feature button clicked in the front-end (/RunFeature endpoints)
    • has a bunch of mandatory query parameters to authenticate and authorize
    • feature will not run if bad authentication or insufficient funds on ledger for feature (as per parameters): will result in "Unauthorized by Ledger-Based AuthZ-" response.
    • the back-end calls overhide APIs to check authorizations, and requires the following pieces of information from the front-end (the /RunFeature query parameters):
      • sku — the feature name / tag to derefernce fees schedule
      • currency — one of 'dollars', 'ethers', 'bitcoins'
      • from — ledger specific address of the customer (the 'from')
      • message — message signed to prove ownership of address (NOTE, this is base64 encoded)
      • signature — signature of message for from
      • isTest — whether testnet ledgers should be used for authorization

The endpoints for these are discussed in the Local Development section below.

The /demo-back-end code runs both as stand-alone node.js as well as on Azure Functions (instructions below in Local Development section).

The above demos that hit this back-end code, hit it as it's stood up at https://demo-back-end.azurewebsites.net/api on Azure; but, it's easy enough to stand-up locally and play around (again, see Local Development below).

Distributable

Why is it so big?

We depend on web3.js which has bloat issues:

https://github.com/ChainSafe/web3.js/issues/1178

As soon as that gets resolved, this distro will be smaller.

The pay2my.app 'dist' folder contains the distributable artifact.

You'll likely want to import the library in your script code.

Within your front-end projects; using npm simply: npm install pay2my.app --save-prod.

Enabling with Token

APIs abstracted by pay2my.app require a bearer-token. The token is passed in to the <pay2myapp-hub token=".."> component (see the pay2myapp-hub component section for details).

The component either takes a token=".." retrieved from a back-end (optional) or an apiKey=".." provided statically — less bad-actor proof, but OK for some projects.

Retrieve an API key from https://token.overhide.io/register.

After that, a token can be retrieved with a GET /token call (see https://token.overhide.io/swagger.html).

All demos below show one or the other.

CDN

You can include pay2my.app via CDN:

  • https://cdn.jsdelivr.net/npm/pay2my.app@latest/dist/pay2my.app.js

You can see all the /demo-front-end/*.html demos load it this way:

<script src="https://cdn.jsdelivr.net/npm/pay2my.app@latest/dist/pay2my.app.js"></script>

In our demos we specifically load the latest version, e.g. version 1.4.11: https://cdn.jsdelivr.net/npm/pay2my.app@latest/dist/pay2my.app.js

The widgets can then be used in your DOM and via your framework JavaScript.

In npm based app projects, include the components and TypeScript definitions with your package.json:

"dependencies": {
  ..
  "pay2my.app": "1.4.11",
  ..
}

Content-Security-Policy

If you're serving pages with these components from a server that sets the Content-Security-Policy header, you'll need the following adjustments to your CSP:

script-src 'self' *.overhide.io *.stripe.com
connect-src *.overhide.io *.stripe.com
style-src 'self' 'unsafe-inline'
default-src 'self' *.stripe.com
frame-src 'self' *.overhide.io overhide.github.io overhide.b2clogin.com *.stripe.com
frame-ancestors 'self'

Widget Reference

Below is a reference of the four web-components provided, their attributes, properties, events, and override slots for customizing.

<pay2myapp-hub ..>

The pay2myapp-hub comopnent is the main glue component of the whole subsystem.

There can be only one pay2myapp-hub shared by all the other components.

Each other component must be provided with an pay2myapp-hub either via the DOM or programatically.

Setting the pay2myapp-hub via DOM

Simply set an ID on the pay2myapp-hub component and pass it into the other components as the hubId attribute:

<pay2myapp-hub id="demo-hub" ...></pay2myapp-hub> 

<pay2myapp-appsell 
  hubId="demo-hub" 
  ...
</pay2myapp-appsell>

With this setup, if we're providing our API key right in the client code, just set the apiKey attribute on the pay2myapp-hub element (a la no-back-end and simplest demos).

The basic and javascript-hub demos provide the apiKey to the lucchetto.js helper which provides it to the injected hub.

The custom demo provides the pay2myapp-hub element with a token explicitly retrieved from our /demo-back-end — effectively moving the apiKey from sitting in the HTML code to sitting in the back-end:

<script>
  // Set the token from back-end
  window.onload = (event) => {
  fetch(`${BACKEND_CONNECTION_STRING}/GetToken`)
    .then(async (response) => {
      if (response.ok) {
        const hub = document.querySelector('#demo-hub');
        hub.setAttribute('token', await response.text());
      } else {
        console.error(`error talking to back-end &mdash; ${response.status} &mdash; ${response.statusText}`);
      }
    }).catch(e => console.error(`error talking to back-end &mdash; ${e}`));
  };
</script>
  • the wiring above is in response to retrieving a valid token from the back-end — the fetch
  • we set the token on the hub using setAttribute('token',..)
  • the BACKEND_CONNECTION_STRING points at our back-end server (see Target a Back-End section)
Setting the pay2myapp-hub Programatically

We can get an instance of the pay2myapp-hub Web component by instantiating right in JavaScript via document.createElement('pay2myapp-hub').

We then provide it into each component using the setHub(..) setter via ES6 / TypeScript class.

Take a look at the javascript-hub demo code (demo).

Here, the components wired into the DOM do not have a hubId=.. attribute specified. There is no <pay2myapp-hub id=..> component in the template. Everything is done in the window.onload:

<script>
    ...
    var hub = document.createElement('pay2myapp-hub'); 
    hub.setAttribute('isTest', true);
    ...
    // Set the hub programatically
    window.onload = (event) => {
      hub.init();

      // inject hub into other components
      document.querySelector('pay2myapp-login').setHub(hub);
      document.querySelector('pay2myapp-status').setHub(hub);
      document.querySelectorAll('pay2myapp-appsell').forEach(e => e.setHub(hub));
    };
    ...
  </script>

  • note that lucchetto.js sets our hub apiKey on this hub instance, not shown for brevity
  • we optionally set the isTest attribute
  • since we're not wiring the pay2myapp-hub component into the DOM, we explicitly call hub.init()
  • the remaining document.querySelector.. calls find all the other pay2my.app web-components to set the newly initialized hub against them via their setHub(..) method
Attributes

isTest

  • set on element to indicate that all transactions/checks should be done against testnets
  • leave out if production / live environment

noCache

  • set on element to indicate login metadata should not be persisted in the browser-local session cache; to aide perserve data across browser refreshes
  • usually left out

apiKey

  • set on element if not providing a token but providing the apiKey
  • we do this in the no-back-end and simplest demos only — demos where we do not leverage a back-end
  • this allows anyone to see your apiKey; in the future we might throttle/black-list basedon apiKey (we don't as of yet)

token

  • set on element to provide a token retrieved via your own back-end
  • most demos do this, see code exaple in section above
  • it's preferred— but not strictly necessary — to have this indirection in case we start throttling by apiKey in the future: this way your apiKey is not shared
Properties / Methods

See IPay2MyAppHub in /src/components/hub/definitions.ts.

Slots

N/A — this is an invisible element and not customizable via slots.

Events

pay2myapp-hub-sku-authentication-changed

export interface IPay2MyAppSkuAuthenticationChangedEvent {
  message: string,
  signature: string,
  from: string,
  imparter: Imparter,
  isAuthenticated: boolean;
}
  • indicated a change in authentication status
  • imparter indicates which authenticated, or Unknown if not authenticated (isAuthenticated === false)
  • isAuthenticated === false event only sent on logout
  • isAuthenticated === true events sent on successful login

pay2myapp-hub-sku-authorization-changed

export interface IPay2MyAppSkuAuthorizationChangedEvent {
  sku: string,
  isAuthorized: boolean,
  asOf: string | null | undefined
}
  • indicated a change in authorization status
  • isAuthorized === false events may not be sent

pay2myapp-hub-pending-transaction

export interface IPay2MyAppPendingTransactionEvent {
  isPending: boolean;
  currency: string | null;
}
  • fired when we have a pending transaction. We're waiting for a transaction to finish.
  • this should be useful for spinners on custom pay2myapp-appsell components.
  • see use in demos when showing the VISA instructional helper
// This event fires whenever we're asked to topup funds.
// We're using it here to show the VISA instructional helper image.
window.addEventListener('pay2myapp-hub-pending-transaction',(e) => { 
  console.log(`pending-transaction :: ${JSON.stringify(e.detail, null, 2)}`);
  if (e.detail.currency == 'dollars') {
    document.querySelector("#visa").style.opacity = e.detail.isPending ? "1" : "0";
  }
}, false);

<pay2myapp-login ..>

The login widget.

The login providers you want to make available to your users can be customized here.

This component must be in your DOM, the other components such as pay2myapp-appsell and pay2myapp-status will trigger this component to raise a modal showing login providers — when necessary.

All login providers configured here should have corresponding addresses configured on all your pay2myapp-appsell buttons.

Attributes

hubId

  • connect to the one and only hub shared among all components in this eco-system
  • this is the actual element ID of the pay2myapp-hub in the document model
  • if the pay2myapp-hub is not in the DOM or doesn't have an ID, you'll need to use the setHub(..) method (see setting the hub programatically).

overhideSocialMicrosoftEnabled

  • if set on the element, enables US dollar ledger login / IAPs via Microsoft account social-login

  • requires that your pay2myapp-appsell components specify your overhideAddress attribute (you're onboarded onto the pay2myapp-ledger)

overhideSocialGoogleEnabled

  • if set on the element, enables US dollar ledger login / IAPs via Google account social-login

  • requires that your pay2myapp-appsell components specify your overhideAddress attribute (you're onboarded onto the pay2myapp-ledger)

ethereumWeb3Enabled

  • if set on the element, enables Ethereum ledger login / IAPs via ethereum wallet such as MetaMask

  • requires that your pay2myapp-appsell components specify your ethereumAddress attribute (you're onboarded onto the pay2myapp-ledger)

bitcoinEnabled

  • if set on the element, enables Bitcoin ledger login / IAPs via bitcoin signing

  • requires that your pay2myapp-appsell components specify your bitcoinAddress attribute (you're onboarded onto Bitcoin)

overhideSecretTokenEnabled

  • if set on the element, enables US dollar ledger login / IAPs via secret token

  • requires that your pay2myapp-appsell components specify your overhideAddress attribute (you're onboarded onto the pay2myapp-ledger)
Properties / Methods

See IPay2MyAppLogin in /src/components/hub/definitions.ts.

Slots

closeButton

  • the slot representing the little close button on the login modal
  • can be hidden or re-styled

header

  • allows creating a header at the top of the login modal — no header by default
  • see custom buttons demo (code) for example, e.g.
  <pay2myapp-login ..>
	<div slot="header" class="header-envelope">
	  <img src="./assets/logo.png" class="header-logo">
	  <div class="headers">
		<div class="header">Custom Login</div>
		<div>(logo + no <em>Google</em> or <em>bitcoin</em>)</div>
	  </div>
	</div>
  </pay2myapp-login>

Events

pay2myapp-login-open

  • emited on modal open

pay2myapp-login-close

  • emited on modal close

<pay2myapp-appsell ..>

The main buttons that enable authorized features in your application.

Clicking on a feature button when not logged in causes login unless the inhibitLogin attribute is specified.

Clicking on a feature that isn't authorized triggers the authorization flow (in-app purchase).

Clicking on a feature that's authorized raises the pay2myapp-appsell-sku-clicked event in response to which the feature-flow can continue to your back-end and be re-verified (for authorizations).

These widgets are fully customizable through slots.

Attributes

hubId

  • connect to the one and only hub shared among all components in this eco-system
  • this is the actual element ID of the pay2myapp-hub in the document model
  • if the pay2myapp-hub is not in the DOM or doesn't have an ID, you'll need to use the setHub(..) method (see setting the hub programatically).

orientation

  • the customization slots in this element are by default in a vertical orientation, top-to-bottom
  • set this to 'horizontal' if the slots are to be oriented left-to-right

sku

  • a unique name for the feature being authorized using this button

priceDollars

  • US dollars and cents as the cost of this feature
  • the amount is always specified in US dollars, the system converts to necessary ethers or bitcoins

loginMessage

  • if this button is supposed to be an overall login button and never be used for a feature, specify this message
  • if this message is specified, do not specify any other attributes other than the hubId
  • this message is shown in the authorized-button and unauthorized-button slots

alwaysLogin

  • if this button should always show the login modal when clicked
  • set to true when no means to logout is provided — enables user to always choose authorization method
  • likely shouldn't be set if a button with loginMessage is provided or an pay2myapp-status component is used in the page — as those buttons allow re-login
  • useful for donation buttons when they're the sole button on the page

authorizedMessage

  • the button label to show in the authorized-button slot when this feature is authorized

unauthorizedTemplate

  • the button label to show in the unauthorized-button slot when this feature is not yet authorized
  • the ${topup} placeholder can be used in the template to show the outstanding amount of US dollars — how much the user need to pay to authorize

inhibitLogin

  • if provided on the element, do not allow the user to login using this button when clicked, and the user is not yet logged in
  • this is useful if you do not want users to login using the feature buttons, only an explicit pay2myapp-appsell button with a loginMessage attribute set

bitcoinAddress

  • the bitcoin address into which paid bitcoins are deposited — and which is checked for sufficient monies paid to authorize
  • do not have too many distinct bitcoin addresses in your rendered route / page
    • usually it's recommended you have one per rendered route (e.g. hitting F5 will cause a single request)
    • all addresses are checked for topups and the APIs are rate-limited per IP
    • your users will start getting 429 - Too Many Requests if too many addresses are provided and they're all checked on refresh

ethereumAddress

  • the ethereum address into which paid ethers are deposited — and which is checked for sufficient monies paid to authorize
  • do not have too many distinct ethereum addresses in your rendered route / page
    • usually it's recommended you have one per rendered route (e.g. hitting F5 will cause a single request)
    • all addresses are checked for topups and the APIs are rate-limited per IP
    • your users will start getting 429 - Too Many Requests if too many addresses are provided and they're all checked on refresh

overhideAddress

  • the US dollars ledger address which shows receipts for deposited payments — and which is checked for sufficient monies paid to authorize
  • do not have too many distinct overhide addresses in your rendered route / page
    • usually it's recommended you have one per rendered route (e.g. hitting F5 will cause a single request)
    • all addresses are checked for topups and the APIs are rate-limited per IP
    • your users will start getting 429 - Too Many Requests if too many addresses are provided and they're all checked on refresh

withinMinutes

  • specifies the number of minutes the feature should be authorized once sufficient priceDollars is paid
  • this is useful for subscription features
  • in our demos we usually have one button that expires after 30 minutes
  • leave out for indefinite — default
Properties / Methods

See IPay2MyAppAppsell in /src/components/hub/definitions.ts.

Slots

These elements have three slots for authorized versions of each button and three slots for unauthorized versions of each button.

The authorized versions are shown when sufficient monies have been paid to authorize the feature.

The authorized slots are:

  • authorized-header
  • authorized-button
  • authorized-footer

The unauthorized slots are:

  • unauthorized-header
  • unauthorized-button
  • unauthorized-footer

By default nothing is rendered in the -header or the -footer slots, all rendering is done in the -button slot. E.g. the various messages from the attributes are rendered in the authorized-button or unauthorized-button.

The content of the authorized-button and unauthorized-button slots are overwritten by the loginMessage, authorizedMessage and unauthorizedTemplate attributes. These slots are only useful for styling the messages. To modify the look and feel beyond that, use the -header and -footer slots.

See the custom buttons demo (code) for examples.

Events

pay2myapp-appsell-sku-clicked

 export interface IPay2MyAppSkuClickedEvent {
  sku: string,
  message: string,
  signature: string,
  from: string,
  to: string,
  currency: Currency,
  imparter: Imparter,
  isTest: boolean,
  asOf: string,
  priceDollars: string,
  withinMinutes: string
}
  • the event fired by an pay2myapp-appsell component when an appsell SKU deemed authorized by overhide is clicked by the user
  • usually safest to route state-changes in response to this event via a back-end — and let the back-end re-validate authorizations
  • all necessary information to validate is provided in this event
  • passing the asOf timestamp to your back-end — and having your back-end pass this value to overhide APIs when checking authorizations — is an important optimization. Since the overhide services already recently checked these transactions as part of this front-end work; the asOf timestamp ensures we re-load these resutls from cache and do not get rate-limited in the back-end.
  • example:
    <script>
      window.addEventListener('pay2myapp-appsell-sku-clicked',(e) => { /* react to feature being used, only if, auth'ed */ });
    </script>

pay2myapp-appsell-topup-outstanding

export interface IPay2MyAppSkuTopupOutstandingEvent {
  sku: string,
  topup: number
}
  • an event fired by an pay2myapp-appsell component when there was an authorization attempt but insufficient funds to authorize
  • this even contains the outstanind topup funds required: in US dollars

<pay2myapp-status ..>

A very simple widget usually provided in the nav-bar of an application.

Shows the currently logged in address and against which login provider (icon).

Allows manually refreshing payments and a logout button.

When logged in, clicking the address shows a transaction history.

When logged out, clicking the "sign-in" text triggers login.

Attributes

hubId

  • connect to the one and only hub shared among all components in this eco-system
  • this is the actual element ID of the pay2myapp-hub in the document model
  • if the pay2myapp-hub is not in the DOM or doesn't have an ID, you'll need to use the setHub(..) method (see setting the hub programatically).
Properties / Methods

See IPay2MyAppStatus in /src/components/hub/definitions.ts.

Slots

N/A

Events

N/A

Local Development

Target a Back-End

You can more easily leverge the overhide.io hosted back-end for your development (and later production). This is why it's there — its raison d'être. This is shown in the basic and javascript-hub demos.

If you already have a back-end or want to write your own, the rest of this section is concerned with that.

The custom demo runs against the sample ./demo-back-end.

We have several ways to run the ./demo-back-end for demo/development purposes. The script constant BACKEND_CONNECTION_STRING points at one of the back-end instances, either:

Modify this constant as needed.

Run a Demo Back-End

The /demo-front-end/no-back-end.html doesn't use a back-end — shows use of widgets without a back-end, the back-end setup can be ignored for this one.

The ./demo-back-end folder has all the code for a minimal back-end, whether it runs using node.js locally on your development machine or as an Azure Function (how these demos are hosted).

To start running the back-end on your local development machine:

  1. prerequesites:
    • node.js
  2. open a console to the ./demo-back-end subfolder of this repo
  3. npm install
  4. npm run dev

The backend is now running.

You can try hitting it with:

Alternativelly, if you want to leverage the Azure Function core tooling:

  1. prerequesites:
    • node.js
    • Azure Functions core tools: npm install -g azure-functions-core-tools@3 --unsafe-perm true
  2. open a console to the ./demo-back-end subfolder of this repo
  3. npm install
  4. func start

The you can try hitting the local AZ functions with:

ASIDE: deploying to Azure Functions:

if you followed the latter, you can deploy to Azure using:

az login
func azure functionapp publish <function name>

Then you can hit the functions in Azure, for example, for this demo's name of demo-back-end we have:

Readme

Keywords

none

Package Sidebar

Install

npm i pay2my.app

Homepage

overhide.io

Weekly Downloads

2

Version

1.4.19

License

ISC

Unpacked Size

1.49 MB

Total Files

28

Last publish

Collaborators

  • overhide