WalletPlug Merchant API

Integrate WalletPlug payment gateway into your application with our comprehensive RESTful API. Accept payments from wallets, cards, and multiple payment methods with enterprise-grade security.

Production Ready This API documentation covers production-ready endpoints with complete integration examples for multiple platforms.
Fast Integration

Get started in minutes with our simple REST API

Secure Payments

Bank-grade security with HMAC signature verification

Multi-Platform

Works with any programming language or framework

Authentication

WalletPlug API uses API keys to authenticate requests. You can obtain your credentials from your merchant dashboard.

Environment-Aware API Integration

WalletPlug API supports both sandbox (testing) and production environments. Always test in sandbox first before going live.

Environment Configuration
Sandbox Mode

Use for: Development, testing, integration

X-Environment: sandbox

Credentials: Use test_* prefixed API keys

Production Mode

Use for: Live payments, real money

X-Environment: production

Credentials: Use production API keys (no prefix)

Required Credentials

Credential Header Description Location
Merchant ID X-Merchant-Key Your unique merchant identifier Dashboard → Merchant → CONFIG
API Key X-API-Key API authentication key Dashboard → Merchant → CONFIG
Client Secret - Used for webhook signature verification Dashboard → Merchant → CONFIG
Production API Key X-API-Key Production API key (no prefix) Merchant Dashboard > API Config > Production Mode
Production Merchant Key X-Merchant-Key Production merchant identifier (no prefix) Merchant Dashboard > API Config > Production Mode
Security Notice Never expose your Client Secret in client-side code. Store all credentials securely on your server.

Quick Start

Get up and running with WalletPlug API in just a few steps:

Step 1: Get Credentials
  1. Login to your WalletPlug dashboard
  2. Navigate to Merchant → CONFIG
  3. Copy your Merchant ID, API Key, and Client Secret
Step 2: Make Request
  1. Set required headers with your credentials
  2. POST to /api/v1/initiate-payment
  3. Redirect user to returned payment URL
Test API Now

Try WalletPlug API endpoints directly in your browser

Initiate Payment

Create a new payment request and get a secure checkout URL for your customer. This endpoint works in both sandbox and production environments based on your X-Environment header.

POST /api/v1/initiate-payment

Request Headers

Header Value Required Description
Content-Type application/json Request content type
X-Environment sandbox | production API environment mode
X-Merchant-Key {merchant_key} Your Merchant ID (sandbox: test_ prefix, production: no prefix)
X-API-Key {api_key} Your API Key (sandbox: test_ prefix, production: no prefix)

Request Parameters

Parameter Type Required Description
payment_amount number Payment amount (minimum 1.00)
currency_code string 3-letter currency code (USD, EUR, etc.)
ref_trx string Your unique transaction reference
description string Payment description
success_redirect string Success redirect URL
failure_url string Failure redirect URL
cancel_redirect string Cancel redirect URL
ipn_url string Webhook notification URL (same URL for both environments)
allow_payment_methods string | array Optional. Show only these method names on checkout. Send "card,bank_transfer" or ["card","bank_transfer"]. Case-insensitive. Omit to show all.

Code Examples

Environment Configuration: Replace {environment} with sandbox or production, and use corresponding credentials - test_ prefix for sandbox, no prefix for production.
curl -X POST "https://walletplug.com/api/v1/initiate-payment" \
  -H "Content-Type: application/json" \
  -H "X-Environment: {environment}" \
  -H "X-Merchant-Key: {merchant_key}" \
  -H "X-API-Key: {api_key}" \
  -d '{"payment_amount": 250.00, "currency_code": "USD", "ref_trx": "ORDER_12345", "description": "Premium Subscription", "success_redirect": "https://yoursite.com/payment/success", "failure_url": "https://yoursite.com/payment/failed", "cancel_redirect": "https://yoursite.com/payment/cancelled", "ipn_url": "https://yoursite.com/api/webhooks/WalletPlug", "allow_payment_methods": "card,bank_transfer"}'
<?php

use App\Enums\EnvironmentMode;
use Illuminate\Support\Facades\Http;

class WalletPlugPaymentInitiator
{
    private $environment;
    private $merchantKey;
    private $apiKey;
    private $baseUrl = 'https://walletplug.com/api/v1';

    public function __construct(EnvironmentMode $environment, $merchantKey, $apiKey)
    {
        $this->environment = $environment;
        $this->merchantKey = $merchantKey;
        $this->apiKey = $apiKey;
    }

    // Factory methods for easy configuration
    public static function sandbox($testMerchantKey, $testApiKey): self
    {
        return new self(EnvironmentMode::SANDBOX, $testMerchantKey, $testApiKey);
    }

    public static function production($merchantKey, $apiKey): self
    {
        return new self(EnvironmentMode::PRODUCTION, $merchantKey, $apiKey);
    }

    public function initiatePayment($paymentData)
    {
        try {
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'X-Environment' => $this->environment->value,
                'X-Merchant-Key' => $this->merchantKey,
                'X-API-Key' => $this->apiKey,
            ])->post("{$this->baseUrl}/initiate-payment", $paymentData);

            if ($response->successful()) {
                $data = $response->json();
                
                if ($data['success']) {
                    return ['success' => true, 'data' => $data];
                }
                
                return ['success' => false, 'status' => $data['status'], 'message' => $data['message'] ?? 'Payment initiation failed'];
            }

            return ['success' => false, 'error' => 'API request failed'];
        } catch (Exception $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }
}

// Usage: Choose appropriate factory method based on your environment
$initiator = WalletPlugPaymentInitiator::sandbox('test_merchant_key', 'test_api_key'); // For testing
// $initiator = WalletPlugPaymentInitiator::production('merchant_key', 'api_key'); // For production

$paymentData = [
    'payment_amount' => 250.00,
    'currency_code' => 'USD',
    'ref_trx' => 'ORDER_12345',
    'description' => 'Premium Subscription',
    'success_redirect' => 'https://yoursite.com/payment/success',
    'failure_url' => 'https://yoursite.com/payment/failed',
    'cancel_redirect' => 'https://yoursite.com/payment/cancelled',
    'ipn_url' => 'https://yoursite.com/api/webhooks/WalletPlug',
    // Optional: Limit methods shown on checkout by name (string or array)
    'allow_payment_methods' => ['card', 'bank_transfer'],
];

$result = $initiator->initiatePayment($paymentData);
const axios = require('axios');

const EnvironmentMode = {
    SANDBOX: 'sandbox',
    PRODUCTION: 'production'
};

class WalletPlugPaymentInitiator {
    constructor(environment, merchantKey, apiKey) {
        this.environment = environment;
        this.merchantKey = merchantKey;
        this.apiKey = apiKey;
        this.baseUrl = 'https://walletplug.com/api/v1';
    }

    // Factory methods
    static sandbox(testMerchantKey, testApiKey) {
        return new WalletPlugPaymentInitiator(EnvironmentMode.SANDBOX, testMerchantKey, testApiKey);
    }

    static production(merchantKey, apiKey) {
        return new WalletPlugPaymentInitiator(EnvironmentMode.PRODUCTION, merchantKey, apiKey);
    }

    async initiatePayment(paymentData) {
        try {
            const response = await axios.post(`${this.baseUrl}/initiate-payment`, paymentData, {
                headers: {
                    'Content-Type': 'application/json',
                    'X-Environment': this.environment,
                    'X-Merchant-Key': this.merchantKey,
                    'X-API-Key': this.apiKey
                }
            });

            const data = response.data;

            if (data.success) {
                return { success: true, data };
            }

            return { 
                success: false, 
                status: data.status, 
                message: data.message || 'Payment initiation failed' 
            };

        } catch (error) {
            if (error.response) {
                return { 
                    success: false, 
                    error: error.response.data.error || 'API request failed' 
                };
            }
            return { success: false, error: error.message };
        }
    }
}

// Usage: Choose appropriate factory method based on your environment
const initiator = WalletPlugPaymentInitiator.sandbox('test_merchant_key', 'test_api_key'); // For testing
// const initiator = WalletPlugPaymentInitiator.production('merchant_key', 'api_key'); // For production

const paymentData = {
    payment_amount: 250.00,
    currency_code: 'USD',
    ref_trx: 'ORDER_12345',
    description: 'Premium Subscription',
    success_redirect: 'https://yoursite.com/payment/success',
    failure_url: 'https://yoursite.com/payment/failed',
    cancel_redirect: 'https://yoursite.com/payment/cancelled',
    ipn_url: 'https://yoursite.com/api/webhooks/WalletPlug',
    // Optional: CSV/pipe/space string or array
    allow_payment_methods: ['card', 'bank_transfer'],
};

initiator.initiatePayment(paymentData)
    .then(result => console.log(result))
    .catch(error => console.error(error));
import requests
import logging
from enum import Enum

class EnvironmentMode(Enum):
    SANDBOX = 'sandbox'
    PRODUCTION = 'production'

class WalletPlugPaymentInitiator:
    def __init__(self, environment, merchant_key, api_key):
        self.environment = environment
        self.merchant_key = merchant_key
        self.api_key = api_key
        self.base_url = 'https://walletplug.com/api/v1'

    @classmethod
    def sandbox(cls, test_merchant_key, test_api_key):
        return cls(EnvironmentMode.SANDBOX, test_merchant_key, test_api_key)

    @classmethod
    def production(cls, merchant_key, api_key):
        return cls(EnvironmentMode.PRODUCTION, merchant_key, api_key)

    def initiate_payment(self, payment_data):
        try:
            headers = {
                'Content-Type': 'application/json',
                'X-Environment': self.environment.value,
                'X-Merchant-Key': self.merchant_key,
                'X-API-Key': self.api_key
            }

            response = requests.post(
                f"{self.base_url}/initiate-payment",
                headers=headers,
                json=payment_data,
                timeout=30
            )

            if response.status_code == 200:
                data = response.json()
                
                if data['success']:
                    return {'success': True, 'data': data}
                
                return {
                    'success': False, 
                    'status': data['status'], 
                    'message': data.get('message', 'Payment initiation failed')
                }

            return {'success': False, 'error': f'HTTP {response.status_code}'}

        except requests.RequestException as e:
            return {'success': False, 'error': str(e)}

# Usage: Choose appropriate factory method based on your environment
initiator = WalletPlugPaymentInitiator.sandbox('test_merchant_key', 'test_api_key')  # For testing
# initiator = WalletPlugPaymentInitiator.production('merchant_key', 'api_key')  # For production

payment_data = {
    'payment_amount': 250.00,
    'currency_code': 'USD',
    'ref_trx': 'ORDER_12345',
    'description': 'Premium Subscription',
    'success_redirect': 'https://yoursite.com/payment/success',
    'failure_url': 'https://yoursite.com/payment/failed',
    'cancel_redirect': 'https://yoursite.com/payment/cancelled',
    'ipn_url': 'https://yoursite.com/api/webhooks/WalletPlug',
    # Optional: string or list
    'allow_payment_methods': ['card', 'bank_transfer'],
}

result = initiator.initiate_payment(payment_data)
print(result)

Success Response

200 OK Success
{
    "payment_url": "https://WalletPlug.test/payment/checkout?expires=1753724376&token=AmQvJdGIdGUVJUUMayJZZreBv2UcTyIHclk9Ps1s1pZhLpVlIqIBVPqGTRKQ3NUSehyM3qRUIf69IhLbNfJ1JqiMxlxNrnn22lNz1N01hZQn65r5VZnvhWmQPxQO8UX6rE4yfRUvT6bHdqLj7UDJhRPYRFSgCsG1b86sxSdKTZNOVJdWV5z8L6a5pNMZ2KlpG5e7bYa&signature=e9q7ea91456dcc167e7d498ea486f923570821957be8881566186655950f364",
    "info": {
        "ref_trx": "TXNT4AQFESTAG4F",
        "description": "Order #1234",
        "ipn_url": "https://webhook.site/5711b7d5-917a-4d94-bbb3-c28f4a37bea5",
        "cancel_redirect": "https://merchant.com/cancel",
        "success_redirect": "https://merchant.com/success",
        "merchant_id": 1,
        "merchant_name": "WalletPlug", 
        "amount": 200,
        "currency_code": "USD",
        "environment": "production",
        "is_sandbox": false
    }
}

Error Response

400 Bad Request Error
{
  "success": false,
  "message": "Validation failed",
  "errors": {
    "payment_amount": ["The payment amount field is required."],
    "currency_code": ["The currency code field is required."]
  }
}
Next Step After successful payment initiation, redirect your customer to the payment_url to complete the payment.

Verify Payment

Verify the status of a payment using the WalletPlug transaction ID returned from the payment initiation.

GET /api/v1/verify-payment/{trxId}

Request Headers

Header Value Required Description
Accept application/json Request content type
X-Environment sandbox | production API environment mode
X-Merchant-Key {merchant_key} Your Merchant ID (sandbox: test_ prefix, production: no prefix)
X-API-Key {api_key} Your API Key (sandbox: test_ prefix, production: no prefix)

Path Parameters

Parameter Type Required Description
trxId string WalletPlug transaction ID (e.g., TXNQ5V8K2L9N3XM1)

Code Examples

Environment Configuration: Replace {environment} with sandbox or production, and use corresponding credentials - test_ prefix for sandbox, no prefix for production.
curl -X GET "https://walletplug.com/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
  -H "Accept: application/json" \
  -H "X-Environment: {environment}" \
  -H "X-Merchant-Key: {merchant_key}" \
  -H "X-API-Key: {api_key}"
<?php

use App\Enums\EnvironmentMode;
use Illuminate\Support\Facades\Http;

class WalletPlugPaymentVerifier
{
    private $environment;
    private $merchantKey;
    private $apiKey;
    private $baseUrl = 'https://walletplug.com/api/v1';

    public function __construct(EnvironmentMode $environment, $merchantKey, $apiKey)
    {
        $this->environment = $environment;
        $this->merchantKey = $merchantKey;
        $this->apiKey = $apiKey;
    }

    // Factory methods for easy configuration
    public static function sandbox($testMerchantKey, $testApiKey): self
    {
        return new self(EnvironmentMode::SANDBOX, $testMerchantKey, $testApiKey);
    }

    public static function production($merchantKey, $apiKey): self
    {
        return new self(EnvironmentMode::PRODUCTION, $merchantKey, $apiKey);
    }

    public function verifyPayment($trxId)
    {
        try {
            $response = Http::withHeaders([
                'Accept' => 'application/json',
                'X-Environment' => $this->environment->value,
                'X-Merchant-Key' => $this->merchantKey,
                'X-API-Key' => $this->apiKey,
            ])->get("{$this->baseUrl}/verify-payment/{$trxId}");

            if ($response->successful()) {
                $data = $response->json();
                
                if ($data['status'] === 'completed') {
                    // Payment completed successfully
                    $this->fulfillOrder($data);
                    return ['success' => true, 'data' => $data];
                }
                
                return ['success' => false, 'status' => $data['status'], 'message' => $data['message'] ?? 'Payment not completed'];
            }

            return ['success' => false, 'error' => 'API request failed'];
        } catch (Exception $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    private function fulfillOrder($paymentData)
    {
        // Your order fulfillment logic here
        logger('Payment verified successfully', $paymentData);
    }
}

// Usage: Choose appropriate factory method based on your environment
$verifier = WalletPlugPaymentVerifier::sandbox('test_merchant_key', 'test_api_key'); // For testing
// $verifier = WalletPlugPaymentVerifier::production('merchant_key', 'api_key'); // For production

$result = $verifier->verifyPayment('TXNQ5V8K2L9N3XM1');
const axios = require('axios');

const EnvironmentMode = {
    SANDBOX: 'sandbox',
    PRODUCTION: 'production'
};

class WalletPlugPaymentVerifier {
    constructor(environment, merchantKey, apiKey) {
        this.environment = environment;
        this.merchantKey = merchantKey;
        this.apiKey = apiKey;
        this.baseUrl = 'https://walletplug.com/api/v1';
    }

    // Factory methods
    static sandbox(testMerchantKey, testApiKey) {
        return new WalletPlugPaymentVerifier(EnvironmentMode.SANDBOX, testMerchantKey, testApiKey);
    }

    static production(merchantKey, apiKey) {
        return new WalletPlugPaymentVerifier(EnvironmentMode.PRODUCTION, merchantKey, apiKey);
    }

    async verifyPayment(trxId) {
        try {
            const response = await axios.get(`${this.baseUrl}/verify-payment/${trxId}`, {
                headers: {
                    'Accept': 'application/json',
                    'X-Environment': this.environment,
                    'X-Merchant-Key': this.merchantKey,
                    'X-API-Key': this.apiKey
                }
            });

            const data = response.data;

            if (data.status === 'completed') {
                // Payment completed successfully
                await this.fulfillOrder(data);
                return { success: true, data };
            }

            return { 
                success: false, 
                status: data.status, 
                message: data.message || 'Payment not completed' 
            };

        } catch (error) {
            if (error.response) {
                return { 
                    success: false, 
                    error: error.response.data.error || 'API request failed' 
                };
            }
            return { success: false, error: error.message };
        }
    }

    async fulfillOrder(paymentData) {
        // Your order fulfillment logic here
        console.log('Payment verified successfully:', paymentData);
    }
}

// Usage: Choose appropriate factory method based on your environment
const verifier = WalletPlugPaymentVerifier.sandbox('test_merchant_key', 'test_api_key'); // For testing
// const verifier = WalletPlugPaymentVerifier.production('merchant_key', 'api_key'); // For production

verifier.verifyPayment('TXNQ5V8K2L9N3XM1')
    .then(result => console.log(result))
    .catch(error => console.error(error));
import requests
import logging
from enum import Enum

class EnvironmentMode(Enum):
    SANDBOX = 'sandbox'
    PRODUCTION = 'production'

class WalletPlugPaymentVerifier:
    def __init__(self, environment, merchant_key, api_key):
        self.environment = environment
        self.merchant_key = merchant_key
        self.api_key = api_key
        self.base_url = 'https://walletplug.com/api/v1'

    @classmethod
    def sandbox(cls, test_merchant_key, test_api_key):
        return cls(EnvironmentMode.SANDBOX, test_merchant_key, test_api_key)

    @classmethod
    def production(cls, merchant_key, api_key):
        return cls(EnvironmentMode.PRODUCTION, merchant_key, api_key)

    def verify_payment(self, trx_id):
        try:
            headers = {
                'Accept': 'application/json',
                'X-Environment': self.environment.value,
                'X-Merchant-Key': self.merchant_key,
                'X-API-Key': self.api_key
            }

            response = requests.get(
                f"{self.base_url}/verify-payment/{trx_id}",
                headers=headers,
                timeout=30
            )

            if response.status_code == 200:
                data = response.json()
                
                if data['status'] == 'completed':
                    # Payment completed successfully
                    self.fulfill_order(data)
                    return {'success': True, 'data': data}
                
                return {
                    'success': False, 
                    'status': data['status'], 
                    'message': data.get('message', 'Payment not completed')
                }

            return {'success': False, 'error': f'HTTP {response.status_code}'}

        except requests.RequestException as e:
            return {'success': False, 'error': str(e)}

    def fulfill_order(self, payment_data):
        """Your order fulfillment logic here"""
        logging.info(f"Payment verified successfully: {payment_data}")

# Usage: Choose appropriate factory method based on your environment
verifier = WalletPlugPaymentVerifier.sandbox('test_merchant_key', 'test_api_key')  # For testing
# verifier = WalletPlugPaymentVerifier.production('merchant_key', 'api_key')  # For production

result = verifier.verify_payment('TXNQ5V8K2L9N3XM1')
print(result)

Success Response

200 OK Success
{
    "status": "completed",
    "trx_id": "TXNQ5V8K2L9N3XM1",
    "amount": 237.5,
    "fee": 12.5,
    "currency": "USD",
    "net_amount": 237.5,
    "customer": {
        "name": "John Doe",
        "email": "john@example.com"
    },
    "description": "Premium Subscription Payment",
    "created_at": "2024-01-15T10:30:00.000000Z",
    "updated_at": "2024-01-15T10:35:45.000000Z"
}

Failed/Canceled Transaction Response

{
    "status": "failed",
    "trx_id": "TXNQ5V8K2L9N3XM1",
    "message": "Payment failed or canceled."
}

Pending Transaction Response

{
    "status": "pending",
    "trx_id": "TXNQ5V8K2L9N3XM1",
    "message": "Payment is still pending."
}

Payment Status Values

Status Description Action Required
pending Payment is still processing Wait for webhook notification
completed Payment was successful Fulfill order/service
failed Payment failed Handle failed payment
cancelled Payment was cancelled by user Handle cancellation
expired Payment session expired Create new payment
Rate Limiting This endpoint is rate-limited to 60 requests per minute per merchant.

Embedded Checkout (No Redirect)

Keep the entire payment on YOUR page. Instead of redirecting customers to the hosted checkout, drop our embeddable checkout into your own UI — the card form renders inline, fully white-labeled (no WalletPlug branding), while the sensitive card fields stay hosted and tokenized on our side. Your platform never touches raw card data, keeping you out of PCI scope (SAQ-A).

Single-page checkout: This is the same engine behind our WooCommerce "Card Only" plugin — a direct card form with no payment-method screen, no redirect and no third-party branding.

How it works

  1. Call initiate-payment as usual, restricting the session to card with allow_payment_methods.
  2. The response includes card_url — a signed, short-lived URL that renders ONLY the card form (no method selection, no branding).
  3. Embed card_url in an iframe inside your checkout page.
  4. On completion the frame navigates the top window to your success_redirect / failure_url / cancel_redirect.
  5. Treat the signed IPN webhook as the source of truth, and/or confirm with verify-payment.

1. Create a card-only session

curl -X POST "https://walletplug.com/api/v1/initiate-payment" \
  -H "Content-Type: application/json" \
  -H "X-Environment: production" \
  -H "X-Merchant-Key: {merchant_key}" \
  -H "X-API-Key: {api_key}" \
  -d '{
    "payment_amount": 49.99,
    "currency_code": "USD",
    "ref_trx": "order_10021",
    "description": "Order #10021",
    "allow_payment_methods": ["card"],
    "success_redirect": "https://yourapp.com/pay/success",
    "failure_url": "https://yourapp.com/pay/failed",
    "cancel_redirect": "https://yourapp.com/checkout",
    "ipn_url": "https://yourapp.com/webhooks/walletplug"
  }'

2. Response

{
  "status": "success",
  "payment_url": "https://walletplug.com/payment/checkout?token=...",
  "card_url": "https://walletplug.com/payment/card?token=...&signature=...",
  "request_id": "req_8f2c1b"
}
FieldUse it when
payment_urlYou want the full hosted checkout (all payment methods, redirect flow). Also embeddable in an iframe if you want every method inline.
card_urlYou want a single-page, white-labeled CARD form inline on your own checkout. No method screen, no branding. Signed and expires after 15 hours.

3. Embed it on your page

<iframe
  src="{card_url from the API response}"
  style="width:100%; min-height:620px; border:0; border-radius:12px;"
  allow="payment"
  title="Secure card payment">
</iframe>

The card inputs inside the frame are hosted fields served by the card processor — card numbers are tokenized before they ever reach a server you or we control. When the customer completes (or cancels) payment, the page inside the frame navigates the TOP window to the corresponding URL you supplied at initiation, so your single-page flow resumes on your domain automatically. No JavaScript is required on your page for this to work.

4. Confirm the payment (server side)

Never fulfil on the redirect alone. Confirm using the signed IPN webhook (recommended) or the verify-payment endpoint:

// Node.js — verifying the IPN signature
const crypto = require('crypto');

app.post('/webhooks/walletplug', express.raw({ type: '*/*' }), (req, res) => {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.WALLETPLUG_CLIENT_SECRET)
    .update(req.body)                 // RAW body, exactly as received
    .digest('hex');

  if (req.get('X-Signature') !== expected) return res.status(401).end();

  const event = JSON.parse(req.body);
  if (event.status === 'completed') {
    // mark order event.data.ref_trx as paid — check amount & currency too
  }
  res.status(200).end();
});
White-label guarantee: The card_url page contains no WalletPlug logo, name or link — your customers see only your site and a card form.
Customizing the embedded card form

The card form is fully customizable per session. Pass any of these optional fields in your /api/v1/initiate-payment request body — they are embedded inside the signed card_url, so they cannot be altered after generation:

FieldTypeEffect
embed_stylestring"minimal" = one switch: hides the amount banner, the header and the footer, and the button becomes Pay Now. The cleanest form for custom checkouts.
embed_hide_amountbooleanHides the purple "Amount to Pay" banner only.
embed_hide_headerbooleanHides the title/logo header only.
embed_hide_footerbooleanHides the footer (SSL badge, card brand icons, secured-by line).
embed_pay_labelstring (max 40)Custom pay-button text, e.g. "Pay Now" or "Complete Order". Without it the button shows the amount.

Example — minimal form:

{
  "payment_amount": 33.80,
  "currency_code": "EUR",
  "ref_trx": "ORDER-1042",
  "allow_payment_methods": ["card"],
  "embed_style": "minimal",
  "success_redirect": "https://yourstore.com/thanks",
  "ipn_url": "https://yourstore.com/ipn"
}

Example — keep the amount, custom label only:

{
  "payment_amount": 33.80,
  "currency_code": "EUR",
  "ref_trx": "ORDER-1042",
  "allow_payment_methods": ["card"],
  "embed_hide_footer": true,
  "embed_pay_label": "Pay Now"
}

Amounts remain enforced server-side — hiding the banner or changing the label never changes what is charged. Works with the WooCommerce, Shopify and French Card Only plugins unchanged.

Refunds

WalletPlug supports full and partial refunds on completed transactions. Refunds are processed back to the original payment method used by the customer.

Refund Timeline Refunds are typically processed within 1–5 business days depending on the customer's bank or payment provider. WalletPlug wallet refunds are instant.
POST /api/v1/refund

Initiate a full or partial refund on a completed transaction. Requires the original WalletPlug transaction ID.

Request Headers

Header Value Required Description
Content-Type application/json Request content type
X-Environment sandbox | production API environment mode
X-Merchant-Key {merchant_key} Your Merchant ID
X-API-Key {api_key} Your API Key

Request Parameters

Parameter Type Required Description
trx_id string WalletPlug transaction ID from the original payment (e.g. TXNQ5V8K2L9N3XM1)
amount number Refund amount. Omit to refund the full transaction amount. Must be ≤ original amount.
reason string Reason for the refund — stored on the transaction and visible in your merchant dashboard.
ref_refund string Your unique refund reference for idempotency. Submitting the same ref_refund twice returns the first refund without creating a duplicate.

Code Example

curl -X POST "https://walletplug.com/api/v1/refund" \
  -H "Content-Type: application/json" \
  -H "X-Environment: production" \
  -H "X-Merchant-Key: your_merchant_key" \
  -H "X-API-Key: your_api_key" \
  -d '{
    "trx_id": "TXNQ5V8K2L9N3XM1",
    "amount": 50.00,
    "reason": "Customer requested refund — order cancelled",
    "ref_refund": "REFUND_ORDER_12345"
  }'

Success Response 200 OK

{
    "success": true,
    "refund_id": "RFD_9X2K7P1N4M3L8Q5",
    "trx_id": "TXNQ5V8K2L9N3XM1",
    "amount": 50.00,
    "currency": "USD",
    "status": "processing",
    "reason": "Customer requested refund — order cancelled",
    "created_at": "2026-03-22T10:30:00.000000Z",
    "estimated_completion": "2026-03-25T00:00:00.000000Z"
}

Error Response 400 Bad Request

{
    "success": false,
    "error_code": "REFUND_EXCEEDS_AMOUNT",
    "message": "Refund amount (150.00) exceeds original transaction amount (100.00)."
}

Refund Status Values

Status Description
processing Refund accepted and being processed — awaiting bank confirmation
completed Refund successfully delivered to customer's original payment method
failed Refund could not be processed — contact support with the refund ID

Refund Webhook Notification

When a refund status changes, WalletPlug delivers a signed webhook to your IPN URL:

{
    "status": "completed",
    "event": "refund.completed",
    "data": {
        "refund_id": "RFD_9X2K7P1N4M3L8Q5",
        "trx_id": "TXNQ5V8K2L9N3XM1",
        "amount": 50.00,
        "currency": "USD",
        "reason": "Customer requested refund",
        "environment": "production",
        "is_sandbox": false
    },
    "timestamp": 1705747245
}

The X-Signature header is included on refund webhooks — verify it using the same HMAC-SHA256 method as payment webhooks.

Refund Rules
  • Only completed transactions can be refunded. Pending or failed transactions cannot.
  • Partial refunds can be issued multiple times as long as the total does not exceed the original amount.
  • Refund requests must be submitted within 180 days of the original transaction.

Webhooks (IPN)

WalletPlug sends real-time notifications to your specified IPN URL when payment status changes. This ensures you're immediately notified of payment completions, failures, and other status updates. Webhooks work identically in both sandbox and production environments.

Environment-Aware Webhooks

Use the same webhook URL for both sandbox and production. WalletPlug will include environment context in webhook payloads to help you differentiate between test and live transactions.

Reliable Delivery WalletPlug implements retry logic for failed webhook deliveries. We'll retry up to 5 times with exponential backoff.

Webhook Headers

Header Description Example
Content-Type Always application/json application/json
X-Signature HMAC-SHA256 signature for verification a8b9c2d1e5f3...

Webhook Payload

All webhook payloads include environment information to help you differentiate between sandbox and production transactions:

Environment Context: environment field will be sandbox for test transactions or production for live transactions. Transaction IDs are prefixed accordingly (SANDBOX_ or PRODUCTION_).
{
    "data": {
        "ref_trx": "TXNT4AQFESTAG4F",
        "description": "Order #1234",
        "ipn_url": "https://webhook.site/5711b7d5-917a-4d94-bbb3-c28f4a37bea5",
        "cancel_redirect": "https://merchant.com/cancel",
        "success_redirect": "https://merchant.com/success",
        "customer_name": "John Doe",
        "customer_email": "john@example.com",
        "merchant_name": "Xanthus Wiggins",
        "amount": 200,
        "currency_code": "USD",
        "environment": "production",
        "is_sandbox": false
    },
    "message": "Payment Completed",
    "status": "completed",
    "timestamp": 1705747245
}

Signature Verification

Always verify webhook signatures to ensure authenticity and prevent unauthorized requests. Use your API secret (environment-specific) to verify signatures:

Environment-Specific Secrets: Use test_webhook_secret for sandbox and webhook_secret for production environments.
<?php
// Laravel Webhook Handler
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Enums\EnvironmentMode;

class WalletPlugWebhookController extends Controller
{
    public function handle(Request $request)
    {
        // Get webhook headers
        $environment = $request->header('X-Environment', 'production');
        $signature = $request->header('X-Signature');
        $webhookId = $request->header('X-Webhook-ID');
        
        // Get appropriate secret based on environment
        $secret = $this->getSecretForEnvironment($environment);
        
        // Verify signature
        if (!$this->verifySignature($request->getContent(), $signature, $secret)) {
            Log::warning('WalletPlug webhook signature verification failed', [
                'webhook_id' => $webhookId,
                'environment' => $environment
            ]);
            
            return response()->json(['error' => 'Invalid signature'], 401);
        }
        
        $payload = $request->json()->all();
        
        // Handle based on environment
        if ($environment === EnvironmentMode::SANDBOX->value) {
            return $this->handleSandboxWebhook($payload);
        } else {
            return $this->handleProductionWebhook($payload);
        }
    }
    
    private function getSecretForEnvironment(string $environment): string
    {
        // Return test secret for sandbox, live secret for production
        return $environment === 'sandbox' 
            ? config('walletplug.test_webhook_secret')
            : config('walletplug.webhook_secret');
    }
    
    private function verifySignature(string $payload, string $signature, string $secret): bool
    {
        $expectedSignature = hash_hmac('sha256', $payload, $secret);
        return hash_equals($expectedSignature, $signature);
    }
    
    private function handleSandboxWebhook(array $payload): JsonResponse
    {
        Log::info('Processing sandbox webhook', $payload);
        
        // Your sandbox-specific logic here
        // Don't fulfill orders, don't send emails to real customers, etc.
        
        return response()->json(['status' => 'sandbox_processed']);
    }
    
    private function handleProductionWebhook(array $payload): JsonResponse
    {
        Log::info('Processing production webhook', $payload);
        
        // Your production logic here
        // Fulfill orders, send confirmation emails, etc.
        
        return response()->json(['status' => 'processed']);
    }
}
const crypto = require('crypto');
const express = require('express');

const EnvironmentMode = {
    SANDBOX: 'sandbox',
    PRODUCTION: 'production'
};

// Webhook handler
app.post('/api/webhooks/walletplug', async (req, res) => {
    const environment = req.headers['x-environment'] || 'production';
    const signature = req.headers['x-signature'];
    const webhookId = req.headers['x-webhook-id'];
    
    // Get appropriate secret based on environment
    const secret = getSecretForEnvironment(environment);
    
    // Verify signature
    if (!verifySignature(JSON.stringify(req.body), signature, secret)) {
        console.warn('WalletPlug webhook signature verification failed', {
            webhook_id: webhookId,
            environment: environment
        });
        
        return res.status(401).json({ error: 'Invalid signature' });
    }
    
    const payload = req.body;
    
    try {
        // Handle based on environment
        if (environment === EnvironmentMode.SANDBOX) {
            await handleSandboxWebhook(payload);
        } else {
            await handleProductionWebhook(payload);
        }
        
        res.json({ status: 'processed' });
    } catch (error) {
        console.error('Webhook processing error:', error);
        res.status(500).json({ error: 'Processing failed' });
    }
});

function getSecretForEnvironment(environment) {
    // Return test secret for sandbox, live secret for production
    return environment === 'sandbox' 
        ? process.env.WALLETPLUG_TEST_WEBHOOK_SECRET
        : process.env.WALLETPLUG_WEBHOOK_SECRET;
}

function verifySignature(payload, signature, secret) {
    if (!signature) {
        return false;
    }
    
    const expectedSignature = 'sha256=' + crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');
    
    return crypto.timingSafeEqual(
        Buffer.from(expectedSignature),
        Buffer.from(signature)
    );
}

async function handleSandboxWebhook(payload) {
    console.log('Processing sandbox webhook:', payload);
    
    // Your sandbox-specific logic here
    // Don't fulfill orders, don't send emails to real customers, etc.
}

async function handleProductionWebhook(payload) {
    console.log('Processing production webhook:', payload);
    
    // Your production logic here
    // Fulfill orders, send confirmation emails, etc.
}
import hmac
import hashlib
import json
import logging
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods

logger = logging.getLogger(__name__)

ENVIRONMENT_MODE = {
    'SANDBOX': 'sandbox',
    'PRODUCTION': 'production'
}

@csrf_exempt
@require_http_methods(["POST"])
def walletplug_webhook(request):
    environment = request.headers.get('X-Environment', 'production')
    signature = request.headers.get('X-Signature', '')
    webhook_id = request.headers.get('X-Webhook-ID')
    
    // Get appropriate secret based on environment
    secret = get_secret_for_environment(environment)
    
    // Verify signature
    if not verify_signature(request.body, signature, secret):
        logger.warning('WalletPlug webhook signature verification failed', extra={
            'webhook_id': webhook_id,
            'environment': environment
        })
        
        return JsonResponse({'error': 'Invalid signature'}, status=401)
    
    try:
        payload = json.loads(request.body)
        
        // Handle based on environment
        if environment == ENVIRONMENT_MODE['SANDBOX']:
            handle_sandbox_webhook(payload)
        else:
            handle_production_webhook(payload)
        
        return JsonResponse({'status': 'processed'})
    
    except Exception as e:
        logger.error(f'Webhook processing error:{str(e)}')
        return JsonResponse({'error': 'Processing failed'}, status=500)

def get_secret_for_environment(environment):
    from django.conf import settings
    
    // Return test secret for sandbox, live secret for production
    return (settings.WALLETPLUG_TEST_WEBHOOK_SECRET 
            if environment == 'sandbox' 
            else settings.WALLETPLUG_WEBHOOK_SECRET)

def verify_signature(payload, signature, secret):
    if not signature:
        return False
    
    expected_signature = 'sha256=' + hmac.new(
        secret.encode('utf-8'),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(expected_signature, signature)

def handle_sandbox_webhook(payload):
    logger.info('Processing sandbox webhook', extra=payload)
    
    // Your sandbox-specific logic here
    // Don't fulfill orders, don't send emails to real customers, etc.

def handle_production_webhook(payload):
    logger.info('Processing production webhook', extra=payload)
    
    // Your production logic here
    // Fulfill orders, send confirmation emails, etc.

Environment-Specific Best Practices

Sandbox Webhooks
  • Use for testing webhook integration
  • No real money transactions
  • Don't fulfill actual orders
  • Don't send emails to real customers
  • Use test webhook secret for verification
Production Webhooks
  • Process real customer orders
  • Send confirmation emails
  • Update inventory systems
  • Trigger fulfillment processes
  • Use production webhook secret for verification

Transaction Lifecycle

Every payment created via the WalletPlug API moves through a defined set of states. Understanding this lifecycle helps you implement correct webhook handlers, retry logic, and order management.

Payment State Machine

Initiated
API call made
Pending
Customer at checkout
Completed
Payment succeeded
Failed
Payment declined
Cancelled
Customer cancelled
Expired
Session timed out (60 min)
Refunded
Via Refunds API

Status Reference

Status Webhook Delivered Can Refund Terminal Recommended Action
pending Yes No No Wait for next status change. Do not fulfil order yet.
completed Yes Yes Yes Fulfil the order. Send confirmation email.
failed Yes No Yes Notify customer. Prompt them to retry with a new payment.
cancelled Yes No Yes Release held inventory. Restore cart if applicable.
expired Yes No Yes Create a new payment session. Sessions expire after 60 minutes of inactivity.
refunded Yes Partial only No Update order status in your system. Notify customer of refund timeline.

Idempotency & Duplicate Prevention

The ref_trx field in POST /api/v1/initiate-payment acts as your idempotency key. If you submit two requests with the same ref_trx value:

  • If the first request is still pending — the same payment_url is returned.
  • If the first request has completed — a DUPLICATE_REFERENCE error is returned. Do not retry.
  • If the first request failed or expired — a new payment session is created.
Best Practice: Always use a unique ref_trx per order. A good pattern is STORE_{order_id}_{timestamp} — it guarantees uniqueness and lets you quickly identify orders in your dashboard.

Handling Failed or Expired Payments

When a payment fails or expires, the correct approach is to create a fresh payment session rather than reusing the old URL:

// ❌ Wrong — never redirect to old payment_url after failure
window.location.href = oldPaymentUrl;

// ✅ Correct — create a new session with a fresh ref_trx
const result = await fetch('/api/v1/initiate-payment', {
    method: 'POST',
    body: JSON.stringify({
        payment_amount: 100.00,
        currency_code: 'USD',
        ref_trx: `ORDER_${orderId}_${Date.now()}`, // fresh reference
        // ... other params
    })
});
const { payment_url } = await result.json();
window.location.href = payment_url;

Subscriptions API

WalletPlug's Subscriptions API lets you build recurring billing into your product in minutes. Create plans, store customers, attach payment methods, and let WalletPlug bill your customers automatically on every cycle — with retries, dunning, and outbound webhooks.

Base URL
https://walletplug.com/api/v1/billing

Core Concepts

ResourceDescription
PlanA reusable pricing template: amount + cycle + trial. Each plan has a stable UUID and a public checkout URL.
CustomerA buyer that belongs to your merchant account. Identified uniquely by email within your account.
PaymentMethodTokenised card reference issued by WalletPlug after secure capture on the WalletPlug hosted checkout. Tokens never expose raw card numbers.
SubscriptionA live billing agreement between a Customer and a Plan. Has a status, cycle counters, and a next_billing_at timestamp.
InvoiceA single billing period charge. One subscription generates many invoices over time.
EventAnything that happens — plan.created, subscription.activated, invoice.paid, invoice.failed, etc. All events fire your webhook endpoints.

Subscription Lifecycle

incomplete → trialing? → active → past_due ⇆ active → canceled / expired

A failed charge moves the subscription to past_due. After 3 failed attempts the subscription remains past_due until either the next retry succeeds or the merchant/customer cancels.

Authentication

Every Subscriptions API request uses the same authentication as the rest of the WalletPlug merchant API:

HeaderValue
X-Merchant-KeyYour WalletPlug merchant_key
X-API-KeyYour WalletPlug api_key (or test_api_key for sandbox)
X-Environmentproduction | sandbox
Content-Typeapplication/json

Plans

POST /api/v1/billing/plans

Create a recurring pricing plan.

Request Body

FieldTypeRequiredDescription
namestringDisplay name, e.g. "Pro Monthly"
descriptionstringOptional marketing copy
amountdecimalCharge amount per cycle, e.g. 29.99
currencystring(3)USD, EUR, NGN, …
billing_intervalenumday | week | month | year
interval_countintegere.g. 1 month, 3 months, 6 months
trial_daysinteger0 = no trial
total_cyclesintegernull/0 = indefinite, otherwise stop after N cycles
metadataobjectFree-form key/value attached to plan

Example

curl -X POST https://walletplug.com/api/v1/billing/plans \
  -H "X-Merchant-Key: $WP_MERCHANT_KEY" \
  -H "X-API-Key: $WP_API_KEY" \
  -H "X-Environment: production" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pro Monthly",
    "amount": 29.99,
    "currency": "USD",
    "billing_interval": "month",
    "interval_count": 1,
    "trial_days": 14
  }'

Response (201)

{
  "data": {
    "uuid": "5f8a2b1e-9c4d-4e7f-b2c1-a3d4e5f6g7h8",
    "name": "Pro Monthly",
    "amount": "29.99",
    "currency": "USD",
    "billing_interval": "month",
    "interval_count": 1,
    "trial_days": 14,
    "total_cycles": null,
    "is_active": true,
    "created_at": "2026-01-15T10:23:45.000000Z"
  }
}

Other Plan Endpoints

MethodPathDescription
GET/api/v1/billing/plansList all your plans
GET/api/v1/billing/plans/{uuid}Retrieve one plan
PATCH/api/v1/billing/plans/{uuid}Update name / description / is_active / metadata
DELETE/api/v1/billing/plans/{uuid}Soft-archive (sets is_active=false, existing subs continue)

Customers

POST /api/v1/billing/customers

Create a customer (idempotent on email).

Example

curl -X POST https://walletplug.com/api/v1/billing/customers \
  -H "X-Merchant-Key: $WP_MERCHANT_KEY" \
  -H "X-API-Key: $WP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alex@example.com",
    "name": "Alex Doe",
    "phone": "+14155550100",
    "metadata": {"signup_source": "landing-page-v2"}
  }'

Attach a Payment Method

POST /api/v1/billing/customers/{uuid}/payment-methods

{
  "gateway": "walletplug",
  "gateway_token": "wptok_1OZxyzAbcDef123",
  "brand": "visa",
  "last4": "4242",
  "exp_month": 12,
  "exp_year": 2028
}

In most integrations you do not call this endpoint directly. The WalletPlug hosted checkout captures the card and creates the payment method server-side; the resulting subscription comes back ready to charge. This endpoint is exposed for advanced integrations that have already tokenised a card through a WalletPlug client SDK.

Subscriptions

POST /api/v1/billing/subscriptions

Subscribe a customer to a plan. The first invoice is charged immediately unless the plan has a trial.

Request Body

FieldRequiredDescription
planPlan UUID
customerCustomer UUID
payment_methodPaymentMethod UUID. Defaults to the customer's default method.
metadataFree-form key/value

Example

curl -X POST https://walletplug.com/api/v1/billing/subscriptions \
  -H "X-Merchant-Key: $WP_MERCHANT_KEY" \
  -H "X-API-Key: $WP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "plan": "5f8a2b1e-9c4d-4e7f-b2c1-a3d4e5f6g7h8",
    "customer": "8a1b2c3d-4e5f-6789-abcd-ef0123456789"
  }'

Response

{
  "data": {
    "uuid": "sub_2a3b4c5d6e7f",
    "status": "active",
    "amount": "29.99",
    "currency": "USD",
    "billing_interval": "month",
    "interval_count": 1,
    "cycles_completed": 1,
    "current_period_start": "2026-01-15T10:24:00Z",
    "current_period_end":   "2026-02-15T10:24:00Z",
    "next_billing_at":      "2026-02-15T10:24:00Z",
    "plan":     { "uuid": "...", "name": "Pro Monthly" },
    "customer": { "uuid": "...", "email": "alex@example.com" }
  }
}

Other Subscription Endpoints

MethodPathDescription
GET/api/v1/billing/subscriptions?status=activeList with optional status filter
GET/api/v1/billing/subscriptions/{uuid}Retrieve with invoices included
POST/api/v1/billing/subscriptions/{uuid}/cancelCancel. Pass at_period_end=true to schedule.

Hosted Checkout

Every plan automatically gets a public checkout URL. Share it on your website, in an email, or as a QR code — no integration code required.

URL pattern
https://walletplug.com/subscribe/{plan_uuid}

The customer enters their email and card details on a WalletPlug-hosted page. On success, your webhook receives subscription.activated and invoice.paid.

Embedding on Your Site

<a href="https://walletplug.com/subscribe/5f8a2b1e-9c4d-4e7f-b2c1-a3d4e5f6g7h8"
   class="btn btn-primary">
  Subscribe — $29.99/month
</a>

Webhooks

Register an HTTPS endpoint in your merchant dashboard and WalletPlug will POST a signed JSON payload on every lifecycle event.

Event Types

EventWhen it fires
plan.createdA plan is created
customer.createdA new customer is created
subscription.createdSubscription record is created (may be in trial)
subscription.activatedFirst successful charge — sub is now active
subscription.past_duePayment failed; entered dunning
subscription.cancel_scheduledCancel-at-period-end requested
subscription.canceledCanceled immediately
subscription.expiredTotal cycle limit reached
invoice.paidA charge succeeded
invoice.failedA charge attempt failed

Payload Format

{
  "id": "evt_a1b2c3d4",
  "type": "invoice.paid",
  "created": 1718640000,
  "data": {
    "invoice": { "uuid": "...", "amount": "29.99", "status": "paid" }
  }
}

Verifying Signatures

Every request includes an X-WalletPlug-Signature header in the form t={timestamp},v1={hmac}. Verify it by computing HMAC-SHA256 over {timestamp}.{raw_body} with your endpoint's signing secret:

$payload = file_get_contents('php://input');
$header  = $_SERVER['HTTP_X_WALLETPLUG_SIGNATURE'];
preg_match('/t=(\d+),v1=([a-f0-9]+)/', $header, $m);
[$ts, $sig] = [$m[1], $m[2]];

$expected = hash_hmac('sha256', $ts . '.' . $payload, $signing_secret);
if (!hash_equals($expected, $sig)) {
    http_response_code(400);
    exit('Invalid signature');
}

// Reject replays older than 5 minutes
if (abs(time() - (int)$ts) > 300) {
    http_response_code(400);
    exit('Stale timestamp');
}

$event = json_decode($payload, true);
// ... handle $event['type'] ...
http_response_code(200);

Retry Policy

If your endpoint returns a non-2xx status or times out (10 s), the event is retried with exponential backoff: 5 min → 30 min → 2 h → 12 h → 24 h. After 5 failed attempts the event is marked dead and surfaced in your dashboard.

End-to-End Example

A complete flow: create a plan, share its hosted checkout URL, and listen for the webhook when the customer subscribes.

<?php
$base    = 'https://walletplug.com/api/v1/billing';
$headers = [
    'X-Merchant-Key: ' . getenv('WP_MERCHANT_KEY'),
    'X-API-Key: '      . getenv('WP_API_KEY'),
    'X-Environment: production',
    'Content-Type: application/json',
];

function wp($method, $url, $body, $headers) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_POSTFIELDS     => $body ? json_encode($body) : null,
        CURLOPT_HTTPHEADER     => $headers,
    ]);
    return json_decode(curl_exec($ch), true);
}

// 1. Create a plan (do this once, in your admin)
$plan = wp('POST', "$base/plans", [
    'name'             => 'Pro Monthly',
    'amount'           => 29.99,
    'currency'         => 'USD',
    'billing_interval' => 'month',
    'interval_count'   => 1,
    'trial_days'       => 14,
], $headers);

$planUuid = $plan['data']['uuid'];

// 2. Send the customer to the hosted checkout — WalletPlug will create the
//    customer, capture the card, and create the active subscription for you.
$checkoutUrl = "https://walletplug.com/subscribe/{$planUuid}";
header("Location: {$checkoutUrl}");

// 3. In your webhook handler, react when the subscription activates:
//      POST /your-webhook  →  event.type = "subscription.activated"
//                           → event.data.subscription.uuid is now active
echo "Sent customer to {$checkoutUrl}";

Integrating Subscriptions Into Your App

This is the end-to-end pattern for selling subscriptions on your website using WalletPlug. Most merchants only need this one page to ship a complete recurring billing flow.

The big picture

Customers pay on a WalletPlug-hosted page. The moment they pay, we POST a signed JSON event to your server. Your server reads the event and grants the customer access in your own database. That's it — no API polling, no client-side trust, no PCI scope.

1. Customer clicks "Subscribe" on YOUR site
   ↓
2. They land on walletplug.com/subscribe/{plan_uuid}
   ↓
3. They enter email + card and click Subscribe
   ↓
4. WalletPlug charges the card through your gateway
   ↓
5. WalletPlug POSTs to YOUR webhook URL:
   POST https://yoursite.com/webhooks/walletplug
   {
     "type": "subscription.activated",
     "data": { "customer": { "email": "alice@example.com" }, ... }
   }
   ↓
6. Your server finds Alice, marks her as paid, grants access

Step 1 — Create a plan

From your dashboard click 'New plan'. Set the name, amount, currency, and billing interval. You'll get back a plan UUID and a hosted checkout URL like:

https://walletplug.com/subscribe/5f8a2b1e-9c4d-4e7f-b2c1-a3d4e5f6g7h8

Step 2 — Put the subscribe link on your website

Any link, button, or pricing card. Reuse the same URL for every customer — WalletPlug captures their email at checkout.

<a href="https://walletplug.com/subscribe/5f8a2b1e-..." class="btn btn-primary">
    Subscribe — $29/month
</a>

Or use the embeddable widget — see the SDKs & Plugins section.

Step 3 — Tell us where to send webhook events

Go to Webhooks and add your endpoint URL plus the events you care about. We recommend the 'Essential' preset to start:

  • subscription.activated — grant access
  • invoice.paid — a renewal succeeded
  • invoice.failed — a charge failed (still retrying)
  • subscription.canceled — revoke access

Copy the signing secret WalletPlug generates — your handler verifies every payload with it.

Step 4 — Build your webhook handler

Pick your language. All three examples below do exactly the same thing — verify the signature, route by event type, update the user.

PHP / Laravel

<?php
// routes/web.php
Route::post('/webhooks/walletplug', function (Request $request) {
    // 1. Verify signature
    $payload   = $request->getContent();
    $signature = $request->header('X-WalletPlug-Signature');
    [$ts, $sig] = explode(',', str_replace(['t=', 'v1='], '', $signature));

    $expected = hash_hmac('sha256', $ts . '.' . $payload, env('WALLETPLUG_WEBHOOK_SECRET'));
    if (!hash_equals($expected, $sig)) {
        return response('Invalid signature', 400);
    }
    // 2. Reject events older than 5 minutes (replay protection)
    if (abs(time() - (int)$ts) > 300) return response('Stale', 400);

    // 3. Parse and route
    $event = json_decode($payload, true);

    // 4. Idempotency — don't process the same event twice
    $processed = DB::table('webhook_log')->where('event_id', $event['id'])->exists();
    if ($processed) return response('OK', 200);
    DB::table('webhook_log')->insert(['event_id' => $event['id'], 'created_at' => now()]);

    // 5. Handle the event
    $email = $event['data']['customer']['email'] ?? null;
    $user  = User::firstWhere('email', $email);
    if (!$user) {
        // Account doesn't exist yet — auto-create + email a magic-login link
        $user = User::create(['email' => $email, 'password' => bcrypt(Str::random(32))]);
        Mail::to($email)->send(new MagicLoginEmail($user));
    }

    switch ($event['type']) {
        case 'subscription.activated':
            $user->update([
                'subscription_status' => 'active',
                'subscription_plan'   => $event['data']['plan']['name'],
                'walletplug_sub_uuid' => $event['data']['subscription']['uuid'],
            ]);
            break;
        case 'invoice.paid':
            // A renewal — extend access if you're tracking expiry locally
            break;
        case 'invoice.failed':
            $user->update(['subscription_status' => 'past_due']);
            break;
        case 'subscription.canceled':
            $user->update(['subscription_status' => 'canceled']);
            break;
    }

    return response()->json(['ok' => true]);
});

Node.js / Express

import express from 'express';
import crypto from 'crypto';

const app = express();
app.use('/webhooks/walletplug', express.raw({ type: 'application/json' }));

const processed = new Set(); // use Redis/DB in production

app.post('/webhooks/walletplug', (req, res) => {
    // 1. Verify signature
    const sigHeader = req.headers['x-walletplug-signature'] || '';
    const [tsPart, sigPart] = sigHeader.split(',');
    const ts  = tsPart.replace('t=', '');
    const sig = sigPart.replace('v1=', '');

    const expected = crypto
        .createHmac('sha256', process.env.WALLETPLUG_WEBHOOK_SECRET)
        .update(`${ts}.${req.body.toString()}`)
        .digest('hex');

    if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig))) {
        return res.status(400).send('Invalid signature');
    }
    if (Math.abs(Date.now()/1000 - parseInt(ts)) > 300) {
        return res.status(400).send('Stale');
    }

    // 2. Parse
    const event = JSON.parse(req.body.toString());

    // 3. Idempotency
    if (processed.has(event.id)) return res.json({ ok: true });
    processed.add(event.id);

    const email = event.data?.customer?.email;

    switch (event.type) {
        case 'subscription.activated':
            // grantAccess(email, event.data.plan.name);
            break;
        case 'invoice.failed':
            // markPastDue(email);
            break;
        case 'subscription.canceled':
            // revokeAccess(email);
            break;
    }

    res.json({ ok: true });
});

app.listen(3000);

Python / Flask

import os, hmac, hashlib, time
from flask import Flask, request, abort, jsonify

app = Flask(__name__)
SECRET = os.environ['WALLETPLUG_WEBHOOK_SECRET']
processed = set()  # use Redis/DB in production

@app.post('/webhooks/walletplug')
def walletplug_webhook():
    # 1. Verify signature
    header = request.headers.get('X-WalletPlug-Signature', '')
    parts = dict(p.split('=', 1) for p in header.split(','))
    ts, sig = parts.get('t'), parts.get('v1')

    expected = hmac.new(
        SECRET.encode(),
        f"{ts}.{request.data.decode()}".encode(),
        hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(expected, sig or ''):
        abort(400, 'Invalid signature')
    if abs(time.time() - int(ts)) > 300:
        abort(400, 'Stale')

    event = request.get_json()

    # 2. Idempotency
    if event['id'] in processed:
        return jsonify(ok=True)
    processed.add(event['id'])

    email = event.get('data', {}).get('customer', {}).get('email')

    handlers = {
        'subscription.activated': lambda: grant_access(email, event['data']['plan']['name']),
        'invoice.failed':         lambda: mark_past_due(email),
        'subscription.canceled':  lambda: revoke_access(email),
    }
    if event['type'] in handlers:
        handlers[event['type']]()

    return jsonify(ok=True)

Two ways to match the customer

Option A — Match by email (most common)

If the customer already has an account on your site, they use the same email at checkout. Your webhook handler does: User::where('email', $event['data']['customer']['email']).

Option B — Match by metadata (most reliable)

Append your internal user ID to the subscribe link:

<a href="https://walletplug.com/subscribe/{plan_uuid}?metadata[user_id]=42&metadata[ref]=blog">
    Subscribe
</a>

That metadata appears in every webhook payload:

{
  "type": "subscription.activated",
  "data": {
    "subscription": {
      "uuid": "sub_xyz",
      "metadata": { "user_id": "42", "ref": "blog" }
    }
  }
}

Then your handler can match by your own ID: User::find($event['data']['subscription']['metadata']['user_id']).

Retry policy you should know about

  • If your endpoint returns anything other than 2xx, we retry.
  • Retry delays: 5 min → 30 min → 2 h → 12 h → 24 h
  • After 5 failed attempts the delivery is marked dead and shown in your dashboard.
  • We expect a response within 10 seconds — do slow work asynchronously.

Common gotchas

  • Always verify the signature — Otherwise anyone can POST fake events to your webhook URL and unlock your product for free.
  • Always check idempotency — Webhooks can fire twice. Track event IDs and skip ones you've already processed.
  • Don't block on the response — Return 200 immediately, then process asynchronously. Slow webhooks miss the 10-second deadline and get retried unnecessarily.
  • Handle the trial-end transition — During a trial, status is trialing. Don't revoke access just because last_payment_at is null.

Test it before going live

  1. Add your endpoint and select events.
  2. Click 'Send test event' on the endpoint card. We'll POST a sample subscription.activated to your URL.
  3. Verify your handler returns 200 in the Recent Deliveries panel.
  4. Do a real $1 subscription with your own card to confirm the full flow end-to-end.
Tip: During local development, expose your localhost to the internet with ngrok http 3000 and point WalletPlug at the ngrok URL. Webhook deliveries will hit your laptop in real time.

WordPress Plugin

Drop subscription checkout into any WordPress site with our official plugin. No code required — just paste a shortcode or use the Gutenberg block.

Install
  1. Download the plugin zip: Download (.zip)
  2. In WP-Admin → Plugins → Add New → Upload Plugin → choose the zip → Activate.
  3. Paste the shortcode anywhere:
[walletplug_subscribe plan="YOUR_PLAN_UUID" label="Subscribe — $29/mo"]

Or use the Gutenberg block: WalletPlug Subscribe.

Plain HTML Embed

Works on any site — landing pages, no-code builders, plain HTML. Two lines.

<script src="https://walletplug.com/js/walletplug-billing.js" async></script>
<walletplug-button plan="YOUR_PLAN_UUID">Subscribe</walletplug-button>

Or use a data attribute on any link / button you already have:

<a href="#" data-walletplug-plan="YOUR_PLAN_UUID">Start free trial</a>

Listen for subscription events:

window.addEventListener('walletplug:subscription', (e) => {
    console.log('New subscription:', e.detail);
    // e.g. redirect to thank-you page
    window.location = '/thank-you';
});

PHP / Laravel SDK Example

Server-side: create a plan and send the customer to the WalletPlug hosted checkout.

<?php
use GuzzleHttp\Client;

$wp = new Client([
    'base_uri' => 'https://walletplug.com/api/v1/billing/',
    'headers'  => [
        'X-Merchant-Key' => env('WP_MERCHANT_KEY'),
        'X-API-Key'      => env('WP_API_KEY'),
        'X-Environment'  => 'production',
        'Accept'         => 'application/json',
    ],
]);

// 1. Create a plan once
$plan = json_decode($wp->post('plans', [
    'json' => [
        'name'             => 'Pro Monthly',
        'amount'           => 29.99,
        'currency'         => 'USD',
        'billing_interval' => 'month',
        'interval_count'   => 1,
        'trial_days'       => 14,
    ]
])->getBody(), true);

$planUuid = $plan['data']['uuid'];

// 2. Send the user to the WalletPlug hosted checkout.
//    WalletPlug captures the card, creates the customer + subscription,
//    and fires `subscription.activated` to your webhook on success.
return redirect("https://walletplug.com/subscribe/{$planUuid}");

Node.js / TypeScript Example

const BASE = 'https://walletplug.com/api/v1/billing';
const headers = {
    'X-Merchant-Key': process.env.WP_MERCHANT_KEY,
    'X-API-Key':      process.env.WP_API_KEY,
    'X-Environment':  'production',
    'Content-Type':   'application/json',
};

async function wp(method, path, body) {
    const r = await fetch(`${BASE}${path}`, {
        method, headers, body: body ? JSON.stringify(body) : undefined,
    });
    if (!r.ok) throw new Error(await r.text());
    return r.json();
}

// Create a plan
const plan = await wp('POST', '/plans', {
    name: 'Pro Monthly', amount: 29.99, currency: 'USD',
    billing_interval: 'month', interval_count: 1, trial_days: 14
});

// Redirect the user to the WalletPlug hosted checkout
const checkoutUrl = `https://walletplug.com/subscribe/${plan.data.uuid}`;
console.log('Send your user to:', checkoutUrl);

Python Example

import os, requests

BASE = "https://walletplug.com/api/v1/billing"
H = {
    "X-Merchant-Key": os.environ["WP_MERCHANT_KEY"],
    "X-API-Key":      os.environ["WP_API_KEY"],
    "X-Environment":  "production",
    "Content-Type":   "application/json",
}

def wp(method, path, body=None):
    r = requests.request(method, BASE + path, headers=H, json=body, timeout=15)
    r.raise_for_status()
    return r.json()

plan = wp("POST", "/plans", {
    "name":"Pro Monthly", "amount":29.99, "currency":"USD",
    "billing_interval":"month", "interval_count":1, "trial_days":14,
})

# Send your user to the WalletPlug hosted checkout
checkout_url = f"https://walletplug.com/subscribe/{plan['data']['uuid']}"
print("Redirect user to:", checkout_url)

cURL One-liners

# List plans
curl -H "X-Merchant-Key: $KEY" -H "X-API-Key: $SECRET" \
     https://walletplug.com/api/v1/billing/plans

# Cancel subscription immediately
curl -X POST -H "X-Merchant-Key: $KEY" -H "X-API-Key: $SECRET" \
     https://walletplug.com/api/v1/billing/subscriptions/SUB_UUID/cancel

# Cancel at period end
curl -X POST -H "X-Merchant-Key: $KEY" -H "X-API-Key: $SECRET" \
     -d 'at_period_end=true' \
     https://walletplug.com/api/v1/billing/subscriptions/SUB_UUID/cancel

Rate Limits

The WalletPlug API uses rate limiting to ensure stability and fair usage across all merchants. Limits are applied per merchant account, not per IP address.

429 Too Many Requests When you exceed a rate limit the API returns HTTP 429. Always implement exponential backoff — do not immediately retry on 429.

Limits by Endpoint

Endpoint Limit Window Scope
POST /api/v1/initiate-payment 120 requests per minute per merchant
GET /api/v1/verify-payment/{trxId} 60 requests per minute per merchant
Webhook delivery (inbound) No limit WalletPlug to your server
Interactive testing console 20 requests per minute per IP address

Rate Limit Response Headers

Every API response includes these headers so you can monitor your usage:

Header Description Example
X-RateLimit-Limit Maximum requests allowed in the window 120
X-RateLimit-Remaining Requests remaining in the current window 87
X-RateLimit-Reset Unix timestamp when the window resets 1705747260
Retry-After Seconds to wait before retrying (only on 429) 34

Recommended Retry Strategy

When you receive a 429, read the Retry-After header and wait that many seconds before retrying. If the header is absent, use exponential backoff:

async function apiCallWithRetry(fn, maxRetries = 3) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
        const response = await fn();
        if (response.status !== 429) return response;
        const retryAfter = response.headers.get('Retry-After');
        const waitMs = retryAfter
            ? parseInt(retryAfter) * 1000
            : Math.pow(2, attempt) * 1000;
        await new Promise(resolve => setTimeout(resolve, waitMs));
    }
    throw new Error('Max retries exceeded');
}
Need higher limits? Enterprise merchants can request elevated rate limits. Contact chat@walletplug.com with your merchant ID and expected request volume.

Supported Currencies & Countries

WalletPlug is a global fintech platform — Plug to the World. We power international payments for merchants and customers across every major region: the Americas, Europe, Asia Pacific, the Middle East, and Africa. One integration, one API, the entire world.

135+
Countries supported
50+
Currencies accepted
100+
Payment methods
6
Global regions
Currency Matching The currency_code you send in POST /api/v1/initiate-payment must match the currency configured on your merchant account. Contact support to enable additional currencies.

Supported Currencies

All major global and regional currencies are supported. Minimum amounts apply per currency.

Code Currency Min Amount Region
USDUS Dollar1.00Global
EUREuro1.00Europe, Global
GBPBritish Pound1.00United Kingdom, Global
CADCanadian Dollar1.00Canada
AUDAustralian Dollar1.00Australia, Oceania
CHFSwiss Franc1.00Switzerland
JPYJapanese Yen100Japan
CNYChinese Yuan5.00China, Asia
HKDHong Kong Dollar8.00Hong Kong
SGDSingapore Dollar1.00Singapore, Southeast Asia
NZDNew Zealand Dollar1.00New Zealand
SEKSwedish Krona10.00Sweden, Scandinavia
NOKNorwegian Krone10.00Norway, Scandinavia
DKKDanish Krone7.00Denmark, Scandinavia
AEDUAE Dirham4.00United Arab Emirates
SARSaudi Riyal4.00Saudi Arabia
QARQatari Riyal4.00Qatar
KWDKuwaiti Dinar0.30Kuwait
BHDBahraini Dinar0.40Bahrain
INRIndian Rupee50.00India
BDTBangladeshi Taka100.00Bangladesh
PKRPakistani Rupee250.00Pakistan
MYRMalaysian Ringgit4.00Malaysia
IDRIndonesian Rupiah15000Indonesia
PHPPhilippine Peso50.00Philippines
THBThai Baht35.00Thailand
VNDVietnamese Dong25000Vietnam
NGNNigerian Naira500.00Nigeria
GHSGhanaian Cedi10.00Ghana
KESKenyan Shilling100.00Kenya
ZARSouth African Rand10.00South Africa
UGXUgandan Shilling3500.00Uganda
TZSTanzanian Shilling2500.00Tanzania
RWFRwandan Franc1000.00Rwanda
XOFWest African CFA Franc500.00Francophone West Africa
XAFCentral African CFA Franc500.00Central Africa
EGPEgyptian Pound30.00Egypt
MADMoroccan Dirham10.00Morocco
ZMWZambian Kwacha20.00Zambia
ETBEthiopian Birr55.00Ethiopia
BRLBrazilian Real5.00Brazil, Latin America
MXNMexican Peso17.00Mexico
ARSArgentine Peso900.00Argentina
COPColombian Peso4000.00Colombia
CLPChilean Peso900.00Chile

Supported Countries

WalletPlug supports merchants and customers across every major region worldwide. If your country is not listed below contact us — we likely already support it.

Americas
United StatesCanadaBrazilMexicoArgentinaColombiaChilePeruEcuadorUruguayBoliviaParaguayVenezuelaPanamaCosta RicaGuatemalaHondurasEl SalvadorNicaraguaDominican RepublicPuerto RicoJamaicaTrinidad and TobagoBarbadosBahamasBelizeGuyanaSuriname
Europe
United KingdomGermanyFranceSpainItalyNetherlandsBelgiumPortugalSwitzerlandSwedenNorwayDenmarkPolandAustriaIrelandFinlandCzech RepublicRomaniaGreeceHungaryBulgariaCroatiaSlovakiaSloveniaLithuaniaLatviaEstoniaCyprusMaltaLuxembourgIcelandSerbiaUkraineGeorgiaAzerbaijanArmeniaAlbaniaNorth MacedoniaBosniaMontenegroMoldova
Africa

WalletPlug has expanded deep across Africa with local currency, mobile money, and bank transfer integration on every major market.

NigeriaGhanaKenyaSouth AfricaTanzaniaUgandaRwandaEthiopiaZambiaZimbabweSenegalCameroonEgyptMoroccoTunisiaAlgeriaAngolaMozambiqueMalawiMadagascarBotswanaNamibiaSierra LeoneLiberiaGambiaTogoBeninBurkina FasoMaliNigerChadDRCCongoSudanSouth SudanEritreaDjiboutiSomaliaComorosCape VerdeGuineaEquatorial GuineaGabonLesothoEswatiniMauritiusSeychellesCote dIvoire
Middle East
United Arab EmiratesSaudi ArabiaQatarKuwaitBahrainOmanJordanLebanonIsraelTurkeyIraqYemenPalestine
Asia Pacific
IndiaChinaJapanSouth KoreaSingaporeMalaysiaIndonesiaPhilippinesThailandVietnamHong KongBangladeshPakistanSri LankaNepalAustraliaNew ZealandTaiwanCambodiaMyanmarLaosMongoliaKazakhstanUzbekistanAfghanistanBruneiPapua New GuineaFijiSamoaTonga
And More

WalletPlug is continuously expanding. Contact us if you need a specific country enabled — we likely already support it.

RussiaBelarusMaldivesBhutanGreenlandCayman IslandsBermudaGuadeloupeMartiniqueCuracaoArubaAntiguaSaint LuciaSaint VincentMauritaniaLibya

Supported Payment Methods

WalletPlug is an all-in-one payment platform. Merchants integrate once and instantly support every major payment method globally — no separate gateway accounts, no extra integrations, no complexity.

All Cards — Debit and Credit

Accept every card type from customers worldwide. All major card networks are supported — no restrictions.

VisaMastercardAmerican ExpressVerveDiscoverUnionPayJCBDiners ClubMaestroLocal Debit CardsPrepaid CardsVirtual Cards
3D Secure (3DS2) supported on all card networks for fraud prevention
Bank Transfers — All Types

Local and international bank-to-bank transfers across all supported countries — real-time where available.

Local Bank TransferSWIFT / Wire TransferSEPA (Europe)ACH (United States)Faster Payments (UK)BACS (UK)CHAPS (UK)UPI (India)PIX (Brazil)SPEI (Mexico)Interac (Canada)OSKO (Australia)Real-Time PaymentsInstant Bank Pay
Mobile Money

The dominant payment method across Africa and parts of Asia — deeply integrated with all major operators.

MTN Mobile MoneyAirtel MoneyM-PesaVodafone CashOrange MoneyWaveTigo CashMoov MoneySafaricomGLO Pay9mobile PayFree MoneyDjamoYUP
Digital Wallets and BNPL

Global digital wallets and buy-now-pay-later options for maximum checkout conversion worldwide.

WalletPlug WalletApple PayGoogle PaySamsung PayAlipayWeChat PayGrabPayDanaTrueMoneyGoPayOVOKlarnaAfterpay / ClearpayZipLaybuySezzlePaidy
Vouchers and Prepaid

Prepaid voucher redemption — essential for markets with high unbanked populations.

WalletPlug VoucherPrepaid CardsGift CardsScratch CardsAirtime / Top-upeScratchPaysafecardNeosurf
Cryptocurrency

Accept crypto from customers anywhere and settle in your preferred local currency — no volatility risk for merchants.

Bitcoin (BTC)Ethereum (ETH)USDT (Tether)USDCBNB (BEP-20)Solana (SOL)Litecoin (LTC)Polygon (MATIC)Tron (TRX)Ripple (XRP)
Crypto settled to fiat instantly at point of payment — merchant receives local currency

Filter Payment Methods at Checkout

Use the optional allow_payment_methods parameter to restrict which methods appear at checkout. Omit it to show all methods available in the customer's region — recommended for maximum conversion.

{
    "payment_amount": 100.00,
    "currency_code": "USD",
    "ref_trx": "ORDER_12345",
    "allow_payment_methods": "card,bank_transfer,wallet"
}
Value Methods shown at checkout
cardAll cards — Visa, Mastercard, Verve, Amex, UnionPay, JCB, Discover, and all local debit networks
bank_transferAll local and international bank transfer methods — SEPA, ACH, SWIFT, Faster Payments, UPI, PIX, and local variants
mobile_moneyMTN, Airtel, M-Pesa, Wave, Vodafone Cash, and all supported mobile money operators
walletWalletPlug Wallet, Apple Pay, Google Pay, Samsung Pay, Alipay, WeChat Pay, and all digital wallets
voucherWalletPlug Voucher, prepaid cards, gift cards, and all voucher-based payment methods
cryptoBitcoin, Ethereum, USDT, USDC, and all supported cryptocurrency options
omittedRecommended — All methods for the customer's region shown automatically for maximum conversion
One Integration. The Entire World. WalletPlug aggregates every major payment method globally into a single API call. No separate accounts. No multiple integrations. No complexity. Integrate once — accept payments from anyone, anywhere.
Need a country, currency, or method not listed? Contact chat@walletplug.com with your merchant ID and what you need — our team enables it for your account, often within one business day.

Security & Compliance

WalletPlug is built as an enterprise-grade fintech platform. This section covers our security architecture, compliance posture, and the responsibilities shared between WalletPlug and merchants integrating the API.

PCI DSS
SAQ-A Compliant
TLS 1.2+
All connections encrypted
HMAC-SHA256
Webhook signing
AES-256
Credentials at rest

PCI DSS Compliance

WalletPlug operates as a PCI DSS SAQ-A compliant payment service provider. Card data is never processed, stored, or transmitted through your servers — all sensitive data is handled exclusively on WalletPlug 's hosted checkout pages.

WalletPlug's Responsibility
  • All card data processing on PCI-certified infrastructure
  • Tokenisation of payment instruments
  • Network segmentation and penetration testing
  • Annual PCI DSS audit and certification
Merchant's Responsibility
  • Never log or store X-API-Key or X-Merchant-Key in client-side code
  • Store webhook secrets using environment variables, never in source code
  • Keep your server OS and dependencies up to date
  • Use HTTPS on all pages that link to WalletPlug checkout

Transport Security

Requirement Detail
Minimum TLS version TLS 1.2 — TLS 1.0 and 1.1 are rejected
Certificate pinning Recommended for mobile SDKs — see Android/iOS SDK docs
API base URL https://walletplug.com — HTTP requests are rejected with 301 Moved Permanently
Webhook delivery WalletPlug only delivers webhooks to HTTPS endpoints. HTTP webhook URLs are rejected at configuration time.

Credential Security Best Practices

Use environment variables

Never hardcode credentials. Store them in .env files, server environment variables, or secrets managers (AWS Secrets Manager, HashiCorp Vault).

Separate sandbox and production keys

Never use production keys during development. Sandbox keys are prefixed test_ — they will not process real money even if accidentally exposed.

Rotate keys immediately if exposed

If a key is accidentally committed to a public repository or exposed in logs, rotate it immediately from Dashboard → Merchant → CONFIG. Old keys are invalidated instantly.

Always verify webhook signatures

Never process a webhook without first verifying the X-Signature HMAC-SHA256 header. An unverified webhook could be spoofed to mark orders as paid.

Webhook Signature Verification — Deep Dive

WalletPlug signs every webhook delivery using HMAC-SHA256. The signature is computed over the raw request body using your Client Secret as the key.

X-Signature: sha256=a8b9c2d1e5f3... (HMAC-SHA256 of raw body using Client Secret)
Use timing-safe comparison Always use hash_equals() (PHP) or crypto.timingSafeEqual() (Node.js) to compare signatures. String equality operators are vulnerable to timing attacks.

Additional webhook security checklist:

  • Reject webhooks where X-Signature is missing or empty
  • Reject webhooks with a timestamp older than 5 minutes (replay attack prevention)
  • Return 200 OK quickly (within 5 seconds) — process heavy logic asynchronously
  • Make your webhook handler idempotent — the same event may be delivered more than once on retry

Responsible Disclosure

We take security seriously. If you discover a vulnerability in the WalletPlug API or platform, please report it responsibly rather than disclosing it publicly.

  • Email: security@walletplug.com
  • Include a clear description of the vulnerability and steps to reproduce
  • We aim to acknowledge reports within 24 hours and provide a fix within 30 days
  • We do not pursue legal action against researchers acting in good faith

Official SDKs & Packages

WalletPlug publishes official SDK packages for the most popular server-side languages. Each package handles authentication, request signing, automatic retries, error normalisation, and typed responses — so you can integrate in minutes instead of hours.

Official Packages Only Always install from the official package registries listed below. Verify the package source is walletplug before installing.

Node.js / TypeScript

walletplug-node — npm
v1.0.0

Official Node.js SDK with full TypeScript support. Works with Express, Next.js, NestJS, Fastify, and any Node runtime. Node.js 16+.

Install
npm install walletplug-node
Quick Start
import WalletPlug from 'walletplug-node';

const wp = new WalletPlug({
  merchantKey: process.env.WALLETPLUG_MERCHANT_KEY,
  apiKey:      process.env.WALLETPLUG_API_KEY,
  environment: 'sandbox',
});
wp.setWebhookSecret(process.env.WALLETPLUG_WEBHOOK_SECRET);

// Initiate payment
const result = await wp.payments.initiate({
  amount: 250.00, currency: 'USD', reference: 'ORDER_12345',
  successUrl: 'https://yoursite.com/success',
  failureUrl: 'https://yoursite.com/failed',
  cancelUrl:  'https://yoursite.com/cancel',
  webhookUrl: 'https://yoursite.com/webhook',
});
res.redirect(result.paymentUrl);

// Verify payment
const payment = await wp.payments.verify('TXNQ5V8K2L9N3XM1');

// Webhook — use express.raw() for HMAC verification
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const payload = wp.webhooks.verifyAndParse(
    req.body.toString('utf8'),
    req.headers['x-signature']
  );
  if (payload.status === 'completed') fulfillOrder(payload.data.ref_trx);
  res.json({ received: true });
});

PHP / Composer

walletplug/walletplug-php — Packagist
v1.0.0

Official PHP SDK with first-class Laravel support — auto-discovered Service Provider, publishable config, and Facade. Also works with Symfony, WordPress, and plain PHP 7.4+.

Install
composer require walletplug/walletplug-php
Quick Start (Plain PHP)
<?php
use WalletPlug\WalletPlug;

$wp = new WalletPlug([
    'merchant_key'   => getenv('WALLETPLUG_MERCHANT_KEY'),
    'api_key'        => getenv('WALLETPLUG_API_KEY'),
    'webhook_secret' => getenv('WALLETPLUG_WEBHOOK_SECRET'),
    'environment'    => 'sandbox',
]);

$result = $wp->payments->initiate([
    'amount' => 250.00, 'currency' => 'USD', 'reference' => 'ORDER_12345',
    'success_url' => 'https://yoursite.com/success',
    'failure_url' => 'https://yoursite.com/failed',
    'cancel_url'  => 'https://yoursite.com/cancel',
    'webhook_url' => 'https://yoursite.com/webhook',
]);
header('Location: ' . $result->paymentUrl);
Laravel Integration
php artisan vendor:publish --provider="WalletPlug\Laravel\WalletPlugServiceProvider"
<?php
// .env
WALLETPLUG_MERCHANT_KEY=test_your_merchant_key
WALLETPLUG_API_KEY=test_your_api_key
WALLETPLUG_WEBHOOK_SECRET=your_client_secret
WALLETPLUG_ENVIRONMENT=sandbox

// Controller (dependency injection)
class PaymentController extends Controller {
    public function __construct(private readonly WalletPlug $walletplug) {}

    public function pay(Request $request) {
        $result = $this->walletplug->payments->initiate([
            'amount' => $request->amount, 'currency' => 'USD',
            'reference'   => 'ORDER_' . $request->order_id,
            'success_url' => route('payment.success'),
            'failure_url' => route('payment.failed'),
            'cancel_url'  => route('payment.cancel'),
            'webhook_url' => route('payment.webhook'),
        ]);
        return redirect($result->paymentUrl);
    }
}

Python

walletplug-python — PyPI
v1.0.0

Official Python SDK with sync and async clients. Full type hints, dataclass models, Django, FastAPI, and Flask support. Python 3.8+.

Install
pip install walletplug-python
Quick Start (Django / Flask)
from walletplug import WalletPlug
import os

wp = WalletPlug(
    merchant_key=os.getenv('WALLETPLUG_MERCHANT_KEY'),
    api_key=os.getenv('WALLETPLUG_API_KEY'),
    environment='sandbox',
)
wp.set_webhook_secret(os.getenv('WALLETPLUG_WEBHOOK_SECRET'))

result = wp.payments.initiate(
    amount=250.00, currency='USD', reference='ORDER_12345',
    success_url='https://yoursite.com/success',
    failure_url='https://yoursite.com/failed',
    cancel_url='https://yoursite.com/cancel',
    webhook_url='https://yoursite.com/webhook',
)
return redirect(result.payment_url)
Async Client (FastAPI)
from walletplug import AsyncWalletPlug
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse

app = FastAPI()
wp  = AsyncWalletPlug.sandbox('test_merchant_key', 'test_api_key')
wp.set_webhook_secret(os.getenv('WALLETPLUG_WEBHOOK_SECRET'))

@app.post('/pay')
async def pay(order_id: str):
    result = await wp.payments.initiate(
        amount=100.00, currency='USD', reference=f'ORDER_{order_id}',
        success_url='https://yoursite.com/success',
        failure_url='https://yoursite.com/failed',
        cancel_url='https://yoursite.com/cancel',
        webhook_url='https://yoursite.com/webhook',
    )
    return RedirectResponse(result.payment_url)

@app.post('/webhook')
async def webhook(request: Request):
    raw  = (await request.body()).decode('utf-8')
    sig  = request.headers.get('x-signature', '')
    data = wp.webhooks.verify_and_parse(raw, sig)
    if data.status == 'completed':
        await fulfill_order(data.data.ref_trx)
    return {'received': True}

Postman Collection & OpenAPI Spec

One-click setup for any tool

Import the WalletPlug API directly into Postman, Insomnia, or any OpenAPI-compatible tool. Pre-configured with sandbox credentials and all endpoints ready to test.

Download Postman Collection File → Import in Postman. Set MERCHANT_KEY and API_KEY variables.
Download OpenAPI 3.0 Spec (YAML) Compatible with Swagger UI, Redoc, Insomnia, and any OpenAPI tool.

SDK Feature Comparison

FeatureNode.jsPHPPython
Initiate Payment
Verify Payment
Refunds
Webhook HMAC Verification
Auto retry on 5xx + network errors
Rate limit auto-retry with backoff
Typed error classes
TypeScript / Python type hints
Async / Await support
Laravel Service Provider + Facade
FastAPI async support
Open Source All official WalletPlug SDKs are open source and MIT licensed. Bug reports, pull requests, and contributions are welcome on GitHub at github.com/walletplug.

Integration Examples

Complete integration examples for popular platforms and frameworks.

Environment Configuration: Replace {environment} with sandbox or production, and use corresponding credentials - test_ prefix for sandbox, no prefix for production in your configuration files.
<?php
// Laravel Integration Service
namespace App\Services;

use Illuminate\Support\Facades\Http;
use Exception;

class WalletPlugService
{
    private string $baseUrl;
    private string $merchantKey;
    private string $apiKey;
    private string $environment;

    public function __construct()
    {
        $this->baseUrl = config('walletplug.base_url');
        $this->merchantKey = config('walletplug.merchant_key');
        $this->apiKey = config('walletplug.api_key');
        $this->environment = config('walletplug.environment'); // 'sandbox' or 'production'
    }

    public function initiatePayment(array $paymentData): array
    {
        try {
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'X-Environment' => $this->environment,
                'X-Merchant-Key' => $this->merchantKey,
                'X-API-Key' => $this->apiKey,
            ])->post("{$this->baseUrl}/api/v1/initiate-payment", $paymentData);

            if ($response->successful()) {
                return $response->json();
            }

            throw new Exception('WalletPlug API Error: Payment initiation failed');
        } catch (Exception $e) {
            throw new Exception('WalletPlug API Error: ' . $e->getMessage());
        }
    }

    public function verifyPayment(string $transactionId): array
    {
        try {
            $response = Http::withHeaders([
                'Accept' => 'application/json',
                'X-Environment' => $this->environment,
                'X-Merchant-Key' => $this->merchantKey,
                'X-API-Key' => $this->apiKey,
            ])->get("{$this->baseUrl}/api/v1/verify-payment/{$transactionId}");

            if ($response->successful()) {
                return $response->json();
            }

            throw new Exception('WalletPlug API Error: Payment verification failed');
        } catch (Exception $e) {
            throw new Exception('WalletPlug API Error: ' . $e->getMessage());
        }
    }
}

// Configuration (config/walletplug.php)
return [
    'base_url' => env('WALLETPLUG_BASE_URL', 'https://walletplug.com'),
    'environment' => env('WALLETPLUG_ENVIRONMENT', 'sandbox'), // sandbox or production
    'merchant_key' => env('WALLETPLUG_MERCHANT_KEY'), // Use appropriate prefix
    'api_key' => env('WALLETPLUG_API_KEY'), // Use appropriate prefix
];

// Usage in Controller
class PaymentController extends Controller
{
    public function initiatePayment(Request $request, WalletPlugService $walletplug)
    {
        $paymentData = [
            'payment_amount' => $request->amount,
            'currency_code' => 'USD',
            'ref_trx' => 'ORDER_' . time(),
            'description' => $request->description,
            'success_redirect' => route('payment.success'),
            'failure_url' => route('payment.failed'),
            'cancel_redirect' => route('payment.cancelled'),
            'ipn_url' => route('webhooks.walletplug'),
        ];

        try {
            $result = $walletplug->initiatePayment($paymentData);
            return redirect($result['payment_url']);
        } catch (Exception $e) {
            return back()->withErrors(['error' => $e->getMessage()]);
        }
    }
}
// Node.js Integration Service
const axios = require('axios');

class WalletPlugService {
    constructor() {
        this.baseUrl = process.env.WALLETPLUG_BASE_URL || 'https://walletplug.com';
        this.environment = process.env.WALLETPLUG_ENVIRONMENT || 'sandbox'; // sandbox or production
        this.merchantKey = process.env.WALLETPLUG_MERCHANT_KEY; // Use appropriate prefix
        this.apiKey = process.env.WALLETPLUG_API_KEY; // Use appropriate prefix
    }

    async initiatePayment(paymentData) {
        try {
            const response = await axios.post(`${this.baseUrl}/api/v1/initiate-payment`, paymentData, {
                headers: {
                    'Content-Type': 'application/json',
                    'X-Environment': this.environment,
                    'X-Merchant-Key': this.merchantKey,
                    'X-API-Key': this.apiKey
                }
            });

            return response.data;
        } catch (error) {
            throw new Error(`WalletPlug API Error: ${error.message}`);
        }
    }

    async verifyPayment(transactionId) {
        try {
            const response = await axios.get(`${this.baseUrl}/api/v1/verify-payment/${transactionId}`, {
                headers: {
                    'Accept': 'application/json',
                    'X-Environment': this.environment,
                    'X-Merchant-Key': this.merchantKey,
                    'X-API-Key': this.apiKey
                }
            });

            return response.data;
        } catch (error) {
            throw new Error(`WalletPlug API Error: ${error.message}`);
        }
    }
}

// Express.js Route Example
const express = require('express');
const app = express();
const walletplug = new WalletPlugService();

app.post('/initiate-payment', async (req, res) => {
    const paymentData = {
        payment_amount: req.body.amount,
        currency_code: 'USD',
        ref_trx: `ORDER_${Date.now()}`,
        description: req.body.description,
        success_redirect: `${req.protocol}://${req.get('host')}/payment/success`,
        failure_url: `${req.protocol}://${req.get('host')}/payment/failed`,
        cancel_redirect: `${req.protocol}://${req.get('host')}/payment/cancelled`,
        ipn_url: `${req.protocol}://${req.get('host')}/webhooks/walletplug`,
    };

    try {
        const result = await walletplug.initiatePayment(paymentData);
        res.redirect(result.payment_url);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

module.exports = WalletPlugService;
# Python/Django Integration Service
import os
import requests
from django.conf import settings

class WalletPlugService:
    def __init__(self):
        self.base_url = getattr(settings, 'WALLETPLUG_BASE_URL', 'https://walletplug.com')
        self.environment = getattr(settings, 'WALLETPLUG_ENVIRONMENT', 'sandbox')  # sandbox or production
        self.merchant_key = getattr(settings, 'WALLETPLUG_MERCHANT_KEY')  # Use appropriate prefix
        self.api_key = getattr(settings, 'WALLETPLUG_API_KEY')  # Use appropriate prefix

    def initiate_payment(self, payment_data):
        try:
            headers = {
                'Content-Type': 'application/json',
                'X-Environment': self.environment,
                'X-Merchant-Key': self.merchant_key,
                'X-API-Key': self.api_key
            }

            response = requests.post(
                f"{self.base_url}/api/v1/initiate-payment",
                headers=headers,
                json=payment_data,
                timeout=30
            )

            response.raise_for_status()
            return response.json()

        except requests.RequestException as e:
            raise Exception(f'WalletPlug API Error: {str(e)}')

    def verify_payment(self, transaction_id):
        try:
            headers = {
                'Accept': 'application/json',
                'X-Environment': self.environment,
                'X-Merchant-Key': self.merchant_key,
                'X-API-Key': self.api_key
            }

            response = requests.get(
                f"{self.base_url}/api/v1/verify-payment/{transaction_id}",
                headers=headers,
                timeout=30
            )

            response.raise_for_status()
            return response.json()

        except requests.RequestException as e:
            raise Exception(f'WalletPlug API Error: {str(e)}')

# Django Settings Configuration
WALLETPLUG_BASE_URL = 'https://walletplug.com'
WALLETPLUG_ENVIRONMENT = 'sandbox'  # Change to 'production' for live
WALLETPLUG_MERCHANT_KEY = os.environ.get('WALLETPLUG_MERCHANT_KEY')  # Use appropriate prefix
WALLETPLUG_API_KEY = os.environ.get('WALLETPLUG_API_KEY')  # Use appropriate prefix

# Django View Example
from django.shortcuts import redirect
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json

walletplug = WalletPlugService()

@csrf_exempt
def initiate_payment(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        
        payment_data = {
            'payment_amount': data['amount'],
            'currency_code': 'USD',
            'ref_trx': f'ORDER_{int(time.time())}',
            'description': data['description'],
            'success_redirect': request.build_absolute_uri('/payment/success/'),
            'failure_url': request.build_absolute_uri('/payment/failed/'),
            'cancel_redirect': request.build_absolute_uri('/payment/cancelled/'),
            'ipn_url': request.build_absolute_uri('/webhooks/walletplug/'),
        }

        try:
            result = walletplug.initiate_payment(payment_data)
            return redirect(result['payment_url'])
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)
# Environment Variables Setup
export WALLETPLUG_ENVIRONMENT="sandbox"  # or "production"
export WALLETPLUG_MERCHANT_KEY="test_merchant_your_key"  # or "merchant_your_key" for production
export WALLETPLUG_API_KEY="test_your_api_key"  # or "your_api_key" for production

# Initiate Payment
curl -X POST "https://walletplug.com/api/v1/initiate-payment" \
  -H "Content-Type: application/json" \
  -H "X-Environment: $WALLETPLUG_ENVIRONMENT" \
  -H "X-Merchant-Key: $WALLETPLUG_MERCHANT_KEY" \
  -H "X-API-Key: $WALLETPLUG_API_KEY" \
  -d '{
    "payment_amount": 250.00,
    "currency_code": "USD",
    "ref_trx": "ORDER_12345",
    "description": "Premium Subscription",
    "success_redirect": "https://yoursite.com/payment/success",
    "failure_url": "https://yoursite.com/payment/failed",
    "cancel_redirect": "https://yoursite.com/payment/cancelled",
    "ipn_url": "https://yoursite.com/api/webhooks/walletplug"
  }'

# Verify Payment
curl -X GET "https://walletplug.com/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
  -H "Accept: application/json" \
  -H "X-Environment: $WALLETPLUG_ENVIRONMENT" \
  -H "X-Merchant-Key: $WALLETPLUG_MERCHANT_KEY" \
  -H "X-API-Key: $WALLETPLUG_API_KEY"

# Environment-specific credential examples:
# Sandbox: test_merchant_xxxxx, test_api_key_xxxxx
# Production: merchant_xxxxx, api_key_xxxxx

Mobile SDKs (Android & iOS)

Official lightweight clients for integrating WalletPlug payments in native mobile apps.

Android SDK (Kotlin)
v1.0.0
  • Initiate payment, verify payment, and fetch site info.
  • Uses X-Environment, X-Merchant-Key, X-API-Key for authentication and environment selection.
iOS SDK (Swift)
v1.0.0
  • Initiate payment, verify payment, and fetch site info.
  • No external dependencies; built on URLSession.

Configuration

API Base URL
https://walletplug.com

Use the same base for both sandbox and production; environment is selected via header.

Authentication Headers
X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Android (Kotlin) Quick Start

Gradle Dependency
dependencies {
    implementation "com.squareup.okhttp3:okhttp:4.12.0"
    // org.json is available in Android SDK
}
Initialize Client
val client = WalletplugClient(
    WalletplugConfig(
        baseUrl = "https://walletplug.com",
        merchantKey = "test_merchant_key", // or live key
        apiKey = "test_api_key",           // or live key
        environment = EnvironmentMode.SANDBOX // or PRODUCTION
    )
)
Initiate Payment
val req = InitiatePaymentRequest(
    payment_amount = 250.00,
    currency_code = "USD",
    ref_trx = "ORDER_12345",
    description = "Premium Subscription",
    success_redirect = "https://yoursite.com/payment/success",
    failure_url = "https://yoursite.com/payment/failed",
    cancel_redirect = "https://yoursite.com/payment/cancelled",
    ipn_url = "https://yoursite.com/api/webhooks/walletplug",
    allow_payment_methods = listOf("card", "wallet"),
    customer_name = "John Doe",
    customer_email = "john@example.com"
)

val res = client.initiatePayment(req)
// Open res.paymentUrl in Custom Tabs/WebView to complete checkout
Verify Payment
val verification = client.verifyPayment("TXNQ5V8K2L9N3XM1")
// Handle status: success | pending | failed

iOS (Swift) Quick Start

Initialize Client
let client = WalletplugClient(
    config: WalletplugConfig(
        baseURL: URL(string: "https://walletplug.com")!,
        merchantKey: "test_merchant_key", // or live key
        apiKey: "test_api_key",           // or live key
        environment: .sandbox              // or .production
    )
)
Initiate Payment
let req = InitiatePaymentRequest(
    payment_amount: 250.0,
    currency_code: "USD",
    ref_trx: "ORDER_12345",
    description: "Premium Subscription",
    success_redirect: "https://yoursite.com/payment/success",
    failure_url: "https://yoursite.com/payment/failed",
    cancel_redirect: "https://yoursite.com/payment/cancelled",
    ipn_url: "https://yoursite.com/api/webhooks/walletplug",
    allow_payment_methods: ["card", "wallet"],
    customer_name: "John Doe",
    customer_email: "john@example.com"
)

client.initiatePayment(req) { result in
    switch result {
    case .success(let payload):
        let paymentUrl = payload.paymentUrl
        // Present SFSafariViewController / ASWebAuthenticationSession with paymentUrl
    case .failure(let error):
        print("Initiation failed: \(error)")
    }
}
Verify Payment
client.verifyPayment(trxId: "TXNQ5V8K2L9N3XM1") { result in
    print(result)
}
Security & Environment Always use HTTPS. Use sandbox credentials and X-Environment=sandbox for testing; switch to production for live transactions. Do not store API keys in source code—use secure storage (Keystore/Keychain).

React Native SDK

WalletPlug provides an official React Native SDK for building payment flows in any React Native or Expo mobile app. The SDK includes a drop-in WalletPlugCheckout WebView component, a useWalletPlug hook, typed API client, and full TypeScript support. Compatible with React Native 0.68+ and all Expo SDK versions.

WalletPlug Pay for React Native

Drop-in checkout component, payment initiation and verification client, useWalletPlug hook, and TypeScript types — everything needed to add WalletPlug payments to any React Native or Expo app in minutes.

v1.0SDK
ExpoCompatible
TSTypeScript
Latest SDK Download

Complete React Native SDK — API client, WalletPlugCheckout WebView component, useWalletPlug hook, TypeScript types, and error classes.

SDK Size: ~22 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • React Native 0.68+ or any Expo SDK
  • Node.js 16+
  • react-native-webview (peer dependency)
  • iOS 12+ / Android API 21+
  • WalletPlug Merchant Account
  • Backend server for webhook handling
Production Ready

Installation

# React Native CLI
npm install walletplug-react-native react-native-webview
cd ios && pod install

# Expo
npx expo install walletplug-react-native react-native-webview

Complete Integration Example

End-to-end payment flow using the useWalletPlug hook and WalletPlugCheckout component

import React, { useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import WalletPlug, { WalletPlugCheckout, useWalletPlug } from 'walletplug-react-native';

// Initialise once — outside your component
const wp = WalletPlug.sandbox('test_merchant_key', 'test_api_key');
// For production: WalletPlug.production('merchant_key', 'api_key')

export default function CheckoutScreen({ navigation, route }) {
  const { order } = route.params;
  const { initiatePayment, verifyPayment, loading, error, paymentResult, clearError } = useWalletPlug(wp);

  const handlePay = async () => {
    await initiatePayment({
      amount:      order.total,
      currency:    'USD',
      reference:   `ORDER_${order.id}_${Date.now()}`,
      description: `Order #${order.id}`,
      // Your backend handles the webhook — not the mobile app
      successUrl:  'walletplug://payment/success',
      failureUrl:  'walletplug://payment/failure',
      cancelUrl:   'walletplug://payment/cancel',
      webhookUrl:  'https://your-backend.com/webhook/walletplug',
    });
  };

  const handleSuccess = async (trxId) => {
    // Optionally verify the payment from your app
    const payment = await verifyPayment(trxId);
    navigation.replace('OrderConfirmation', {
      orderId: order.id,
      status:  payment?.status,
      trxId,
    });
  };

  // Show checkout WebView when paymentUrl is ready
  if (paymentResult) {
    return (
      <WalletPlugCheckout
        paymentUrl={paymentResult.paymentUrl}
        onSuccess={handleSuccess}
        onFailure={(err) => navigation.navigate('PaymentFailed', { error: err })}
        onCancel={() => navigation.goBack()}
        showCloseButton={true}
        closeButtonLabel="Cancel Payment"
      />
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Order #{order.id}</Text>
      <Text style={styles.amount}>${order.total} USD</Text>

      {error && (
        <View style={styles.errorBox}>
          <Text style={styles.errorText}>{error}</Text>
          <Button title="Try Again" onPress={clearError} />
        </View>
      )}

      <Button
        title={loading ? 'Please wait...' : 'Pay with WalletPlug'}
        onPress={handlePay}
        disabled={loading}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', padding: 24, gap: 16 },
  title:     { fontSize: 22, fontWeight: '600', textAlign: 'center' },
  amount:    { fontSize: 32, fontWeight: '700', textAlign: 'center', color: '#0066cc' },
  errorBox:  { backgroundColor: '#fef2f2', padding: 12, borderRadius: 8 },
  errorText: { color: '#dc2626', marginBottom: 8 },
});

Architecture — Mobile + Backend

For security, never store your API keys in your mobile app. The recommended architecture is:

1
Mobile app → your backend

The app sends order details (amount, currency, order ID) to your backend server.

2
Backend → WalletPlug API

Your backend calls POST /api/v1/initiate-payment with your API keys (stored securely as environment variables) and returns the payment_url to the app.

3
App shows WalletPlugCheckout

The app opens the WalletPlugCheckout component with the payment_url. Customer completes payment on WalletPlug's hosted page.

4
WalletPlug → backend webhook

WalletPlug sends the signed IPN webhook to your backend server to confirm the payment. The app can also call wp.payments.verify(trxId) for an additional check.

API Reference

WalletPlug class
Method / PropertyDescription
new WalletPlug(config)Create a new client instance
WalletPlug.sandbox(key, apiKey)Factory method for sandbox instance
WalletPlug.production(key, apiKey)Factory method for production instance
wp.payments.initiate(params)Create a payment session, returns { paymentUrl, info }
wp.payments.verify(trxId)Verify a payment by transaction ID
wp.isSandboxBoolean — true if environment is sandbox
useWalletPlug(client) hook
Return valueTypeDescription
initiatePayment(params)async functionInitiate payment, stores result in paymentResult
verifyPayment(trxId)async functionVerify a payment by trxId
loadingbooleanTrue while an API call is in progress
errorstring | nullLast error message
clearError()functionReset the error state
paymentResultobject | nullLast successful initiate result

Troubleshooting

White screen or WebView not loading

Solutions:

  • Confirm react-native-webview is installed and pod install was run (iOS)
  • Check the paymentUrl is a valid HTTPS URL — run the payment initiation again if expired
  • On Android, add android:usesCleartextTraffic="true" to your manifest if testing on HTTP in development
onSuccess / onFailure not firing

Solutions:

  • Ensure your backend sets success_redirect to walletplug://payment/success?trx_id=TXNXXXXX when calling the API
  • Confirm deep link scheme walletplug:// is registered in your app (see React Navigation / Expo setup in README)
  • Test the redirect URL manually in your device browser to confirm deep linking is configured correctly

Flutter SDK

WalletPlug provides an official Flutter SDK published on pub.dev. Accept international payments in any Flutter mobile, web, or desktop app with a drop-in WalletPlugCheckout widget, typed Dart models, a full exception hierarchy, and HMAC-SHA256 webhook verification. Compatible with Flutter 3.7+, Dart 2.19+, iOS 12+, Android API 21+, and all Dart server frameworks including Dart Frog and Shelf.

WalletPlug Flutter SDK

Drop-in WalletPlugCheckout widget, payments.initiate() / verify() / refund(), HMAC webhook verification, typed models and exceptions, auto-retry with backoff, sandbox and production factory constructors — everything needed to add payments to any Flutter app in minutes.

pub.devPublished
DartType Safe
iOS+AndroidCross-Platform
SDK Download

Complete Flutter SDK — WalletPlugCheckout widget, typed models, payments and webhooks resources, exception classes, HTTP client with retry logic, and a full example app.

SDK Size: ~28 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • Flutter 3.7+ / Dart 2.19+
  • iOS 12+ or Android API 21+
  • webview_flutter ^4.4.0 (peer dependency)
  • http ^1.2.0
  • crypto ^3.0.3
  • WalletPlug Merchant Account
pub.dev verified

SDK Features

The most complete Flutter payment SDK for international merchants on pub.dev

Drop-in Checkout Widget

WalletPlugCheckout — a full-screen WebView widget that handles loading, deep-link interception, and fires onSuccess / onFailure / onCancel callbacks automatically

Full Dart Type Safety

Every API response is a typed Dart model. Every error is a typed exception. Enums for PaymentStatus, RefundStatus, and WalletPlugEnvironment — no string comparisons

Auto Retry + Backoff

Automatic retry on network errors and 5xx responses with exponential backoff. Rate-limit retry respects the Retry-After header automatically

HMAC Webhook Verification

Constant-time HMAC-SHA256 signature verification for Dart Frog and Shelf backend use. verifyAndParse() combines verification and parsing in one call

Factory Constructors

WalletPlug.sandbox() and WalletPlug.production() for instant environment switching — no config files needed

Dart Server Ready

Works on Dart Frog, Shelf, and any Dart HTTP server. Webhook verification and payment operations run anywhere the Dart VM runs — not just Flutter mobile

Installation & Setup

1
Add dependency
dependencies:
  walletplug: ^1.0.0
flutter pub get
2
iOS — add to Info.plist
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>
3
Android — add to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
4
Initialise the SDK
import 'package:walletplug/walletplug.dart';

// Initialise once — outside your widget tree
final wp = WalletPlug(
  merchantKey: const String.fromEnvironment('WALLETPLUG_MERCHANT_KEY'),
  apiKey:      const String.fromEnvironment('WALLETPLUG_API_KEY'),
  environment: WalletPlugEnvironment.sandbox,
);
wp.setWebhookSecret(
  const String.fromEnvironment('WALLETPLUG_WEBHOOK_SECRET'),
);

Complete Payment Flow

import 'package:flutter/material.dart';
import 'package:walletplug/walletplug.dart';

final wp = WalletPlug.sandbox('test_merchant_key', 'test_api_key');

class CheckoutPage extends StatefulWidget {
  const CheckoutPage({super.key, required this.orderId, required this.amount});
  final String orderId;
  final double amount;
  @override
  State<CheckoutPage> createState() => _CheckoutPageState();
}

class _CheckoutPageState extends State<CheckoutPage> {
  bool _loading = false;
  String? _error;

  Future<void> _pay() async {
    setState(() { _loading = true; _error = null; });

    try {
      final result = await wp.payments.initiate(
        amount:      widget.amount,
        currency:    'USD',
        reference:   'ORDER_${widget.orderId}',
        description: 'Order #${widget.orderId}',
        successUrl:  'walletplug://payment/success',
        failureUrl:  'walletplug://payment/failure',
        cancelUrl:   'walletplug://payment/cancel',
        webhookUrl:  'https://your-backend.com/webhook',
        // Optional: restrict payment methods
        // allowPaymentMethods: ['card', 'mobile_money'],
      );

      if (!mounted) return;

      await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => WalletPlugCheckout(
            paymentUrl: result.paymentUrl,
            onSuccess: (trxId) async {
              Navigator.pop(context);
              // Optionally verify on-device
              final payment = await wp.payments.verify(trxId);
              if (payment.isCompleted) showSuccess(payment);
            },
            onFailure: (error) {
              Navigator.pop(context);
              setState(() => _error = error);
            },
            onCancel: () => Navigator.pop(context),
          ),
        ),
      );
    } on WalletPlugAuthException {
      setState(() => _error = 'Invalid credentials.');
    } on WalletPlugNetworkException {
      setState(() => _error = 'Network error. Check your connection.');
    } on WalletPlugException catch (e) {
      setState(() => _error = e.message);
    } finally {
      if (mounted) setState(() => _loading = false);
    }
  }

  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(title: const Text('Checkout')),
    body: Padding(
      padding: const EdgeInsets.all(24),
      child: Column(
        children: [
          if (_error != null) Text(_error!, style: const TextStyle(color: Colors.red)),
          const Spacer(),
          FilledButton.icon(
            onPressed: _loading ? null : _pay,
            icon: _loading
              ? const SizedBox(width:16,height:16,child:CircularProgressIndicator(strokeWidth:2,color:Colors.white))
              : const Icon(Icons.payment),
            label: Text(_loading ? 'Please wait…' : 'Pay \$${widget.amount.toStringAsFixed(2)}'),
            style: FilledButton.styleFrom(minimumSize: const Size.fromHeight(50)),
          ),
        ],
      ),
    ),
  );
}

Verify & Refund

// Verify a payment
final payment = await wp.payments.verify('TXNQ5V8K2L9N3XM1');
print(payment.status);       // PaymentStatus.completed
print(payment.amount);       // 99.99
print(payment.currency);     // USD
print(payment.isCompleted);  // true
print(payment.customer.name);

// Issue a partial refund
final refund = await wp.payments.refund(
  trxId:     'TXNQ5V8K2L9N3XM1',
  amount:    50.00,                      // omit for full refund
  reason:    'Customer requested refund',
  refRefund: 'REFUND_${orderId}',        // idempotency key
);
print(refund.status);    // RefundStatus.processing
print(refund.refundId);

Deep Link Configuration

Configure walletplug:// as a custom URL scheme so the checkout redirects back to your app after payment.

Android — AndroidManifest.xml
<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:scheme="walletplug"/>
</intent-filter>
iOS — Info.plist
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>walletplug</string>
    </array>
  </dict>
</array>

Production Checklist

Troubleshooting

White screen in WalletPlugCheckout

Solutions:

  • Ensure webview_flutter is in pubspec.yaml and flutter pub get has been run
  • On iOS, add NSAllowsArbitraryLoads to Info.plist
  • Confirm the paymentUrl is a valid HTTPS URL — re-call payments.initiate() if the session may have expired (60-minute timeout)
onSuccess not firing after payment

Solutions:

  • Ensure successUrl is set to walletplug://payment/success when calling payments.initiate()
  • Register the walletplug:// URL scheme in AndroidManifest.xml and Info.plist
  • Check that your backend sets the correct success_redirect URL when calling the WalletPlug API
WalletPlugAuthException on every request

Solutions:

  • Confirm Merchant ID and API Key are entered correctly — copy directly from WalletPlug Dashboard → Merchant → CONFIG
  • Ensure environment matches your key prefix — sandbox keys begin with test_
  • Check you are not accidentally swapping the Merchant ID and API Key fields

WooCommerce Integration

Advanced WalletPlug payment gateway for WooCommerce — fully mobile-responsive checkout, WooCommerce Blocks (Gutenberg) support, HPOS compatible, refund support, and enterprise-grade HMAC webhook security. Compatible with WooCommerce 7.0+ on WordPress 5.8+. Version 2.0.

WalletPlug Pay for WooCommerce v2

Mobile-responsive checkout with payment method badges, WooCommerce Blocks (Gutenberg) full support, HPOS (High-Performance Order Storage) compatible, built-in refund API support, sandbox mode indicator, and HMAC-SHA256 verified IPN webhooks.

v2.0 Plugin
Mobile Responsive
HPOS Compatible
Latest Plugin Download

Enterprise-grade WooCommerce payment gateway with modern Blocks support and dynamic branding.

Plugin Size: 63.2 KB
Version: 2.9.0
Last Updated: Jul 28, 2026

No Redirecting Version — embedded checkout: your customers pay in a secure WalletPlug window without ever leaving your store. Orders complete automatically.

Plugin Size: 16.4 KB
Version: 1.0.9
Download No-Redirect Plugin v1.0.9

Card Only Version — the card form loads directly on your checkout: no payment-method screen and no third-party branding. Orders complete automatically.

Plugin Size: 10.5 KB
Version: 1.0.0

Card Only — French Version (Version française) — the same Card Only plugin with the whole payment experience in French: the checkout shows « Carte de crédit / débit » and the card form renders in French (Numéro de carte, Date d'expiration, Code postal, Montant à payer, Payer, Annuler et retourner). Install this instead of the English Card Only plugin on French-speaking stores — both can also run side by side.

Plugin Size: 10.7 KB
Version: 1.0.0 (FR)
System Requirements
  • WordPress 5.8+
  • WooCommerce 6.0+
  • PHP 8.1+ (8.2+ Recommended)
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • WooCommerce Blocks Support
Production Ready

Advanced Features

Enterprise-grade payment processing with modern architecture

WooCommerce Blocks

Full Gutenberg checkout compatibility with React-based UI

Dynamic Branding

Auto-fetch logo, colors, and branding from WalletPlug API

Secure Webhooks

HMAC-SHA256 signature verification for payment callbacks

Compact Mobile UI

Space-efficient, responsive design for all devices

Advanced Security

Multi-header authentication with environment isolation

Test/Live Mode

Seamless sandbox testing with production deployment

Quick Installation Guide

Get started with WalletPlug WooCommerce integration in minutes

1
Download Latest Plugin

Download WalletPlug WooCommerce Gateway v2.9.0 from the download section above. This includes all latest features and security updates.

2
Install via WordPress Admin

Navigate to Plugins → Add New → Upload Plugin and select the downloaded ZIP file. The plugin will auto-extract and install.

3
Activate & Configure

Activate the plugin and go to WooCommerce → Settings → Payments → WalletPlug. Enter your API credentials and webhook secret.

4
Test Integration

Enable Test Mode, process a sandbox transaction to verify Blocks checkout, webhook delivery, and order completion.

5
Go Live

Disable test mode, ensure production API keys are configured, and start accepting real payments with full webhook processing.

API Configuration

Essential API settings for secure payment processing

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your unique merchant credentials from WalletPlug dashboard

Required
Webhook Secret

HMAC-SHA256 signature verification for secure callbacks

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment status updates and order processing

Webhook Endpoint
https://yoursite.com/wc-api/walletplug_webhook

Configure this URL in your WalletPlug merchant dashboard for automatic order updates.

Supported Events
  • Payment Success
  • Payment Failed
  • Payment Cancelled
  • Payment Pending
  • Refund Processed
  • Payment Timeout

WooCommerce Blocks Integration

Modern Gutenberg checkout with React-based payment UI

Responsive Design

Compact, mobile-optimized payment interface that adapts to any screen size.

Dynamic Branding

Automatically fetches and displays your WalletPlug branding and logos.

Security Indicators

Clear SSL and security badges to build customer trust during checkout.

Test Mode Support

Clear sandbox indicators for testing without affecting live transactions.

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug WooCommerce integration

Payment method not showing in checkout

Solutions:

  • Verify plugin is activated and enabled in WooCommerce → Settings → Payments
  • Clear browser cache and WooCommerce cache
  • Check if API credentials are correctly configured
  • Ensure SSL certificate is properly installed
401 Unauthorized API errors

Solutions:

  • Verify Merchant ID and API Key are correct
  • Ensure environment (sandbox/production) matches your credentials
  • Check that all required headers are being sent
  • Contact WalletPlug support to verify account status
Orders not updating after payment

Solutions:

  • Verify webhook URL is configured in WalletPlug dashboard
  • Check webhook secret key matches plugin configuration
  • Review WordPress error logs for webhook processing errors
  • Test webhook delivery using WalletPlug dashboard tools

Shopify Integration

Accept WalletPlug payments directly inside your Shopify store with a fully offsite payment gateway plugin — supporting sandbox testing, real-time webhook order updates, and one-click deployment.

WalletPlug Pay for Shopify

Production-ready Shopify payment plugin with offsite checkout, HMAC-verified webhooks, sandbox/production switching, and automatic order status updates.

5 Minutes Setup
99.9% Uptime
24/7 Webhook Support
Latest Plugin Download

Complete Shopify payment gateway plugin — Node.js backend with OAuth install, automatic order settlement, theme pay button, webhook handlers, and full setup guide.

Plugin Size: ~17 KB
Version: 2.0.0
Last Updated: Jul 28, 2026
System Requirements
  • Node.js 18+
  • Shopify Partner Account
  • Shopify Store (any plan)
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • HTTPS-enabled app server
Production Ready

Plugin Features

Enterprise-grade Shopify payment processing built on the WalletPlug API

Shopify Checkout UI

Native "Pay with WalletPlug" button embedded directly in the Shopify checkout

Offsite Redirect Flow

Secure redirect to WalletPlug hosted checkout — no card data touches your server

HMAC Webhook Verification

All payment callbacks cryptographically verified using SHA-256 signatures

Auto Order Updates

Orders automatically marked paid, failed, or cancelled via real-time webhooks

Sandbox / Production

Single environment toggle — test with sandbox credentials, go live with one config change

Mobile Optimised

Fully responsive checkout UI with clear sandbox indicators during testing

Payment Flow

How the Shopify plugin processes a customer payment end-to-end

1
Customer Clicks Pay

Customer selects WalletPlug Pay at Shopify checkout and clicks the payment button.

2
Payment Session Created

Plugin POSTs order details to /api/payment/initiate which calls the WalletPlug API and returns a payment_url.

3
Redirect to Checkout

Customer is redirected to the secure WalletPlug hosted checkout page to complete payment.

4
Webhook Notification

WalletPlug sends a signed IPN webhook to /api/payment/webhook with the payment result.

5
Order Updated & Redirect

Shopify order status is updated automatically, and the customer is returned to the Shopify confirmation page.

Quick Installation Guide

Get started with WalletPlug Shopify integration in minutes

1
Download & Extract Plugin

Download the ZIP above and extract it. You will find the backend/, theme-snippet/, and config files inside.

2
Configure Credentials

Copy .env.example to .env and fill in your WalletPlug Merchant ID, API Key, Webhook Secret, and Shopify App credentials.

3
Deploy the Backend

Run npm install && npm start on an HTTPS server (Railway, Render, or VPS). Copy your deployed URL — you will need it next.

4
Set Webhook URL

In your WalletPlug merchant dashboard, set the IPN/Webhook URL to: https://your-server.com/api/payment/webhook

5
Deploy to Shopify

Run shopify app deploy via the Shopify CLI, or upload the ZIP through your Shopify Partner Dashboard to register the payment extension.

6
Test & Go Live

Enable sandbox mode and process a test payment. When verified, switch WALLETPLUG_ENVIRONMENT=production and go live.

API Configuration

Environment variables required to connect the plugin to WalletPlug

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your WalletPlug credentials from Dashboard → Merchant → CONFIG

Required
Webhook Secret

Client Secret used to verify all incoming webhook signatures

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment status updates and automatic order processing

Webhook Endpoint
https://your-app-server.com/api/payment/webhook

Set this URL in your WalletPlug merchant dashboard. The plugin verifies every webhook using HMAC-SHA256 before processing.

Supported Events
  • Payment Completed
  • Payment Failed
  • Payment Cancelled
  • Payment Pending
  • Refund Processed
  • Payment Timeout

Plugin API Endpoints

Backend endpoints exposed by the Shopify plugin server

POST /api/payment/initiate

Creates a WalletPlug payment session from Shopify order data and returns the payment_url.

POST /api/payment/webhook

Receives signed IPN from WalletPlug, verifies the signature, and updates the Shopify order status.

GET /api/payment/success

Customer redirect landing page after a successful payment — optionally re-verifies before confirming to Shopify.

GET /api/payment/verify

Manually verify a transaction status by passing ?trx_id=TXNXXXXXX — useful for debugging.

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug Shopify integration

Payment button not appearing at checkout

Solutions:

  • Verify the Shopify app is installed and the extension is active in your Shopify Partner Dashboard
  • Confirm SHOPIFY_APP_URL in .env matches your live deployed server URL
  • Check that the backend server is running and reachable over HTTPS
  • Clear Shopify checkout cache and try in an incognito window
401 Unauthorized from WalletPlug API

Solutions:

  • Verify WALLETPLUG_MERCHANT_KEY and WALLETPLUG_API_KEY are correct in .env
  • Ensure WALLETPLUG_ENVIRONMENT matches the prefix of your keys (test_ for sandbox, none for production)
  • Check that all required headers are being sent by the plugin
  • Contact WalletPlug support to verify your merchant account status
Shopify orders not updating after payment

Solutions:

  • Confirm the webhook URL is correctly set in your WalletPlug merchant dashboard
  • Verify WALLETPLUG_WEBHOOK_SECRET in .env matches the Client Secret in your dashboard
  • Check your server logs at /api/payment/webhook for signature verification errors
  • Use the GET /api/payment/verify?trx_id=TXN... endpoint to manually check transaction status

OpenCart Integration

Accept WalletPlug payments directly inside your OpenCart store with a native payment gateway extension — supporting sandbox testing, HMAC-verified webhooks, and automatic order status updates.

WalletPlug Pay for OpenCart

Production-ready OpenCart 3.x / 4.x payment extension with offsite checkout, signed webhook callbacks, sandbox/production switching, and automatic order status management.

5 Minutes Setup
v1.0 Extension
HMAC Secured
Latest Extension Download

Native OpenCart payment extension — admin settings panel, checkout button, webhook handler, and HMAC signature verification all included.

Extension Size: ~18 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • OpenCart 3.x or 4.x
  • PHP 7.4+ (8.1+ Recommended)
  • cURL PHP extension enabled
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • OpenCart Extension Installer access
Production Ready

Extension Features

Enterprise-grade OpenCart payment processing built on the WalletPlug API

Native OC Extension

Installs via OpenCart's built-in Extension Installer — no manual file editing required

Offsite Redirect Flow

Secure redirect to WalletPlug hosted checkout — no sensitive card data on your server

HMAC Webhook Verification

All IPN callbacks verified with HMAC-SHA256 before order status is updated

Auto Order Status

Orders automatically set to Completed, Failed, or Cancelled based on payment outcome

Multi-Currency Support

Passes OpenCart's active currency directly to WalletPlug — no conversion needed

Geo Zone Restriction

Optionally restrict the payment method to specific countries or regions

Quick Installation Guide

Get started with WalletPlug OpenCart integration in minutes

1
Download the Extension

Download the .ocmod.zip file above. This is the ready-to-install OpenCart extension package.

2
Upload via Extension Installer

In OpenCart Admin go to Extensions → Installer, click Upload, and select the downloaded ZIP. OpenCart installs all files automatically.

3
Refresh Modifications

Go to Extensions → Modifications and click the Refresh button (top right) to apply the extension changes.

4
Activate & Configure

Go to Extensions → Extensions → Payments, find WalletPlug Pay, click Install then Edit. Enter your Merchant ID, API Key, and Webhook Secret.

5
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-store.com/index.php?route=extension/payment/walletplug/callback
6
Test & Go Live

Set Environment to Sandbox, place a test order, verify the webhook updates order status, then switch to Production to go live.

API Configuration

Settings configured in OpenCart Admin → Extensions → Payments → WalletPlug Pay → Edit

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your WalletPlug credentials from Dashboard → Merchant → CONFIG

Required
Webhook Secret

Client Secret used to verify all incoming IPN webhook signatures

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment status updates and automatic order processing

Webhook Endpoint
https://your-store.com/index.php?route=extension/payment/walletplug/callback

Set this URL in your WalletPlug merchant dashboard. Every incoming webhook is verified with HMAC-SHA256 before the order status is changed.

Order Status Mapping
  • completed → Configurable (e.g. Processing)
  • failed → Configurable (e.g. Failed)
  • cancelled → Cancelled (ID 7)
  • pending → Pending (ID 1)
  • HMAC-SHA256 verified
  • Order history comment added

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug OpenCart integration

WalletPlug Pay not showing at checkout

Solutions:

  • Go to Extensions → Extensions → Payments and confirm WalletPlug Pay is set to Enabled
  • Go to Extensions → Modifications and click Refresh
  • Clear OpenCart cache: System → Tools → Cache → Clear Cache
  • Verify your store's Geo Zone settings allow the customer's country
401 Unauthorized from WalletPlug API

Solutions:

  • Verify your Merchant ID and API Key in the extension settings
  • Make sure Environment matches your credentials — sandbox keys must have a test_ prefix
  • Confirm cURL is enabled on your server (phpinfo() → search for curl)
  • Contact WalletPlug support to verify your merchant account status
Orders not updating after payment

Solutions:

  • Confirm the webhook URL is correctly set in your WalletPlug merchant dashboard
  • Verify the Webhook Secret in your extension settings matches the Client Secret in your dashboard
  • Check OpenCart error logs: system/storage/logs/error.log
  • Ensure your store URL is publicly accessible (not localhost) so WalletPlug can reach the webhook endpoint

PrestaShop Integration

Accept WalletPlug payments natively inside your PrestaShop store — a full payment module with offsite checkout, HMAC-verified IPN webhooks, sandbox/production switching, and automatic order status management. Compatible with PrestaShop 1.7.x and 8.x.

WalletPlug Pay for PrestaShop

Production-ready PrestaShop 1.7 / 8 payment module with offsite redirect flow, cryptographically signed webhooks, configurable order statuses, and a one-click admin setup.

5 Minutes Setup
v1.0 Module
HMAC Secured
Latest Module Download

Complete PrestaShop payment module — main class, front controllers, Smarty templates, webhook handler, and admin config form.

Module Size: ~22 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • PrestaShop 1.7.x or 8.x
  • PHP 7.4+ (8.1+ Recommended)
  • cURL PHP extension enabled
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • Module Manager admin access
Production Ready

Module Features

Enterprise-grade PrestaShop payment processing built on the WalletPlug API

Native PS Module

Installs via PrestaShop Module Manager in one click — no FTP or manual file editing

Offsite Redirect Flow

Secure redirect to WalletPlug hosted checkout — no sensitive card data touches your server

HMAC Webhook Verification

All IPN callbacks cryptographically verified before any order status change

Auto Order History

Order status and history updated automatically with transaction reference and sandbox flag

Multi-Currency

Passes PrestaShop's active currency ISO code directly to WalletPlug — no conversion needed

Configurable Statuses

Map completed and failed payment outcomes to any PrestaShop order status you choose

Quick Installation Guide

Get started with WalletPlug PrestaShop integration in minutes

1
Download the Module

Download the .zip file above. It contains the complete walletplug/ module folder ready to upload.

2
Upload via Module Manager

In PrestaShop Admin go to Modules → Module Manager → Upload a module and select the downloaded ZIP. PrestaShop installs all files automatically.

3
Configure the Module

Click Configure on WalletPlug Pay. Enter your Merchant ID, API Key, and Webhook Secret from your WalletPlug dashboard. Choose your environment.

4
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-store.com/module/walletplug/webhook
5
Test Integration

Set Environment to Sandbox and place a test order using the demo credentials. Verify the webhook updates order status correctly.

6
Go Live

Switch Environment to Production, replace sandbox keys with live credentials, and start accepting real payments.

API Configuration

Settings configured in PrestaShop Admin → Modules → WalletPlug Pay → Configure

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your WalletPlug credentials from Dashboard → Merchant → CONFIG

Required
Webhook Secret

Client Secret for HMAC-SHA256 webhook signature verification

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment notifications with automatic PrestaShop order updates

Webhook Endpoint
https://your-store.com/module/walletplug/webhook

Set this URL in your WalletPlug merchant dashboard. The module verifies every request using HMAC-SHA256 before processing the order update.

Order Status Mapping
  • completed → Configurable (e.g. Payment accepted)
  • failed → Configurable (e.g. Payment error)
  • cancelled → PS_OS_CANCELED
  • pending → PS_OS_BANKWIRE (Awaiting)
  • HMAC-SHA256 verified
  • Order history entry added

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug PrestaShop integration

WalletPlug Pay not visible at checkout

Solutions:

  • Confirm the module is Enabled in Modules → Module Manager
  • Clear PrestaShop cache: Advanced Parameters → Performance → Clear cache
  • Verify your store is running over HTTPS — payment modules require SSL
  • Check module hooks are correctly registered: Design → Positions
401 Unauthorized from WalletPlug API

Solutions:

  • Verify Merchant ID and API Key in the module configuration
  • Check Environment matches your key prefix — sandbox keys must start with test_
  • Ensure cURL is enabled on your server
  • Contact WalletPlug support to verify your account status
Orders not updating after payment

Solutions:

  • Confirm the webhook URL is set correctly in your WalletPlug merchant dashboard
  • Verify the Webhook Secret matches the Client Secret in your dashboard
  • Check PrestaShop logs: Advanced Parameters → Logs
  • Ensure your store is publicly accessible (not localhost) so WalletPlug can POST to the webhook endpoint

Magento / Adobe Commerce Integration

Accept WalletPlug payments natively inside your Magento 2 or Adobe Commerce store — a full payment module with offsite checkout, HMAC-verified IPN webhooks, encrypted credential storage, and automatic order state management. Compatible with Magento 2.4.x and Adobe Commerce 2.4.x.

WalletPlug Pay for Magento 2

Enterprise-grade Magento 2 / Adobe Commerce payment module with offsite redirect, cryptographically signed webhooks, Magento DI architecture, and encrypted API credential storage in the admin.

10 Minutes Setup
v1.0 Module
HMAC Secured
Latest Module Download

Complete Magento 2 payment module — registration, DI config, payment model, front controllers, webhook handler, and admin system config.

Module Size: ~28 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • Magento 2.4.x or Adobe Commerce 2.4.x
  • PHP 8.1+ (8.2+ Recommended)
  • Composer 2.x
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • SSH / CLI access to run bin/magento
Production Ready

Module Features

Enterprise-grade Magento 2 payment processing built on the WalletPlug API

Native M2 Architecture

Built with Magento DI, virtual types, and payment gateway abstractions — no hacks or workarounds

Offsite Redirect Flow

Customer redirected to WalletPlug hosted checkout — no card data on your servers

HMAC Webhook Verification

All IPN callbacks cryptographically verified with HMAC-SHA256 before order state changes

Encrypted Credentials

Merchant ID, API Key, and Webhook Secret stored encrypted in Magento config — never plaintext

Multi-Store / Multi-Currency

Configurable per website and store view — supports all Magento currency codes natively

Country Restriction

Restrict the payment method to specific countries using Magento's native allowed countries config

Quick Installation Guide

Get started with WalletPlug Magento 2 integration in minutes

1
Download & Extract Module

Download the ZIP above and extract it. Copy the app/code/WalletPlug/Pay/ folder into your Magento root at the same path.

2
Enable via CLI

SSH into your server and run:

bin/magento module:enable WalletPlug_Pay
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
3
Configure in Admin

Go to Stores → Configuration → Sales → Payment Methods → WalletPlug Pay. Set Enabled = Yes, enter your Merchant ID, API Key, Webhook Secret, and choose your Environment.

4
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-store.com/walletplug/webhook/index
5
Test Integration

Set Environment to Sandbox, place a test order, and verify that the webhook correctly updates the Magento order state to Processing.

6
Go Live

Switch Environment to Production, replace sandbox credentials with live keys, flush the cache, and start accepting real payments.

API Configuration

Settings configured in Stores → Configuration → Sales → Payment Methods → WalletPlug Pay

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your WalletPlug credentials — stored encrypted in Magento config

Required
Webhook Secret

Client Secret for HMAC-SHA256 signature verification — stored encrypted

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment notifications with automatic Magento order state updates

Webhook Endpoint
https://your-store.com/walletplug/webhook/index

Set this URL in your WalletPlug merchant dashboard. Magento CSRF validation is bypassed for this route — all security is handled by HMAC-SHA256 signature verification.

Order State Mapping
  • completed → STATE_PROCESSING
  • failed → STATE_CANCELED
  • cancelled → STATE_CANCELED
  • pending → Comment added only
  • HMAC-SHA256 verified
  • Order history comment added

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug Magento 2 integration

WalletPlug Pay not visible at checkout

Solutions:

  • Confirm module is enabled: bin/magento module:status WalletPlug_Pay
  • Set Enabled = Yes in Stores → Configuration → Payment Methods → WalletPlug Pay
  • Run bin/magento cache:flush and bin/magento setup:di:compile
  • Check that your store currency is supported by WalletPlug
401 Unauthorized from WalletPlug API

Solutions:

  • Re-save credentials in admin — encrypted fields sometimes need re-entry after deploy
  • Ensure Environment matches your key prefix — sandbox keys must start with test_
  • Check var/log/system.log and var/log/exception.log for detailed errors
  • Contact WalletPlug support to verify your merchant account status
Orders not updating after payment

Solutions:

  • Confirm the webhook URL is publicly accessible — Magento in developer mode may block it
  • Verify Webhook Secret matches Client Secret in your WalletPlug dashboard
  • Check var/log/system.log for [WalletPlug] entries
  • Use GET /api/v1/verify-payment/{trxId} to manually confirm transaction status

BigCommerce Integration

Accept WalletPlug payments inside your BigCommerce store via a hosted app — OAuth-based installation, HMAC-verified webhooks, automatic order status updates, and a lightweight checkout script injected via BigCommerce Script Manager.

WalletPlug Pay for BigCommerce

Production-ready BigCommerce payment app with OAuth store installation, offsite WalletPlug checkout, HMAC-signed IPN webhooks, and a storefront Script Manager injection — no theme editing required.

10 Minutes Setup
v1.0 App
HMAC Secured
Latest App Download

Complete BigCommerce app — Express backend, OAuth auth flow, WalletPlug payment service, BigCommerce API service, webhook handler, and storefront checkout script.

App Size: ~20 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • BigCommerce store (any paid plan)
  • BigCommerce Developer Portal account
  • Node.js 18+ on your app server
  • SSL Certificate on app server (Required)
  • WalletPlug Merchant Account
  • Script Manager access (Stencil theme)
Production Ready

App Features

Enterprise-grade BigCommerce payment processing built on the WalletPlug API

OAuth App Install

One-click installation from BigCommerce App Marketplace using standard OAuth 2.0 flow

Offsite Redirect Flow

Secure redirect to WalletPlug hosted checkout — no sensitive card data on your servers

HMAC Webhook Verification

All IPN callbacks cryptographically verified with HMAC-SHA256 before order updates

Script Manager Injection

Checkout button injected via BigCommerce Script Manager — no theme file editing needed

Auto Order Updates

BigCommerce orders automatically updated to Processing, Awaiting Payment, or Cancelled

Multi-Currency

Passes BigCommerce's active currency code directly to WalletPlug — no conversion needed

Quick Installation Guide

Get started with WalletPlug BigCommerce integration in minutes

1
Register a BigCommerce App

Go to devtools.bigcommerce.com, create a new app, and set the Auth / Load / Uninstall callback URLs to your deployed server. Copy your Client ID and Client Secret.

2
Download & Configure

Download the ZIP above, extract it, copy .env.example.env, and fill in your BigCommerce App credentials and WalletPlug API keys.

3
Deploy the App Server

Run npm install && npm start on an HTTPS server. The app must be publicly accessible for BigCommerce OAuth and WalletPlug webhooks to reach it.

4
Install App on Your Store

In BigCommerce Admin go to Apps → My Apps → My Draft Apps, find your app, and click Install. The OAuth flow will exchange credentials automatically.

5
Add Checkout Script

In BigCommerce Admin go to Storefront → Script Manager → Add Script. Set Location to Footer, Pages to Checkout, then paste the contents of public/checkout-script.js — updating APP_URL to your server.

6
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-app-server.com/api/payment/webhook
7
Test & Go Live

Set WALLETPLUG_ENVIRONMENT=sandbox and place a test order. When verified, switch to production keys and go live.

API Configuration

Environment variables configured in your app server .env file

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your WalletPlug credentials from Dashboard → Merchant → CONFIG

Required
Webhook Secret

Client Secret for HMAC-SHA256 webhook signature verification

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment notifications with automatic BigCommerce order status updates

Webhook Endpoint
https://your-app-server.com/api/payment/webhook

Set this URL in your WalletPlug merchant dashboard. All signatures are verified with HMAC-SHA256 before any order update is applied.

BigCommerce Order Status Mapping
  • completed → Processing (ID 2)
  • failed → Awaiting Payment (ID 13)
  • cancelled → Cancelled (ID 4)
  • pending → Pending (ID 1)
  • HMAC-SHA256 verified
  • BigCommerce V2 API updated

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug BigCommerce integration

WalletPlug Pay button not showing at checkout

Solutions:

  • Confirm the script was added in Storefront → Script Manager with location Footer and pages Checkout
  • Verify APP_URL inside checkout-script.js points to your live server (not localhost)
  • Check your browser console for JavaScript errors on the checkout page
  • Ensure your server is reachable over HTTPS from the customer's browser
401 Unauthorized from WalletPlug API

Solutions:

  • Verify WALLETPLUG_MERCHANT_KEY and WALLETPLUG_API_KEY are correct in .env
  • Ensure WALLETPLUG_ENVIRONMENT matches the prefix of your keys — sandbox keys need test_ prefix
  • Restart the app server after changing .env values
  • Contact WalletPlug support to verify your merchant account status
BigCommerce orders not updating after payment

Solutions:

  • Confirm the webhook URL is set correctly in your WalletPlug merchant dashboard
  • Verify WALLETPLUG_WEBHOOK_SECRET in .env matches the Client Secret in your dashboard
  • Check your app server logs for [WalletPlug] Webhook entries and any signature errors
  • Use GET /api/payment/verify?trx_id=TXN... to manually check a transaction status

Easy Digital Downloads Integration

Accept WalletPlug payments inside your Easy Digital Downloads store — a native WordPress payment gateway with offsite checkout, HMAC-verified IPN webhooks, automatic payment status updates, and purchase receipt emails triggered on completion. Compatible with EDD 3.0+ on WordPress 5.8+.

WalletPlug Pay for Easy Digital Downloads

Production-ready EDD payment gateway plugin with offsite redirect checkout, HMAC-signed IPN webhooks, configurable environments, and automatic EDD payment status lifecycle management.

5 Minutes Setup
v1.0 Plugin
HMAC Secured
Latest Plugin Download

Complete EDD payment gateway plugin — gateway registration, checkout flow, HMAC webhook handler, admin settings, and checkout form template.

Plugin Size: ~18 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • Easy Digital Downloads 3.0+
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ Recommended)
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • WordPress permalink structure enabled
Production Ready

Plugin Features

Enterprise-grade EDD payment processing built on the WalletPlug API

Native EDD Gateway

Registers as a standard EDD payment gateway — appears in Active Gateways list alongside other methods

Offsite Redirect Flow

Secure redirect to WalletPlug hosted checkout — no card data stored on your WordPress site

HMAC Webhook Verification

All IPN callbacks verified with HMAC-SHA256 before any EDD payment record is updated

Receipt Emails on Completion

EDD edd_complete_purchase hook fires on webhook completion — purchase receipts sent automatically

Full Payment Lifecycle

Pending → Complete / Failed / Abandoned — all EDD statuses mapped to WalletPlug payment outcomes

Multi-Currency

Uses EDD's active currency directly — no conversion or additional configuration needed

Quick Installation Guide

Get started with WalletPlug Easy Digital Downloads integration in minutes

1
Download & Upload Plugin

Download the ZIP above. In WordPress Admin go to Plugins → Add New → Upload Plugin, select the ZIP, and click Install Now.

2
Activate & Enable Gateway

Activate the plugin, then go to Downloads → Settings → Payment Gateways → Active Gateways and check WalletPlug Pay.

3
Configure Credentials

Go to Downloads → Settings → Payment Gateways → WalletPlug Pay. Enter your Merchant ID, API Key, and Webhook Secret, then choose your Environment.

4
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-site.com/?walletplug_action=webhook

This URL is also shown in the plugin settings page for easy copying.

5
Test Integration

Set Environment to Sandbox and complete a test purchase. Verify the webhook updates the EDD payment to Complete and the receipt email is sent.

6
Go Live

Switch Environment to Production, replace sandbox keys with live credentials, and start accepting real payments.

API Configuration

Settings configured in Downloads → Settings → Payment Gateways → WalletPlug Pay

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your WalletPlug credentials from Dashboard → Merchant → CONFIG

Required
Webhook Secret

Client Secret for HMAC-SHA256 webhook signature verification

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment notifications with automatic EDD payment status lifecycle management

Webhook Endpoint
https://your-site.com/?walletplug_action=webhook

Set this URL in your WalletPlug merchant dashboard. Every request is HMAC-SHA256 verified before any EDD payment record is modified.

EDD Payment Status Mapping
  • completed → Complete + receipt email
  • failed → Failed
  • cancelled → Abandoned
  • pending → Note added only
  • HMAC-SHA256 verified
  • Payment note logged per event

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug Easy Digital Downloads integration

WalletPlug Pay not showing at checkout

Solutions:

  • Go to Downloads → Settings → Payment Gateways → Active Gateways and tick WalletPlug Pay
  • Confirm the plugin is activated in WordPress → Plugins
  • Verify Easy Digital Downloads 3.0+ is installed and active
  • Clear any caching plugin cache and check again
401 Unauthorized from WalletPlug API

Solutions:

  • Re-enter your Merchant ID and API Key in Downloads → Settings → Payment Gateways → WalletPlug Pay
  • Verify Environment matches your key prefix — sandbox keys must start with test_
  • Check WordPress debug log (wp-content/debug.log) for detailed error messages
  • Contact WalletPlug support to verify your merchant account status
EDD payment not updating to Complete after payment

Solutions:

  • Confirm the webhook URL /?walletplug_action=webhook is set in your WalletPlug merchant dashboard
  • Verify the Webhook Secret matches the Client Secret in your dashboard
  • Ensure your site is publicly accessible — webhooks cannot reach localhost or staging behind HTTP auth
  • Check WordPress debug log and PHP error log for [WalletPlug EDD] entries

CS-Cart / Multi-Vendor Integration

Accept WalletPlug payments natively inside your CS-Cart or Multi-Vendor store — a full payment addon with offsite checkout, HMAC-verified IPN webhooks, automatic order status updates, and Multi-Vendor marketplace support. Compatible with CS-Cart 4.14+ and Multi-Vendor 4.14+.

WalletPlug Pay for CS-Cart

Production-ready CS-Cart 4.x / Multi-Vendor payment addon with offsite redirect flow, HMAC-signed IPN webhooks, CS-Cart order status lifecycle management, and full Multi-Vendor marketplace compatibility.

5 Minutes Setup
v1.0 Addon
HMAC Secured
Latest Addon Download

Complete CS-Cart payment addon — addon manifest, payment processor, frontend/backend controllers, Smarty checkout template, webhook handler, and language strings.

Addon Size: ~20 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • CS-Cart 4.14+ or Multi-Vendor 4.14+
  • PHP 7.4+ (8.1+ Recommended)
  • cURL PHP extension enabled
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • Responsive theme (default CS-Cart theme)
Production Ready

Addon Features

Enterprise-grade CS-Cart payment processing built on the WalletPlug API

Native CS-Cart Addon

Installs via CS-Cart's built-in addon manager — appears in Payment Methods alongside all other gateways

Offsite Redirect Flow

Secure redirect to WalletPlug hosted checkout — no card data touches your CS-Cart server

HMAC Webhook Verification

All IPN callbacks verified with HMAC-SHA256 before any CS-Cart order status is updated

Multi-Vendor Support

Works out of the box with CS-Cart Multi-Vendor — process payments across all vendor storefronts

Auto Order Status

Orders automatically set to Processed, Failed, or Declined based on WalletPlug payment outcome

Multi-Currency

Uses CS-Cart's primary currency directly — no extra conversion or configuration required

Quick Installation Guide

Get started with WalletPlug CS-Cart integration in minutes

1
Download the Addon

Download the ZIP above. It contains the complete addon structure ready for upload.

2
Install via Addon Manager

In CS-Cart Admin go to Add-ons → Manage Add-ons → Upload and Install (the + button), select the downloaded ZIP, and CS-Cart installs it automatically.

3
Add Payment Method

Go to Administration → Payment Methods → Add Payment Method. Set the Processor dropdown to WalletPlug Pay and give it a name customers will see at checkout.

4
Configure Credentials

In the payment method settings enter your Merchant ID, API Key, and Webhook Secret from your WalletPlug dashboard. Choose your environment and click Save.

5
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-store.com/index.php?dispatch=payment_notification.walletplug_pay_webhook
6
Test Integration

Set Environment to Sandbox and place a test order. Verify the payment completes and the CS-Cart order status updates to Processed.

7
Go Live

Switch Environment to Production, replace sandbox credentials with live keys, and start accepting real payments.

API Configuration

Settings configured in Administration → Payment Methods → WalletPlug Pay

API Base URL

https://walletplug.com

Auto-configured
Merchant ID & API Key

Your WalletPlug credentials from Dashboard → Merchant → CONFIG

Required
Webhook Secret

Client Secret for HMAC-SHA256 webhook signature verification

Recommended
Authentication Headers

Required headers for all WalletPlug API requests:

X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json

Webhook Configuration

Real-time payment notifications with automatic CS-Cart order status updates

Webhook Endpoint
https://your-store.com/index.php?dispatch=payment_notification.walletplug_pay_webhook

Set this URL in your WalletPlug merchant dashboard. Every request is HMAC-SHA256 verified before any CS-Cart order status is modified.

CS-Cart Order Status Mapping
  • completed → Processed (P)
  • failed → Failed (F)
  • cancelled → Declined (D)
  • pending → Note added, status unchanged
  • HMAC-SHA256 verified
  • CS-Cart event log updated

Production Deployment Checklist

Ensure everything is configured correctly before going live

Technical Requirements
API Configuration
Final Verification

Troubleshooting

Common issues and solutions for WalletPlug CS-Cart integration

WalletPlug Pay not appearing at checkout

Solutions:

  • Confirm the addon is Active in Add-ons → Manage Add-ons
  • Confirm the payment method is enabled in Administration → Payment Methods
  • Check that the payment method is not restricted to a specific user group that excludes the test customer
  • Clear the CS-Cart cache: Administration → Storage → Clear cache
401 Unauthorized from WalletPlug API

Solutions:

  • Re-enter your Merchant ID and API Key in the payment method settings
  • Check Environment matches your key prefix — sandbox keys must start with test_
  • Confirm cURL is enabled on your server
  • Contact WalletPlug support to verify your merchant account status
CS-Cart orders not updating after payment

Solutions:

  • Confirm the webhook URL is set correctly in your WalletPlug merchant dashboard
  • Verify the Webhook Secret matches the Client Secret in your dashboard
  • Check CS-Cart logs: Administration → Logs → Events — filter by walletplug_pay
  • Ensure your store is publicly accessible — webhooks cannot reach a store behind HTTP authentication or on localhost

Gravity Forms Integration

Accept WalletPlug payments inside any Gravity Forms form — donations, order forms, event registrations, membership signups, and bookings. A native Gravity Forms payment addon built on the GF Payment Addon Framework with HMAC-verified webhooks, per-form feed configuration, and automatic GF entry status management. Compatible with Gravity Forms 2.6+ on WordPress 5.8+.

WalletPlug Pay for Gravity Forms

Production-ready Gravity Forms payment addon — GF Payment Addon Framework integration, per-form feed configuration, offsite checkout, HMAC-signed IPN webhooks, and GF entry payment lifecycle management including receipt email triggers.

5Minutes Setup
v1.0Addon
HMACSecured
Latest Plugin Download

Complete Gravity Forms payment addon — GF framework integration, per-form feeds, API class, IPN webhook handler, and return URL management.

Plugin Size: ~18 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • Gravity Forms 2.6+
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ Recommended)
  • SSL Certificate (Required)
  • WalletPlug Merchant Account
  • Gravity Forms Developer or Elite license recommended
Production Ready

Plugin Features

Purpose-built for Gravity Forms using the official GF Payment Addon Framework

GF Payment Framework

Built on Gravity Forms' official Payment Addon Framework — fully integrated with GF's entry management, notifications, and confirmations

Per-Form Feed Config

Configure separate payment feeds per form — map payment amount fields, billing info, and conditional logic independently for each form

GF Receipt Emails

On completed webhook, GF's gform_post_payment_completed hook fires — all configured notifications and confirmations send automatically

Any Form Type

Works with donation forms, order forms, event registrations, memberships, bookings — any GF form with a payment/price field

HMAC Webhook Verification

All IPN callbacks verified with HMAC-SHA256 before any GF entry status is updated

Conditional Logic

Use GF conditional logic to show WalletPlug Pay only for specific form submissions or customer types

Quick Installation Guide

Get started with WalletPlug Gravity Forms integration in minutes

1
Install & Activate Plugin

Upload and activate the plugin via WordPress Admin → Plugins → Add New → Upload.

2
Configure Global Settings

Go to Forms → Settings → WalletPlug Pay. Enter your Merchant ID, API Key, Webhook Secret, and choose your Environment.

3
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-site.com/?walletplug_gf_action=webhook
4
Create a Payment Feed

Edit your form → go to Settings → WalletPlug Pay → Add New. Map your payment amount field, billing info, and configure any conditional logic.

5
Test & Go Live

Submit a test form entry in Sandbox mode. Verify the entry status updates to Paid after the webhook fires, then switch to Production.

Webhook Configuration

Real-time payment notifications with automatic GF entry status management

Webhook Endpoint
https://your-site.com/?walletplug_gf_action=webhook
GF Entry Status Mapping
  • completed → Paid + GF notifications sent
  • failed → Failed
  • cancelled → Voided
  • pending → Processing
  • HMAC-SHA256 verified
  • GF entry note added per event

Troubleshooting

Common issues and solutions for WalletPlug Gravity Forms integration

WalletPlug Pay not appearing on the form

Solutions:

  • Confirm the plugin is active and a payment feed has been created for the form
  • Ensure the form has at least one Product, Price, or Total field mapped in the feed
  • Check any conditional logic on the feed — it may be preventing WalletPlug Pay from showing
GF entry status stuck on Processing after payment

Solutions:

  • Confirm the webhook URL is set in your WalletPlug dashboard
  • Check GF Logging: Forms → Settings → Logging — enable logging and re-test
  • Verify your Webhook Secret matches the Client Secret in your WalletPlug dashboard
  • Ensure your site is publicly accessible — webhooks cannot reach sites behind HTTP auth

Ecwid / Lightspeed E-Series Integration

Accept WalletPlug payments in your Ecwid or Lightspeed E-Series store using Ecwid's Custom Payment Method API. The plugin runs as a WordPress companion app — no coding required, full HMAC-verified webhook support, and automatic Ecwid order status updates via the Ecwid REST API. Compatible with Ecwid Free, Venture, Business, and Unlimited plans and Lightspeed E-Series.

WalletPlug Pay for Ecwid / Lightspeed E-Series

Production-ready Ecwid Custom Payment integration — WordPress companion plugin, offsite checkout via WalletPlug, HMAC-signed IPN webhooks, and Ecwid REST API order updates (PAID / DECLINED / CANCELLED).

10Minutes Setup
v1.0Plugin
HMACSecured
Latest Plugin Download

Complete Ecwid / Lightspeed integration — WordPress plugin with settings admin page, payment initiation handler, IPN webhook, and Ecwid REST API order update.

Plugin Size: ~18 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
System Requirements
  • Ecwid Free / Venture / Business / Unlimited
  • OR Lightspeed E-Series (any plan)
  • WordPress 5.8+ (for companion plugin)
  • PHP 7.4+ on WordPress server
  • SSL Certificate on WordPress site (Required)
  • WalletPlug Merchant Account
Production Ready

Plugin Features

Built on Ecwid's Custom Payment API for seamless checkout integration

Ecwid Custom Payment API

Uses Ecwid's official Custom Payment Method — no theme modification, no JavaScript injection required

Offsite Redirect Flow

Ecwid redirects customer to WalletPlug hosted checkout — no card data on your server

Ecwid REST API Updates

After payment, the Ecwid REST API is called to update order status — PAID, DECLINED, or CANCELLED

HMAC Webhook Verification

All IPN callbacks verified with HMAC-SHA256 before any Ecwid order is updated

WordPress Admin Settings

Clean admin settings page — configure credentials, environment, and payment methods without touching code

Multi-Currency

Uses Ecwid's active store currency — no conversion or extra configuration needed

Quick Installation Guide

Two-part setup — WordPress plugin + Ecwid custom payment method

1
Install WordPress Plugin

Upload and activate the plugin via WordPress Admin → Plugins → Add New → Upload. This provides the payment endpoint and webhook handler.

2
Configure Credentials

Go to WordPress Admin → Settings → WalletPlug Ecwid. Enter your Ecwid Store ID, WalletPlug Merchant ID, API Key, Webhook Secret, and Environment.

3
Add Custom Payment in Ecwid

In Ecwid Admin go to Settings → Payment → Add Payment Method → Other. Name it WalletPlug Pay and set the Payment URL to:

https://your-wp-site.com/?walletplug_ecwid_action=pay
4
Set Webhook URL

In your WalletPlug merchant dashboard set the IPN/Webhook URL to:

https://your-wp-site.com/?walletplug_ecwid_action=webhook
5
Test in Sandbox

Place a test order in Ecwid, pay with sandbox credentials, and verify the Ecwid order status updates to PAID.

6
Go Live

Switch Environment to Production, replace sandbox credentials, and start accepting real payments.

Webhook Configuration

Real-time payment notifications with automatic Ecwid order status updates

Webhook Endpoint
https://your-wp-site.com/?walletplug_ecwid_action=webhook

Set this URL in your WalletPlug merchant dashboard. All requests are HMAC-SHA256 verified, then the Ecwid REST API is called to update the order status.

Ecwid Payment Status Mapping
  • completed → PAID
  • failed → DECLINED
  • cancelled → CANCELLED
  • pending → AWAITING_PAYMENT
  • HMAC-SHA256 verified
  • Ecwid REST API v3 updated

Troubleshooting

Common issues and solutions for WalletPlug Ecwid integration

WalletPlug Pay not showing at Ecwid checkout

Solutions:

  • Confirm the Custom Payment Method is enabled in Ecwid Admin → Settings → Payment
  • Verify the Payment URL is correctly set to your WordPress site URL with ?walletplug_ecwid_action=pay
  • Ensure the WordPress plugin is activated and the WordPress site is publicly accessible
Ecwid order status not updating after payment

Solutions:

  • Confirm the webhook URL is set in your WalletPlug dashboard
  • Verify your Ecwid Store ID is correctly entered in the WordPress plugin settings
  • Check WordPress PHP error log for [WalletPlug Ecwid] entries
  • Ensure the Ecwid API Key (secret key) has write permissions for orders

WHMCS Integration

Integrate WalletPlug as an offsite/redirect payment gateway in WHMCS with secure webhooks and API-compatible payloads.

Production-ready WHMCS Module

Redirect flow, HMAC-SHA256 webhook verification, and the same API contract used by WooCommerce integration.

5 Minutes Setup
v1.0 Module
HMAC Secured
Latest Module Download

Production-ready WHMCS payment gateway module for quick install.

About the WHMCS Gateway Module

WalletPlug's WHMCS payment gateway module enables a secure offsite checkout for WHMCS invoices, with verified callbacks to automatically mark invoices as Paid, Cancelled, or Failed.

  • HMAC-SHA256 signature verification on all callbacks
  • Sandbox and Production environments with a single toggle
  • Merchant ID, API Key, and Webhook Secret managed from the WalletPlug dashboard
  • Consistent API contract shared with our WooCommerce integration
  • Clear redirect URLs for success, failure, and cancel states
  • Multi-currency friendly; amounts and currency codes are passed through transparently

Plugin Description (WHMCS)

This is the short description that appears in WHMCS after you install/activate the gateway module.

WalletPlug is a secure offsite (redirect) payment gateway for WHMCS. It redirects customers to WalletPlug checkout and updates invoice statuses automatically via signed webhooks. Configure your Merchant ID, API Key, Webhook Secret and toggle Test Mode from the module settings.

  • HMAC-SHA256 verification on callbacks to prevent tampering
  • Automatic invoice status updates (Paid, Cancelled, Failed)
  • Clear return URLs for success, failure and cancel
  • Sandbox/Production switching via Test Mode
  • Multi-currency ready; amounts and currency codes preserved

Callback (Webhook) Path

{your_whmcs_url}/modules/gateways/callback/walletplug.php

Quick Installation Guide

Install the WHMCS gateway module and start accepting payments via WalletPlug.

1
Download & Extract

After downloading, upload the ZIP to your WHMCS root and extract. Ensure these files exist:

/modules/gateways/walletplug.php
/modules/gateways/callback/walletplug.php

Then proceed to activation and configuration steps below.

2
Activate in WHMCS

Go to WHMCS → Setup → Payments → Payment Gateways, select walletplug, and click Activate.

3
Configure Credentials
  • API Base URL: https://walletplug.com
  • Merchant ID & API Key: From WalletPlug dashboard
  • Webhook Secret Key: From WalletPlug dashboard
  • Test Mode: Enable for sandbox

Click Save Changes.

4
Set Webhook (Callback)

Set the webhook URL in your WalletPlug merchant dashboard:

https://walletplug.com/modules/gateways/callback/walletplug.php

Ensure the same Webhook Secret Key is set in both systems.

5
Test & Go Live

Use sandbox to test an invoice payment. When verified, disable Test Mode to start live processing.

API Contract

Essential headers and payload example.

Authentication Headers
X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json
Initiate Payment

POST https://walletplug.com/api/v1/initiate-payment

{
  "payment_amount": 100.00,
  "currency_code": "USD",
  "ref_trx": "{invoiceId}",
  "description": "Invoice #{invoiceId}",
  "success_redirect": "{whmcs}/viewinvoice.php?id={invoiceId}",
  "failure_url": "{whmcs}/viewinvoice.php?id={invoiceId}",
  "cancel_redirect": "{whmcs}/viewinvoice.php?id={invoiceId}",
  "ipn_url": "{whmcs}/modules/gateways/callback/walletplug.php"
}

Webhook signature: X-Signature: sha256={hmac} (HMAC-SHA256 of raw JSON using your secret)

Troubleshooting

Quick fixes for common integration issues

  • Module not visible: Ensure files exist in /modules/gateways/ and clear template cache.
  • 401 Unauthorized: Check Merchant ID, API Key, Base URL, and X-Environment header.
  • Invoice not paid: Verify webhook URL and secret; inspect Billing → Gateway Log.

Bubble.io Integration

Accept WalletPlug payments inside your Bubble no-code app using three server-side actions — Initiate Payment, Verify Payment, and Refund Payment. A lightweight companion server handles HMAC-verified webhook delivery to your Bubble Data API. Compatible with all Bubble plans.

WalletPlug Pay for Bubble.io

3 server-side actions (Initiate, Verify, Refund) plus a Node.js companion server for HMAC-verified IPN webhooks that write directly to your Bubble Data API — triggering your workflows automatically on every payment event.

3Actions
0Code in Bubble
HMACSecured
Latest Plugin Download

Complete Bubble.io plugin package — plugin manifest JSON, 3 server-side action files, companion server source, and full setup guide.

~18 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • Any Bubble.io plan (Free and up)
  • Bubble Data API enabled (for webhooks)
  • Node.js 16+ for companion server
  • Free host: Render.com or Railway.app
  • WalletPlug Merchant Account
How it works Bubble server-side actions call the WalletPlug API with your credentials kept secure on the server — never exposed to the browser. A companion server (free to host on Render or Railway) receives HMAC-signed IPN notifications, verifies them, and creates records in your Bubble database so your backend workflows trigger automatically.

The 3 Server-Side Actions

Initiate Payment

Creates a payment session and returns a hosted checkout URL. Redirect the user to this URL.

Key inputs: amount, currency, reference, success_url, failure_url, cancel_url, webhook_url

Returns: payment_url, ref_trx, is_sandbox, error_message

Verify Payment

Checks the current status of a payment by transaction ID. Run on your success page after redirect.

Input: trx_id

Returns: status, amount, currency, customer_name, customer_email, is_completed, error_message

Refund Payment

Issues a full or partial refund on a completed transaction. Leave amount blank for full refund.

Inputs: trx_id, amount (optional), reason, ref_refund

Returns: refund_id, status, error_message

Setup Guide

Three parts — Bubble plugin editor, Bubble app data, companion server

A1
Create the Bubble Plugin

In Bubble go to Plugins → Plugin Editor → New Plugin, name it WalletPlug Pay. Under Shared → Plugin Settings add 4 fields: merchant_key, api_key (private), webhook_secret (private), environment.

A2
Add the 3 Server-Side Actions

Click Add a server-side action for each of the 3 actions. Paste the JavaScript from the plugin/actions/ folder and add the input fields and return value fields as defined in plugin/plugin.json.

A3
Install Plugin & Enter Credentials

Install the plugin into your app. Go to Plugins → WalletPlug Pay and enter your Merchant ID, API Key, Webhook Secret, and set Environment to sandbox or production.

B1
Create "WalletPlug Webhook" Data Type

In Data → Data types add a type WalletPlug Webhook with fields: status (text), ref_trx (text), amount (number), currency (text), is_sandbox (yes/no), customer_name (text), customer_email (text), raw_payload (text), received_at (text).

B2
Enable Bubble Data API

Go to Settings → API, enable the Data API, enable Create for WalletPlug Webhook, and copy the API key for the companion server.

B3
Build Payment Workflow

On your Pay button: Action 1 → Initiate WalletPlug Payment. Action 2 → Navigate to external website using Step 1's payment_url (condition: Step 1's error_message is empty).

C1
Deploy Companion Server

Push companion-server/ to GitHub and deploy to Render.com (free tier) or Railway. Set environment variables from .env.example. Your webhook endpoint will be:

https://your-companion-server.com/webhook/walletplug
C2
Create Bubble Backend Workflow

In Workflows → Backend Workflows create a workflow triggered when A new WalletPlug Webhook is created. Add actions to update your orders, send receipt emails, grant access, etc.

Troubleshooting

Action returns credential error message

Solutions:

  • Go to Plugins → WalletPlug Pay and confirm Merchant ID and API Key are filled in correctly
  • Check Environment matches your key prefix — sandbox keys must start with test_
Webhook records not appearing in Bubble database

Solutions:

  • Confirm the companion server is running — visit its URL and check the JSON health check response
  • Verify BUBBLE_APP_NAME and BUBBLE_API_KEY environment variables are correct
  • Confirm Create is enabled for WalletPlug Webhook in Settings → API → Data API
  • Check companion server logs — every webhook received and any Bubble API errors are logged
Navigate to payment_url does nothing

Solutions:

  • Confirm the Navigate action only runs when error_message is empty
  • Add a second action to show an error popup when error_message is not empty so you can see the actual issue

GiveWP Integration

Accept WalletPlug donations in any GiveWP donation form — the first truly global all-in-one donation gateway for GiveWP. Cards, mobile money, bank transfers, wallets, crypto, and vouchers in 135+ countries. Compatible with GiveWP 3.0+ on WordPress 5.8+.

WalletPlug Pay for GiveWP

Native GiveWP payment gateway registration, HMAC-verified IPN webhooks, automatic donation receipt emails via give_complete_donation, GiveWP settings panel, and full donation lifecycle management — pending → completed → failed.

v1.0Plugin
GiveWP 3+Compatible
HMACSecured
Download Plugin

Complete GiveWP payment gateway plugin — gateway registration, payment processing, HMAC-verified IPN webhook, GiveWP settings panel, and automatic donation receipt triggers.

Plugin Size: ~18 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • GiveWP 3.0+
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ recommended)
  • SSL Certificate (required)
  • WalletPlug Merchant Account
Production Ready

Installation Guide

1
Install & Activate

Upload and activate via WordPress Admin → Plugins → Add New → Upload.

2
Configure Credentials

Go to Donations → Settings → Payment Gateways → WalletPlug Pay. Enter your Merchant ID, API Key, Webhook Secret, and Environment.

3
Enable on Donation Forms

Edit any GiveWP form → Payment Gateways → enable Pay with WalletPlug.

4
Set Webhook URL
https://your-site.com/?walletplug_givewp_action=webhook
5
Test & Go Live

Make a sandbox donation. Verify the donation status updates to Complete and the receipt email fires. Then switch to Production.

Webhook & Donation Status Mapping

  • completed → GiveWP status: Complete + receipt email sent
  • failed → GiveWP status: Failed
  • cancelled → GiveWP status: Cancelled
  • pending → GiveWP status: Pending
  • All webhooks HMAC-SHA256 verified
  • give_complete_donation hook fires on completion

Troubleshooting

WalletPlug Pay not appearing on donation forms

Solutions:

  • Confirm the plugin is active and credentials are saved in GiveWP Settings → Payment Gateways
  • Edit the specific donation form → Payment Gateways tab → enable WalletPlug Pay for that form
  • Check that GiveWP 3.0+ is active — this plugin requires GiveWP 3.x or later
Donation stuck on Pending after payment

Solutions:

  • Confirm the webhook URL is set in your WalletPlug dashboard
  • Check GiveWP logs: Donations → Tools → Logs — filter by WalletPlug
  • Verify the Webhook Secret matches the Client Secret in your WalletPlug dashboard

WPForms Integration

Accept WalletPlug payments in any WPForms form — order forms, deposits, event registrations, and bookings. Supports all payment methods globally including mobile money, cards, wallets, bank transfers, and crypto. The first truly international payment addon for WPForms' 5 million active installs. Compatible with WPForms 1.8+ on WordPress 5.8+.

WalletPlug Pay for WPForms

Native WPForms payment integration — fires on wpforms_process_complete, HMAC-verified webhooks, WPForms entry status management, WordPress admin settings page, and automatic customer name and email extraction from form fields.

5M+Installs
v1.0Plugin
GlobalAll Countries
Download Plugin

Complete WPForms payment plugin — hooks into WPForms payment processing, HMAC-verified IPN webhook, entry status management, and a WordPress admin settings page.

Plugin Size: ~22 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • WPForms 1.8+ (Pro recommended for payments)
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ recommended)
  • SSL Certificate (required)
  • WalletPlug Merchant Account
Production Ready

Installation Guide

1
Install & Activate

Upload and activate via WordPress Admin → Plugins → Add New → Upload.

2
Configure Credentials

Go to WPForms → WalletPlug Pay in the admin menu. Enter your Merchant ID, API Key, Webhook Secret, and Environment.

3
Enable on Forms

Edit any WPForms form → Payments → WalletPlug Pay → Enable payments. Add a Total or Single Item field to your form to set the payment amount.

4
Set Webhook URL
https://your-site.com/?walletplug_wpforms_action=webhook
5
Test & Go Live

Submit a test form in Sandbox mode. Verify the WPForms entry status updates to Approved and switch to Production when ready.

Webhook & Entry Status Mapping

  • completed → WPForms entry: Approved
  • failed → WPForms entry: Failed
  • cancelled → WPForms entry: Abandoned
  • All webhooks HMAC-SHA256 verified
  • Customer name and email auto-extracted from form fields
  • Reference: WPF_{form_id}_{entry_id}_{timestamp}

Troubleshooting

Payment not triggering after form submission

Solutions:

  • Ensure the form has a Total, Single Item, or Payment Summary field with a value greater than 0
  • Confirm WalletPlug Pay is enabled in the form's Payments settings panel
  • WPForms Pro is required for the payment fields — confirm your WPForms licence includes payment features
Entry status not updating after payment

Solutions:

  • Confirm webhook URL is set in your WalletPlug dashboard
  • Check PHP error log for [WalletPlug WPForms] entries
  • Verify the Webhook Secret matches the Client Secret in your WalletPlug dashboard

Webflow Integration

Accept WalletPlug payments in any Webflow site using a lightweight companion server and a custom code embed. The first global all-in-one payment solution for Webflow merchants outside Stripe and PayPal's supported countries — covering 135+ countries, mobile money, crypto, and local bank transfers that Webflow's built-in gateways don't support. Compatible with all Webflow plans including Starter.

WalletPlug Pay for Webflow

Two-part integration — a deployable Node.js companion server (Railway / Render / Fly.io) and a Webflow custom code embed. Data attributes on any Webflow button trigger payment. HMAC-verified webhook IPN with Make.com / Airtable / Notion integration hooks built in.

3.5M+Webflow sites
Node.jsServer
HMACSecured
Download Integration Package

Complete Webflow integration — Express companion server, Webflow custom code embed snippet, .env.example, and a full deployment guide for Railway, Render, and Vercel.

Package: ~12 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • Any Webflow plan (including Starter)
  • Node.js 18+ hosting (Railway / Render / Fly.io — free tiers available)
  • WalletPlug Merchant Account
  • Make.com / Airtable / Zapier for order fulfilment (optional)
All Webflow Plans

How It Works

Webflow does not support custom payment gateways natively. This integration uses a companion server you deploy for free.

1
Customer clicks Pay button on Webflow site

A button with data-walletplug-pay attributes triggers a fetch() call to your companion server with the order details.

2
Companion server calls WalletPlug API

Your server calls POST /api/v1/initiate-payment with your API credentials (stored safely as environment variables — never exposed to the browser) and receives a payment_url.

3
Customer redirected to WalletPlug checkout

The customer completes payment on WalletPlug's secure hosted checkout page — cards, mobile money, wallets, crypto, and more.

4
WalletPlug sends HMAC-signed webhook to your server

Your companion server verifies the signature and updates your order records — Airtable, Notion, Google Sheets, or any database via Make.com / Zapier.

5
Customer redirected to Webflow success / failure page

Your companion server redirects the customer back to your Webflow success or failure page with the order ID as a query parameter.

Setup Guide

1
Deploy the companion server

Download the package, push to GitHub, and deploy to Railway or Render (both have free tiers). Set environment variables from .env.example. Your server gets a public URL like https://your-app.railway.app.

2
Add the embed to Webflow

Open src/webflow-embed.html, replace YOUR_SERVER_URL with your deployed server URL, then paste the whole thing into: Webflow Designer → Page Settings → Before </body> tag.

3
Add a Pay button with data attributes

In Webflow, add a Button element and set these Custom Attributes:

AttributeValue
data-walletplug-pay(no value needed)
data-amount99.99 (or a CMS dynamic field)
data-currencyUSD
data-order-idYour order ID or CMS item slug
data-customer-emailOptional — pre-fill checkout
4
Set Webhook URL in WalletPlug dashboard
https://your-app.railway.app/webhook
5
Connect to your database (optional)

In src/server.js find the YOUR FULFILMENT LOGIC GOES HERE comment in the /webhook route. Add your Airtable, Notion, or Make.com webhook call to update order records when payment completes.

Button Example

Add this button to any Webflow page using the Embed element or Custom Attributes panel. The script in your page settings wires it automatically.

<!-- Option A: HTML Embed element in Webflow -->
<button
  data-walletplug-pay
  data-amount="99.99"
  data-currency="USD"
  data-order-id="ORDER_001"
  data-description="Premium Plan"
  data-customer-email="customer@email.com"
  style="padding:14px 28px;background:#4353ff;color:#fff;border:none;border-radius:8px;font-size:15px;cursor:pointer;"
>
  Pay with WalletPlug
</button>

<!-- Option B: Webflow native button with Custom Attributes -->
<!-- Add data-walletplug-pay, data-amount, data-currency, data-order-id -->
<!-- in Webflow Designer → Element Settings → Custom Attributes -->

Troubleshooting

Button click shows alert "Payment could not be started"

Solutions:

  • Check the browser console for [WalletPlug] errors — it shows the exact API error message
  • Verify YOUR_SERVER_URL was replaced correctly in the embed code
  • Check the companion server logs — the /pay endpoint logs all errors
  • Confirm Merchant ID and API Key environment variables are set on your deployed server
CORS error in browser console

Solutions:

  • Set WEBFLOW_SITE_URL environment variable to your exact Webflow site URL including protocol, e.g. https://your-site.webflow.io
  • If using a custom domain, set WEBFLOW_SITE_URL to the custom domain URL
  • Redeploy the server after changing environment variables

Squarespace Integration

Accept WalletPlug payments on any Squarespace site — the first global all-in-one payment solution for Squarespace merchants who need more than the built-in options. Cards, mobile money, bank transfers, wallets, and crypto in 135+ countries. Fully mobile-responsive embed — works on all Squarespace 7.0 and 7.1 templates. Compatible with all Squarespace plans.

WalletPlug Pay for Squarespace

Two-part integration — a deployable Node.js companion server (Railway / Render free tiers) and a mobile-responsive Code Block embed pasted into any Squarespace page. HMAC-verified webhook IPN with Make.com / Zapier / Airtable fulfilment hooks built in.

4.4M+SQS sites
Node.jsServer
MobileResponsive
Download Integration Package

Complete Squarespace integration — Express companion server, mobile-responsive Code Block embed, .env.example, and deployment guide for Railway and Render.

Package: ~14 KB
Version: 1.0.0
Mobile Responsive: Yes
Requirements
  • Any Squarespace plan (including Personal)
  • Node.js 18+ hosting — Railway or Render (free tiers available)
  • WalletPlug Merchant Account
  • Make.com / Airtable / Zapier for order fulfilment (optional)
All Squarespace Plans — Mobile Responsive

How It Works

1
Customer clicks Pay button on Squarespace page

A mobile-responsive WalletPlug button added via Squarespace's Code Block calls your companion server with the order details.

2
Companion server calls WalletPlug API

Your server initiates the payment — API credentials are stored as server environment variables, never exposed in the browser.

3
Customer completes payment on WalletPlug checkout

WalletPlug's hosted checkout is fully mobile-optimised — cards, mobile money, wallets, and more work seamlessly on any device.

4
HMAC-verified webhook updates your order system

Your companion server receives a signed IPN and updates your Squarespace Commerce, Airtable, or Make.com order records.

5
Customer redirected back to Squarespace

Your server redirects to your success or failure Squarespace page — with the order ID as a query parameter.

Setup Guide

1
Deploy the companion server

Download the package, push to GitHub, and deploy to Railway or Render (both have free tiers). Set environment variables from .env.example. You'll get a URL like https://your-app.railway.app.

2
Add the Code Block to Squarespace

Open src/squarespace-embed.html, replace YOUR_SERVER_URL with your deployed server URL. In Squarespace Designer, add a Code Block to your product or checkout page and paste the entire file.

3
Set amount and order ID

Update the data-amount, data-currency, and data-order-id attributes on the button to match your product price. For dynamic pages use Squarespace's {tag} syntax or JavaScript to populate them.

4
Set Webhook URL in WalletPlug dashboard
https://your-app.railway.app/webhook
5
Test on mobile and desktop

Open your Squarespace preview on a mobile device. The WalletPlug button and payment methods should display correctly at all screen sizes. Test a sandbox payment end-to-end.

Mobile-Responsive Button Code

Add this to any Squarespace Code Block. Fully responsive — works on 320px mobile screens up to 1440px desktop.

<!-- WalletPlug Pay Button — paste into Squarespace Code Block -->
<button
  class="wp-pay-btn"
  onclick="WalletPlugSquarespace.pay()"
  data-amount="99.99"
  data-currency="USD"
  data-order-id="ORDER_001"
  data-description="Product Name"
>
  Pay with WalletPlug
</button>
<!-- Full CSS + JS included in squarespace-embed.html -->

Troubleshooting

Button click shows error "Payment initiation failed"

Solutions:

  • Check browser console for [WalletPlug] errors — it shows the exact API message
  • Confirm YOUR_SERVER_URL was replaced in the embed code
  • Verify Merchant ID and API Key are set as environment variables on your deployed server
CORS error in browser console

Solutions:

  • Set SQUARESPACE_SITE_URL to your exact Squarespace URL including protocol
  • If using a custom domain, set the custom domain URL — not squarespace.com
  • Redeploy the server after changing environment variables
Button looks wrong on mobile

Solutions:

  • Ensure the full squarespace-embed.html was pasted — the CSS at the top is required for responsive behaviour
  • In Squarespace 7.1 some templates inject extra margin — add margin: 0; to .wp-pay-wrap if needed
  • Use Squarespace's mobile preview to test at 375px width

LearnDash LMS Integration

Accept WalletPlug payments directly in LearnDash course and group checkouts — the first truly global payment gateway for LearnDash LMS. Cards, mobile money, bank transfers, wallets, and crypto in 135+ countries. Compatible with LearnDash 4.0+ on WordPress 5.8+.

WalletPlug Pay for LearnDash

Native LearnDash payment gateway — course and group enrollment, automatic user access provisioning on payment, HMAC-verified IPN webhooks, LearnDash transaction logging, and a WordPress admin settings panel under LearnDash LMS → WalletPlug Pay.

v1.0Plugin
LD 4.0+Compatible
HMACSecured
Download Plugin

Complete LearnDash payment gateway — course and group enrollment, payment button injection, IPN webhook handler, transaction logging, and WordPress admin settings.

Plugin Size: ~22 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • LearnDash LMS 4.0+
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ recommended)
  • SSL Certificate (required)
  • WalletPlug Merchant Account
Production Ready

Installation Guide

1
Install & Activate

Upload and activate via WordPress Admin → Plugins → Add New → Upload.

2
Configure Credentials

Go to LearnDash LMS → WalletPlug Pay. Enter your Merchant ID, API Key, Webhook Secret, and Environment.

3
Set Course Price

Edit any course → Settings → Access Settings → set Price Type to Closed and enter a price. WalletPlug Pay button will appear on the course page automatically.

4
Set Webhook URL
https://your-site.com/?walletplug_ld_action=webhook
5
Test & Go Live

Purchase a course in Sandbox mode. Verify enrollment is granted automatically. Switch to Production when ready.

Webhook & Enrollment Flow

  • completed → User enrolled in course/group
  • completed → LearnDash transaction logged
  • failed → Access not granted
  • All webhooks HMAC-SHA256 verified
  • Works with courses and groups
  • Reference: LD_{post_id}_{user_id}_{timestamp}

Troubleshooting

Pay with WalletPlug button not showing

Solutions:

  • Confirm the course Price Type is set to Closed with a price greater than 0
  • Ensure Merchant ID and API Key are saved in LearnDash LMS → WalletPlug Pay
  • Check that the plugin is active and LearnDash 4.0+ is running
User not enrolled after successful payment

Solutions:

  • Confirm the webhook URL is set in your WalletPlug dashboard
  • Check your WordPress debug log for [WalletPlug LearnDash] errors
  • Verify the Webhook Secret matches the Client Secret in your WalletPlug dashboard

LifterLMS Integration

Accept WalletPlug payments directly in LifterLMS course and membership checkouts — the first truly global payment gateway for LifterLMS. Cards, mobile money, bank transfers, wallets, and crypto in 135+ countries. Built on LifterLMS's official LLMS_Payment_Gateway class. Compatible with LifterLMS 6.0+ on WordPress 5.8+.

WalletPlug Pay for LifterLMS

Native LifterLMS payment gateway — extends LLMS_Payment_Gateway, branded checkout widget, automatic course and membership enrollment on payment, HMAC-verified IPN webhooks, full order lifecycle management, and a WordPress admin settings page under LifterLMS → WalletPlug Pay.

v1.0Plugin
LLMS 6+Compatible
HMACSecured
Download Plugin

Complete LifterLMS payment gateway — extends LLMS_Payment_Gateway, branded checkout widget, HMAC-verified IPN webhook, automatic enrollment on payment, and WordPress admin settings panel.

Plugin Size: ~24 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • LifterLMS 6.0+ (free or pro)
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ recommended)
  • SSL Certificate (required)
  • WalletPlug Merchant Account
  • Works with the free LifterLMS plugin
Works with Free LifterLMS

Plugin Features

Built on LifterLMS's official payment gateway framework for full platform compatibility

Native LLMS Gateway

Extends LLMS_Payment_Gateway — appears in LifterLMS payment methods alongside all other gateways automatically

Auto Enrollment

Students are enrolled in courses and memberships automatically on IPN webhook confirmation — no manual intervention

HMAC Webhook Security

All IPN notifications verified with HMAC-SHA256 before any enrollment or order update is processed

Branded Checkout Widget

Full WalletPlug branded checkout — logo header, card network icons, payment category pills, mobile-responsive

Courses & Memberships

Works with both LifterLMS courses and membership plans — any product type with a price is supported

Full Sandbox Testing

Complete sandbox environment — test course purchases and enrollment flows before going live

Installation Guide

1
Install & Activate

Upload and activate via WordPress Admin → Plugins → Add New → Upload Plugin. LifterLMS must be active first.

2
Configure Credentials

Go to LifterLMS → WalletPlug Pay in the WordPress admin. Enter your Merchant ID, API Key, Webhook Secret, and choose your Environment.

3
Enable in LifterLMS Payment Settings

Go to LifterLMS → Settings → Checkout. Under Payment Gateways, enable WalletPlug Pay and save.

4
Set Webhook URL

Copy the Webhook URL from the settings page and set it in your WalletPlug merchant dashboard:

https://your-site.com/?walletplug_llms_action=webhook
5
Test & Go Live

Purchase a course in Sandbox mode. Verify enrollment is granted automatically after the webhook fires. Switch to Production when ready.

Webhook & Enrollment Flow

  • completed → Order: Complete + student enrolled
  • completed → lifterlms_order_complete action fires
  • failed → Order: Failed
  • cancelled → Order: Pending Cancel
  • refunded → Order: Refunded
  • All webhooks HMAC-SHA256 verified
  • Reference: LLMS_{order_id}_{timestamp}
  • Works with courses & memberships

Troubleshooting

WalletPlug Pay not showing at checkout

Solutions:

  • Confirm the gateway is enabled in LifterLMS → Settings → Checkout → Payment Gateways
  • Confirm the Merchant ID and API Key are saved in LifterLMS → WalletPlug Pay
  • Check that LifterLMS 6.0+ is active — earlier versions use a different gateway API
Student not enrolled after successful payment

Solutions:

  • Confirm the Webhook URL is set in your WalletPlug merchant dashboard
  • Check WordPress debug log for [WalletPlug LifterLMS] errors
  • Verify the Webhook Secret in plugin settings matches the Client Secret in your WalletPlug dashboard
  • Ensure your site is publicly accessible — webhooks cannot reach sites behind HTTP authentication

MemberPress Integration

Accept WalletPlug payments in MemberPress membership sites — the first truly global payment gateway for MemberPress. Cards, mobile money, bank transfers, wallets, and crypto in 135+ countries. Built on the official MemberPress gateway API. Compatible with MemberPress 1.9+ on WordPress 5.8+.

WalletPlug Pay for MemberPress

Extends MemberPress's official MeprBaseRealGateway class — full gateway settings panel inside MemberPress, per-gateway field configuration, HMAC-verified IPN webhooks, automatic membership activation on payment, and MemberPress receipt email triggers.

v1.0Plugin
MP 1.9+Compatible
HMACSecured
Download Plugin

Complete MemberPress payment gateway — extends MeprBaseRealGateway, settings panel in MemberPress admin, HMAC webhook verification, membership activation, and receipt email triggers.

Plugin Size: ~24 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • MemberPress 1.9+
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ recommended)
  • SSL Certificate (required)
  • WalletPlug Merchant Account
Production Ready

Installation Guide

1
Install & Activate

Upload and activate via WordPress Admin → Plugins → Add New → Upload.

2
Configure Gateway

Go to MemberPress → Settings → Payments → Add Payment Method and select WalletPlug Pay. Enter your Merchant ID, API Key, Webhook Secret, and choose your Environment.

3
Assign to Memberships

Edit any membership → Price Box → Payment Methods → enable WalletPlug Pay for that membership.

4
Set Webhook URL
https://your-site.com/?walletplug_mp_action=webhook
5
Test & Go Live

Purchase a membership in Sandbox mode. Verify membership is activated and receipt email fires. Switch Environment to Production when ready.

Webhook & Transaction Status Mapping

  • completed → MemberPress status: Complete + receipt email sent
  • failed → MemberPress status: Failed
  • refunded → MemberPress status: Refunded
  • All webhooks HMAC-SHA256 verified
  • MeprUtils receipt email fires on completion
  • Reference: MP_{txn_id}_{timestamp}

Troubleshooting

WalletPlug Pay not showing at checkout

Solutions:

  • Confirm the gateway is added and saved in MemberPress → Settings → Payments
  • Ensure WalletPlug Pay is enabled for the specific membership in the Price Box settings
  • Check that Merchant ID and API Key are saved correctly
Membership not activated after payment

Solutions:

  • Confirm the webhook URL is set in your WalletPlug dashboard
  • Check MemberPress transaction log: MemberPress → Transactions
  • Verify the Webhook Secret matches the Client Secret in your WalletPlug dashboard

Paid Memberships Pro Integration

Accept WalletPlug payments in Paid Memberships Pro (PMPro) membership sites — the first truly global payment gateway for PMPro's 100,000+ free installs worldwide. Cards, mobile money, bank transfers, wallets, and crypto in 135+ countries. Built on PMPro's official PMProGateway API. Compatible with PMPro 2.9+ on WordPress 5.8+.

WalletPlug Pay for Paid Memberships Pro

Extends PMPro's official PMProGateway base class — settings panel under Memberships → Payment Settings, HMAC-verified IPN webhooks, automatic membership activation via pmpro_after_checkout, and full order lifecycle management.

v1.0Plugin
100K+PMPro installs
FreePMPro compatible
Download Plugin

Complete PMPro payment gateway — extends PMProGateway, settings panel in PMPro admin, HMAC webhook verification, automatic membership activation, and full order status management.

Plugin Size: ~22 KB
Version: 1.0.0
Last Updated: Jul 28, 2026
Requirements
  • Paid Memberships Pro 2.9+ (free or paid)
  • WordPress 5.8+
  • PHP 7.4+ (8.1+ recommended)
  • SSL Certificate (required)
  • WalletPlug Merchant Account
Works with Free PMPro

Installation Guide

1
Install & Activate

Upload and activate via WordPress Admin → Plugins → Add New → Upload.

2
Configure Gateway

Go to Memberships → Payment Settings. Select WalletPlug Pay as your gateway. Enter your Merchant ID, API Key, Webhook Secret, and Environment.

3
Set Webhook URL
https://your-site.com/?walletplug_pmpro_action=webhook
4
Test & Go Live

Sign up for a membership level in Sandbox mode. Verify membership is activated automatically. Switch to Production when ready.

Webhook & Order Status Mapping

  • completed → PMPro order: success + membership activated
  • failed → PMPro order: error
  • refunded → PMPro order: refunded
  • All webhooks HMAC-SHA256 verified
  • pmpro_after_checkout fires on success
  • Reference: PMPRO_{order_id}_{timestamp}

Troubleshooting

WalletPlug Pay not listed in Payment Settings

Solutions:

  • Ensure PMPro 2.9+ is active — earlier versions have a different gateway API
  • Confirm the plugin is activated in WordPress Admin → Plugins
  • Check your PHP error log for any class loading errors
Membership not activated after payment

Solutions:

  • Confirm the webhook URL is set in your WalletPlug dashboard
  • Check PMPro orders: Memberships → Orders — look for the transaction status
  • Verify the Webhook Secret in Payment Settings matches the Client Secret in your WalletPlug dashboard

Interactive Testing Console

Test the WalletPlug API directly in your browser. Enter your sandbox credentials and fire real requests against the API — responses appear instantly below each request.

Sandbox Only Use test_ prefixed credentials only. Never enter production keys into a browser tool.
Credentials
Run Initiate Payment first — the trxId is filled automatically.
Sandbox Test Methods
MethodTest CredentialsResult
Demo WalletID: 123456789 / Password: demo123Completes payment
Demo VoucherCode: TESTVOUCHERCompletes payment
GatewayAuto-approves all transactionsCompletes payment
Decline TestUse amount: 0.01Triggers failure

Step-by-step guides

Tutorial Videos

Watch exactly how to connect WalletPlug to your platform — every screen shown as you'll really see it, with a clear click path for each step. No code required.

More platform tutorials coming soon — Magento and the plain HTML embed for custom sites.

Error Codes

The WalletPlug API uses conventional HTTP status codes and machine-readable error codes on every error response. Always check the error_code field to programmatically handle errors — never rely on the message string alone as it may change.

Error Response Structure

{
    "success":    false,
    "message":    "Human-readable error description",
    "error_code": "MACHINE_READABLE_CODE",
    "errors": {
        "field_name": ["Validation message for this field"]
    }
}

HTTP Status Codes

HTTP Status Meaning What to do
200 OKRequest succeededProcess the response
400 Bad RequestInvalid parametersCheck the errors object for field-level details and fix your request
401 UnauthorizedInvalid or missing API credentialsCheck X-Merchant-Key and X-API-Key. Ensure environment matches key prefix.
403 ForbiddenValid credentials but action not permittedCheck your account status in the WalletPlug Dashboard
404 Not FoundResource does not existVerify the transaction ID or endpoint path is correct
422 UnprocessableRequest valid but cannot be processedCheck message — e.g. transaction already refunded
429 Too Many RequestsRate limit exceededRead Retry-After header and wait before retrying. Use exponential backoff.
500 Server ErrorUnexpected server errorRetry with exponential backoff. Contact support if persistent.
503 UnavailableAPI temporarily unavailableRetry after a short delay.

WalletPlug Error Codes

The error_code field is always a stable machine-readable string. Use it in your code — never match on the message string.

error_code HTTP Description Fix
INVALID_CREDENTIALS401Merchant key or API key is invalid or does not match the environmentRe-enter credentials from Dashboard. Check environment matches key prefix.
ACCOUNT_SUSPENDED403Merchant account is suspendedContact WalletPlug support.
ACCOUNT_NOT_VERIFIED403Merchant account not verified for productionComplete verification in the WalletPlug Dashboard.
VALIDATION_ERROR400One or more required parameters are missing or invalidCheck the errors object for field-level messages.
INVALID_AMOUNT400Payment amount below minimum or invalid formatEnsure amount is a positive number with up to 2 decimal places.
INVALID_CURRENCY400Currency code is not a supported ISO 4217 codeUse a valid 3-letter code. See Supported Currencies.
DUPLICATE_REFERENCE400The ref_trx has already been used for another transactionUse a unique reference for every payment request.
INVALID_URL400A redirect or webhook URL is malformedAll URLs must be valid HTTPS URLs.
TRANSACTION_NOT_FOUND404No transaction found with the provided trx_idVerify the ID. Sandbox and production IDs are not interchangeable.
TRANSACTION_NOT_COMPLETED422Refund requested on a non-completed transactionOnly completed transactions can be refunded.
TRANSACTION_ALREADY_REFUNDED422Transaction has already been fully refundedCheck refund history before retrying.
REFUND_AMOUNT_EXCEEDS_PAYMENT422Refund amount greater than original paymentRefund amount cannot exceed the original transaction amount.
RATE_LIMITED429Too many requests in the current windowRead Retry-After header. Implement exponential backoff.
INVALID_SIGNATURE401Webhook HMAC-SHA256 signature verification failedUse the raw request body (not decoded JSON) and the correct Client Secret.

Handling Errors in Code

// Node.js — recommended error handling pattern
import WalletPlug, { WalletPlugAuthError, WalletPlugValidationError, WalletPlugRateLimitError } from 'walletplug-node';

try {
  const result = await wp.payments.initiate({ ... });
  res.redirect(result.paymentUrl);

} catch (err) {
  if (err instanceof WalletPlugAuthError) {
    // 401 — check API keys in dashboard
  } else if (err instanceof WalletPlugValidationError) {
    // 400 — show field-level errors to user
    console.error(err.errors);
  } else if (err instanceof WalletPlugRateLimitError) {
    // 429 — wait and retry
    await new Promise(r => setTimeout(r, err.retryAfter * 1000));
  } else {
    // Unexpected — log fully
    console.error(err.statusCode, err.errorCode, err.message);
  }
}
Idempotent Retries Always use the same ref_trx when retrying a failed initiate-payment request — the API will return the existing session instead of creating a duplicate. For refunds, pass the same ref_refund to safely retry without double-refunding.

Changelog

All notable changes to the WalletPlug API, SDKs, and platform plugins are documented here. We follow semantic versioning — breaking changes are always announced with a major version bump and a minimum 30-day migration window.

Versioning Policy The current stable API is v1. All v1 endpoints are backwards-compatible within the same major version. Breaking changes will be released as v2 with a deprecation notice and dual-support period.

v2.0.0 — Subscriptions Billing

Latest Major Release
May 21, 2026
Introducing Subscriptions Billing Merchants can now sell recurring subscriptions on their websites with WalletPlug — enterprise-grade plans, hosted checkout, customer portal, webhooks, and a full REST API. No bank integration required for your customers; cards charge through your existing WalletPlug gateways.
Added — Subscriptions Billing Engine
  • Merchant-owned plans — reusable pricing templates: amount + currency + billing interval (day/week/month/year) + interval count + optional trial days + optional total cycle limit. Each plan is a stable UUID with metadata support.
  • Customers & payment methods — store customers (idempotent on email) and tokenised payment methods. Raw card numbers never touch your server.
  • Subscriptions lifecycleincomplete → trialing → active → past_due → canceled / expired, with cycle counters, next-billing scheduling, cancel-at-period-end, prorated upgrades/downgrades, and SCA / 3D Secure handoff.
  • Invoices — one per billing period: paid / failed / refunded / voided states, discount tracking, partial-refund support, and unique INV-XXXX numbering.
  • Coupons — percent or fixed discounts; once / repeating(N months) / forever duration; max-redemption caps; expiry dates.
  • Billing cycle worker — hourly cron charges due subscriptions, retries failed cards with dunning, advances trial-to-active transitions, and processes scheduled cancellations.
Added — Gateway Adapters
  • Pluggable registry — new gateways implement the BillingGateway interface (charge / refund / verify webhook).
Added — REST API /api/v1/billing/*
  • Full Plan CRUD: POST/GET/PATCH/DELETE /plans.
  • Customer + payment method management: POST/GET /customers, POST /customers/{uuid}/payment-methods.
  • Subscription operations: POST/GET /subscriptions, POST /subscriptions/{uuid}/cancel with at_period_end flag.
  • Idempotency-Key header — safely retry POST / PATCH / DELETE requests.
  • Rate limiting — 60 requests/minute/merchant on all /v1/billing/* endpoints.
  • Sandbox mode — pass X-Environment: sandbox to use test gateway keys.
Added — Hosted Checkout & Embed Widgets
  • Hosted checkout URL — every plan gets https://walletplug.com/subscribe/{plan_uuid}.
  • JavaScript widget<walletplug-button plan="UUID"> custom element, data-walletplug-plan attribute, and WalletPlug.openSubscribe(uuid) programmatic API. Launches modal checkout on any page.
  • iFrame embed/embed/subscribe/{plan_uuid} for embedding checkout inside a page.
  • Pricing Table — multi-plan comparison at /pricing/{merchant_key} with "Most Popular" highlight.
  • postMessage events — listen for walletplug:subscription DOM events on success.
Added — Customer Self-Service Portal
  • Signed portal URL/portal/{customer_uuid}?signature=... with 7-day TTL.
  • View active subscriptions, view invoice history, cancel (immediate or at period end), update default payment method (auto-repoints all active subs).
  • No login required — signed URL acts as bearer credential; ideal for receipt-email "Manage subscription" buttons.
Added — Outbound Webhooks
  • Event types: plan.created, customer.created, subscription.created, subscription.activated, subscription.past_due, subscription.cancel_scheduled, subscription.canceled, subscription.expired, subscription.plan_changed, invoice.paid, invoice.failed, invoice.refunded.
  • HMAC-SHA256 signatureX-WalletPlug-Signature: t={ts},v1={hmac} signed over {ts}.{body}.
  • Exponential retry — 5 min → 30 min → 2 h → 12 h → 24 h. After 5 attempts the delivery is marked dead.
  • Full delivery log with response code, body, and next retry timestamp.
Added — Inbound Webhooks (Gateway → us)
  • One endpoint per gateway: /webhooks/billing/{gateway}.
  • Signature verification — each gateway's native scheme; rejected events return 400.
  • Idempotency dedup — gateway event IDs stored in billing_inbound_events; replays return 200.
  • Automatic state sync for Stripe payment_intent.payment_failed and charge.refunded.
Added — Merchant Dashboard
  • New Subscriptions section in user sidebar: Overview, Plans, Subscribers, Customers, Coupons, Webhooks.
  • 12-month revenue chart on the Billing Overview.
  • Embed Code modal on every plan row (Button / Hosted Link / iFrame) with live preview + copy buttons.
  • WordPress Plugin download button.
Added — Admin Oversight /AdminPanel/billing
  • Platform MRR, active subs, past_due, 30-day churn, merchants using billing, 30-day revenue.
  • 12-month revenue line chart, top 10 merchants by MRR, last 30 platform events.
Added — Invoice Documents
  • Hosted invoice URL/invoices/{uuid}/view — public, brand-styled invoice page.
  • PDF download/invoices/{uuid}/pdf — DomPDF-generated; filename = invoice number.
Added — Email Notifications
  • subscription.created — welcome email with plan and next billing date.
  • invoice.paid — payment receipt.
  • invoice.failed — failure notice with "update card" prompt.
  • trial_will_end — sent 2–4 days before the trial converts.
  • subscription.canceled — cancellation confirmation.
  • Dunning campaign — automatic daily reminders to past_due customers (max 3 attempts over 7 days).
Added — WordPress Plugin
  • walletplug-subscriptions v1.0.0 — downloadable from /downloads/walletplug-subscriptions.zip.
  • Shortcode: [walletplug_subscribe plan="UUID" label="Subscribe — $29/mo"].
  • Gutenberg block: "WalletPlug Subscribe".
  • Admin settings page under Settings → WalletPlug Subscriptions.
Added — SDK Examples & Documentation
  • New Subscriptions section in API docs with Overview, Auth, Plans, Customers, Create Subscription, Hosted Checkout, Webhooks, and Full Example sub-sections.
  • New SDKs & Plugins sub-section with WordPress Plugin, HTML Embed, and PHP / Node.js / Python / cURL code samples.
Database Migrations
  • New tables: billing_plans, billing_customers, billing_payment_methods, billing_subscriptions, billing_invoices, billing_events, billing_webhooks, billing_webhook_deliveries, billing_idempotency_keys, billing_inbound_events, billing_coupons.
  • All additive — no existing tables modified.
Security & Compliance
  • PCI-safe — cards are tokenised client-side by WalletPlug Secure Capture. WalletPlug servers never see raw PAN, CVV, or expiry.
  • SCA / 3D Secure — surfaced via requires_action + action_url.
  • Webhook replay protection, inbound dedup, rate limiting (60/min/merchant), signed customer portal URLs.
Versioning Note
  • Major version bump (v1 → v2) because Subscriptions Billing is a new product surface — not because of breaking changes.
  • All v1 endpoints continue to work unchanged. No migration required for existing one-off payment integrations.

v1.5.0

Stable
Mar 26, 2026
Added — New Platform Plugins
  • LearnDash LMS plugin (walletplug-learndash) v1.0.0 — native LearnDash payment gateway, automatic course and group enrollment on payment, HMAC-verified IPN webhooks, LearnDash transaction logging, compatible with LearnDash 4.0+
  • MemberPress plugin (walletplug-memberpress) v1.0.0 — extends official MeprBaseRealGateway, full gateway settings panel inside MemberPress, automatic membership activation, MeprUtils receipt email triggers
  • Paid Memberships Pro plugin (walletplug-pmpro) v1.0.0 — extends official PMProGateway, settings under Memberships → Payment Settings, pmpro_after_checkout hook, works with free PMPro
  • Squarespace integration (walletplug-squarespace) v1.0.0 — Node.js companion server (Railway / Render), mobile-responsive Code Block embed, HMAC-verified IPN, Make.com / Zapier / Airtable fulfilment hooks
Improved — WooCommerce Plugin
  • WooCommerce plugin updated to v2.0.0 — full rebuild with branded checkout widget, mobile-responsive display (320px–1440px), HPOS (High-Performance Order Storage) compatibility declared, refund API support via POST /api/v1/refund, sandbox mode indicator at checkout, payment method category badges
  • Checkout now displays WalletPlug branded header bar (gradient blue-to-green, dark purple logo pill, green security shield), card network icons (VISA, Mastercard, Discover, JCB, OD/Diners, UnionPay, American Express, Maestro), and payment category pills (Cards, Mobile Money, Bank Transfer, Wallet, Crypto)
Improved — Checkout Branding (All WordPress Plugins)
  • Shared walletplug-checkout-branding.php function deployed to all WordPress plugins — WooCommerce, GiveWP, WPForms, Gravity Forms, EDD, LearnDash, MemberPress, PMPro
  • All WordPress plugins now render the identical branded checkout widget — WalletPlug logo header, card network icons row, payment category pills, and sandbox warning bar
  • Checkout widget is fully mobile-responsive with CSS breakpoints at 480px and 360px
Improved — Documentation
  • New LearnDash, MemberPress, Paid Memberships Pro, and Squarespace sections added to API docs sidebar and content
  • WooCommerce docs section updated to reflect v2.0.0 — mobile responsive, HPOS compatible, refund support
  • Gravity Forms section icon fixed — replaced incorrect fa-wpforms icon with fa-paper-plane throughout section heading, header, and feature cards
  • Full CDN cache purge and Laravel view cache cleared — all documentation updates now live

v1.4.0

Mar 24, 2026
Added — SDKs
  • Official Node.js / TypeScript SDK (walletplug-node) — published to npm. Full TypeScript types, typed error classes, automatic retry on 5xx, rate-limit backoff, factory methods, and webhooks.verifyAndParse()
  • Official PHP Composer SDK (walletplug/walletplug-php) — published to Packagist. Guzzle HTTP client, Guzzle retry middleware, Laravel auto-discovered Service Provider, publishable config, and Facade
  • Official Python PyPI SDK (walletplug-python) — published to PyPI. Sync WalletPlug client and async AsyncWalletPlug client (httpx), full type hints, dataclass models, Django and FastAPI integration examples
  • Official React Native SDK (walletplug-react-native) — published to npm. Drop-in WalletPlugCheckout WebView component, useWalletPlug hook, Expo compatible, TypeScript types
  • All SDKs include payments.initiate(), payments.verify(), payments.refund(), and webhooks.verifyAndParse()
Added — Platform Plugins
  • CS-Cart / Multi-Vendor addon (walletplug_pay) v1.0.0 — native addon with IPN webhook, HMAC verification, order status lifecycle, Multi-Vendor marketplace support
  • Gravity Forms addon (walletplug-gravityforms) v1.0.0 — GF Payment Addon Framework integration, per-form feeds, conditional logic, gform_post_payment_completed trigger
  • Ecwid / Lightspeed E-Series plugin (walletplug-ecwid) v1.0.0 — Ecwid Custom Payment API, Ecwid REST API v3 order updates, WordPress companion plugin
Added — API Endpoints
  • POST /api/v1/refund — new endpoint for full and partial refunds on completed transactions
  • Refund webhook events — refund.completed and refund.failed now delivered to merchant IPN URL
  • customer_name and customer_email parameters added to POST /api/v1/initiate-payment main endpoint documentation (previously only in mobile SDK docs)
Improved — Documentation
  • New Rate Limits section — per-endpoint limits table, response headers, retry strategy code example
  • New Currencies & Countries section — 50+ currencies, 135+ countries across 6 regions, full payment methods breakdown
  • New Transaction Lifecycle section — visual state machine, status reference table, idempotency guide
  • New Security & Compliance section — PCI DSS SAQ-A, TLS 1.2+, credential best practices, webhook security deep-dive, responsible disclosure
  • New Changelog section — this page
  • Sidebar restructured into 6 logical groups: Getting Started, Core API, Reference, SDKs & Examples, Platform Plugins, Support

v1.3.0

Mar 15, 2026
Added — Platform Plugins
  • Shopify payment plugin v1.0.0 — Node.js backend, Checkout UI extension, HMAC-verified webhooks, sandbox/production switching
  • OpenCart extension v1.0.0 — native OpenCart 3.x/4.x payment extension, geo zone restriction, multi-currency, admin settings panel
  • PrestaShop module v1.0.0 — GF Payment Addon Framework, front controllers, Smarty templates, PS_OS_PAYMENT lifecycle
  • Magento 2 / Adobe Commerce module v1.0.0 — DI architecture, virtual types, encrypted credential storage, admin system.xml config
  • BigCommerce app v1.0.0 — OAuth store installation, Script Manager checkout injection, BigCommerce V2/V3 API order updates
  • Easy Digital Downloads plugin v1.0.0 — native EDD 3.x gateway, edd_complete_purchase hook, file access grants on completion
Improved
  • WooCommerce plugin updated to v2.8.0 — WooCommerce Blocks (Gutenberg) full support, dynamic branding auto-fetch, compact mobile UI
  • All platform plugins now include production deployment checklists and troubleshooting guides in documentation
  • Documentation sidebar updated with all new platform plugin links and colour-coded icons

v1.2.0

Mar 01, 2026
Added
  • customer_name and customer_email optional parameters added to POST /api/v1/initiate-payment — pre-fills customer details at checkout
  • allow_payment_methods parameter now accepts both JSON array and comma-separated string formats. e.g. "card,bank_transfer" or ["card","bank_transfer"]
  • Sandbox transaction IDs now prefixed with SANDBOX_ for easier log filtering
  • Webhook payload now includes environment and is_sandbox fields in all delivery attempts
  • Android SDK (Kotlin) v1.0.0 and iOS SDK (Swift) v1.0.0 released — see Mobile SDKs section
  • WHMCS payment gateway module v1.0.0 — offsite redirect with HMAC-verified callbacks
Improved
  • Webhook retry logic improved to exponential backoff — up to 5 retries over 24 hours
  • Payment URL expiry extended from 30 minutes to 60 minutes
  • X-Signature header now consistently included on all webhook deliveries including retries

v1.1.0

Feb 01, 2026
Added
  • GET /api/v1/verify-payment/{trxId} — new endpoint to poll transaction status at any time
  • WooCommerce gateway plugin v1.0.0 — initial release with offsite redirect, HMAC webhook verification, order status management
  • Interactive API testing console added to the documentation page — test both endpoints directly in the browser
  • Payment status expired added — sessions expire after 60 minutes of inactivity
Changed
  • failure_url parameter renamed from failed_redirect — old name still accepted but deprecated, will be removed in v2
  • Webhook status field values normalised: successcompleted — old value still delivered for 90 days then removed

v1.0.0

Initial Release
Jan 15, 2026
Added
  • POST /api/v1/initiate-payment — create a payment session and receive a hosted checkout URL
  • Sandbox and Production environment support via X-Environment header
  • HMAC-SHA256 webhook signature verification via X-Signature header
  • Payment status values: pending, completed, failed, cancelled, expired
  • Supported currencies: USD, EUR, GBP, NGN, GHS, KES, ZAR, and all major global currencies
  • Code examples in cURL, PHP / Laravel, Node.js, and Python
  • Sandbox demo credentials — wallet, voucher, and gateway test methods

Deprecation Policy

When we deprecate a feature, parameter, or endpoint we follow this process:

1
Deprecation Notice

The deprecated item is marked in the changelog and documentation with a warning badge. It continues to work normally — no action required immediately.

2
Merchant Email Notification

All active merchants are notified by email with clear migration instructions and the exact removal date. Minimum 30-day notice guaranteed.

3
Dual Support Period

Both the old and new approaches work simultaneously during the migration window so you can upgrade at your own pace without service interruption.

4
Removal

After the migration window the item is removed. A 410 Gone response is returned for removed endpoints. A 400 Bad Request with error code DEPRECATED_PARAMETER is returned for removed parameters.

Error Codes

WalletPlug API uses conventional HTTP response codes to indicate the success or failure of API requests.

HTTP Status Codes

Code Status Description
200 OK Request succeeded
400 Bad Request Invalid request parameters
401 Unauthorized Invalid or missing API credentials
403 Forbidden Insufficient permissions
404 Not Found Resource not found
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Server error occurred

API Error Codes

Error Code Description Solution
INVALID_CREDENTIALS Invalid API credentials provided Check your Merchant ID and API Key
INSUFFICIENT_FUNDS Customer has insufficient funds Customer needs to add funds to their wallet
PAYMENT_DECLINED Payment was declined by payment processor Customer should try a different payment method
INVALID_AMOUNT Payment amount is invalid Check minimum and maximum amount limits
INVALID_CURRENCY Unsupported currency code Use a supported currency code (USD, EUR, etc.)
DUPLICATE_REFERENCE Transaction reference already exists Use a unique transaction reference
EXPIRED_SESSION Payment session has expired Create a new payment request
MERCHANT_SUSPENDED Merchant account is suspended Contact WalletPlug support

Error Response Format

{
  "success": false,
  "message": "Validation failed",
  "error_code": "INVALID_AMOUNT",
  "errors": {
    "payment_amount": [
      "The payment amount must be at least 1.00"
    ]
  },
  "timestamp": "2024-01-20T10:30:00Z"
}
Error Handling Always check the success field in API responses and handle errors appropriately in your application.

Support

Technical Support

Need assistance with WalletPlug API integration? Our technical team provides comprehensive support.

Support Hours: 24/7 for critical issues