payrails client instance. If you haven’t, start with the quick start.
The form renders inside a Payrails-hosted iframe, so the shopper’s details are never part of your page’s DOM. The fields come from the payment method’s configuration, so you don’t declare them yourself.
Supported payment methods
Pass the code as
paymentMethodCode. The result type determines which events fire after the shopper clicks the pay button, as described in Handle the payment result.
mbWay and sepaDirectDebit are the redirect versions of MB WAY and SEPA Direct Debit. They have no form, so payrails.apmForm() throws for them.
Before you start
- Use
@payrails/web-sdk6.10.0 or later. - Ask your Payrails account manager to enable the payment method for in-page collection. Until they do,
payrails.apmForm()throws aPayrailsErrorbecause the session has no form for that method. - For SEPA Direct Debit, send the shopper’s IP address, user agent and email when you create the execution, in
meta.clientContext.ipAddress,meta.clientContext.userAgentandmeta.customer.email. Payrails rejects the payment without them.
1. Add containers to your page
2. Mount the form
form.mount() is synchronous. The form emits ready once its fields are drawn, so listen for ready instead of waiting on mount(). mount() throws when the selector doesn’t match an element, or when the SDK can’t draw the form. In the second case, the error’s context.reason is 'unrenderable-schema'. Use it to offer the shopper another way to pay.
3. Mount the pay button
validate with isValid: false, and the SDK doesn’t submit the payment:
buttonClicked and requestStart instance events run after the form validates, the same as for card payments. A check you already run there also covers these methods.
Save the instrument for future payments
By default, the button uses the instrument for this payment only. To save it for later payments, for example to charge a SEPA Direct Debit mandate on a subscription, setalwaysStoreInstrument:
alwaysStoreInstrument only when you already have the shopper’s consent to save the instrument. The SDK ignores it on a merchant of record workspace.
4. Handle the payment result
Outcomes are instance events, so subscribe on thepayrails client:
e.paymentMethodCode.
Which events fire depends on the method’s result type in the supported payment methods table:
Approve-in-app methods
The shopper approves the payment in another app, such as their MB WAY app. The SDK handles the wait for you: the form switches to a screen with the payment method’s logo and instructions, the SDK removes the button, and then waits for the shopper to approve. When they do, the wait screen goes away andsuccess fires. Show your own confirmation.
Confirm-with-code methods
The payment provider sends the shopper a one-time code by SMS, such as for STC Pay. The SDK handles the code step for you: the form switches to a screen that asks for the code, with a Confirm button, and the SDK removes your pay button. The shopper can click Confirm once they have typed a valid code. When they click it, the SDK sends the code and checks the payment’s status.- Code accepted: the code screen goes away and
successfires. Show your own confirmation. - Code declined: the code screen shows “The payment couldn’t be completed. Please try again.” for 3 seconds. Then the form comes back with the shopper’s phone number, and your pay button comes back. The SDK fires
sessionExpired, thenfailedwithAUTHORIZATION_ERROR. Thefailedevent’smessageis the provider’s reason, orAuthorization errorwhen the provider gives none. Return fresh init options fromsessionExpiredso the shopper’s retry starts a new payment, with the same handler as in step 5. - No code or no result in time: the shopper doesn’t confirm a code, or the payment has no result before the code expires. The same happens as for a declined code, without the message, and
failedcarriesAUTHORIZATION_ERROR. - No confirmed result: when the SDK can’t confirm the result, for example because the session expired, the form comes back the same way.
failedcarriesAUTHENTICATION_ERRORorUNKNOWN_ERROR. Check the payment’s status before you let the shopper retry.
apmForm, as described in Customize the form and button.
Pending methods
The payment completes after checkout, so the SDK doesn’t have the result yet when the shopper clicks. Treatpending as “order placed” and rely on your webhook for the final status.
5. Handle a declined or expired approve-in-app payment
If the shopper declines in the app, or doesn’t approve in time, the wait screen switches back to the form. The form keeps the shopper’s details, and the button reappears. The SDK then firessessionExpired, followed by failed with AUTHORIZATION_ERROR. Return fresh init options from sessionExpired so the shopper’s retry starts a new payment:
failed carries AUTHENTICATION_ERROR or UNKNOWN_ERROR. The shopper may still approve in their app afterwards, so check the payment’s status before you let them retry, or they could pay twice:
6. Customize the form and button
The form and the button each take their ownappearance. Form rules cross into the iframe and apply to the .payrails-* classes. Rules under actionScreen style only the screens shown after the shopper submits the payment: the wait screen of an approve-in-app method and the code screen of a confirm-with-code method:
translations.errors replaces the form’s default error messages. The appearance reference lists every class.
Change the texts on each screen
translations.fields changes the texts of one field, by the field’s name. The same translations cover every screen the form shows, including the wait screen and the code screen. A field you don’t translate keeps the text from the payment method’s configuration.
Each field takes
label, placeholder and errors. The code screen’s Confirm button takes label. Your pay button’s text stays on apmButton, in translations.label.
The message after a declined code belongs to apmButton, not to the form. Pass translations.paymentFailed to replace the default “The payment couldn’t be completed. Please try again.”:
failed event’s message.
Style the code screen
actionScreen rules style the code screen as well as the wait screen. The SDK draws the Confirm button inside the form, so apmButton’s appearance doesn’t reach it. Style it with the form’s appearance, and repeat your pay button’s rules there if both buttons need the same look:
Offer more than one method
Create a form and button pair per method, each in its own containers. Element ids default to one per payment method, so two methods on the same page don’t collide. Passid only if you mount two forms for the same method.
payrails reference and the events reference.