diff --git a/astro.config.mjs b/astro.config.mjs index 54d72b5..62e921c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -8,6 +8,9 @@ export default defineConfig({ integrations: [ starlight({ title: "Payment Pointers", + customCss: [ + './src/styles/custom.css' + ], description: "Payment Pointers are a standardized identifier for payment accounts. In the same way that an email address provides an identifier for a mailbox in the email ecosystem a payment pointer is used by an account holder to share the details of their account with a counter-party.", head: [ @@ -40,12 +43,12 @@ export default defineConfig({ github: "https://github.com/interledger/paymentpointers.org", }, sidebar: [ - { label: "Explainer", link: "/" }, - { label: "Design Goals", link: "/goals" }, - { label: "Flow", link: "/flow" }, - { label: "Syntax and Resolution", link: "/syntax" }, - { label: "IANA Considerations", link: "/iana" }, - { label: "Security Considerations", link: "/security" }, + { label: "Overview", link: "overview" }, + { label: "How it works", link: "how-it-works" }, + { label: "Syntax and resolution", link: "/syntax" }, + { label: "Security considerations", link: "/security" }, + { label: "Example implementation - Interledger", link: "/examples/ilp-implementation" }, + { label: "IANA considerations", link: "/iana" }, { label: "About", link: "/about" }, ], }), diff --git a/src/content/docs/about.md b/src/content/docs/about.md index fefcdb4..257f47f 100644 --- a/src/content/docs/about.md +++ b/src/content/docs/about.md @@ -2,4 +2,24 @@ title: About --- -The **Payment Pointers** specification is published by the [Interledger Community Group](https://interledger.org) at [W3C](https://w3.org). +This payment pointers specification is published by the Interledger Community Group at W3C. + +## Design goals + +Payment pointers are designed with very specific goals in mind. + +### Unique and easily recognizable + +Various standardized and defacto-standardized identifiers are widely used on the Internet today, such as email addresses and social media handles. Payment pointers must be obviously unique so that they aren't confused with another type of identifier and also so that other identifiers aren't assumed to be payment pointers. + +### Simple transcription + +It should be easy for someone to exchange their payment pointer with a counterparty by saying it, writing it down, or sending it in a digital message. + +### Flexible + +Payment pointers shouldn't be tightly coupled to a specific payment service. It should be possible for any new payment service to leverage payment pointers by implementing Interledger's Simple Payment Setup Protocol. + +### Widely usable + +It should be simple for individuals or small companies to host their own payment service endpoints at a URL that can resolve via a simple and easily recognizable payment pointer. Likewise, it should be possible for a payment services provider to host payment service endpoints for multiple entities without the risk of hosting them at endpoint URLs that conflict with their other services. To that end, the provider should have the option of hosting different endpoints under the same domain and a different path or at a different sub-domain for each user. diff --git a/src/content/docs/examples/ilp-implementation.md b/src/content/docs/examples/ilp-implementation.md new file mode 100644 index 0000000..1ddc584 --- /dev/null +++ b/src/content/docs/examples/ilp-implementation.md @@ -0,0 +1,80 @@ +--- +title: 'Example implementation - Interledger' +--- + +This page provides a high-level description of how the Interledger Protocol (ILP) has implemented payment pointers. ILP is an open suite of protocols for transferring packets of value across different payment networks and ledgers. + +## Interledger's Simple Payment Setup Protocol (SPSP) + +Interledger's SPSP is a protocol used by clients, such as mobile and web apps, to obtain the destination account and shared secret details required to set up an Interledger payment. + +The details are obtained via an HTTPS request to an SPSP server endpoint. Interledger uses payment pointers as a user-friendly way to express the endpoint URLs. + +### Example: Sending an Interledger payment + +You use a payment app to send a payment to a friend. You enter an amount and your friend’s payment pointer into the app. Your friend's payment pointer is `$alice.wallet.example`. + +First, the app follows the [syntax and resolution](/syntax) rules to convert the payment pointer to an HTTPS URL. The URL is the endpoint for an SPSP server: + +```http +https://alice.wallet.example/.well-known/pay +``` + +The app queries the URL by sending a `GET` request with a MIME type of `application/spsp4+json` included in the header. + +```http title="Example request" +curl --request GET \ + --url https://alice.wallet.example/.well-known/pay \ + --header 'accept: application/spsp4+json' +``` + +The SPSP server responds with the following connection details. + +* `destination_account` - An ILP address, which provides a way to route ILP packets to their intended destination. ILP addresses aren't meant to be user-facing. +* `shared_secret` - A shared secret between the app and the SPSP server. + +```json title="Example response" wrap +{ + "destination_account":"example.dev.0.wallet.cloudnine.swx0a0.~ipr.cdfa5e16-e759", + "shared_secret":"7h0s7EpQDqcgzqmX-mwrNHFHinPvJq8Jw", +}, +``` + +After the app has the destination account and shared secret, it no longer needs the payment pointer. The next step is for the app to use the details to set up a STREAM connection. STREAM is Interledger's transport layer protocol that creates and transmits the Interledger packets that make up a payment. + +## Interledger and Open Payments + +Open Payments is an open API standard for implementation by banks, mobile money providers, and other account servicing entities (ASEs). It allows developers to build payment capabilities into their clients by calling Open Payments APIs to issue payment instructions to ASEs without needing custom integrations. + +Open Payments is an alternative to Interledger’s SPSP. As such, getting the details needed to set up a payment is done through an Open Payments API call. + +While Open Payments doesn’t use SPSP, it does use Interledger’s STREAM protocol. The Open Payments standard is designed so that it can relay payment instructions between transacting parties atop any payment method. However, Interledger is the only method that’s currently integrated with Open Payments. + +### Payment pointers and wallet addresses + +Instead of payment pointers, the Open Payments standard uses wallet addresses to identify Open Payments-enabled accounts. Wallet addresses are expressed as HTTPS URLs which makes them identical to the URL form of payment pointers. However, wallet addresses resolve to Open Payments API endpoints instead of SPSP server endpoints. + +```http title="Example wallet address" +https://wallet.example.com/bob +``` + +You can query the URL by sending a `GET` request with `application/json` in the header. + +```http title="Example request" +curl --request GET \ + --url https://wallet.example.com/bob \ + --header `accept: application/json` +``` + +You can also use `application/spsp4+json` since Open Payments uses Interledger as its payment method, but in either case you'll receive an Open Payments response. + +```json title="Example response" +{ + "id": "https://wallet.example.com/bob", + "publicName": "Bob", + "assetCode": "USD", + "assetScale": 2, + "authServer": "https://auth.wallet.example.com", + "resourceServer": "https://wallet.example.com", +} +``` diff --git a/src/content/docs/goals.md b/src/content/docs/goals.md deleted file mode 100644 index 2bc82e4..0000000 --- a/src/content/docs/goals.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Design Goals ---- - -Payment Pointers were designed with very specific goals in mind: - -## Unique and Easily Recognizable - -Various standardized and defacto-standardized identifiers are widely used on the Internet today such as email addresses and social media handles. The Payment Pointer must be obviously unique so that it is not confused with another type of identifier and also so that other identifiers are not assumed to be Payment Pointers. - -## Simple Transcription - -It should be easy for someone to exchange their payment pointer with a counter-party either by saying it, writing it down or sending it in a digital message. - -## Flexible - -The payment pointer should not be tightly coupled to a specific payment service. It should be possible for any new payment service to leverage payment pointers by implementing the [Open Payments](https://openpayments.dev) standard. - -## Widely Usable - -It should be simple for individuals or small companies to host their own payment service endpoints at a URL that can be resolved via a simple and easily recognizable payment pointer. Likewise, it should be possible for a payment services provider to host payment service endpoints for multiple entities without the risk of hosting them at endpoint URLs that conflict with their other services. To that end the provider should have the option of hosting different endpoints under the same domain and a different path or at a different sub-domain for each user. diff --git a/src/content/docs/how-it-works.md b/src/content/docs/how-it-works.md new file mode 100644 index 0000000..c85a84d --- /dev/null +++ b/src/content/docs/how-it-works.md @@ -0,0 +1,182 @@ +--- +title: How it works +--- + +A payment service endpoint provides the information that's necessary for interacting with a payment pointer's underlying payment account. Payment service endpoints **MUST** accept HTTP GET requests and be identifiable by an HTTPS URI as defined in RFC7230. + +:::note +In addition to payment service endpoint requirements, you should familiarize yourself with the [syntax and resolution](/syntax) requirements of payment pointers. +::: + +Payment pointers aren't meant to be tightly coupled to any specific payment service. Individuals and small companies can host their own payment service endpoints at URLs that resolve to payment pointers. + +Likewise, payment service providers can host payment service endpoints for multiple entities without the risk of hosting them at endpoint URLs that conflict with their other services. To that end, providers have the option of hosting different endpoints under the same domain and a different path, or at a different sub-domain for each of their users. + +## Step 1: Resolve server meta-data URL + +Let's say you are using a payment app to send a payment to a friend. You enter your friend's payment pointer into the app. + +The first step a client (for example, your payment app) must perform is to decode the endpoint URL from the payment pointer using the [rules](/syntax#resolution) defined in this specification. + +
+
+ + +
+

+
+ +## Step 2: Discover endpoints + +The client then uses the HTTP protocol to query (`GET`) the resolved endpoint URL. The client uses the `Accept` header to express the media types of the protocol messages it supports. + +```http title="Example" +GET /.well-known/pay HTTP/1.1 +Host: alice.wallet.example +Accept: application/json +``` + +The response contains details the client needs to discover the payment service endpoints for interacting with the underlying account. + +The resolved endpoint **MAY** redirect the client to another URL but the client **MUST** ensure it affords the sender an opportunity to verify both the originally resolved and ultimate endpoint hosts. + +## Step 3: Initiate payment + +Having discovered the available endpoint, the client initiates the payment using the payment setup protocol appropriate to the use case. + + + + diff --git a/src/content/docs/iana.md b/src/content/docs/iana.md index 2e2270c..eb3699b 100644 --- a/src/content/docs/iana.md +++ b/src/content/docs/iana.md @@ -2,7 +2,7 @@ title: IANA Considerations --- -## Well-Known URI +## Well-known URI This specification registers a new well-known URI. diff --git a/src/content/docs/index.md b/src/content/docs/index.md index 5ca7187..ac6f8e9 100644 --- a/src/content/docs/index.md +++ b/src/content/docs/index.md @@ -1,170 +1,15 @@ --- title: Payment Pointers +template: splash +hero: + tagline: Payment pointers are unique, easily recognizable, and standardized identifers for a payment account. + actions: + - text: Read the docs + link: /overview + icon: open-book + variant: primary + attrs: + data-umami-event: Landing page - Payment Pointer docs +prev: false +next: false --- - -## Explainer - -**Payment Pointers** are a standardized identifier for payment accounts. In the same way that an email address provides an identifier for a mailbox in the email ecosystem a payment pointer is used by an account holder to share the details of their account with a counter-party. - -A Payment Pointer resolves to a URL (with the https scheme) that can be used to discover the [Open Payments](https://openpayments.dev) endpoints for interacting with the account. Using the [Open Payments](https://openpayments.dev) protocol the counter-party can initiate a payment to or from the owner of the Payment Pointer. - -
-
- - -
-

-
- -### Syntax - -Payment Pointers start with a `$` character to distinguish them from other identifiers and make it obvious that they are related to payments. To convert a Payment Pointer to a URL the `$` is replaced with the standard prefix of a secure URL, `https://`. - -Payment Pointers don't contain query strings or fragments, however [Open Payments](https://openpayments.dev) MAY define standard parameters that can be used by a client when connecting to an [Open Payments](https://openpayments.dev) service endpoint. - -[More details...](/syntax) - -### Flow - -When making or a receiving a payment, a user passes a Payment Pointer to the counter-party who decodes it to the corresponding URL. - -That URL represents an account at a wallet and the client begins an interaction with the wallet using the [Open Payments](https://docs.openpayments.dev) protocol. - -[More details...](/flow) - - - - diff --git a/src/content/docs/flow.md b/src/content/docs/overview.md similarity index 53% rename from src/content/docs/flow.md rename to src/content/docs/overview.md index 23dd267..e3b73a5 100644 --- a/src/content/docs/flow.md +++ b/src/content/docs/overview.md @@ -1,16 +1,18 @@ --- -title: Flow +title: Overview --- -When a user wishes to make or receive a payment, and is engaging with a counter-party that is able to process Payment Pointers, it provides a Payment Pointer to the counter-party. +Payment pointers are unique, recognizable, and standardized identifiers for payment accounts. -The counter-party's client then uses this Payment Pointer as described below to discover the services and accounts linked to the Payment Pointer and interact with these to send or request a payment. +Other standardized identifiers, such as email addresses and social media handles, are widely used across the Internet and provide a simple and straightforward way to exchange information with others. The intent behind payment pointers is no different. -This is analogous to how a user may provide a credit card number to a merchant to make a payment online, or provide their bank account details to a payer to receive a payment. However, in the case of Payment Pointers the pointer and the services are loosely coupled so a variety of service types could be discovered and payments can be both pushed and pulled from the user's account initiated via the same Payment Pointer. +Payment pointers begin with a `$` to distinguish them from other types of identifiers. For example, `$wallet.example.com/alice`. Every payment pointer also has a corresponding HTTPS URL. -## Step 1: Resolve Open Payments Server Meta-Data URL +**Although originally developed for Interledger, payment pointers are not tightly coupled with the protocol.** Any payment setup protocol is welcome to leverage payment pointers without integrating with Interledger. Interledger is just one [active implementation](/examples/ilp-implementation) of payment pointers. -The first step the client performs is to decode the **Payment Pointer URL** from the Payment Pointer using the [rules](/syntax#resolution) defined in this specification. +## Get your payment pointer's URL + +If you already have a payment pointer and need to convert it to its corresponding HTTPS URL, enter it in the field below.
@@ -26,44 +28,26 @@ The first step the client performs is to decode the **Payment Pointer URL** from

-## Step 2: Discover Open Payments Endpoints - -The client then uses the HTTP protocol to query the resolved **Open Payments account** URL and [discover](https://docs.openpayments.dev/discovery) the Open Payments services endpoints. - -The resolved endpoint MAY redirect the client to another URL but the client MUST ensure it affords the sender an opportunity to verify both the originally resolved and ultimate endpoint hosts. - -### Example: - -```http -GET /.well-known/pay HTTP/1.1 -Host: alice.wallet.example -Accept: application/json -``` - -## Step 3: Initiate Payment - -Having discovered the available endpoints, the client initiates the payment using one of the supported [Open Payments](https://openpayments.dev) protocols appropriate to the use case. - +## Brief history + +Payment pointers were developed alongside the Interledger Protocol stack as a way to express URL endpoints in a user-friendly way. + +Interledger's Simple Payment Setup Protocol (SPSP) exchanges the connection details needed to set up an Interledger payment. An SPSP server exposes an HTTPS endpoint that a client can query to get those details. For example, `https://alice.wallet.example/.well-known/pay`. + +Endpoints like that can become unwieldy and hard to remember. Instead of entering the endpoint into a client or sharing the address with a counter-party, the URL can instead be expressed in shorthand form as a payment pointer: `$alice.wallet.example`. + +For more information on how Interledger uses payment pointers, see its [implementation example](/examples/ilp-implementation) page. +