From 72915b6ed7aa9ec87cbeeb6731aa4a3b151c358a Mon Sep 17 00:00:00 2001 From: Melissa Henderson <57110301+melissahenderson@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:19:31 -0400 Subject: [PATCH] docs: fixes #53 A number of people have pointed out that the updates made to this site in 2020 don't mention anything about the Interledger protocol and that all references lead to Open Payments, which isn't entirely accurate. This PR attempts to fix these issues. --- astro.config.mjs | 15 +- src/content/docs/about.md | 22 ++- .../docs/examples/ilp-implementation.md | 80 ++++++++ src/content/docs/goals.md | 21 -- src/content/docs/how-it-works.md | 182 ++++++++++++++++++ src/content/docs/iana.md | 2 +- src/content/docs/index.md | 179 ++--------------- src/content/docs/{flow.md => overview.md} | 68 +++---- src/content/docs/security.md | 29 ++- src/content/docs/syntax.md | 49 ++--- 10 files changed, 369 insertions(+), 278 deletions(-) create mode 100644 src/content/docs/examples/ilp-implementation.md delete mode 100644 src/content/docs/goals.md create mode 100644 src/content/docs/how-it-works.md rename src/content/docs/{flow.md => overview.md} (53%) 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. + +