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.
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 |
Quick Start
Get up and running with WalletPlug API in just a few steps:
Step 1: Get Credentials
- Login to your WalletPlug dashboard
- Navigate to Merchant → CONFIG
- Copy your Merchant ID, API Key, and Client Secret
Step 2: Make Request
- Set required headers with your credentials
- POST to
/api/v1/initiate-payment - Redirect user to returned payment URL
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.
/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
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
{
"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
{
"success": false,
"message": "Validation failed",
"errors": {
"payment_amount": ["The payment amount field is required."],
"currency_code": ["The currency code field is required."]
}
}
Verify Payment
Verify the status of a payment using the WalletPlug transaction ID returned from the payment initiation.
/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
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
{
"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 |
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).
How it works
- Call initiate-payment as usual, restricting the session to card with allow_payment_methods.
- The response includes card_url — a signed, short-lived URL that renders ONLY the card form (no method selection, no branding).
- Embed card_url in an iframe inside your checkout page.
- On completion the frame navigates the top window to your success_redirect / failure_url / cancel_redirect.
- 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"
}
| Field | Use it when |
|---|---|
payment_url | You want the full hosted checkout (all payment methods, redirect flow). Also embeddable in an iframe if you want every method inline. |
card_url | You 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();
});
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:
| Field | Type | Effect |
|---|---|---|
embed_style | string | "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_amount | boolean | Hides the purple "Amount to Pay" banner only. |
embed_hide_header | boolean | Hides the title/logo header only. |
embed_hide_footer | boolean | Hides the footer (SSL badge, card brand icons, secured-by line). |
embed_pay_label | string (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.
/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.
- Only
completedtransactions 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.
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 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:
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 samepayment_urlis returned. - If the first request has
completed— aDUPLICATE_REFERENCEerror is returned. Do not retry. - If the first request
failedorexpired— a new payment session is created.
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.
https://walletplug.com/api/v1/billing
Core Concepts
| Resource | Description |
|---|---|
Plan | A reusable pricing template: amount + cycle + trial. Each plan has a stable UUID and a public checkout URL. |
Customer | A buyer that belongs to your merchant account. Identified uniquely by email within your account. |
PaymentMethod | Tokenised card reference issued by WalletPlug after secure capture on the WalletPlug hosted checkout. Tokens never expose raw card numbers. |
Subscription | A live billing agreement between a Customer and a Plan. Has a status, cycle counters, and a next_billing_at timestamp. |
Invoice | A single billing period charge. One subscription generates many invoices over time. |
Event | Anything 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:
| Header | Value |
|---|---|
X-Merchant-Key | Your WalletPlug merchant_key |
X-API-Key | Your WalletPlug api_key (or test_api_key for sandbox) |
X-Environment | production | sandbox |
Content-Type | application/json |
Plans
POST /api/v1/billing/plans
Create a recurring pricing plan.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Display name, e.g. "Pro Monthly" |
description | string | — | Optional marketing copy |
amount | decimal | ✅ | Charge amount per cycle, e.g. 29.99 |
currency | string(3) | ✅ | USD, EUR, NGN, … |
billing_interval | enum | ✅ | day | week | month | year |
interval_count | integer | ✅ | e.g. 1 month, 3 months, 6 months |
trial_days | integer | — | 0 = no trial |
total_cycles | integer | — | null/0 = indefinite, otherwise stop after N cycles |
metadata | object | — | Free-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
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/billing/plans | List 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
| Field | Required | Description |
|---|---|---|
plan | ✅ | Plan UUID |
customer | ✅ | Customer UUID |
payment_method | — | PaymentMethod UUID. Defaults to the customer's default method. |
metadata | — | Free-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
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/billing/subscriptions?status=active | List with optional status filter |
| GET | /api/v1/billing/subscriptions/{uuid} | Retrieve with invoices included |
| POST | /api/v1/billing/subscriptions/{uuid}/cancel | Cancel. 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.
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
| Event | When it fires |
|---|---|
plan.created | A plan is created |
customer.created | A new customer is created |
subscription.created | Subscription record is created (may be in trial) |
subscription.activated | First successful charge — sub is now active |
subscription.past_due | Payment failed; entered dunning |
subscription.cancel_scheduled | Cancel-at-period-end requested |
subscription.canceled | Canceled immediately |
subscription.expired | Total cycle limit reached |
invoice.paid | A charge succeeded |
invoice.failed | A 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 accessinvoice.paid— a renewal succeededinvoice.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 becauselast_payment_atis null.
Test it before going live
- Add your endpoint and select events.
- Click 'Send test event' on the endpoint card. We'll POST a sample
subscription.activatedto your URL. - Verify your handler returns 200 in the Recent Deliveries panel.
- Do a real
$1subscription with your own card to confirm the full flow end-to-end.
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.
- Download the plugin zip: Download (.zip)
- In WP-Admin → Plugins → Add New → Upload Plugin → choose the zip → Activate.
- 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.
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');
}
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.
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 |
|---|---|---|---|
USD | US Dollar | 1.00 | Global |
EUR | Euro | 1.00 | Europe, Global |
GBP | British Pound | 1.00 | United Kingdom, Global |
CAD | Canadian Dollar | 1.00 | Canada |
AUD | Australian Dollar | 1.00 | Australia, Oceania |
CHF | Swiss Franc | 1.00 | Switzerland |
JPY | Japanese Yen | 100 | Japan |
CNY | Chinese Yuan | 5.00 | China, Asia |
HKD | Hong Kong Dollar | 8.00 | Hong Kong |
SGD | Singapore Dollar | 1.00 | Singapore, Southeast Asia |
NZD | New Zealand Dollar | 1.00 | New Zealand |
SEK | Swedish Krona | 10.00 | Sweden, Scandinavia |
NOK | Norwegian Krone | 10.00 | Norway, Scandinavia |
DKK | Danish Krone | 7.00 | Denmark, Scandinavia |
AED | UAE Dirham | 4.00 | United Arab Emirates |
SAR | Saudi Riyal | 4.00 | Saudi Arabia |
QAR | Qatari Riyal | 4.00 | Qatar |
KWD | Kuwaiti Dinar | 0.30 | Kuwait |
BHD | Bahraini Dinar | 0.40 | Bahrain |
INR | Indian Rupee | 50.00 | India |
BDT | Bangladeshi Taka | 100.00 | Bangladesh |
PKR | Pakistani Rupee | 250.00 | Pakistan |
MYR | Malaysian Ringgit | 4.00 | Malaysia |
IDR | Indonesian Rupiah | 15000 | Indonesia |
PHP | Philippine Peso | 50.00 | Philippines |
THB | Thai Baht | 35.00 | Thailand |
VND | Vietnamese Dong | 25000 | Vietnam |
NGN | Nigerian Naira | 500.00 | Nigeria |
GHS | Ghanaian Cedi | 10.00 | Ghana |
KES | Kenyan Shilling | 100.00 | Kenya |
ZAR | South African Rand | 10.00 | South Africa |
UGX | Ugandan Shilling | 3500.00 | Uganda |
TZS | Tanzanian Shilling | 2500.00 | Tanzania |
RWF | Rwandan Franc | 1000.00 | Rwanda |
XOF | West African CFA Franc | 500.00 | Francophone West Africa |
XAF | Central African CFA Franc | 500.00 | Central Africa |
EGP | Egyptian Pound | 30.00 | Egypt |
MAD | Moroccan Dirham | 10.00 | Morocco |
ZMW | Zambian Kwacha | 20.00 | Zambia |
ETB | Ethiopian Birr | 55.00 | Ethiopia |
BRL | Brazilian Real | 5.00 | Brazil, Latin America |
MXN | Mexican Peso | 17.00 | Mexico |
ARS | Argentine Peso | 900.00 | Argentina |
COP | Colombian Peso | 4000.00 | Colombia |
CLP | Chilean Peso | 900.00 | Chile |
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
Europe
Africa
WalletPlug has expanded deep across Africa with local currency, mobile money, and bank transfer integration on every major market.
Middle East
Asia Pacific
And More
WalletPlug is continuously expanding. Contact us if you need a specific country enabled — we likely already support it.
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.
Bank Transfers — All Types
Local and international bank-to-bank transfers across all supported countries — real-time where available.
Mobile Money
The dominant payment method across Africa and parts of Asia — deeply integrated with all major operators.
Digital Wallets and BNPL
Global digital wallets and buy-now-pay-later options for maximum checkout conversion worldwide.
Vouchers and Prepaid
Prepaid voucher redemption — essential for markets with high unbanked populations.
Cryptocurrency
Accept crypto from customers anywhere and settle in your preferred local currency — no volatility risk for merchants.
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 |
|---|---|
card | All cards — Visa, Mastercard, Verve, Amex, UnionPay, JCB, Discover, and all local debit networks |
bank_transfer | All local and international bank transfer methods — SEPA, ACH, SWIFT, Faster Payments, UPI, PIX, and local variants |
mobile_money | MTN, Airtel, M-Pesa, Wave, Vodafone Cash, and all supported mobile money operators |
wallet | WalletPlug Wallet, Apple Pay, Google Pay, Samsung Pay, Alipay, WeChat Pay, and all digital wallets |
voucher | WalletPlug Voucher, prepaid cards, gift cards, and all voucher-based payment methods |
crypto | Bitcoin, Ethereum, USDT, USDC, and all supported cryptocurrency options |
| omitted | Recommended — All methods for the customer's region shown automatically for maximum conversion |
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 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-KeyorX-Merchant-Keyin 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)
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-Signatureis missing or empty - Reject webhooks with a
timestampolder than 5 minutes (replay attack prevention) - Return
200 OKquickly (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.
walletplug before installing. Node.js / TypeScript
walletplug-node — npmOfficial 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-nodeQuick 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 — PackagistOfficial 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-phpQuick 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 — PyPIOfficial Python SDK with sync and async clients. Full type hints, dataclass models, Django, FastAPI, and Flask support. Python 3.8+.
Install
pip install walletplug-pythonQuick 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 toolImport the WalletPlug API directly into Postman, Insomnia, or any OpenAPI-compatible tool. Pre-configured with sandbox credentials and all endpoints ready to test.
SDK Feature Comparison
| Feature | Node.js | PHP | Python |
|---|---|---|---|
| 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 |
github.com/walletplug.
Integration Examples
Complete integration examples for popular platforms and frameworks.
<?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.comUse 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/jsonAndroid (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 checkoutVerify Payment
val verification = client.verifyPayment("TXNQ5V8K2L9N3XM1")
// Handle status: success | pending | failediOS (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)
}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.
Latest SDK Download
Complete React Native SDK — API client, WalletPlugCheckout WebView component, useWalletPlug hook, TypeScript types, and error classes.
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
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-webviewComplete 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:
Mobile app → your backend
The app sends order details (amount, currency, order ID) to your backend server.
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.
App shows WalletPlugCheckout
The app opens the WalletPlugCheckout component with the payment_url. Customer completes payment on WalletPlug's hosted page.
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 / Property | Description |
|---|---|
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.isSandbox | Boolean — true if environment is sandbox |
useWalletPlug(client) hook
| Return value | Type | Description |
|---|---|---|
initiatePayment(params) | async function | Initiate payment, stores result in paymentResult |
verifyPayment(trxId) | async function | Verify a payment by trxId |
loading | boolean | True while an API call is in progress |
error | string | null | Last error message |
clearError() | function | Reset the error state |
paymentResult | object | null | Last successful initiate result |
Troubleshooting
White screen or WebView not loading
Solutions:
- Confirm
react-native-webviewis installed andpod installwas run (iOS) - Check the
paymentUrlis 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_redirecttowalletplug://payment/success?trx_id=TXNXXXXXwhen 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.
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.
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
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
Add dependency
dependencies:
walletplug: ^1.0.0flutter pub getiOS — add to Info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>Android — add to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>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_flutteris inpubspec.yamlandflutter pub gethas been run - On iOS, add
NSAllowsArbitraryLoadstoInfo.plist - Confirm the
paymentUrlis a valid HTTPS URL — re-callpayments.initiate()if the session may have expired (60-minute timeout)
onSuccess not firing after payment
Solutions:
- Ensure
successUrlis set towalletplug://payment/successwhen callingpayments.initiate() - Register the
walletplug://URL scheme inAndroidManifest.xmlandInfo.plist - Check that your backend sets the correct
success_redirectURL 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
environmentmatches your key prefix — sandbox keys begin withtest_ - 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.
Latest Plugin Download
Enterprise-grade WooCommerce payment gateway with modern Blocks support and dynamic branding.
No Redirecting Version — embedded checkout: your customers pay in a secure WalletPlug window without ever leaving your store. Orders complete automatically.
Card Only Version — the card form loads directly on your checkout: no payment-method screen and no third-party branding. Orders complete automatically.
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.
System Requirements
- WordPress 5.8+
- WooCommerce 6.0+
- PHP 8.1+ (8.2+ Recommended)
- SSL Certificate (Required)
- WalletPlug Merchant Account
- WooCommerce Blocks Support
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
Download Latest Plugin
Download WalletPlug WooCommerce Gateway v2.9.0 from the download section above. This includes all latest features and security updates.
Install via WordPress Admin
Navigate to Plugins → Add New → Upload Plugin and select the downloaded ZIP file. The plugin will auto-extract and install.
Activate & Configure
Activate the plugin and go to WooCommerce → Settings → Payments → WalletPlug. Enter your API credentials and webhook secret.
Test Integration
Enable Test Mode, process a sandbox transaction to verify Blocks checkout, webhook delivery, and order completion.
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
Merchant ID & API Key
Your unique merchant credentials from WalletPlug dashboard
RequiredWebhook Secret
HMAC-SHA256 signature verification for secure callbacks
RecommendedAuthentication 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.
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.
System Requirements
- Node.js 18+
- Shopify Partner Account
- Shopify Store (any plan)
- SSL Certificate (Required)
- WalletPlug Merchant Account
- HTTPS-enabled app server
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
Customer Clicks Pay
Customer selects WalletPlug Pay at Shopify checkout and clicks the payment button.
Payment Session Created
Plugin POSTs order details to /api/payment/initiate which calls the WalletPlug API and returns a payment_url.
Redirect to Checkout
Customer is redirected to the secure WalletPlug hosted checkout page to complete payment.
Webhook Notification
WalletPlug sends a signed IPN webhook to /api/payment/webhook with the payment result.
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
Download & Extract Plugin
Download the ZIP above and extract it. You will find the backend/, theme-snippet/, and config files inside.
Configure Credentials
Copy .env.example to .env and fill in your WalletPlug Merchant ID, API Key, Webhook Secret, and Shopify App credentials.
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.
Set Webhook URL
In your WalletPlug merchant dashboard, set the IPN/Webhook URL to: https://your-server.com/api/payment/webhook
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.
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
Merchant ID & API Key
Your WalletPlug credentials from Dashboard → Merchant → CONFIG
RequiredWebhook Secret
Client Secret used to verify all incoming webhook signatures
RecommendedAuthentication 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_URLin.envmatches 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_KEYandWALLETPLUG_API_KEYare correct in.env - Ensure
WALLETPLUG_ENVIRONMENTmatches 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_SECRETin.envmatches the Client Secret in your dashboard - Check your server logs at
/api/payment/webhookfor 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.
Latest Extension Download
Native OpenCart payment extension — admin settings panel, checkout button, webhook handler, and HMAC signature verification all included.
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
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
Download the Extension
Download the .ocmod.zip file above. This is the ready-to-install OpenCart extension package.
Upload via Extension Installer
In OpenCart Admin go to Extensions → Installer, click Upload, and select the downloaded ZIP. OpenCart installs all files automatically.
Refresh Modifications
Go to Extensions → Modifications and click the Refresh button (top right) to apply the extension changes.
Activate & Configure
Go to Extensions → Extensions → Payments, find WalletPlug Pay, click Install then Edit. Enter your Merchant ID, API Key, and Webhook Secret.
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
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
Merchant ID & API Key
Your WalletPlug credentials from Dashboard → Merchant → CONFIG
RequiredWebhook Secret
Client Secret used to verify all incoming IPN webhook signatures
RecommendedAuthentication 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 → Paymentsand confirm WalletPlug Pay is set to Enabled - Go to
Extensions → Modificationsand 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 —
sandboxkeys must have atest_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.
Latest Module Download
Complete PrestaShop payment module — main class, front controllers, Smarty templates, webhook handler, and admin config form.
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
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
Download the Module
Download the .zip file above. It contains the complete walletplug/ module folder ready to upload.
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.
Configure the Module
Click Configure on WalletPlug Pay. Enter your Merchant ID, API Key, and Webhook Secret from your WalletPlug dashboard. Choose your environment.
Set Webhook URL
In your WalletPlug merchant dashboard set the IPN/Webhook URL to:
https://your-store.com/module/walletplug/webhook
Test Integration
Set Environment to Sandbox and place a test order using the demo credentials. Verify the webhook updates order status correctly.
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
Merchant ID & API Key
Your WalletPlug credentials from Dashboard → Merchant → CONFIG
RequiredWebhook Secret
Client Secret for HMAC-SHA256 webhook signature verification
RecommendedAuthentication 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.
Latest Module Download
Complete Magento 2 payment module — registration, DI config, payment model, front controllers, webhook handler, and admin system config.
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
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
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.
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
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.
Set Webhook URL
In your WalletPlug merchant dashboard set the IPN/Webhook URL to:
https://your-store.com/walletplug/webhook/index
Test Integration
Set Environment to Sandbox, place a test order, and verify that the webhook correctly updates the Magento order state to Processing.
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
Merchant ID & API Key
Your WalletPlug credentials — stored encrypted in Magento config
RequiredWebhook Secret
Client Secret for HMAC-SHA256 signature verification — stored encrypted
RecommendedAuthentication 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:flushandbin/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.logandvar/log/exception.logfor 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.logfor[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.
Latest App Download
Complete BigCommerce app — Express backend, OAuth auth flow, WalletPlug payment service, BigCommerce API service, webhook handler, and storefront checkout script.
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)
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
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.
Download & Configure
Download the ZIP above, extract it, copy .env.example → .env, and fill in your BigCommerce App credentials and WalletPlug API keys.
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.
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.
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.
Set Webhook URL
In your WalletPlug merchant dashboard set the IPN/Webhook URL to:
https://your-app-server.com/api/payment/webhook
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
Merchant ID & API Key
Your WalletPlug credentials from Dashboard → Merchant → CONFIG
RequiredWebhook Secret
Client Secret for HMAC-SHA256 webhook signature verification
RecommendedAuthentication 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 Managerwith location Footer and pages Checkout - Verify
APP_URLinsidecheckout-script.jspoints 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_KEYandWALLETPLUG_API_KEYare correct in.env - Ensure
WALLETPLUG_ENVIRONMENTmatches the prefix of your keys — sandbox keys needtest_prefix - Restart the app server after changing
.envvalues - 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_SECRETin.envmatches the Client Secret in your dashboard - Check your app server logs for
[WalletPlug] Webhookentries 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.
Latest Plugin Download
Complete EDD payment gateway plugin — gateway registration, checkout flow, HMAC webhook handler, admin settings, and checkout form template.
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
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
Download & Upload Plugin
Download the ZIP above. In WordPress Admin go to Plugins → Add New → Upload Plugin, select the ZIP, and click Install Now.
Activate & Enable Gateway
Activate the plugin, then go to Downloads → Settings → Payment Gateways → Active Gateways and check WalletPlug Pay.
Configure Credentials
Go to Downloads → Settings → Payment Gateways → WalletPlug Pay. Enter your Merchant ID, API Key, and Webhook Secret, then choose your Environment.
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.
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.
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
Merchant ID & API Key
Your WalletPlug credentials from Dashboard → Merchant → CONFIG
RequiredWebhook Secret
Client Secret for HMAC-SHA256 webhook signature verification
RecommendedAuthentication 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 Gatewaysand 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=webhookis 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.
Latest Addon Download
Complete CS-Cart payment addon — addon manifest, payment processor, frontend/backend controllers, Smarty checkout template, webhook handler, and language strings.
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)
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
Download the Addon
Download the ZIP above. It contains the complete addon structure ready for upload.
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.
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.
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.
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
Test Integration
Set Environment to Sandbox and place a test order. Verify the payment completes and the CS-Cart order status updates to Processed.
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
Merchant ID & API Key
Your WalletPlug credentials from Dashboard → Merchant → CONFIG
RequiredWebhook Secret
Client Secret for HMAC-SHA256 webhook signature verification
RecommendedAuthentication 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 bywalletplug_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.
Latest Plugin Download
Complete Gravity Forms payment addon — GF framework integration, per-form feeds, API class, IPN webhook handler, and return URL management.
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
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
Install & Activate Plugin
Upload and activate the plugin via WordPress Admin → Plugins → Add New → Upload.
Configure Global Settings
Go to Forms → Settings → WalletPlug Pay. Enter your Merchant ID, API Key, Webhook Secret, and choose your Environment.
Set Webhook URL
In your WalletPlug merchant dashboard set the IPN/Webhook URL to:
https://your-site.com/?walletplug_gf_action=webhook
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.
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).
Latest Plugin Download
Complete Ecwid / Lightspeed integration — WordPress plugin with settings admin page, payment initiation handler, IPN webhook, and Ecwid REST API order update.
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
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
Install WordPress Plugin
Upload and activate the plugin via WordPress Admin → Plugins → Add New → Upload. This provides the payment endpoint and webhook handler.
Configure Credentials
Go to WordPress Admin → Settings → WalletPlug Ecwid. Enter your Ecwid Store ID, WalletPlug Merchant ID, API Key, Webhook Secret, and Environment.
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
Set Webhook URL
In your WalletPlug merchant dashboard set the IPN/Webhook URL to:
https://your-wp-site.com/?walletplug_ecwid_action=webhook
Test in Sandbox
Place a test order in Ecwid, pay with sandbox credentials, and verify the Ecwid order status updates to PAID.
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.
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.phpQuick Installation Guide
Install the WHMCS gateway module and start accepting payments via WalletPlug.
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.
Activate in WHMCS
Go to WHMCS → Setup → Payments → Payment Gateways, select walletplug, and click Activate.
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.
Set Webhook (Callback)
Set the webhook URL in your WalletPlug merchant dashboard:
https://walletplug.com/modules/gateways/callback/walletplug.phpEnsure the same Webhook Secret Key is set in both systems.
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/jsonInitiate 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-Environmentheader. - 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.
Latest Plugin Download
Complete Bubble.io plugin package — plugin manifest JSON, 3 server-side action files, companion server source, and full setup guide.
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
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
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.
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.
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.
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).
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.
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).
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
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 Payand 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_NAMEandBUBBLE_API_KEYenvironment 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 emptyso 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.
Download Plugin
Complete GiveWP payment gateway plugin — gateway registration, payment processing, HMAC-verified IPN webhook, GiveWP settings panel, and automatic donation receipt triggers.
Requirements
- GiveWP 3.0+
- WordPress 5.8+
- PHP 7.4+ (8.1+ recommended)
- SSL Certificate (required)
- WalletPlug Merchant Account
Installation Guide
Install & Activate
Upload and activate via WordPress Admin → Plugins → Add New → Upload.
Configure Credentials
Go to Donations → Settings → Payment Gateways → WalletPlug Pay. Enter your Merchant ID, API Key, Webhook Secret, and Environment.
Enable on Donation Forms
Edit any GiveWP form → Payment Gateways → enable Pay with WalletPlug.
Set Webhook URL
https://your-site.com/?walletplug_givewp_action=webhookTest & 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_donationhook 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.
Download Plugin
Complete WPForms payment plugin — hooks into WPForms payment processing, HMAC-verified IPN webhook, entry status management, and a WordPress admin settings page.
Requirements
- WPForms 1.8+ (Pro recommended for payments)
- WordPress 5.8+
- PHP 7.4+ (8.1+ recommended)
- SSL Certificate (required)
- WalletPlug Merchant Account
Installation Guide
Install & Activate
Upload and activate via WordPress Admin → Plugins → Add New → Upload.
Configure Credentials
Go to WPForms → WalletPlug Pay in the admin menu. Enter your Merchant ID, API Key, Webhook Secret, and Environment.
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.
Set Webhook URL
https://your-site.com/?walletplug_wpforms_action=webhookTest & 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
Paymentssettings 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.
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.
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)
How It Works
Webflow does not support custom payment gateways natively. This integration uses a companion server you deploy for free.
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.
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.
Customer redirected to WalletPlug checkout
The customer completes payment on WalletPlug's secure hosted checkout page — cards, mobile money, wallets, crypto, and more.
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.
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
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.
Add a Pay button with data attributes
In Webflow, add a Button element and set these Custom Attributes:
| Attribute | Value |
|---|---|
data-walletplug-pay | (no value needed) |
data-amount | 99.99 (or a CMS dynamic field) |
data-currency | USD |
data-order-id | Your order ID or CMS item slug |
data-customer-email | Optional — pre-fill checkout |
Set Webhook URL in WalletPlug dashboard
https://your-app.railway.app/webhookConnect 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_URLwas replaced correctly in the embed code - Check the companion server logs — the
/payendpoint 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_URLenvironment variable to your exact Webflow site URL including protocol, e.g.https://your-site.webflow.io - If using a custom domain, set
WEBFLOW_SITE_URLto 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.
Download Integration Package
Complete Squarespace integration — Express companion server, mobile-responsive Code Block embed, .env.example, and deployment guide for Railway and Render.
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)
How It Works
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.
Companion server calls WalletPlug API
Your server initiates the payment — API credentials are stored as server environment variables, never exposed in the browser.
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.
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.
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
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.
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.
Set Webhook URL in WalletPlug dashboard
https://your-app.railway.app/webhookTest 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_URLwas 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_URLto 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.htmlwas 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-wrapif 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.
Download Plugin
Complete LearnDash payment gateway — course and group enrollment, payment button injection, IPN webhook handler, transaction logging, and WordPress admin settings.
Requirements
- LearnDash LMS 4.0+
- WordPress 5.8+
- PHP 7.4+ (8.1+ recommended)
- SSL Certificate (required)
- WalletPlug Merchant Account
Installation Guide
Install & Activate
Upload and activate via WordPress Admin → Plugins → Add New → Upload.
Configure Credentials
Go to LearnDash LMS → WalletPlug Pay. Enter your Merchant ID, API Key, Webhook Secret, and Environment.
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.
Set Webhook URL
https://your-site.com/?walletplug_ld_action=webhookTest & 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.
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.
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
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
Install & Activate
Upload and activate via WordPress Admin → Plugins → Add New → Upload Plugin. LifterLMS must be active first.
Configure Credentials
Go to LifterLMS → WalletPlug Pay in the WordPress admin. Enter your Merchant ID, API Key, Webhook Secret, and choose your Environment.
Enable in LifterLMS Payment Settings
Go to LifterLMS → Settings → Checkout. Under Payment Gateways, enable WalletPlug Pay and save.
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
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_completeaction 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.
Download Plugin
Complete MemberPress payment gateway — extends MeprBaseRealGateway, settings panel in MemberPress admin, HMAC webhook verification, membership activation, and receipt email triggers.
Requirements
- MemberPress 1.9+
- WordPress 5.8+
- PHP 7.4+ (8.1+ recommended)
- SSL Certificate (required)
- WalletPlug Merchant Account
Installation Guide
Install & Activate
Upload and activate via WordPress Admin → Plugins → Add New → Upload.
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.
Assign to Memberships
Edit any membership → Price Box → Payment Methods → enable WalletPlug Pay for that membership.
Set Webhook URL
https://your-site.com/?walletplug_mp_action=webhookTest & 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.
Download Plugin
Complete PMPro payment gateway — extends PMProGateway, settings panel in PMPro admin, HMAC webhook verification, automatic membership activation, and full order status management.
Requirements
- Paid Memberships Pro 2.9+ (free or paid)
- WordPress 5.8+
- PHP 7.4+ (8.1+ recommended)
- SSL Certificate (required)
- WalletPlug Merchant Account
Installation Guide
Install & Activate
Upload and activate via WordPress Admin → Plugins → Add New → Upload.
Configure Gateway
Go to Memberships → Payment Settings. Select WalletPlug Pay as your gateway. Enter your Merchant ID, API Key, Webhook Secret, and Environment.
Set Webhook URL
https://your-site.com/?walletplug_pmpro_action=webhookTest & 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_checkoutfires 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.
test_ prefixed credentials only. Never enter production keys into a browser tool. Sandbox Test Methods
| Method | Test Credentials | Result |
|---|---|---|
| Demo Wallet | ID: 123456789 / Password: demo123 | Completes payment |
| Demo Voucher | Code: TESTVOUCHER | Completes payment |
| Gateway | Auto-approves all transactions | Completes payment |
| Decline Test | Use amount: 0.01 | Triggers 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.
Shopify Tutorial
Install the app, connect your keys, activate at checkout, test in sandbox, and go live.
WooCommerce Tutorial
Upload the plugin to WordPress, enable it, paste your keys, test in sandbox, and go live.
OpenCart Tutorial
Upload the extension, install it under Payments, connect your keys, test in sandbox, and go live.
PrestaShop Tutorial
Upload the module in Module Manager, configure it, connect your keys, test in sandbox, and go live.
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 OK | Request succeeded | Process the response |
| 400 Bad Request | Invalid parameters | Check the errors object for field-level details and fix your request |
| 401 Unauthorized | Invalid or missing API credentials | Check X-Merchant-Key and X-API-Key. Ensure environment matches key prefix. |
| 403 Forbidden | Valid credentials but action not permitted | Check your account status in the WalletPlug Dashboard |
| 404 Not Found | Resource does not exist | Verify the transaction ID or endpoint path is correct |
| 422 Unprocessable | Request valid but cannot be processed | Check message — e.g. transaction already refunded |
| 429 Too Many Requests | Rate limit exceeded | Read Retry-After header and wait before retrying. Use exponential backoff. |
| 500 Server Error | Unexpected server error | Retry with exponential backoff. Contact support if persistent. |
| 503 Unavailable | API temporarily unavailable | Retry 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_CREDENTIALS | 401 | Merchant key or API key is invalid or does not match the environment | Re-enter credentials from Dashboard. Check environment matches key prefix. |
ACCOUNT_SUSPENDED | 403 | Merchant account is suspended | Contact WalletPlug support. |
ACCOUNT_NOT_VERIFIED | 403 | Merchant account not verified for production | Complete verification in the WalletPlug Dashboard. |
VALIDATION_ERROR | 400 | One or more required parameters are missing or invalid | Check the errors object for field-level messages. |
INVALID_AMOUNT | 400 | Payment amount below minimum or invalid format | Ensure amount is a positive number with up to 2 decimal places. |
INVALID_CURRENCY | 400 | Currency code is not a supported ISO 4217 code | Use a valid 3-letter code. See Supported Currencies. |
DUPLICATE_REFERENCE | 400 | The ref_trx has already been used for another transaction | Use a unique reference for every payment request. |
INVALID_URL | 400 | A redirect or webhook URL is malformed | All URLs must be valid HTTPS URLs. |
TRANSACTION_NOT_FOUND | 404 | No transaction found with the provided trx_id | Verify the ID. Sandbox and production IDs are not interchangeable. |
TRANSACTION_NOT_COMPLETED | 422 | Refund requested on a non-completed transaction | Only completed transactions can be refunded. |
TRANSACTION_ALREADY_REFUNDED | 422 | Transaction has already been fully refunded | Check refund history before retrying. |
REFUND_AMOUNT_EXCEEDS_PAYMENT | 422 | Refund amount greater than original payment | Refund amount cannot exceed the original transaction amount. |
RATE_LIMITED | 429 | Too many requests in the current window | Read Retry-After header. Implement exponential backoff. |
INVALID_SIGNATURE | 401 | Webhook HMAC-SHA256 signature verification failed | Use 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);
}
}
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.
v2.0.0 — Subscriptions Billing
Latest Major ReleaseAdded — 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 lifecycle —
incomplete → 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-XXXXnumbering. - Coupons — percent or fixed discounts;
once/repeating(N months)/foreverduration; 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
BillingGatewayinterface (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}/cancelwithat_period_endflag. - 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: sandboxto 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-planattribute, andWalletPlug.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:subscriptionDOM 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 signature —
X-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_failedandcharge.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
StableAdded — 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 officialMeprBaseRealGateway, full gateway settings panel inside MemberPress, automatic membership activation,MeprUtilsreceipt email triggers - Paid Memberships Pro plugin (
walletplug-pmpro) v1.0.0 — extends officialPMProGateway, settings under Memberships → Payment Settings,pmpro_after_checkouthook, 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.phpfunction 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-wpformsicon withfa-paper-planethroughout section heading, header, and feature cards - Full CDN cache purge and Laravel view cache cleared — all documentation updates now live
v1.4.0
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, andwebhooks.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. SyncWalletPlugclient and asyncAsyncWalletPlugclient (httpx), full type hints, dataclass models, Django and FastAPI integration examples - Official React Native SDK (
walletplug-react-native) — published to npm. Drop-inWalletPlugCheckoutWebView component,useWalletPlughook, Expo compatible, TypeScript types - All SDKs include
payments.initiate(),payments.verify(),payments.refund(), andwebhooks.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_completedtrigger - 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.completedandrefund.failednow delivered to merchant IPN URL customer_nameandcustomer_emailparameters added toPOST /api/v1/initiate-paymentmain 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, 2026Added — 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_PAYMENTlifecycle - 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_purchasehook, 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, 2026Added
customer_nameandcustomer_emailoptional parameters added toPOST /api/v1/initiate-payment— pre-fills customer details at checkoutallow_payment_methodsparameter 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
environmentandis_sandboxfields 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-Signatureheader now consistently included on all webhook deliveries including retries
v1.1.0
Feb 01, 2026Added
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
expiredadded — sessions expire after 60 minutes of inactivity
Changed
failure_urlparameter renamed fromfailed_redirect— old name still accepted but deprecated, will be removed in v2- Webhook
statusfield values normalised:success→completed— old value still delivered for 90 days then removed
v1.0.0
Initial ReleaseAdded
POST /api/v1/initiate-payment— create a payment session and receive a hosted checkout URL- Sandbox and Production environment support via
X-Environmentheader - HMAC-SHA256 webhook signature verification via
X-Signatureheader - 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:
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.
Merchant Email Notification
All active merchants are notified by email with clear migration instructions and the exact removal date. Minimum 30-day notice guaranteed.
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.
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"
}
Support
Technical Support
Need assistance with WalletPlug API integration? Our technical team provides comprehensive support.