Writing a payment gateway
Writing a payment gateway
Connect a payment provider that PremiumPress does not ship a plugin for.
Gateways are separate plugins, not part of the theme, so a gateway can be updated on its own. Before writing one, check the ready-made gateways at premiumpress.com/plugins.
How a payment flows
- The buyer chooses your gateway at checkout. The theme creates an order and asks your gateway where to send the buyer (
ppt_gateway_start). - You create the payment at your provider and return the address of its payment page.
- The buyer pays there and the provider sends them back to the return address the theme gave you.
- The theme asks your gateway whether the payment really went through (
ppt_gateway_verify). The order completes only when you answertrue.
The same flow serves every kind of purchase: listing plans, memberships, credits and bookings.
1. Register the gateway
Your gateway appears on the Payments screen, with its settings, as soon as you add it to ppt_payment_gateways. Only id is required.
<?php
/*
Plugin Name: MyPay for PremiumPress
*/
add_filter('ppt_payment_gateways', function (array $gateways) {
$gateways[] = array(
'id' => 'mypay',
'name' => 'MyPay',
'desc' => 'Accept card payments with MyPay.',
'logo' => plugins_url('logo.svg', __FILE__), // optional
'fields' => array(
array('id' => 'mode', 'label' => 'Mode', 'type' => 'select',
'options' => array('test' => 'Test', 'live' => 'Live'), 'default' => 'test'),
array('id' => 'api_key', 'label' => 'API key', 'type' => 'password',
'hint' => 'In your MyPay dashboard under Developers.'),
),
'notes' => 'Create your API key in the MyPay dashboard first.',
);
return $gateways;
});
| Key | What it is |
|---|---|
id | A short unique name, used everywhere below. Required. |
name, desc, logo, notes | What the site owner sees on the Payments screen. |
fields | Settings for the owner to fill in. Each has id, label, type (text, password, select, textarea or checkbox), and optionally options, default and hint. |
recurring | true if your gateway can take repeat payments for subscriptions. |
trial | true if it supports free-trial subscriptions. |
can_test | true to show a Test connection button (answer it with ppt_gateway_test). |
Read the owner's settings with:
$key = \Ppt\Admin\Payments::value('mypay', 'api_key');
$live = \Ppt\Admin\Payments::value('mypay', 'mode', 'test') === 'live';
$on = \Ppt\Admin\Payments::isEnabled('mypay');
2. Send the buyer to pay
add_filter('ppt_gateway_start', function ($url, $gatewayId, $order, $returnUrl) {
if ($gatewayId !== 'mypay') {
return $url; // another gateway's order: leave it alone
}
// Create the payment at your provider. Use the order ID as your reference
// and the theme's return address as the provider's success address.
$payment = mypay_create_payment(array(
'amount' => $order['total'],
'currency' => $order['currency'] ?? 'USD',
'reference' => $order['id'],
'return_url' => $returnUrl,
));
return $payment ? $payment['checkout_url'] : ''; // '' cancels the order
}, 10, 4);
$order includes id, total, currency, name and description, plus recurring, duration and trial_days for subscriptions. Return an empty value if you cannot start the payment: the buyer goes back to checkout with a "payment unavailable" message and the order is cancelled.
3. Confirm the payment
When the buyer comes back, the theme asks you to confirm. Only a strict true completes the order. Anything else leaves it pending; if you return a sentence, the buyer sees it.
add_filter('ppt_gateway_verify', function ($result, $gatewayId, $order) {
if ($gatewayId !== 'mypay') {
return $result;
}
// Ask the provider's server. Never decide from what the browser sent back.
$paid = mypay_payment_is_paid($order['id']);
return $paid ? true : __('We are still waiting for MyPay to confirm your payment.', 'mypay');
}, 10, 3);
$order here has id, ref, total, currency, listing and plan. Bookings pass only id and ref.
4. Webhooks
If your provider confirms payments by webhook, for example when a buyer closes the tab before returning, complete the order from your webhook handler once you have verified the webhook's signature:
\Ppt\Payments\CheckoutFlow::markPaid($orderId); // safe to call twice
For subscription renewals, record each new payment with \Ppt\Payments\CheckoutFlow::renewOrder($orderId, $providerEventId).
Optional extras
| Hook | Use it to |
|---|---|
ppt_gateway_can_refund / ppt_gateway_refund | Offer refunds from the admin. The refund receives the order ID, amount, currency, reason and a key to stop a refund being sent twice; return array('ok' => true, 'id' => '…', 'message' => '…'). |
ppt_gateway_cancel | Cancel a subscription at the provider; return true when done. |
ppt_gateway_can_manage / ppt_gateway_manage_url | Give members a link to manage their subscription at the provider. |
ppt_gateway_test | Answer the Test connection button. |
ppt_gateway_card_after | Print extra help under your gateway's card on the Payments screen. |
Testing
Turn on your provider's test mode, enable the gateway on Payments, and buy something on the site: a listing plan is quickest. Check the order shows as complete on the Orders screen, and that a declined test card leaves it pending. The theme's built-in test gateway is a complete small example of every hook on this page.