arrow_backKnowledge base folderPerno Orchestration

How to integrate with Perno Orchestration through the API?

A step-by-step guide to setting up a merchant account and signing key, issuing payment links through the API, signing them correctly, and confirming payment.

This guide is for anyone who wants to issue and settle payments through Perno Orchestration from their own system (a store backend, an app) instead of creating every payment link by hand in the dashboard. It assumes you already have an API token and at least one merchant account - if not, see How to use the Perno API? and How to add a merchant account in Perno? first.

Before you start: two different secrets

Integrating with Orchestration involves two separate secrets that are easy to mix up:

Secret Purpose
API Token Authenticates you as a user. Sent as Authorization: Token YOUR_API_TOKEN on every request.
Transaction Signing Key Used only to build the trx_hash when creating a payment link. Never sent in the request body itself.

You'll find the Transaction Signing Key in Orchestration settings (Perno Orchestration context → Perno Orchestration in the left sidebar), alongside the default payment gateway, the return URLs (Default/Success/Cancel Return URL), and the notification URLs (Transaction and Payment Link Notification URL). The API's return_url* and notification_url fields are optional precisely because of this - leave them out and Perno falls back to whatever you've set here.

Step 1: check or create a merchant account

List the merchant accounts connected to your Orchestration account:

curl -X GET "https://perno.io/api/v1/orchestration/merchant-accounts/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Look for the one with "default": true - that's where a payment link routes to unless you specify a different account. Full details: Retrieve merchant accounts.

If you'd rather create a merchant account programmatically than through the dashboard, use Create merchant account:

curl -X POST "https://perno.io/api/v1/orchestration/merchant-accounts/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_account_name": "Stripe EU",
    "payment_gateway": "stripe",
    "payment_gateway_type": {"type": "production"},
    "default": true,
    "api_data_1": "sk_live_..."
  }'

supported_currencies, supported_languages, supported_countries, and supported_payment_methods are arrays of Perno lookup-table IDs, not text codes. The simplest approach is to configure these once in the dashboard (How to add a merchant account in Perno?) and read the resulting values back with GET - or check the payment method codes in step 2 below.

To change which account is the default, call Set default merchant account:

curl -X POST "https://perno.io/api/v1/orchestration/merchant-accounts/{account_id}/set-default/" \
  -H "Authorization: Token YOUR_API_TOKEN"

Step 2: check the available payment methods

If you're building your own checkout and want to show the customer available payment methods up front, instead of sending them straight to Perno's hosted page, fetch them from List payment methods:

curl -X GET "https://perno.io/api/v1/orchestration/payment-methods/?merchant_account_id=1¤cy=PLN&amount=10.00" \
  -H "Authorization: Token YOUR_API_TOKEN"

The response is a list of {code, name, active, sequence} objects. The endpoint also accepts optional country, language, and payment_gateway_type (production or sandbox) filters, so you can narrow it down to what a given customer will actually see.

Step 3: sign and create the payment link

Creating a payment link needs a valid trx_hash, computed with the Transaction Signing Key:

trx_hash = SHA256("|" + amount + "|" + trx_id + "|" + transaction_signing_key)

Perno recomputes the same hash on its side and compares it - if it doesn't match, the request is rejected with a Wrong hash error. Example in Python:

import hashlib

def build_trx_hash(amount, trx_id, transaction_signing_key):
    raw = f"|{amount}|{trx_id}|{transaction_signing_key}"
    return hashlib.sha256(raw.encode()).hexdigest()

With a valid trx_hash in hand, call Create payment link:

curl -X POST "https://perno.io/api/v1/payment_links/" \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_account": 1,
    "amount": "10.00",
    "currency": "PLN",
    "trx_id": "order-4821",
    "trx_hash": "…computed hash…",
    "customer_email": "[email protected]",
    "one_time_link": true
  }'

You can leave out merchant_account - Perno then uses the default account from step 1. The same goes for return_url, return_url_success, return_url_cancel, and notification_url - only set these when a specific payment needs different addresses than the Orchestration defaults. one_time_link: true stops the link being paid twice. The response includes payment_hash - the new link's unique identifier.

Step 4: send the link to your customer

The API doesn't hand back a ready-to-share URL - it manages the record itself. A link created through the API shows up in the same list as links created by hand: in the dashboard, under the Perno Orchestration context → Payment links, every entry has its own hosted address in the Link column - copy it from there to send to your customer (see How to manage payment links in Perno?). Opened, it leads to a checkout page showing the amount and payment methods such as card, Apple Pay, Revolut Pay, or Klarna.

Step 5: confirm the payment

The best approach is a webhook: the Payment Link Notification URL configured in Orchestration settings is called whenever a link's status changes, so your endpoint learns about payment without polling. If Send multiple webhooks is enabled in those settings, expect the same event to arrive more than once - make your webhook handler idempotent (key it on trx_id or payment_hash).

If you'd rather check status yourself (or want a fallback), fetch the link's details with Get payment link details:

curl -X GET "https://perno.io/api/v1/payment-links/{payment_hash}/" \
  -H "Authorization: Token YOUR_API_TOKEN"

The used field flips to true once the link has been paid (or consumed, for one-time links). The full, detailed payment record - gateway, status (paid, pending, need 3ds, and so on), and its link to the payment link - lives in the dashboard's Transactions view (see What is transaction in Perno Orchestration?); transactions aren't exposed as a separate resource in the v1 API yet.

Step 6: monitor the integration

To check whether the payment-link endpoints are up, use Health check payment links API - a good candidate for your own uptime monitoring:

curl -X GET "https://perno.io/api/v1/payment_links/health_check" \
  -H "Authorization: Token YOUR_API_TOKEN"

The flow, summarized

  • Set up a merchant account and the Transaction Signing Key (once).
  • Check the default merchant account and, optionally, the available payment methods.
  • Compute trx_hash and create a payment link for the order.
  • Get its address from the dashboard and send it to the customer.
  • Handle the webhook, or check the used field, to confirm payment.

Ready to put this knowledge into practice?

Create your Perno workspace and turn these instructions into a working process for your business.