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: '5000',
currency: 'XOF',
accepts: [{ rail: 'mobile_money', currency: 'XOF' }],
feeDisclosure: {
network_fee: '0',
operator_fee: '25',
currency: 'XOF',
total_deducted: '25',
},
orderReference: 'ord_10482',
expiresAt: new Date(Date.now() + 86_400_000).toISOString(),
},
`ord_10482`,
);
request.reference; // "7fk2m9pq3vx8"
request.url; // "https://api.example.com/p/7fk2m9pq3vx8"Open amounts
await path.createRequest({ currency: 'XOF' });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.
Fee disclosure
Passed here, the fee travels inside the signature, so it 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/p/7fk2m9pq3vx8');
req.amount; // "5000" — or null, meaning the payer chooses
req.currency; // "XOF"
req.issuer; // "example-member"
req.fees; // disclosed, before the payer commits
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.
Checkout sessions
const session = await path.createCheckoutSession({
requestReference: request.reference,
successUrl: 'https://store.example.com/thanks?order=10482',
cancelUrl: 'https://store.example.com/cart',
webhookUrl: 'https://store.example.com/hooks/path',
});
const state = await path.getCheckoutSession(session.id); // publicpayer_member on the session is the wallet that completed it — and it may belong to a member you
have never integrated with. That is the protocol working.