Make a one-time payment
The Open Payments APIs facilitate multiple uses cases for payments to and from different Open Payments-enabled wallets. In this guide we look at the steps for making a one time payment.
Examples of use cases for a one-time payment might be an e-commerce or a money transmitter application.
Dependencies
Endpoints
-
Grant Request
-
Get a Wallet address
-
Create an Incoming Payment
-
Create a Quote
-
Create an Outgoing Payment
- Node 18
- A package manager such as NPM or PNPM
-
Open Payments SDK
- TSX
Additional configuration
Add "type": "module"
to package.json
Add the following to tsconfig.json
Steps
1. Import dependencies
Import createAuthenticatedClient
from the Open Payments SDK package.
Import dependencies
import { createAuthenticatedClient } from "@interledger/open-payments";
2. Create an authenticated Open Payments client
Create an Open Payments-authenticated client by providing the following properties:
walletAddressURL
: your Open Payments-enabled wallet address that your client will use to authenticate itself to one or more Authorization Servers (AS).privateKey
: the EdDSA-Ed25519 key or preferably the absolute or relative file path to the key that is bound to your wallet address. A public key signed with this private key must be made available as a public JWK document at{walletAddressUrl}/jwks.json
url.keyId
: the identifier of the private key and the corresponding public key.
Initialize Open Payments client
const client = await createAuthenticatedClient({
walletAddressUrl: WALLET_ADDRESS,
privateKey: PRIVATE_KEY_PATH,
keyId: KEY_ID,
});
3. Request an Incoming Payment grant
Request an incomingPayment
grant from the payee wallet’s AS.
Request incoming payment grant
const grant = await client.grant.request(
{
url: walletAddress.authServer,
},
{
access_token: {
access: [
{
type: "incoming-payment",
actions: ["list", "read", "read-all", "complete", "create"],
},
],
},
},
);
4. Create an Incoming Payment
Create an incomingPayment
on the payee wallet’s Resource Server (RS) using the access token returned by the AS in the grant request and specify the walletAddress
with the URL of the payee’s wallet.
Add the incomingAmount
object and define the following properties:
value
: the maximum allowable amount that will be paid to the payee’s wallet address.assetCode
: the ISO 4217 currency code representing the underlying asset used to make the payment.assetScale
: the scale of amounts denoted in the corresponding asset code.
Optionally you may add the expiresAt
property which is the date and time after which payments to the incoming payments will no longer be accepted.
Create incoming payment
const incomingPayment = await client.incomingPayment.create(
{
url: new URL(WALLET_ADDRESS).origin,
accessToken: INCOMING_PAYMENT_ACCESS_TOKEN,
},
{
walletAddress: WALLET_ADDRESS,
incomingAmount: {
value: "1000",
assetCode: "USD",
assetScale: 2,
},
expiresAt: new Date(Date.now() + 60_000 * 10).toISOString(),
},
);
5. Request a Quote grant
Request a quote
grant from the payer wallet’s AS.
Request quote grant
const grant = await client.grant.request(
{
url: walletAddress.authServer,
},
{
access_token: {
access: [
{
type: "quote",
actions: ["create", "read", "read-all"],
},
],
},
},
);
6. Create a Quote
Create a quote
on the payer wallet’s RS using the access token returned by the AS in the grant request.
Add the following properties:
method
: the payment method used to facilitate the payment. Set this property toilp
as Open Payments only supports Interledger payments at this time.walletAddress
: the URL of the payer’s wallet address.receiver
: the URL of the incoming payment that will receive the payment.
Create quote
const quote = await client.quote.create(
{
url: new URL(WALLET_ADDRESS).origin,
accessToken: QUOTE_ACCESS_TOKEN,
},
{
method: "ilp",
walletAddress: WALLET_ADDRESS,
receiver: INCOMING_PAYMENT_URL,
},
);
7. Request an Outgoing Payment grant
Request an outgoingPayment
grant from the payer wallet’s AS.
Add the limits
object with the following properties:
debitAmount
: the maximum amount to be deducted from the payer’s wallet.receiveAmount
: the maximum amount to be received in the payee’s wallet.
Request outgoing payment grant
const grant = await client.grant.request(
{
url: walletAddress.authServer,
},
{
access_token: {
access: [
{
identifier: walletAddress.id,
type: "outgoing-payment",
actions: ["list", "list-all", "read", "read-all", "create"],
limits: {
debitAmount: {
assetCode: quote.debitAmount.assetCode,
assetScale: quote.debitAmount.assetScale,
value: quote.debitAmount.value,
},
},
},
],
},
interact: {
start: ["redirect"],
finish: {
method: "redirect",
uri: "http://localhost:3344",
nonce: NONCE,
},
},
},
);
8. Create an Outgoing Payment
Create an outgoingPayment
on the payer wallet’s RS using the access token returned by the AS in the grant request.
Add the following properties:
walletAddress
: the URL of the payer’s wallet address.quoteId
: the URL of the quote specifying the payment amount.
Create outgoing payment
const outgoingPayment = await client.outgoingPayment.create(
{
url: new URL(WALLET_ADDRESS).origin,
accessToken: OUTGOING_PAYMENT_ACCESS_TOKEN,
},
{
walletAddress: WALLET_ADDRESS,
quoteId: QUOTE_URL,
},
);