@intrpay/react
v0.1.4
Published
A package for integrating Intrpay payments into your React application
Maintainers
Readme
@intrpay/react
A lightweight React package for embedding the Intrpay payment page: use the payment form as an inline embed or in a drawer.
Installation
npm install @intrpay/reactUsage
Inline embed
Use PaymentEmbed to render the payment form directly in your page:
import { PaymentEmbed } from '@intrpay/react';
function CheckoutPage() {
return (
<div>
<h1>Complete your payment</h1>
<PaymentEmbed
paymentLinkId="your-payment-link-id"
params={{
amount: 99.99,
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
}}
height={500}
onSuccess={(data) => console.log('Payment successful!', data)}
onFailure={(data) => console.log('Payment failed.', data)}
/>
</div>
);
}Auto height
Pass height="auto" to size the iframe to the payment page's content. The page reports its height over postMessage (intrpay:resize), so the embed grows and shrinks with the form and never shows an internal scrollbar:
<PaymentEmbed paymentLinkId="your-payment-link-id" height="auto" />Until the first height report arrives (or with an older deployed payment page that does not send one), the iframe falls back to the default 400px.
Drawer
Use PaymentDrawer to show the payment form in a slide-out drawer:
import { useState } from 'react';
import { PaymentDrawer } from '@intrpay/react';
function App() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Open Payment</button>
<PaymentDrawer
open={open}
onClose={() => setOpen(false)}
paymentLinkId="your-payment-link-id"
params={{
amount: 99.99,
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
}}
onSuccess={(data) => console.log('Payment successful!', data)}
onFailure={(data) => console.log('Payment failed.', data)}
/>
</>
);
}Fixed (locked) amount
Pass lockAmount: true together with amount to prevent the payer from editing the amount:
<PaymentEmbed paymentLinkId="your-payment-link-id" params={{ amount: 250, lockAmount: true }} />This disables the amount input on the payment page while the value is still submitted and validated. It is a UI lock; server-side rules (minimum amount, invoice totals) always apply on top.
Controlling payment methods
You can narrow which payment methods are shown using an allow-list, a hide-list, or both:
// Show only ACH (even if the link also enables card):
<PaymentEmbed paymentLinkId="..." params={{ paymentMethods: ["ach"] }} />
// Hide card, keep everything else the link enables:
<PaymentEmbed paymentLinkId="..." params={{ hidePaymentMethods: ["card"] }} />Narrowing precedence: the payment link's enabled methods (backend) -> paymentMethods (allow-list) -> hidePaymentMethods (hide-list) -> optional paymentMethod (lock to one). The package can only narrow the set of methods the payment link enables - it can never enable a method the link does not support. If narrowing would remove every method, the filters are ignored and the link's enabled methods are shown.
How it works (communication)
The components render the Intrpay payment page (pay.intrpay.us) in an iframe and configure it over a postMessage handshake - configuration is not placed in the iframe URL, so it cannot be tampered with by editing query params:
- The iframe loads with a minimal URL (
/pay/<paymentLinkId>). - The payment page posts
intrpay:readyto the host page. - The package replies with
intrpay:configcontaining yourparams, targeted at the pay origin only. - Payment results come back as
payment_success/payment_failuremessages, delivered to youronSuccess/onFailurecallbacks. Both sides validate the message origin and source window.
URL query params remain supported as a fallback for raw-URL embeds (e.g. linking directly to pay.intrpay.us/pay/<id>?amount=50), but postMessage values win when both are present.
What you can and cannot control
Package-controlled (display & prefill): title, description, primaryColor, secondaryColor, textColor, logo, buttonText, showHeader, showContactForm, contact prefill (firstName, lastName, email, phone, companyName), amount (+ lockAmount).
Backend-enforced (the package can only narrow, never expand): which payment methods are enabled, minimum amount, partial payments, processing fees, gateway settings, link type, invoice totals. For example, passing paymentMethods: ["ach"] on a link that does not enable ACH will not show ACH.
Props
PaymentEmbedProps
| Prop | Type | Default | Description |
| --------------- | ------------------------- | -------- | ------------------------------------------------------------------------------------------- |
| paymentLinkId | string | required | Payment link ID |
| params | PaymentParams | - | Payment parameters (see below) |
| onSuccess | (data: unknown) => void | - | Callback when payment succeeds; receives iframe message |
| onFailure | (data: unknown) => void | - | Callback when payment fails; receives iframe message |
| height | string \| number | 400 | Height of the iframe (e.g. 400, "100%", or "auto" to track the page's content height) |
| width | string \| number | "100%" | Width of the iframe |
| className | string | - | Optional CSS class for the wrapper div |
| style | CSSProperties | - | Optional inline styles for the wrapper div |
PaymentDrawerProps
| Prop | Type | Default | Description |
| --------------------- | ------------------------- | --------- | --------------------------------------------------------------------- |
| open | boolean | required | Whether the drawer is open |
| onClose | () => void | required | Callback when the drawer should close |
| paymentLinkId | string | required | Payment link ID |
| params | PaymentParams | - | Payment parameters (see below) |
| width | string \| number | 550 | Width of the drawer |
| position | 'left' \| 'right' | 'right' | Position of the drawer |
| showOverlay | boolean | true | Whether to show overlay backdrop |
| onSuccess | (data: unknown) => void | - | Callback when payment succeeds; receives message data from the iframe |
| onFailure | (data: unknown) => void | - | Callback when payment fails; receives message data from the iframe |
| closeOnOverlayClick | boolean | true | Whether clicking overlay closes the drawer |
| zIndex | number | 2000 | Z-index for the drawer |
PaymentParams
| Param | Type | Description |
| ---------------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| amount | number | Payment amount (prefill; editable unless lockAmount is set) |
| lockAmount | boolean | Lock the amount input so the payer cannot edit it (requires amount) |
| maxAmount | number | Maximum payable amount (UI cap on the editable amount; server limits still apply) |
| firstName | string | Customer's first name |
| lastName | string | Customer's last name |
| email | string | Customer's email |
| phone | string | Customer's phone number |
| companyName | string | Company name |
| showContactForm | boolean | Whether to show the contact form |
| checkoutItems | string[] | Checkout item IDs (filtered against the link's configured items) |
| allowPartialPayments | boolean | Whether to allow partial payment (only honored when the payment link allows it) |
| title | string | Page title shown above the payment form |
| description | string | Payment description |
| primaryColor | string | Primary theme color (hex, e.g. '#000076') |
| secondaryColor | string | Secondary theme color (hex, e.g. '#4774c0') |
| textColor | string | Text color (hex, e.g. '#f3fcff') |
| logo | string | Logo URL |
| buttonText | string | Custom button text |
| showHeader | boolean | Whether to show the header (default false for embeds) |
| paymentMethod | 'card' \| 'daf' \| 'ojc' \| 'pledger' \| 'donorsFund' \| 'matbia' | Lock to a specific payment method (must be enabled on the link) |
| paymentMethods | ('card' \| 'ach' \| 'daf' \| 'wallet')[] | Allow-list: show only these methods (intersected with the link's enabled methods) |
| hidePaymentMethods | ('card' \| 'ach' \| 'daf' \| 'wallet')[] | Hide-list: hide these methods (applied after paymentMethods) |
License
ISC
