Skip to content

Commit 7d4527b

Browse files
docs: fixes #681 (#683)
* docs: update outgoing grant guide Update guide to more closely follow the new format introduced with the Split Payment guide revisions. Summary: * Revised intro * Added Scenario heading * Removed Dependencies section * Other wording updates * Added example responses * Minor updates to some existing TS examples * docs: added badges to guide * docs: add token expiry note
1 parent cafa2b6 commit 7d4527b

File tree

3 files changed

+95
-29
lines changed

3 files changed

+95
-29
lines changed

docs/src/content/docs/guides/outgoing-grant-future-payments.mdx

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Get an outgoing payment grant for future payments
33
---
44

55
import { LinkOut } from '@interledger/docs-design-system'
6-
import { Tabs, TabItem } from '@astrojs/starlight/components'
6+
import { Tabs, TabItem, Badge } from '@astrojs/starlight/components'
77
import InteractionReq from '/src/partials/interaction-required.mdx'
88
import StartInteraction from '/src/partials/grant-start-interaction.mdx'
99
import FinishInteraction from '/src/partials/grant-finish-interaction.mdx'
@@ -12,25 +12,29 @@ import FinishInteraction from '/src/partials/grant-finish-interaction.mdx'
1212
Learn how to get an outgoing payment grant for future payments without specifying any recipients.
1313
:::
1414

15-
Often, a transaction will start with the client getting the recipient's details and asking the recipient's ASE for permission to send money. However, Open Payments also supports a different approach, where the client gets permission from the sender's ASE to send money before knowing who the recipient will be. Web Monetization's pay-as-you-browse model uses this approach.
15+
Often, a transaction starts with the client getting the payment recipient's details and asking the recipient's ASE for permission to send money. However, Open Payments also supports a different approach: the client gets permission from the sender's ASE to send money before knowing who the recipient will be. Web Monetization's pay-as-you-browse model uses this approach.
1616

17-
In this model, a user installs a browser extension and visits a web monetized site. The extension uses Open Payments to issue continuous outgoing payments to the site, on behalf of the user, for as long as the user is on the site. The extension has no idea who the recipient will be until the user visits the site.
17+
**Real-life use case: Web Monetization browser extension**
1818

19-
Setting up the extension requires the user to connect it to their wallet account. They specify a maximum amount they're willing to spend and select whether the amount should renew monthly. The extension then receives an outgoing payment grant from the user's wallet provider, allowing the extension to initiate future payments.
19+
The Web Monetization extension uses Open Payments to issue continuous outgoing payments to a web monetized site. The payments are issued on behalf of the user for as long as the user is on the site. The extension has no idea who the recipient will be until the user visits the site.
2020

21-
In this guide, you'll assume the role of an app developer. The guide takes you through the steps your app will perform to receive an outgoing payment grant with a specified debit amount but no known recipients. The example scenario illustrates how to allow your app's user to send payments of up to $100 CAD a month for three months.
21+
Setting up the extension requires the user to connect it to their wallet account. They specify a maximum amount they're willing to spend and select whether the amount should automatically renew each month. The extension then receives an outgoing payment grant from the user's wallet provider, allowing the extension to initiate future payments.
22+
23+
## Scenario
24+
25+
For this guide, you'll assume the role of an app developer. The guide explains how to allow your app's user to send payments of up to $100 CAD a month for three months without specifying a recipient beforehand.
2226

2327
## Endpoints
2428

25-
- <LinkOut href='https://openpayments.dev/apis/wallet-address-server/operations/get-wallet-address/'>Get Wallet Address</LinkOut>
26-
- <LinkOut href='https://openpayments.dev/apis/auth-server/operations/post-request/'>Grant Request</LinkOut>
27-
- <LinkOut href='https://openpayments.dev/apis/auth-server/operations/post-continue/'>Continue Grant Request</LinkOut>
29+
- <Badge text="GET" variant="note" /> <LinkOut href='https://openpayments.dev/apis/wallet-address-server/operations/get-wallet-address/'>Get Wallet Address</LinkOut>
30+
- <Badge text="POST" variant="success" /> <LinkOut href='https://openpayments.dev/apis/auth-server/operations/post-request/'>Grant Request</LinkOut>
31+
- <Badge text="POST" variant="success" /> <LinkOut href='https://openpayments.dev/apis/auth-server/operations/post-continue/'>Grant Continuation Request</LinkOut>
2832

2933
## Steps
3034

3135
### 1. Get wallet address information
3236

33-
Let's assume your user saved their wallet address in their account profile when setting up your app. Call the [Get Wallet Address API](/apis/wallet-address-server/operations/get-wallet-address) to get required details about your user's wallet account.
37+
Let's assume your user saved their wallet address in their account profile when setting up your app. Call the <Badge text="GET" variant="note" /> [Get Wallet Address API](/apis/wallet-address-server/operations/get-wallet-address).
3438

3539
<Tabs syncKey="lang">
3640
<TabItem label='TypeScript/JavaScript' icon='seti:javascript'>
@@ -42,19 +46,28 @@ Let's assume your user saved their wallet address in their account profile when
4246
</TabItem>
4347
</Tabs>
4448

45-
### 2. Request an interactive outgoing payment grant
49+
<details>
50+
<summary>Example response</summary>
51+
```json wrap
52+
{
53+
"id": "https://cloudninebank.example.com/user",
54+
"assetCode": "CAD",
55+
"assetScale": 2,
56+
"authServer": "https://auth.cloudninebank.example.com/",
57+
"resourceServer": "https://cloudninebank.example.com/op"
58+
}
59+
```
60+
</details>
4661

47-
Use the authorization server information received in the previous step to call the [Grant Request API](/apis/auth-server/operations/post-request). The purpose of this call is to obtain a token that allows your client to request outgoing payment resources be created on your user's wallet account.
62+
### 2. Request an interactive outgoing payment grant
4863

49-
<InteractionReq />
64+
Use the authorization server information received in the previous step to call the <Badge text="POST" variant="success" /> [Grant Request API](/apis/auth-server/operations/post-request).
5065

51-
In addition to any required parameters, include the following in the request:
66+
This call obtains a token that allows your app to request outgoing payment resources be created on your user's wallet account.
5267

53-
- `limits` object
54-
- `debitAmount` - The maximum amount that your user can send per interval. When the next interval begins, the value resets.
55-
- `interval` - The [time interval](#about-the-interval) under which the grant is valid.
68+
<InteractionReq />
5669

57-
Your user indicates they want to make payments of up to $100 CAD a month for three months. The amount resets each month and any unspent portions don't roll over.
70+
Remember, your user wants to send payments of up to $100 CAD a month for three months. The amount resets each month and any unspent portions don't roll over.
5871

5972
<Tabs syncKey="lang">
6073
<TabItem label='TypeScript/JavaScript' icon='seti:javascript'>
@@ -86,7 +99,7 @@ Your user indicates they want to make payments of up to $100 CAD a month for thr
8699
start: ['redirect'],
87100
finish: {
88101
method: 'redirect',
89-
uri: 'https://cloudninebank.example.com/finish/T8jw5Xy',
102+
uri: 'https://paymentplatform.example/finish/{...}', // where to redirect the user to after they've completed the interaction
90103
nonce: NONCE,
91104
},
92105
},
@@ -96,14 +109,34 @@ Your user indicates they want to make payments of up to $100 CAD a month for thr
96109
</TabItem>
97110
</Tabs>
98111

112+
113+
<details>
114+
<summary>Example response</summary>
115+
```json wrap
116+
{
117+
"interact": {
118+
"redirect": "https://auth.interledger-test.dev/{...}", // uri to redirect the user to, to begin interaction
119+
"finish": "..." // unique key to secure the callback
120+
},
121+
"continue": {
122+
"access_token": {
123+
"value": "..." // access token for continuing the outgoing payment grant request
124+
},
125+
"uri": "https://auth.interledger-test.dev/continue/{...}", // uri for continuing the outgoing payment grant request
126+
"wait": 30
127+
}
128+
}
129+
```
130+
</details>
131+
99132
#### About the interval
100133

101-
The interval used in this guide is `R3/2025-05-20T13:00:00Z/P1M`. Remember that your user wants to send payments up to $100 CAD a month for three months. The interval breaks down like this:
134+
The interval used in this guide is `R3/2025-05-20T13:00:00Z/P1M`. Your user wants to send payments up to $100 CAD a month for three months. The interval breaks down like this:
102135

103136
- `R3/` is the number of repetitions - three.
104137
- `2025-05-20` is the start date of the repeating interval - 20 May 2025
105138
- `T13:00:00Z/` is the start time of the repeating interval - 1:00 PM UTC.
106-
- `P1M` is the period between each interval - one month. Used with `R3`, you have a grant that's valid once a month for three months.
139+
- `P1M` is the period between each interval - one month. Used with `R3/`, you have a grant that's valid once a month for three months.
107140

108141
Altogether, your user can send up to $100 CAD from:
109142

@@ -121,28 +154,61 @@ Altogether, your user can send up to $100 CAD from:
121154

122155
### 5. Request a grant continuation
123156

124-
In this guide, we're assuming the IdP has a user interface with which your user interacts. When the interaction completes, your user is directed back to your app. Now the client can make a grant continuation request.
157+
In our example, we're assuming the IdP the user interacted with has a user interface. When the interaction completes, your user is directed back to your app. Now the client can make a grant continuation request.
125158

126159
:::note
127160
In a scenario where a user interface isn't available, consider implementing a polling mechanism to check for the completion of the interaction.
128161
:::
129162

130-
Add the `interact_ref` returned in the redirect URI's query parameters.
163+
Call the <Badge text="POST" variant="success" /> [Grant Continuation Request API](/apis/auth-server/operations/post-continue/). This call requests an access token that allows your app to request outgoing payment resources be created on the user's wallet account.
164+
165+
Issue the request to the `continue.uri` provided in the initial outgoing payment grant response (Step 2).
166+
167+
Include the `interact_ref` returned in the redirect URI's query parameters.
131168

132169
<Tabs syncKey='lang'>
133170
<TabItem label='TypeScript/JavaScript' icon='seti:javascript'>
134171
```ts wrap
135-
const grant = await client.grant.continue(
172+
const userOutgoingPaymentGrant = await client.grant.continue(
136173
{
137-
accessToken: CONTINUE_ACCESS_TOKEN,
138-
url: CONTINUE_URI,
174+
accessToken: pendingUserOutgoingPaymentGrant.continue.acces_token.value,
175+
url: pendingUserOutgoingPaymentGrant.continue.uri,
139176
},
140177
{
141-
interact_ref: INTERACT_REF,
178+
interact_ref: interactRef,
142179
},
143180
);
144181
```
145182
</TabItem>
146183
</Tabs>
147184

148185
A successful response provides your app with an access token. Now your app can issue outgoing payment requests to future recipients against the grant. Each request must reference the access token.
186+
187+
<details>
188+
<summary>Example response</summary>
189+
```json wrap
190+
{
191+
"access_token": {
192+
"value": "...", // final access token required before creating outgoing payments
193+
"manage": "https://auth.cloudninebank.example.com/token/{...}", // management uri for access token
194+
"access": [
195+
{
196+
"type": "outgoing-payment",
197+
"actions": ["create", "read"],
198+
"identifier": "https://cloudninebank.example.com/user",
199+
}
200+
]
201+
},
202+
"continue": {
203+
"access_token": {
204+
"value": "..." // access token for continuing the request
205+
},
206+
"uri": "https://auth.cloudninebank.example.com/continue/{...}" // continuation request uri
207+
}
208+
}
209+
```
210+
</details>
211+
212+
:::note[Access token expiry]
213+
If an outgoing payment request fails because the grant's access token has expired, you can call the <Badge text="POST" variant="success" /> [Rotate Access Token API](/apis/auth-server/operations/post-token/), then use the new token in the outgoing payment request.
214+
:::

docs/src/content/docs/sdk/before-you-begin.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ Before you can initialize an authenticated Open Payments client, you must obtain
8282
<img src='/img/snippets/tw-dev-keys-tab.png' alt='Developer keys tab with account expanded, showing the upload key and the generate public and private key buttons' class='img-outline' style='max-width:400px'/>
8383
4. Click **Generate public & private key**.
8484
5. Enter any **nickname** for the key pair, then click **Generate keys**. A file named `private.key` automatically downloads to your machine
85-
85+
8686
<img src='/img/snippets/tw-generate-key-pair.png' alt='Generate public and private key screen with nickname field' class='img-outline' style='max-width:400px'/>
8787

8888
<img src='/img/snippets/tw-key-pair-success.png' alt='Key pair generation success screen' class='img-outline' style='max-width:400px'/>
89-
89+
9090
6. Click **Close**. Your key ID appears on the screen, along with a **Show/Hide** option for your public key.
9191
<img src='/img/snippets/tw-key-id.png' alt='Developer keys tab with account expanded, showing the newly generated key id and an option to show the public key' class='img-outline' style='max-width:400px'/>
9292

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
:::note
2-
Outgoing payments require an interactive grant. This type of grant will obtain the customer's consent before an outgoing payment is made against their wallet account. You can find more information in the [Open Payments flow](/concepts/op-flow/#outgoing-payment) and [identity providers](/identity/idp) pages.
2+
Outgoing payments require an interactive grant. This type of grant will obtain the resource owner's consent before an outgoing payment is made against their wallet account. You can find more information in the [Open Payments flow](/concepts/op-flow/#outgoing-payment) and [identity providers](/identity/idp) pages.
33
:::

0 commit comments

Comments
 (0)