GitHub

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 RESPONSIBLE

Then 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); // public

payer_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.

On this page