@fragment-dev/payment-elements
v0.0.4
Published
React components for Fragment Payment Elements
Readme
@fragment-dev/payment-elements
Embed Fragment's Payment Elements in your product to process payments through Fragment.
Install
npm install @fragment-dev/payment-elementsReact 17, 18 or 19 must be a peer dependency.
Usage
Your server calls the server-side Fragment SDK's createPayment and passes the returned Payment to your product's payment page.
import {
Checkout,
PaymentElements,
usePayment,
} from '@fragment-dev/payment-elements';
const PayButton = () => {
const { confirm, canConfirm, isConfirming, isLoading, onError, error } =
usePayment();
return (
<>
<button
type="button"
disabled={isLoading || !canConfirm || isConfirming}
// Call confirm() inside the click handler. It never rejects.
onClick={() => confirm()}
>
Pay
</button>
{error && <p role="alert">{error}</p>}
</>
);
};
const PaymentPage = ({ payment, email }) => (
<PaymentElements>
<Checkout
payment={payment}
billingDetails={{ email }}
onError={showError}
onConfirmed={close}
>
<PayButton />
</Checkout>
</PaymentElements>
);Checkout renders your Pay Button below the address and card fields. It takes
the same props as PaymentSession.
The return type of confirm() is:
type ConfirmOutcome =
| { status: 'confirmed' }
| { status: 'failed'; message: string };Custom layout
To customize the layout, render PaymentSession with AddressElement,
CardElement and your Pay Button as children. Mount one CardElement per
session. AddressElement is optional. See Billing details
to learn more.
Errors
Use usePayment().error to render failures. It clears when a field changes. onError is
called for every failure.
On a payment decline, create and provide a new Payment to refresh the session. The old
attempt and error state are cleared automatically.
Save Payment Methods
Set savePaymentMethod to true to save the card for the payer in billingDetails.email when the
payment confirms. Defaults to false.
Billing details
You can optionally provide the name and address of the person making the payment. Render the
AddressElement if you don't provide them.
Saving a card
To save an end-user's card without charging it, your server calls the
server-side Fragment SDK's createPaymentMethodSetup with the end-user's email
and passes the returned PaymentMethodSetup to your page.
import {
PaymentElements,
SavePaymentMethod,
usePaymentMethodSetup,
} from '@fragment-dev/payment-elements';
const SaveCardButton = () => {
const { state, canSubmit, submit, error } = usePaymentMethodSetup();
if (state.status === 'saved') {
return <p>Card saved.</p>;
}
return (
<>
<button
type="button"
disabled={!canSubmit}
// Call submit() inside the click handler. It never rejects.
onClick={() => submit()}
>
{state.status === 'processing' ? 'Saving…' : 'Save card'}
</button>
{state.status === 'declined' && <p role="alert">{state.message}</p>}
{error && <p role="alert">{error.message}</p>}
</>
);
};
const SaveCardPage = ({ paymentMethodSetup }) => (
<PaymentElements>
<SavePaymentMethod
paymentMethodSetup={paymentMethodSetup}
onPaymentMethodSaved={close}
onPaymentMethodDeclined={recordDecline}
onError={({ message }) => showError(message)}
>
<SaveCardButton />
</SavePaymentMethod>
</PaymentElements>
);SavePaymentMethod renders your Save Button below the address and card fields.
It takes the same props as PaymentMethodSetupSession.
To customize the layout, render PaymentMethodSetupSession with
AddressElement, CardElement and your Save Button as children. Mount one
CardElement per session. AddressElement is optional. See the
billingDetails note below to learn more.
Use usePaymentMethodSetup().state to render the status in your product.
type PaymentMethodSetupState =
| { status: 'loading' }
| { status: 'ready' }
| { status: 'processing' }
| { status: 'declined'; message: string; declineCode: string | null }
| { status: 'saved' };submit()waits for any verification step the card's bank asks for, and resolves after it.onPaymentMethodSavedfires when the payment method was successfully saved. Thesavedstate carries no card details. To read the card, your server queriespaymentMethodSetupand reads itspaymentMethodfield, or lists the end-user's cards withpaymentMethods(filter: { user }).onPaymentMethodDeclinedfires when the payment method was declined. A declined setup is final. Create a new setup to try again.onErroris required and fires for every other non-decline failure. Invalid setups report through this callback and render no children.processingcan rest when the result arrives later. Read the setup's status from Fragment on your server.billingDetailstakes an optionalnameandaddress. Without anAddressElement, saving a card needsname,address.line1,address.postalCodeandaddress.country. Render theAddressElementif you don't provide them.
Theming
Pass a theme to customize the checkout styling. Every field falls back to Fragment's default value:
<PaymentElements
theme={{
colors: { text: 'rgb(20 20 20)', error: 'rgb(200 30 30)' },
fontFamily: 'Inter, sans-serif',
fontSize: '16px',
borderRadius: '8px',
}}
>| Field | Effect |
| -------------- | --------------------------------------------------------------------------------------------- |
| appearance | light or dark. Defaults to the dark class on <html>. |
| colors | text, mutedText, inputBackground, inputFocusBackground, surface, border, error. |
| fontFamily | The iframe loads no web font, so name a family the iframe already has. |
| fontSize | In px. Line height of the form scales with the font size. |
| borderRadius | Applies to the fields, the rows and the suggestion overlay. |
Pass literal colours. The fields render in a cross-origin frame that cannot read your CSS custom properties.
License
MIT
