BoomPay/docs

WooCommerce

A native WC_Payment_Gateway plugin: settings screen, hosted-checkout redirect, and a signed return handler, built on a small PHP client that mirrors the real BoomPay SDK.

PHPNative WC_Payment_GatewaySelf-hosted plugin

WooCommerce has a real extension point for this: WC_Payment_Gateway. The plugin below registers as a proper gateway choice at checkout, redirects to BoomPay's hosted page on process_payment(), and verifies the signed return through a custom woocommerce_api_* route — the same mechanism WooCommerce has used for offsite gateways for years.

Architecture

01

Customer checks out

Shopper selects "Pay with Boomcoin" and places the order.

02

process_payment() runs

The gateway calls BoomPay’s client to create an intent for the order total, then returns a redirect result.

03

WooCommerce redirects

The shopper's browser is sent to the BoomPay-hosted link to approve payment.

04

Signed return

BoomPay sends the shopper back to a woocommerce_api_wc_gateway_boompay route with paymentIntentId and X-Boom-Signature.

05

Order completes

The handler verifies the signature, confirms via getPayment(), and calls payment_complete().

Plugin files

Three files: a thin REST client mirroring the real SDK’s contract, the gateway class itself, and a bootstrap file that registers it.

boompay-for-woocommerce.php
<?php
/**
 * Plugin Name: BoomPay for WooCommerce
 * Description: Accept Boomcoin (BMC) payments through BoomPay's hosted checkout.
 * Version: 1.0.0
 * Requires Plugins: woocommerce
 */

defined('ABSPATH') || exit;

add_action('plugins_loaded', function () {
    if (!class_exists('WC_Payment_Gateway')) {
        return; // WooCommerce isn't active.
    }
    require_once __DIR__ . '/includes/class-boompay-client.php';
    require_once __DIR__ . '/includes/class-wc-boompay-gateway.php';
});

add_filter('woocommerce_payment_gateways', function ($gateways) {
    $gateways[] = 'WC_Gateway_BoomPay';
    return $gateways;
});
includes/class-boompay-client.php
<?php
defined('ABSPATH') || exit;

/**
 * Minimal HTTP client mirroring the official boom-pay-sdk (Node) contract:
 * same two REST endpoints, same x-api-key header, same HMAC-SHA1 signature
 * scheme. There is no official PHP SDK, so this is built from reading the
 * real SDK's source rather than guessing at one. See the API Reference page.
 */
class BoomPay_Client {

    const SANDBOX_BASE = 'https://sapi.boom.market';
    const LIVE_BASE     = 'https://api.boom.market';

    private $api_key;
    private $base_url;

    public function __construct($api_key, $sandbox = false) {
        $this->api_key  = $api_key;
        $this->base_url = $sandbox ? self::SANDBOX_BASE : self::LIVE_BASE;
    }

    public function create_intent($amount, $success_url, $failure_url, $label, $metadata = array()) {
        return $this->request('POST', '/v1/boompay/paymentIntent', array(
            'amount'     => $amount,
            'successUrl' => $success_url,
            'failureUrl' => $failure_url,
            'label'      => $label,
            'metadata'   => $metadata,
        ));
    }

    public function get_payment($id) {
        return $this->request('GET', '/v1/boompay/paymentIntent/' . rawurlencode($id));
    }

    /**
     * signature = base64( HMAC-SHA1( key = apiKey, message = paymentIntentId ) )
     * "+" can arrive as a space after URL-decoding, so restore it before comparing.
     */
    public function verify_signature($payment_intent_id, $signature) {
        $expected = base64_encode(hash_hmac('sha1', $payment_intent_id, $this->api_key, true));
        $received = str_replace(' ', '+', (string) $signature);
        return hash_equals($expected, $received);
    }

    private function request($method, $path, $body = null) {
        $args = array(
            'method'  => $method,
            'timeout' => 30,
            'headers' => array(
                'x-api-key'    => $this->api_key,
                'Content-Type' => 'application/json',
            ),
        );
        if (null !== $body) {
            $args['body'] = wp_json_encode($body);
        }

        $response = wp_remote_request($this->base_url . $path, $args);

        if (is_wp_error($response)) {
            throw new Exception('BoomPay request failed: ' . $response->get_error_message());
        }

        $code = wp_remote_retrieve_response_code($response);
        $data = json_decode(wp_remote_retrieve_body($response), true);

        if ($code < 200 || $code >= 300) {
            $message = isset($data['message']) ? $data['message'] : 'Unknown BoomPay API error';
            throw new Exception("BoomPay API error ({$code}): {$message}");
        }

        return $data;
    }
}
includes/class-wc-boompay-gateway.php
<?php
defined('ABSPATH') || exit;

class WC_Gateway_BoomPay extends WC_Payment_Gateway {

    private $sandbox;
    private $client;

    public function __construct() {
        $this->id                 = 'boompay';
        $this->has_fields         = false;
        $this->method_title       = 'BoomPay (Boomcoin)';
        $this->method_description = "Accept Boomcoin (BMC) payments through BoomPay's hosted checkout.";

        $this->init_form_fields();
        $this->init_settings();

        $this->title       = $this->get_option('title');
        $this->description = $this->get_option('description');
        $this->enabled      = $this->get_option('enabled');
        $this->sandbox      = 'yes' === $this->get_option('sandbox');

        $api_key = $this->sandbox
            ? $this->get_option('sandbox_api_key')
            : $this->get_option('api_key');

        $this->client = new BoomPay_Client($api_key, $this->sandbox);

        add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
        add_action('woocommerce_api_wc_gateway_boompay', array($this, 'handle_return'));
    }

    public function init_form_fields() {
        $this->form_fields = array(
            'enabled' => array(
                'title'   => 'Enable/Disable',
                'type'    => 'checkbox',
                'label'   => 'Enable BoomPay',
                'default' => 'no',
            ),
            'title' => array(
                'title'   => 'Title',
                'type'    => 'text',
                'default' => 'Pay with Boomcoin',
            ),
            'description' => array(
                'title'   => 'Description',
                'type'    => 'textarea',
                'default' => 'You will be redirected to BoomPay to pay from your Boom wallet.',
            ),
            'sandbox' => array(
                'title'   => 'Sandbox mode',
                'type'    => 'checkbox',
                'label'   => 'Enable sandbox / test mode',
                'default' => 'yes',
            ),
            'api_key' => array(
                'title' => 'Live API key',
                'type'  => 'password',
            ),
            'sandbox_api_key' => array(
                'title' => 'Sandbox API key',
                'type'  => 'password',
            ),
        );
    }

    public function process_payment($order_id) {
        $order      = wc_get_order($order_id);
        $return_url = WC()->api_request_url('WC_Gateway_BoomPay');

        try {
            $intent = $this->client->create_intent(
                $this->to_bmc($order->get_total(), $order->get_currency()),
                add_query_arg(array('boompay_status' => 'success', 'order_id' => $order_id), $return_url),
                add_query_arg(array('boompay_status' => 'failure', 'order_id' => $order_id), $return_url),
                sprintf('Order #%s', $order->get_order_number()),
                array('order_id' => $order_id, 'order_key' => $order->get_order_key())
            );
        } catch (Exception $e) {
            wc_add_notice('BoomPay error: ' . $e->getMessage(), 'error');
            return array('result' => 'failure');
        }

        $order->update_meta_data('_boompay_intent_id', $intent['id']);
        $order->update_status('on-hold', 'Awaiting BoomPay payment.');
        $order->save();

        return array(
            'result'   => 'success',
            'redirect' => $intent['link'],
        );
    }

    public function handle_return() {
        $order_id  = isset($_GET['order_id']) ? absint($_GET['order_id']) : 0;
        $intent_id = isset($_GET['paymentIntentId']) ? sanitize_text_field($_GET['paymentIntentId']) : '';
        $signature = isset($_GET['X-Boom-Signature']) ? sanitize_text_field(wp_unslash($_GET['X-Boom-Signature'])) : '';
        $order     = wc_get_order($order_id);

        if (!$order || !$this->client->verify_signature($intent_id, $signature)) {
            wp_die('BoomPay signature verification failed.', 'BoomPay', array('response' => 403));
        }

        $payment = $this->client->get_payment($intent_id);
        $status  = isset($_GET['boompay_status']) ? $_GET['boompay_status'] : '';

        if (!empty($payment['paidAt']) && 'success' === $status) {
            $order->payment_complete($intent_id);
            $order->add_order_note('Paid via BoomPay. Intent: ' . $intent_id);
            wp_safe_redirect($this->get_return_url($order));
        } else {
            $order->update_status('failed', 'BoomPay payment failed or was cancelled.');
            wp_safe_redirect(wc_get_checkout_url());
        }
        exit;
    }

    /**
     * BoomPay settles in BMC and has no FX endpoint (see API Reference > Currency).
     * Replace this with your own fiat -> BMC rate source before going live.
     */
    private function to_bmc($total, $currency) {
        return (float) $total;
    }
}

Install

Zip the three files above preserving the includes/ folder, then upload via Plugins → Add New → Upload Plugin, or drop the folder into wp-content/plugins/boompay-for-woocommerce/ over SFTP. Activate it, then go to WooCommerce → Settings → Payments → BoomPay (Boomcoin) to configure it.

i

Leave Sandbox mode checked and fill in a sandbox API key first. Switch it off and add your live key only once you’ve completed a full test order end to end.

Testing in sandbox

With sandbox mode on, place a test order and choose BoomPay at checkout. You’ll be redirected to BoomPay’s sandbox-hosted page (served from sapi.boom.market); approve it from a Boom wallet configured for testing, and confirm the order lands in WooCommerce → Orders as Processing with an order note recording the intent id. Cancel a second test payment to confirm the order correctly moves to Failed instead.

Go-live checklist

  • Replace the sandbox API key with a live one and uncheck sandbox mode.
  • Implement to_bmc() with a real fiat→BMC conversion rate — the placeholder in this plugin passes your store currency total through unchanged, which is only correct if your store already prices in BMC.
  • Confirm your site serves the return URL over HTTPS; BoomPay’s own hosted page is HTTPS-only, and mixed content will break the redirect back.
  • Run one real, small-value live payment before announcing the option to customers.