@@ -11,8 +11,6 @@ <h4>Wallet address request</h4>
11
11
< ol >
12
12
< li >
13
13
Let |walletAddressUrl:URL| be the result of running [=URL parser=] with |walletAddress|.
14
- </ li >
15
- < li >
16
14
If |walletAddressUrl| [=url/scheme=] is not `https`, return failure.
17
15
</ li >
18
16
< li >
@@ -83,11 +81,7 @@ <h4>Outgoing payment and quote grant request</h4>
83
81
and |interval:DOMString| perform the following steps.
84
82
< ol >
85
83
< li >
86
- Let |authServer:URL| be the result of running [=URL parser=]
87
- with |walletAddressDetails|'s {{WalletAddressDetails/authServer}} property.
88
- </ li >
89
- < li >
90
- If |authServer| [=url/scheme=] is not `https`, return failure.
84
+ Let |authServer:URL| be the result of running [=URL parser=] with |walletAddressDetails|'s {{WalletAddressDetails/authServer}} property.
91
85
</ li >
92
86
< li >
93
87
< p > Construct a {{ GrantRequest }} |grantRequest: GrantRequest| as follows:</ p >
@@ -262,9 +256,6 @@ <h4>Incoming payment grant request</h4>
262
256
< li >
263
257
Let |authServer:URL| be the result of running [=URL parser=] with |websiteWalletAddressDetails|'s {{WalletAddressDetails/authServer}} property.
264
258
</ li >
265
- < li >
266
- If |authServer| [=url/scheme=] is not `https`, return failure.
267
- </ li >
268
259
< li >
269
260
< p > Construct a {{ GrantRequest }} |grantRequest: GrantRequest| as follows:</ p >
270
261
< ol >
@@ -503,6 +494,134 @@ <h4>Cancel grant request</h4>
503
494
</ section >
504
495
</ section >
505
496
497
+ < section >
498
+ < h3 > Resource server operations (RS)</ h3 >
499
+ < section >
500
+ < h4 > Create incoming payment</ h4 >
501
+ < p > The create incoming payment request refers
502
+ to the < a data-cite ="oprs/operations/create-incoming-payment# "> Open Payments create incoming payment</ a > .</ p >
503
+ < div class ="algorithm ">
504
+ When asked to < dfn > send a create incoming payment request</ dfn > ,
505
+ given |websiteWalletAddressDetails:WalletAddressDetails|,
506
+ |incomingPaymentGrant:Grant|, perform the following steps.
507
+ < ol >
508
+ < li >
509
+ Let |resourceServer:URL| be the result of running [=URL parser=] with
510
+ |websiteWalletAddressDetails|'s {{WalletAddressDetails/resourceServer}} property.
511
+ </ li >
512
+ < li >
513
+ Let |incomingPaymentsUrl:URL| be the result of running [=URL parser=] with the string formed by
514
+ concatenating |resourceServer| and "/incoming-payments".
515
+ </ li >
516
+ < li >
517
+ Let |expiresAt:DOMString| be the current date-time plus 10 minutes, formatted as an ISO 8601 string.
518
+ < p class ="note "> The `expiresAt` field is set to the current date plus 10 minutes.
519
+ We assume users typically spend about 5 minutes on a website, making it unnecessary to keep the session active longer.
520
+ Ideally, the browser should terminate the session when the user navigates away from the site.
521
+ However, if that doesn’t happen for any reason, the expiration date will ensure the session is ended.
522
+ If the session expires before the user leaves the website, the browser should reinitialize the session.
523
+ </ p >
524
+ </ li >
525
+ < li >
526
+ < p > Let |body| be a new JavaScript object constructed as follows:</ p >
527
+ < ul >
528
+ < li > Set |body|.walletAddress to |websiteWalletAddressDetails|'s {{WalletAddressDetails/id}}.</ li >
529
+ < li > Set |body|.expiresAt to |expiresAt|.</ li >
530
+ </ ul >
531
+ < p class ="note "> `incomingAmount` is not set, as the amount is not fixed
532
+ and the same incoming payment is reused for the session duration.</ p >
533
+ </ li >
534
+ < li >
535
+ < p > Let |request| be a new [=request=] as follows:</ p >
536
+ < dl >
537
+ < dt > [=request/URL=]</ dt >
538
+ < dd > |incomingPaymentsUrl|</ dd >
539
+ < dt > [=request/method=]</ dt >
540
+ < dd > "POST"</ dd >
541
+ < dt > [=request/body=]</ dt >
542
+ < dd > the result of running [=serialize a JavaScript value to a JSON string=] on |body|</ dd >
543
+ < dt > [=request/redirect mode=]</ dt >
544
+ < dd > "follow"</ dd >
545
+ < dt > [=request/client=]</ dt >
546
+ < dd > null</ dd >
547
+ < dt > {{RequestInit/window}}</ dt >
548
+ < dd > null</ dd >
549
+ < dt > [=request/service-workers mode=]</ dt >
550
+ < dd > "none"</ dd >
551
+ < dt > [=request/destination=]</ dt >
552
+ < dd > "monetization"</ dd >
553
+ < dt > [=request/header list=]</ dt >
554
+ < dd > a list containing a single header with name set to < code > Content-Type</ code > and value set to < code > application/json</ code > .</ dd >
555
+ < dt > [=request/mode=]</ dt >
556
+ < dd > "cors"</ dd >
557
+ </ dl >
558
+ </ li >
559
+ < li >
560
+ Run the [=generate an HTTP message signature=] algorithm on |request| with |incomingPaymentGrant|.{{Grant/access_token}}.{{AccessToken/value}}.
561
+ </ li >
562
+ < li >
563
+ Let |incomingPaymentId:DOMString| be null.
564
+ </ li >
565
+ < li >
566
+ Perform a [=fetch request=] with |request| and with |processResponseConsumeBody| set to the following steps,
567
+ given a [=response=] and |response|'s [=request/body=] |responseBody|:
568
+ < ol >
569
+ < li >
570
+ Let |json| be the result of [=extract the JSON fetch response=] from |response| and |responseBody|.
571
+ </ li >
572
+ < li >
573
+ If |json| does not have an < code > id</ code > property whose value is a string, return failure.
574
+ </ li >
575
+ < li >
576
+ Set |incomingPaymentId| to |json|.id.
577
+ </ li >
578
+ </ ol >
579
+ </ li >
580
+ < li >
581
+ Return |incomingPaymentId|.
582
+ </ li >
583
+ </ ol >
584
+ </ div >
585
+
586
+ < aside class ="example " title ="Create incoming payment JSON payload ">
587
+ < p > This payload is sent to the resource server.</ p >
588
+ < pre class ="json ">
589
+ {
590
+ "walletAddress": "https://wallet.example/website",
591
+ "expiresAt": "2025-10-01T12:10:00Z"
592
+ }
593
+ </ pre >
594
+ </ aside >
595
+ < aside class ="example " title ="Incoming payment response JSON payload ">
596
+ < pre class ="json ">
597
+ {
598
+ "id": "https://rs.wallet.example/incoming-payments/08394f02-7b7b-45e2-b645-51d04e7c330c",
599
+ "walletAddress": "https://wallet.example/website",
600
+ "incomingAmount": {
601
+ "value": "2500",
602
+ "assetCode": "USD",
603
+ "assetScale": 2
604
+ },
605
+ "receivedAmount": {
606
+ "value": "0",
607
+ "assetCode": "USD",
608
+ "assetScale": 2
609
+ },
610
+ "completed": false,
611
+ "createdAt": "2025-10-01T12:00:00Z",
612
+ "methods": [
613
+ {
614
+ "type": "ilp",
615
+ "ilpAddress": "g.example.abcd1234",
616
+ "sharedSecret": "czVjcmV0Ig=="
617
+ }
618
+ ]
619
+ }
620
+ </ pre >
621
+ </ aside >
622
+ </ section >
623
+ </ section >
624
+
506
625
< section >
507
626
< h3 > Helper algorithms</ h3 >
508
627
< section >
0 commit comments