Developers

How x402 paid links work

Use x402 V2 to buy access to a URL with USDC. Payfirst confirms the payment and returns a redirect to the purchased URL.

Protocol
x402 V2
Unpaid request
HTTP 402
Paid response
HTTP 302
On this page

Client requirements

Use an x402 V2 client that supports the exact EVM payment scheme. It needs a signer and enough USDC on the network advertised by the link.

Base mainnet and Base Sepolia use different USDC assets. Match both the network and asset in the payment terms. Base Sepolia tokens are for testing and have no monetary value.

1. Read the payment terms

Replace YOUR_LINK_SLUG with an active paid link. Send a GET request with Accept: application/json to receive HTTP 402 and the PAYMENT-REQUIRED header.

Read-only request
curl -i \
  -H 'Accept: application/json' \
  'https://www.payfirst.app/pay/YOUR_LINK_SLUG'

  • Decode the Base64 PAYMENT-REQUIRED header with your x402 client.
  • Check the scheme, network, token, amount, and recipient against the buyer’s spending rules.

2. Submit the payment

Authorize the approved terms with your x402 signer. Save the exact request URL and serialized payment payload in private, durable storage before sending.

Retry the GET request with that payload in PAYMENT-SIGNATURE. Payfirst verifies and settles the payment before returning the destination.

PAYMENT-REQUIRED

Sent by
Payfirst
Contains
Accepted payment terms

PAYMENT-SIGNATURE

Sent by
Your client
Contains
Authorized payment payload

PAYMENT-RESPONSE

Sent by
Payfirst
Contains
Settlement receipt

3. Open the destination

Read the HTTP 302 response before following it. Save the PAYMENT-RESPONSE receipt and get the destination from Location. In Node.js, set the redirect option to "manual" to keep this response available.

Fetch the approved destination in a separate request without the payment signature, authorization headers, or checkout cookies. Check any further redirects against your client’s allowed destinations.

Payfirst returns a URL. It does not host the file or charge for later requests to it. The destination’s access permissions still apply.

Node.js client

Download payfirst-x402.mjs and save it beside your script. The module reads payment terms, submits an existing authorization, and fetches an approved destination separately.

This command reads the price without paying. To make a purchase, add your x402 signer, spending limits, and payment record storage using the setup instructions.

Read-only request
import { inspectPayfirstLink } from './payfirst-x402.mjs';

const terms = await inspectPayfirstLink(
  'https://www.payfirst.app/pay/YOUR_LINK_SLUG'
);
console.log(terms.accepts);

Interrupted payments

If a request times out or returns a reconciliation response, keep the original authorization. The payment may already have settled.

Follow Retry-After and resubmit the same signed request when instructed. Do not automatically sign another payment. If payment succeeded but the file failed to load, recover the receipt and resolve access to the file.

Response errors

Checkout appears instead of HTTP 402
Use Accept: application/json. Requests for HTML open the browser checkout.
The client rejects the payment terms
Check support for x402 V2, the exact scheme, and the advertised network and USDC asset.
HTTP 503 or x402_reconciliation_required
Read the response body and Retry-After header. Retain the existing signed request while settlement is checked.
Payment succeeded, but the file does not load
Check the destination’s availability and permissions. Do not pay again to retry a file download.
HTTP 404 or 410
Confirm the URL with the seller. The link may be missing or retired. For an earlier payment, follow any recovery instructions in the response.

Documentation