DGateway WordPress Plugin
The DGateway WordPress Plugin lets you accept Mobile Money and Card payments on any WordPress site. It works in two modes:
- Standalone Mode — Use shortcodes to add payment and subscribe buttons anywhere on your site. No WooCommerce required.
- WooCommerce Mode — Full payment gateway integration with automatic checkout, order management, and subscription products.
| Feature | Standalone | WooCommerce |
|---|---|---|
| One-time payments | Yes (shortcode) | Yes (checkout) |
| Recurring subscriptions | Yes (shortcode) | Yes (product type) |
| Mobile Money (MTN, Airtel) | Yes | Yes |
| Card payments (Stripe) | Yes | Yes |
| Admin dashboard | Yes | Yes |
| Webhook handling | Yes | Yes |
| Order management | No | Yes |
Installation
From WordPress Admin
Upload the plugin ZIP file from the WordPress admin panel.
1. Go to Plugins → Add New → Upload Plugin
2. Select the dgateway-plugin.zip file
3. Click "Install Now"
4. Click "Activate"Manual Installation
# Download or clone the plugin
git clone https://github.com/MUKE-coder/dgateway-plugin.git
# Copy to your WordPress plugins directory
cp -r dgateway-plugin /path/to/wordpress/wp-content/plugins/
# Activate from WordPress admin: Plugins → Activate "DGateway Payment Gateway"Configuration
After activation, configure the plugin from the WordPress admin menu.
1. Go to DGateway → Settings in the WordPress admin sidebar
2. Enter your DGateway API URL (default: https://dgatewayapi.desispay.com)
3. Enter your API Key (from the DGateway admin dashboard → Apps → API Keys)
4. Set your default currency (UGX, KES, USD, etc.)
5. Copy the Webhook Secret — you'll need this in your DGateway app settings
6. Click "Save Changes"| Setting | Description | Default |
|---|---|---|
| API URL | Your DGateway server URL | https://dgatewayapi.desispay.com |
| API Key | API key from DGateway dashboard | (empty) |
| Default Currency | Currency for payments | UGX |
| Webhook Secret | Auto-generated secret for verifying webhooks | (auto-generated) |
https://yoursite.com/wp-json/dgateway/v1/webhookImportant: Test vs Live API Keys
When testing with a Test API Key, you cannot use your real phone number. Use the designated test number instead:
Test Phone Number: 0111777777When you switch to a Live API Key, you can use real customer phone numbers to process actual payments.
Payment Button Shortcode
Add a payment button anywhere on your site using the [dgw_pay_button] shortcode. When clicked, it opens a modal where the customer enters their phone number and confirms the payment.
Basic Usage
[dgw_pay_button amount="50000" currency="UGX" description="Premium Access"]All Attributes
| Attribute | Required | Default | Description |
|---|---|---|---|
| amount | Yes | — | Payment amount in the specified currency |
| currency | No | UGX | ISO 4217 currency code |
| description | No | Payment | Description shown to the customer |
| label | No | Pay Now | Button text |
| class | No | (empty) | Additional CSS classes for the button |
| provider | No | (auto) | Force a specific provider: iotec, stripe, relworx |
Examples
// Basic mobile money payment
[dgw_pay_button amount="25000" currency="UGX" description="Event Ticket"]
// USD card payment via Stripe
[dgw_pay_button amount="10" currency="USD" provider="stripe" label="Pay $10"]
// Custom styled button
[dgw_pay_button amount="100000" currency="UGX" label="Buy Course" class="my-custom-btn"]
// Redirect after successful payment
[dgw_pay_button amount="50000" currency="UGX" description="Membership Fee" label="Join Now" success_url="/thank-you"]
// Consultation booking payment
[dgw_pay_button amount="75000" currency="UGX" description="1-Hour Consultation" label="Book & Pay"]
// Event registration with card only
[dgw_pay_button amount="150000" currency="UGX" provider="stripe" description="Conference Pass" label="Register"]The payment flow is fully handled by the plugin — a modal opens with the payment form, the customer enters their phone number (for mobile money) or card details (for Stripe), and the plugin polls for the payment status automatically.
Donation Form Shortcode
Create a donation form with preset amount buttons using the [dgw_donation_form] shortcode. Donors can select a preset amount or enter a custom one.
Basic Usage
[dgw_donation_form amounts="5000,10000,25000,50000" currency="UGX"]All Attributes
| Attribute | Required | Default | Description |
|---|---|---|---|
| amounts | No | 5000,10000,25000,50000 | Comma-separated preset amounts |
| currency | No | UGX | ISO 4217 currency code |
| allow_custom | No | yes | Allow custom amount input (yes/no) |
| title | No | Make a Donation | Form heading text |
| description | No | (empty) | Description shown below the title |
| collect_name | No | no | Show a name field (yes/no) |
| collect_email | No | no | Show an email field (yes/no) |
| success_message | No | Thank you for your donation! | Message shown after success |
| success_url | No | (empty) | Redirect URL after successful donation |
Examples
// Church or NGO donation form
[dgw_donation_form title="Support Our Mission" description="Every contribution makes a difference" amounts="10000,25000,50000,100000" currency="UGX"]
// Donation form with donor info collection
[dgw_donation_form title="Donate" amounts="5000,10000,50000" collect_name="yes" collect_email="yes"]
// Fixed amounts only (no custom input)
[dgw_donation_form amounts="20000,50000,100000" allow_custom="no" title="Choose a Giving Level"]
// USD donation with redirect
[dgw_donation_form amounts="5,10,25,50" currency="USD" title="Make a Gift" success_url="/thank-you"]
// School fundraiser
[dgw_donation_form title="School Building Fund" description="Help us build a new classroom" amounts="10000,25000,50000,100000" collect_name="yes" success_message="Thank you for supporting our school!"]Product Card Shortcode
Display a product card with an image, description, price, and a buy button using the [dgw_product_card] shortcode. No WooCommerce required.
Basic Usage
[dgw_product_card name="Online Course" price="150000" currency="UGX" description="Learn web development"]All Attributes
| Attribute | Required | Default | Description |
|---|---|---|---|
| name | No | Product | Product name displayed on the card |
| price | Yes | — | Product price |
| currency | No | UGX | ISO 4217 currency code |
| image | No | (empty) | Product image URL |
| description | No | (empty) | Product description text |
| button_label | No | Buy Now | Button text |
| success_url | No | (empty) | Redirect URL after successful payment |
Examples
// Digital product with image
[dgw_product_card name="E-Book: Startup Guide" price="25000" currency="UGX" image="/wp-content/uploads/ebook.jpg" description="A complete guide to launching your business" button_label="Buy E-Book"]
// Online course
[dgw_product_card name="Web Dev Masterclass" price="150000" currency="UGX" description="12 hours of video content + certificate" button_label="Enroll Now" success_url="/course-access"]
// Event ticket
[dgw_product_card name="Tech Conference 2026" price="50000" currency="UGX" image="/wp-content/uploads/conference.jpg" description="March 15, 2026 — Kampala Serena Hotel" button_label="Get Ticket"]
// Physical product
[dgw_product_card name="DGateway T-Shirt" price="35000" currency="UGX" image="/wp-content/uploads/tshirt.jpg" description="Premium cotton, available in all sizes"]Subscribe Button Shortcode
Create subscription signup buttons with the [dgw_subscribe_button] shortcode. This opens a modal that collects customer information and initiates the subscription.
Basic Usage
[dgw_subscribe_button plan_id="1" label="Subscribe Monthly"]All Attributes
| Attribute | Required | Default | Description |
|---|---|---|---|
| plan_id | Yes | — | The subscription plan ID from your DGateway dashboard |
| label | No | Subscribe | Button text |
| description | No | (plan name) | Description shown in the modal |
| class | No | (empty) | Additional CSS classes for the button |
Examples
// Monthly subscription
[dgw_subscribe_button plan_id="1" label="Start Monthly Plan"]
// With custom description
[dgw_subscribe_button plan_id="2" label="Go Premium" description="Premium access - UGX 100,000/month"]
// Gym membership
[dgw_subscribe_button plan_id="3" label="Join the Gym" description="Monthly gym access — UGX 80,000/month"]
// SaaS pricing tier
[dgw_subscribe_button plan_id="5" label="Start Pro Plan" description="Unlimited projects, priority support" class="pro-btn"]
// Content/media subscription
[dgw_subscribe_button plan_id="4" label="Subscribe Now" description="Unlimited articles & videos — UGX 15,000/week"]The subscribe modal collects the customer's name, email, and phone number, then creates the subscription via the DGateway API. If the plan has a trial period, the customer is subscribed without immediate payment. Otherwise, the first payment is collected immediately.
Shortcode Options & Styling
Both shortcodes render as standard HTML buttons that you can style with CSS. They include default styles from dgw-checkout.css but you can override them.
/* Custom styles in your theme's CSS */
.dgw-pay-btn {
background: #6c5ce7;
color: white;
padding: 12px 24px;
border-radius: 8px;
font-weight: 600;
border: none;
cursor: pointer;
}
.dgw-pay-btn:hover {
background: #5b4cdb;
}You can also use the buttons programmatically with JavaScript by adding the data-dgw-subscribe attribute to any HTML element:
<!-- Custom subscribe button via data attributes -->
<button
data-dgw-subscribe
data-dgw-plan-id="1"
data-dgw-description="Pro Plan Subscription"
>
Subscribe Now
</button>WooCommerce Payment Gateway
When WooCommerce is active, the plugin automatically registers the "DGateway" payment gateway. Customers can select it at checkout to pay with Mobile Money or Card.
Enable the Gateway
1. Go to WooCommerce → Settings → Payments
2. Find "DGateway Payment Gateway" and click "Set up"
3. Check "Enable DGateway Payment Gateway"
4. Set the Title (shown to customers, e.g. "Mobile Money / Card")
5. Set the Description (e.g. "Pay with MTN, Airtel Mobile Money or Card")
6. Click "Save changes"How Checkout Works
When a customer selects DGateway at checkout:
- The plugin sends a collect request to DGateway with the order amount and customer phone number
- For mobile money: The customer receives a USSD prompt on their phone to confirm payment
- For card payments: The customer is redirected to complete card payment via Stripe
- The plugin polls for payment status and marks the WooCommerce order as paid when confirmed
- If payment fails, the order is marked as failed with an error note
WooCommerce Subscription Products
The plugin adds a "DGateway Subscription" product type to WooCommerce, allowing you to sell recurring subscription products through your store.
Creating a Subscription Product
1. Go to Products → Add New
2. In the "Product data" dropdown, select "DGateway Subscription"
3. Set the product price (this is the recurring amount)
4. Click the "Subscription" tab in the product data panel
5. Enter the DGateway Plan ID (from your DGateway dashboard)
6. Select the Billing Interval (Monthly, Weekly, Daily, Yearly, or Custom)
7. Set Trial Days (0 for no trial)
8. Publish the product| Field | Description |
|---|---|
| DGateway Plan ID | The plan ID from your DGateway dashboard. Must match the plan's amount and interval. |
| Billing Interval | How often the customer is billed: daily, weekly, monthly, yearly, or custom |
| Trial Days | Number of free trial days before billing starts. Set to 0 for no trial. |
WooCommerce Checkout Flow
The checkout flow differs slightly between one-time and subscription products:
One-time Payment Flow
Customer → Adds product to cart → Checkout
→ Selects "DGateway Payment Gateway"
→ Enters phone number
→ Clicks "Place Order"
→ Plugin calls DGateway /v1/payments/collect
→ USSD prompt sent to customer's phone
→ Customer confirms on phone
→ DGateway webhook confirms payment
→ WooCommerce order marked as "Processing"Subscription Payment Flow
Customer → Adds subscription product to cart → Checkout
→ Selects "DGateway Payment Gateway"
→ Enters phone number
→ Clicks "Place Order"
→ Plugin calls DGateway /v1/subscriptions (creates subscription)
→ If trial: Subscription starts in "trialing" state, no immediate charge
→ If no trial: First cycle payment collected via mobile money
→ Customer confirms on phone
→ Subscription activated
→ Next cycle: DGateway sends webhook → Customer pays againHow Subscriptions Work
DGateway uses a "scheduled invoice" model for subscriptions. Unlike traditional auto-charge subscriptions, DGateway does NOT automatically charge customers. Instead:
- When a billing cycle is due, DGateway fires a subscription.payment_due webhook to your app
- Your app notifies the customer (email, SMS, in-app notification) that payment is due
- The customer re-initiates payment through the normal mobile money flow
- Once paid, the cycle advances and the next due date is calculated
Managing Plans
Subscription plans are created and managed through the DGateway admin dashboard or API. Plans define the amount, currency, billing interval, and trial/grace periods.
| Plan Setting | Description | Example |
|---|---|---|
| Name | Display name of the plan | Monthly Pro Plan |
| Amount | Recurring payment amount | 50,000 UGX |
| Currency | Payment currency | UGX |
| Interval | Billing frequency | monthly, weekly, daily, yearly |
| Trial Days | Free trial period before first charge | 7 days |
| Grace Days | Days to pay before subscription is paused | 3 days |
| Max Cycles | Maximum billing cycles (0 = unlimited) | 12 (for annual paid monthly) |
Creating Plans via API
// POST /v1/subscriptions/plans
// Header: X-API-Key: your_api_key
{
"name": "Monthly Pro Plan",
"amount": 50000,
"currency": "UGX",
"interval": "monthly",
"trial_days": 7,
"grace_days": 3,
"max_cycles": 0
}Subscription Lifecycle
Subscriptions move through several statuses during their lifecycle:
trialing → active → past_due → cancelled
│ │ │
│ ├── paused ──→ active (resumed)
│ │
│ └── completed (max_cycles reached)
│
└── active (trial ends, first payment collected)| Status | Description |
|---|---|
| trialing | Customer is in a free trial period. No charges yet. |
| active | Subscription is active. Billing cycles are created on schedule. |
| past_due | Payment is overdue. Grace period has expired but subscription not yet cancelled. |
| paused | Subscription is temporarily paused. No new cycles created. |
| cancelled | Subscription has been cancelled. No further charges. |
| completed | All max_cycles have been fulfilled. Subscription ended naturally. |
Subscription Webhooks
DGateway sends webhook events for subscription lifecycle changes. The WordPress plugin automatically handles these events.
| Event | When | Action |
|---|---|---|
| subscription.created | New subscription created | Log event, send welcome email |
| subscription.payment_due | Billing cycle is due | Notify customer to pay |
| subscription.payment_completed | Customer paid a cycle | Update access, send receipt |
| subscription.past_due | Grace period expired | Warn customer, restrict access |
| subscription.cancelled | Subscription cancelled | Revoke access, send confirmation |
| subscription.paused | Subscription paused | Log event |
| subscription.resumed | Subscription resumed | Restore access |
| subscription.completed | All cycles completed | Send completion notice |
Handling Webhooks in Your Theme
You can hook into subscription events in your theme or custom plugin using WordPress actions:
// In your theme's functions.php or a custom plugin
// Handle subscription webhook events
add_action('dgw_subscription_webhook', function($event, $subscription, $body) {
switch ($event) {
case 'subscription.payment_due':
// Send email notification to customer
$email = $subscription['customer_email'] ?? '';
$plan = $subscription['plan']['name'] ?? 'your plan';
wp_mail($email, 'Payment Due', "Your payment for {$plan} is due.");
break;
case 'subscription.payment_completed':
// Grant access to content
$user_email = $subscription['customer_email'] ?? '';
$user = get_user_by('email', $user_email);
if ($user) {
update_user_meta($user->ID, 'subscription_active', true);
}
break;
case 'subscription.cancelled':
// Revoke access
$user_email = $subscription['customer_email'] ?? '';
$user = get_user_by('email', $user_email);
if ($user) {
delete_user_meta($user->ID, 'subscription_active');
}
break;
}
}, 10, 3);
// Handle one-time payment webhooks
add_action('dgw_webhook_received', function($reference, $status, $body) {
if ($status === 'completed') {
// Payment successful — deliver digital product, update access, etc.
error_log("Payment completed: {$reference}");
}
}, 10, 3);Admin Dashboard
The plugin adds a "DGateway" menu to the WordPress admin sidebar with three pages:
| Page | Description |
|---|---|
| Settings | Configure API URL, API Key, default currency, and webhook secret |
| Transactions | View all payment transactions with status, amounts, and references |
| Subscriptions | View subscription plans and active subscriptions with status filters |
Transactions Page
The transactions page shows all payments processed through DGateway with real-time status updates. You can see the reference, amount, currency, status, and provider for each transaction.
Subscriptions Page
The subscriptions page shows two sections: your subscription plans and active subscriptions. Use the status filter to view subscriptions by their current state (active, trialing, past_due, etc.).
Webhook Handling
The plugin registers a webhook endpoint at /wp-json/dgateway/v1/webhook that receives payment and subscription events from DGateway.
Setting Up Webhooks
1. In the DGateway admin dashboard, go to your App settings
2. Set the Webhook URL to: https://yoursite.com/wp-json/dgateway/v1/webhook
3. Copy the Webhook Secret from WordPress (DGateway → Settings)
4. Paste the secret in the DGateway dashboard webhook secret field
5. Save settings on both sidesWebhook Security
Webhooks are verified using HMAC-SHA256 signatures. The plugin automatically validates the signature header against your webhook secret to ensure the request came from DGateway.
What Webhooks Handle
- Payment completed → WooCommerce order marked as paid
- Payment failed → WooCommerce order marked as failed
- Subscription events → Fired as WordPress actions for custom handling
Troubleshooting
| Issue | Solution |
|---|---|
| Payment button not showing | Ensure the shortcode has a valid amount attribute. Check that the plugin is activated. |
| "API Error" on payment | Verify your API Key and API URL in DGateway → Settings. Test with a small amount first. |
| USSD prompt not received | Check that the phone number includes the country code (e.g., 256771234567 for Uganda). |
| Webhook not updating orders | Verify the webhook URL is correct in the DGateway dashboard. Check the webhook secret matches. |
| WooCommerce gateway not showing | Go to WooCommerce → Settings → Payments and ensure DGateway is enabled. |
| Subscription product type missing | Make sure WooCommerce is activated. The plugin only shows the subscription product type when WooCommerce is active. |
| Modal not opening | Check browser console for JavaScript errors. Ensure jQuery is loaded (WordPress includes it by default). |
| Stripe payments not working | Stripe requires HTTPS. Ensure your site uses SSL. The Stripe publishable key is handled automatically by DGateway. |
Debug Logging
Enable WordPress debug logging to see detailed DGateway logs:
// In wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
// Logs will appear in wp-content/debug.log
// DGateway logs are prefixed with [DGateway] or [DGateway Webhook]If WooCommerce is active, DGateway also logs to the WooCommerce logger. View logs at WooCommerce → Status → Logs → select "dgateway" or "dgateway-webhook" from the dropdown.