Skip to main content

Standard QR Flow - Web Button

An embeddable, self-contained JavaScript payment button that lets any merchant website accept Fex wallet payments with a few lines of code.

How It Works

  1. Merchant calls FexPay.pay() with amount, currency, and optional description.
  2. The widget creates a payment intent on the Fex backend and renders a modal with the QR code.
  3. The customer opens the Fex mobile app, scans the QR, and approves the payment.
  4. The widget polls the backend every 5 seconds (up to 5 minutes) and automatically detects when the payment completes.
  5. On completion, the onSuccess callback fires and the success screen is shown.
Alternatively, if the merchant receives a webhook from the backend, they can call FexPay.confirm() to resolve the payment immediately without waiting for the next poll cycle.

Installation

The script is a self-contained IIFE with no external dependencies. It exposes a single global: window.FexPay.

Quick Start


API Reference

FexPay.init(config)

Must be called once before any pay() call. Typically called on page load.
Throws a synchronous Error if merchantId is missing.

FexPay.pay(params)

Opens the payment modal, creates a payment intent, and starts polling for completion. Returns a Promise that resolves with the created PaymentIntent object once the modal appears (not when payment completes — use onSuccess for that).

onSuccess(intent)

Called with the completed PaymentIntent object:

onError(error)

Called with an error object:

onCancel()

Called when the customer clicks the × button or the backdrop. No arguments.

Example with all params


FexPay.confirm(paymentIntentId?)

Tells the widget that a payment has been confirmed — typically called from your own webhook handler after the Fex backend notifies your server. Stops polling immediately, fetches the latest intent data, and shows the success screen.
If no active session exists, or the ID does not match the active session, the call is silently ignored (a warning is logged to the console).

Webhook Integration

Using callbackUrl + FexPay.confirm() is the most reliable way to detect payment completion — it avoids waiting for the next 5-second poll cycle.

Server-side webhook handler (Node.js example)

Client-side with WebSocket

Client-side with Server-Sent Events


Polling Behaviour

When no webhook is used, the widget polls automatically:
The success screen auto-closes after 3 seconds.

Security Considerations

  • The widget sends your Merchant ID as an X-Merchant-ID header on every API request. This ID is visible in client-side code — it is a public identifier, not a secret.
  • Never embed API keys or secrets in the widget configuration. Authentication of payment outcomes should be verified server-side using the webhook.
  • The modal is rendered in a Shadow DOM (mode: closed) so widget styles are fully isolated from your page and vice versa.
  • All dynamic text inserted into the modal is HTML-escaped to prevent XSS.

Browser Support

Requires: fetch, Promise, Shadow DOM, Intl.NumberFormat — all standard in modern browsers. No polyfills needed.

Demo

Open widget/demo.html directly in a browser (or serve it locally) to test the widget interactively:
The demo page lets you configure Merchant ID, amount, currency, and description, shows a live event log, and includes a Confirm button to simulate merchant-side webhook confirmation.

File Reference