Using an Alphanumeric Anchor

Register a short business alias as a payment point — customers pay by typing the identifier instead of scanning a QR code.

Audience: Developers, Integration Engineers · Read time: 3 min

Not all payment identifiers are visual. Some are typed into a bank app, entered at a payment terminal, or dictated over the phone. A short business alias, a tax ID, or a phone number can all serve as payment anchors — identifiers that resolve to a wallet on the ledger. When a customer enters the identifier, the payment network looks it up, finds the merchant's wallet, and routes the payment.

What you're building

In this guide you'll register greatcoffee123 — a short alias for the Great Coffee store — as a payment anchor pointing to their store wallet. When a customer enters the alias in their bank app, the payment routes to the merchant's settlement account automatically — the same settlement flow as QR, with no encoding and no image.

Prerequisites

  • A merchant wallet already created (see How to Onboard a Merchant)
  • SDK credentials and a connection to a ledger
  • An alphanumeric anchor schema deployed on the ledger

Create the anchor

Register the alias as an anchor

minka anchor create
PromptWhat to enter
HandleThe alias, e.g. greatcoffee123
Schemaanchor-alias
TargetThe store wallet, e.g. store1@greatcoffee.co
curl -X POST "https://{ledger-host}/v2/anchors" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {your-token}" \
  -H "x-ledger: {your-ledger}" \
  -d '{
    "data": {
      "handle": "greatcoffee123",
      "schema": "anchor-alias",
      "target": "store1@greatcoffee.co"
    }
  }'
POST /v2/anchors
// SDK setup: see How to Connect to a Ledger
// /moving-money/connect-to-ledger
const { response } = await sdk.anchor
  .init()
  .data({
    handle: 'greatcoffee123',
    schema: 'anchor-alias',
    target: 'store1@greatcoffee.co',
  })
  .hash()
  .sign([{ keyPair }])
  .send()
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

String json = """
    {
      "data": {
        "handle": "greatcoffee123",
        "schema": "anchor-alias",
        "target": "store1@greatcoffee.co"
      }
    }
    """;

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://{ledger-host}/v2/anchors"))
    .header("Content-Type", "application/json")
    .header("Authorization", "Bearer {your-token}")
    .header("x-ledger", "{your-ledger}")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .build();

HttpResponse<String> response = client.send(
    request, HttpResponse.BodyHandlers.ofString());
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer {your-token}");
client.DefaultRequestHeaders.Add("x-ledger", "{your-ledger}");

var json = """
    {
      "data": {
        "handle": "greatcoffee123",
        "schema": "anchor-alias",
        "target": "store1@greatcoffee.co"
      }
    }
    """;

var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
    "https://{ledger-host}/v2/anchors", content);
var body = await response.Content.ReadAsStringAsync();

The curl examples use a Bearer token for authentication. In production, every mutation also requires a cryptographic signature — see Sign Payments for the full signing flow. The TypeScript SDK handles signing automatically.

Three fields. The handle is the identifier customers will type — a short, memorable alias scoped to the ledger. The schema field tells the ledger this is a plain alias lookup — no QR encoding, no payload generation. The target points to the store wallet that the identifier should resolve to.

The handle can take any form the ledger accepts — a plain alias like greatcoffee123, a tax ID with a prefix like nit:900123456@merchant.co, or a phone number like tel:+573001234567@merchant.co. The ledger stores them as opaque handles; prefixes are routing hints for bridges and alias directories. The anchor-alias schema works the same way regardless of format.

Verify the anchor

Read the anchor back to confirm it maps correctly to the store wallet:

minka anchor read greatcoffee123
curl "https://{ledger-host}/v2/anchors/greatcoffee123" \
  -H "Authorization: Bearer {your-token}" \
  -H "x-ledger: {your-ledger}"
// SDK setup: see How to Connect to a Ledger
// /moving-money/connect-to-ledger
const { anchor } = await sdk.anchor.read('greatcoffee123')
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://{ledger-host}/v2/anchors/greatcoffee123"))
    .header("Authorization", "Bearer {your-token}")
    .header("x-ledger", "{your-ledger}")
    .GET()
    .build();

HttpResponse<String> response = client.send(
    request, HttpResponse.BodyHandlers.ofString());
using System.Net.Http;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer {your-token}");
client.DefaultRequestHeaders.Add("x-ledger", "{your-ledger}");

var response = await client.GetAsync(
    "https://{ledger-host}/v2/anchors/greatcoffee123");
var body = await response.Content.ReadAsStringAsync();

The response should show target: "store1@greatcoffee.co" and schema: "anchor-alias". If you see those two fields, the anchor is live and ready to receive payments routed to that alias.

How the anchor is resolved

When a customer enters greatcoffee123 in their bank app, the payment network queries the ledger to resolve the identifier. The ledger finds the anchor registered under that handle and returns the target wallet — store1@greatcoffee.co.

The bridge then reads the wallet hierarchy. The store wallet has type: "store", so the bridge walks up to main@greatcoffee.co for the merchant-level fields: taxId, category, acquirer, and settlement. It reads the settlement field — svgs:4242@bank.co — and creates a credit intent that routes the payment to the merchant's bank account.

The settlement flow is identical to QR. The only difference is how the identifier reached the ledger — the customer typed it instead of scanning an image.

How it differs from QR

A QR code embeds the full payment payload in an encoded image — merchant name, MCC, acquirer GUID, alias, all baked into a TLV string. An alphanumeric anchor is just a lookup key. The customer types it, the network resolves it, and the bridge handles the rest. No encoding, no image, no EMVco tags. The anchor is simpler to create but requires the customer to know and type the identifier — which works naturally for business-to-business payments, terminal-driven flows, and phone-based collection where visual codes are impractical.

Common alphanumeric identifiers

IdentifierFormatUse case
Custom aliasgreatcoffee123Short business code customers can memorize
NITnit:900123456@merchant.coTax ID payment in Colombia
Phonetel:+573001234567@merchant.coPhone-based merchant payments
Emailemail:pay@merchant.coEmail-based payment links

What you learned

  • How to register a plain alias as a payment anchor with a three-field API call
  • How the anchor-alias schema handles any identifier format — plain or prefixed
  • How the bridge resolves the anchor to a store wallet and walks up to the merchant profile for settlement
  • How alphanumeric anchors use the same settlement flow as QR, without encoding or image generation

Common errors

ErrorCauseFix
alias-already-registeredAnother wallet has already claimed this alphanumeric identifier on the networkChoose a different alias or contact the network administrator to resolve the conflict
schema-validation-failedThe anchor's custom fields don't match the schema requirementsCheck the schema definition to see which fields are required for this anchor type
target-wallet-not-foundThe wallet specified in the target field does not existCreate the target wallet first — see Create a Merchant

Next steps

On this page