SDK reference
Payment requests
Issuing a request, reading one as any wallet, and verifying who signed it.
createRequest(input, idempotencyKey?)
Requires a credential.
const request = await path.createRequest(
{
amount: { value: '5000', asset_type: 'fiat', asset_code: 'USD' },
accepts: [
{
rail: 'book',
asset_type: 'fiat',
asset_code: 'USD',
fees: [{ kind: 'operator', amount: { value: '25', asset_type: 'fiat', asset_code: 'USD' }, paid_by: 'payer' }],
},
],
orderReference: 'ord_10482',
expiresAt: new Date(Date.now() + 86_400_000).toISOString(),
},
`ord_10482`,
);
request.reference; // "7fk2m9pq3vx8"
request.url; // "https://api.example.com/path/7fk2m9pq3vx8"Open amounts
await path.createRequest({
amount: null,
accepts: [{ rail: 'book', asset_type: 'fiat', asset_code: 'USD' }],
});Omit amount and the payer chooses. A first-class case — a tip, a donation, an open invoice — not a
missing field.
Idempotency
Use your own order id as the key. On the retry after a timeout, when you do not know whether the first call landed, a replay returns the original request instead of creating a second one.
Fees
Each accepts entry carries its fees. They travel inside the signature, so they cannot differ
from what the payer was shown. A price disclosed after the decision is not a disclosure.
readRequest(referenceOrUrl, opts?)
No credential. Accepts a reference or a full URL, so a scanned QR code goes straight in.
const req = await path.readRequest('https://pay.example.com/path/7fk2m9pq3vx8');
req.amount; // { value: "5000", asset_type: "fiat", asset_code: "USD" } — or null
req.issuer; // "example-member"
req.accepts; // capabilities, with fees on each entry
req.status; // "created"Verify before displaying
const req = await path.readRequest(url, { verifyWith: issuerPublicKeyHex });
if (!req.verified) throw new Error('Refusing to display an unverified request');or, fetching the key for you:
import { verifyAgainstIssuer } from '@pathprotocol/sdk';
const { valid, reason } = await verifyAgainstIssuer(req, 'https://api.example.com');The domain says WHERE TO FETCH
The signature says WHO IS RESPONSIBLEThen show the issuer's verified name, never the raw URL. A payer confronted with an unfamiliar hostname closes the app — which is why a card terminal shows a merchant name rather than an acquirer's.
Expiry and revocation
try {
const req = await path.readRequest(reference);
} catch (err) {
if (err instanceof PathApiError) {
switch (err.code) {
case 'path.request.expired': // too late — ask for a new link
case 'path.request.revoked': // the issuer withdrew it
case 'path.core.not_found': // wrong reference entirely
}
}
}The three are distinguished on purpose. A payer told "not found" when a link merely expired will retype it, blame themselves, and call support.
revokeRequest(reference)
Requires a credential. Only the issuer may revoke.
await path.revokeRequest('7fk2m9pq3vx8');Irreversible. A payer opening the link afterwards is told it was revoked, not that it never existed.
markPaid(reference, reason?)
Requires a credential. Separate from issuing the receipt.
A grammar-2 request moves to paid on its own once settled receipts cover it. This call checks
the coverage and answers path.request.not_covered when it falls short.
await path.markPaid('7fk2m9pq3vx8');Checkout — the request plus the return URLs — is its own page.