Quickstart
Authenticate, initiate a payment, and receive a webhook in about five minutes.
This quickstart walks through the three API calls every integration makes: exchange your client secret for a JWT, create a payment, and handle the webhook that tells you whether the customer paid.
Prerequisites
- A verified merchant account (sign up)
- At least one bank destination configured in the dashboard
- An API key with a webhook URL — create one at Open Finance → API Keys
Your client secret is shown once at creation time. Store it in an environment variable or a secrets manager on your backend. Never put it in client-side code, browser storage, or a public repository. If it leaks, revoke the key immediately.
1. Get an access token
Exchange your client secret for a short-lived JWT. Tokens are valid for 60 minutes.
curl -X POST https://payment-api.openfinance.aryze.io/v1/auth/token \
-H 'Content-Type: application/json' \
-d '{
"grant_type": "client_credentials",
"client_secret": "'"$ARYZE_CLIENT_SECRET"'"
}'const res = await fetch(
'https://payment-api.openfinance.aryze.io/v1/auth/token',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'client_credentials',
client_secret: process.env.ARYZE_CLIENT_SECRET,
}),
},
);
if (!res.ok) throw new Error(`Auth failed: ${res.status}`);
const { access_token } = await res.json();import os
import requests
res = requests.post(
'https://payment-api.openfinance.aryze.io/v1/auth/token',
json={
'grant_type': 'client_credentials',
'client_secret': os.environ['ARYZE_CLIENT_SECRET'],
},
)
res.raise_for_status()
access_token = res.json()['access_token']using System.Net.Http.Json;
var http = new HttpClient();
var res = await http.PostAsJsonAsync(
"https://payment-api.openfinance.aryze.io/v1/auth/token",
new {
grant_type = "client_credentials",
client_secret = Environment.GetEnvironmentVariable("ARYZE_CLIENT_SECRET"),
});
res.EnsureSuccessStatusCode();
var body = await res.Content.ReadFromJsonAsync<TokenResponse>();
var accessToken = body!.access_token;
record TokenResponse(string access_token, string token_type, int expires_in, string environment);The response contains the token you'll pass as Authorization: Bearer <token>
on every subsequent call.
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"environment": "sandbox"
}2. Initiate a payment
Create a payment session. The destination bank account is read from the API key you authenticated with, so you don't pass it in the request.
curl -X POST https://payment-api.openfinance.aryze.io/v1/payments/initiate \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"redirectUrl": "https://yourapp.com/checkout/return",
"amount": 100.50,
"currencyCode": "EUR",
"reference": "ORDER12345"
}'const res = await fetch(
'https://payment-api.openfinance.aryze.io/v1/payments/initiate',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${access_token}`,
},
body: JSON.stringify({
redirectUrl: 'https://yourapp.com/checkout/return',
amount: 100.5,
currencyCode: 'EUR',
reference: 'ORDER12345',
}),
},
);
const payment = await res.json();
// Redirect the customer to complete the payment:
// window.location.href = payment.flowUrl;res = requests.post(
'https://payment-api.openfinance.aryze.io/v1/payments/initiate',
headers={'Authorization': f'Bearer {access_token}'},
json={
'redirectUrl': 'https://yourapp.com/checkout/return',
'amount': 100.50,
'currencyCode': 'EUR',
'reference': 'ORDER12345',
},
)
res.raise_for_status()
payment = res.json()
# Redirect the customer to payment['flowUrl']http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
var res = await http.PostAsJsonAsync(
"https://payment-api.openfinance.aryze.io/v1/payments/initiate",
new {
redirectUrl = "https://yourapp.com/checkout/return",
amount = 100.50m,
currencyCode = "EUR",
reference = "ORDER12345",
});
res.EnsureSuccessStatusCode();
var payment = await res.Content.ReadFromJsonAsync<PaymentResponse>();The response gives you a flowUrl — redirect the customer there. They'll
choose their bank, authenticate, and authorise the transfer.
{
"transactionId": "2f1a3e8c-9b7d-4a11-8c6f-d3e5e9b1a2c0",
"mastercardPaymentId": "mcob_8f3c2a...",
"flowUrl": "https://payment.aryze.io/complete/abc123...",
"status": "PENDING",
"amount": 100.50,
"currencyCode": "EUR",
"reference": "ORDER12345",
"endToEndId": "E2E-ORDER12345",
"initiationTimestamp": "2026-04-21T14:30:00Z"
}3. Handle the webhook
When the payment status changes, ARYZE POSTs a payment.status_updated event
to the webhook URL on your API key. Always respond with 200 OK, then do any
slow work asynchronously.
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhooks/aryze', async (req, res) => {
const { event, transactionId, status, reference } = req.body;
// Acknowledge immediately, then process.
res.status(200).json({ received: true });
if (event === 'payment.status_updated' && status === 'COMPLETED') {
await markOrderPaid(reference, transactionId);
}
});
app.listen(3000);Webhook retries use fixed backoff: 3 attempts at 1s, 5s, and 15s. Make your handler idempotent — the same event may arrive more than once.