Quickstart
Take payments from your own WordPress plugin through the merchant's PayLexer connection.
If you build a WordPress plugin that PayLexer doesn't integrate with yet (a booking system, a membership plugin, a custom store), you can take payments through the PayLexer plugin instead of talking to PayLexer yourself.
The merchant installs the PayLexer plugin and connects their account once. Your plugin then:
- registers itself as a platform,
- shows the gateways the merchant enabled,
- sends the shopper to PayLexer's hosted checkout, and
- settles its orders when PayLexer's webhooks arrive.
Your plugin never holds PayLexer keys, and never sees gateway credentials. This page uses the paylexer_* functions; the same calls exist as a class, see Platform adapters.
Use the starter template
A working plugin in one command. Edit the parts marked TODO.
Build it by hand
Register, check, create a checkout, open it and settle it from the webhook.
How it works
The webhook reaches your plugin as the paylexer_platform_{id}_payment_completed action, where {id} is your platform ID.
What your plugin can reach. Each call is limited to the orders and subscriptions your platform created. You can't read, refund or cancel a WooCommerce order, or another plugin's order, even though they share the merchant's connection. No function returns the Site Key, tenant ID or webhook secret.
Requirements
- WordPress 6.5 or later, PHP 8.1 or later.
- The PayLexer plugin 2.0.7 or later, connected to the merchant's account, with at least one gateway enabled.
paylexer_api_version()returns1.0or higher.
Fastest start: the starter template
Generate a working plugin, then edit it.
With Composer
cd wp-content/plugins
composer create-project paylexer/wordpress-starter acme-pay
You're asked for your plugin's name, slug, prefix and namespace, and for the platform you integrate: its ID and name (for example acme-bookings and "Acme Bookings").
With WP-CLI
wp package install paylexer/wp-cli-paylexer
wp paylexer scaffold acme-pay --platform=acme-bookings --platform-name="Acme Bookings"
WP-CLI skips the prompts and takes the platform as flags. It runs the same Composer command, so Composer must be installed. See Build an add-on for the flags.
What you get
| File or feature | What it holds |
|---|---|
src/Adapter.php | Your platform adapter: the platform's ID, name and features, and on_event() for verified webhooks. |
| Settings page | The connection, your plugin's settings (test mode, default gateway), the merchant's gateways, and your orders and subscriptions with refund and cancel buttons. |
| Pay shortcode | One-time or subscription, with the browser checkout. |
Everything you'll replace with your own orders is marked TODO.
By hand
Depend on PayLexer
Let your plugin activate without PayLexer (no paylexer in Requires Plugins), and show admins a notice until PayLexer is active:
/**
* Plugin Name: PayLexer for Acme Bookings
*/
add_action( 'plugins_loaded', function () {
if ( ! function_exists( 'paylexer_register_adapter' ) ) {
add_action( 'admin_notices', function () {
echo '<div class="notice notice-error"><p>' . esc_html__( 'PayLexer for Acme Bookings needs the PayLexer plugin (version 2.0.7 or later) installed and activated.', 'paylexer-for-acme-bookings' ) . '</p></div>';
} );
}
} );
The starter template also links the notice to PayLexer's install or activate screen.
Register the platform you integrate
Register the platform your plugin brings to PayLexer (here Acme Bookings, the plugin you're adding payments to), not your plugin itself (PayLexer for Acme Bookings). The platform is what PayLexer records on every order and shows in its dashboard.
Do it inside the paylexer_init action. It fires on plugins_loaded, so it works whatever order WordPress loads plugins in.
add_action( 'paylexer_init', function () {
paylexer_register_platform( 'acme-bookings', array(
'name' => 'Acme Bookings', // your platform's name
'icon' => plugins_url( 'assets/acme.svg', __FILE__ ), // square logo
'by' => 'PayLexer for Acme Bookings', // your plugin
'plugin' => 'acme-bookings/acme-bookings.php', // shows "Activated" or an Activate button
'plugin_url' => 'https://wordpress.org/plugins/acme-bookings/', // Install button; any other URL is a "Get" link
'supports' => array( 'payments', 'refunds', 'subscriptions' ),
) );
} );
Check before showing a pay button
Your platform can take payments while your plugin is active and PayLexer is connected:
if ( paylexer_is_connected() && paylexer_is_platform_enabled( 'acme-bookings' ) ) {
// show checkout
}
Create a checkout
$checkout = paylexer_create_checkout( 'acme-bookings', array(
'reference' => (string) $booking->id, // your order id
'gateway' => 'stripe', // a code from paylexer_get_gateways()
'amount' => 120.00, // major units
'currency' => 'USD',
'customer' => array( 'email' => $email, 'first_name' => $first, 'last_name' => $last ),
'return_url' => $thanks_url,
'cancel_url' => $booking_url,
) );
if ( is_wp_error( $checkout ) ) {
return $checkout;
}
update_post_meta( $booking->id, '_paylexer_order_reference', $checkout['order_reference'] );
Save order_reference on your order. Webhooks identify the order by it.
See Payments and refunds for every field.
Open it in the browser
Load the checkout script in PHP:
$handle = paylexer_enqueue_checkout(); // loads PayLexer.openCheckout()
Then open the checkout in JavaScript:
PayLexer.openCheckout(checkout); // the array paylexer_create_checkout() returned
PayLexer decides whether it opens in the modal or as a full-page redirect, per gateway. You don't choose.
Settle the order from the webhook
add_action( 'paylexer_platform_acme-bookings_payment_completed', function ( array $event ) {
$booking = acme_find_booking_by_paylexer_reference( $event['data']['orderReference'] );
$booking->mark_paid();
} );
PayLexer has already checked the signature, the tenant and replays before your hook runs. If the order is unknown to you, return normally. A retry can still deliver the same event twice and events can arrive out of order, so see Writing safe handlers.
Fulfil and mark the order paid only in this webhook, never from the browser callback or return_url. The shopper can reach the return page without paying.
Check it works
- Pay with a gateway's sandbox card.
- Open PayLexer → Webhook logs to see the delivery.
- Check that your hook marked the order paid.