Create an incoming payment grant request
Before a client can call most of the Open Payments APIs, it must receive a grant from the appropriate authorization server.
The snippets below enable a client to request a grant for an incoming payment. The request to the authorization server must indicate the incoming-payment and the actions the client wants to take at the resource server.
Before you begin
Section titled “Before you begin”We recommend creating a wallet account on the test wallet. Creating an account allows you to test your client against the Open Payments APIs by using an ILP-enabled wallet funded with play money.
Request an incoming payment grant
Section titled “Request an incoming payment grant”Initial configuration
If you’re using JavaScript, only do the first step.
- Add
"type": "module"topackage.json. - Add the following to
tsconfig.json{"compilerOptions": {"target": "ES2022","module": "ES2022"}}
Import dependencies
import { createAuthenticatedClient } from "@interledger/open-payments"; Copied! Initialize Open Payments client
const client = await createAuthenticatedClient({
walletAddressUrl: WALLET_ADDRESS,
privateKey: PRIVATE_KEY_PATH,
keyId: KEY_ID,
}); Copied! Get wallet address information
const walletAddress = await client.walletAddress.get({
url: WALLET_ADDRESS,
}); Copied! 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"],
},
],
},
},
); Copied! Check grant state
if (isPendingGrant(grant)) {
throw new Error("Expected non-interactive grant");
} Copied! Output
console.log("INCOMING_PAYMENT_ACCESS_TOKEN =", grant.access_token.value);
console.log(
"INCOMING_PAYMENT_ACCESS_TOKEN_MANAGE_URL = ",
grant.access_token.manage,
); Copied! For TypeScript, run tsx path/to/directory/index.ts. View full TS source
For JavaScript, run node path/to/directory/index.js. View full JS source
Import dependencies
use open_payments::client::api::UnauthenticatedResources;
use open_payments::client::AuthenticatedResources;
use open_payments::snippets::utils::{create_authenticated_client, get_env_var, load_env};
use open_payments::types::auth::{
AccessItem, AccessTokenRequest, GrantRequest, GrantResponse, IncomingPaymentAction,
}; Copied! Initialize Open Payments client
// Authenticated client can be also used for unauthenticated resources
let client = create_authenticated_client()?; Copied! Get wallet address information
let wallet_address_url = get_env_var("WALLET_ADDRESS_URL")?;
let wallet_address = client.wallet_address().get(&wallet_address_url).await?; Copied! Request incoming payment grant
let grant_request = GrantRequest::new(
AccessTokenRequest {
access: vec![AccessItem::IncomingPayment {
actions: vec![
IncomingPaymentAction::Create,
IncomingPaymentAction::Read,
IncomingPaymentAction::ReadAll,
IncomingPaymentAction::List,
IncomingPaymentAction::Complete,
],
identifier: None,
}],
},
None,
);
println!(
"Grant request JSON: {}",
serde_json::to_string_pretty(&grant_request)?
);
let response = client
.grant()
.request(&wallet_address.auth_server, &grant_request)
.await?; Copied! Output
match response {
GrantResponse::WithToken { access_token, .. } => {
println!("Received access token: {:#?}", access_token.value);
println!(
"Received access token manage URL: {:#?}",
access_token.manage
);
}
GrantResponse::WithInteraction { .. } => {
unreachable!("Interaction not required for incoming payments");
}
} Copied! // Import dependenciesuse OpenPayments\AuthClient;use OpenPayments\Config\Config;
// Initialize Open Payments client$config = new Config( $WALLET_ADDRESS, $PRIVATE_KEY, $KEY_ID);$opClient = new AuthClient($config);// Get wallet address information$wallet = $opClient->walletAddress()->get([ 'url' => $config->getWalletAddressUrl()]);
// Request incoming payment grant$grant = $opClient->grant()->request( [ 'url' => $wallet->authServer ], [ 'access_token' => [ 'access' => [ [ 'type' => 'incoming-payment', 'actions' => ['read', 'complete', 'create', 'list'] ] ] ] ]);
// Check grant stateif (!$grant instanceof \OpenPayments\Models\Grant) { throw new \Error('Expected non-interactive grant');}
// Outputecho 'INCOMING_PAYMENT_GRANT: ' . $grant->access_token->value . PHP_EOL;echo "INCOMING_PAYMENT_ACCESS_TOKEN_MANAGE_URL = " . $grant->access_token->manage . PHP_EOL;echo 'GRANT OBJECT: ' . PHP_EOL . print_r($grant, true);package main
import ( "context" "encoding/json" "fmt" "log"
op "github.com/interledger/open-payments-go" as "github.com/interledger/open-payments-go/generated/authserver")
func main() { // Initialize Open Payments client client, err := op.NewAuthenticatedClient(WALLET_ADDRESS_URL, PRIVATE_KEY_BASE_64, KEY_ID) if err != nil { log.Fatalf("Error creating authenticated client: %v\n", err) }
// Get wallet address information walletAddress, err := client.WalletAddress.Get(context.TODO(), op.WalletAddressGetParams{ URL: WALLET_ADDRESS_URL, }) if err != nil { log.Fatalf("Error fetching wallet address: %v\n", err) }
// Request incoming payment grant incomingAccess := as.AccessIncoming{ Type: as.IncomingPayment, Actions: []as.AccessIncomingActions{ as.AccessIncomingActionsCreate, as.AccessIncomingActionsRead, as.AccessIncomingActionsList, as.AccessIncomingActionsComplete, }, } accessItem := as.AccessItem{} if err := accessItem.FromAccessIncoming(incomingAccess); err != nil { log.Fatalf("Error creating AccessItem: %v\n", err) } accessToken := struct { Access as.Access `json:"access"` }{ Access: []as.AccessItem{accessItem}, }
grant, err := client.Grant.Request(context.TODO(), op.GrantRequestParams{ URL: *walletAddress.AuthServer, RequestBody: as.GrantRequestWithAccessToken{AccessToken: accessToken}, }) if err != nil { log.Fatalf("Error requesting grant: %v\n", err) }
// Check grant state if grant.IsInteractive() { log.Fatalf("Expected non-interactive grant") }
// Output grantJSON, err := json.MarshalIndent(grant, "", " ") if err != nil { log.Fatalf("Error marshaling grant: %v\n", err) } fmt.Println("GRANT:", string(grantJSON)) fmt.Println("INCOMING_PAYMENT_ACCESS_TOKEN =", grant.AccessToken.Value) fmt.Println( "INCOMING_PAYMENT_ACCESS_TOKEN_MANAGE_URL =", grant.AccessToken.Manage, )}