acme/demo-pay, a gateway for a fictional provider with a hosted checkout page and HMAC-signed webhooks. It’s a complete implementation you can adapt to a real provider.
Prerequisites
- A working plugin skeleton. Follow the plugin quickstart first.
- An understanding of the payment lifecycle.
Step 1: Register the gateway
src/Plugin.php
extra.default_url in the manifest to /admin/settings/payments/demo-pay, which is where the payments list links.
Step 2: Implement the gateway
src/DemoPay.php
Key points
isEnabled()must check the configuration too. A gateway that’s switched on but missing credentials shouldn’t appear at checkout.- Store the provider’s reference with
initiatePayment()before redirecting, socompletePurchase()can find the payment even when the provider sends no parameters back. - Verify on the server. Re-fetch the payment and compare the amount and your order reference. Never trust parameters in the return URL.
- Wrap provider failures in
PaymentException, so the user gets a readable message instead of a500.
Step 3: Amounts and currency
Aikeedo stores money as an integer in minor units, along with a currency code. Two conversions matter:Step 4: The settings page
src/SettingsRequestHandler.php
- An enable toggle,
demo_pay[is_enabled] - API credentials
- A currency select, or an “inherit from billing settings” option
- The webhook URL, with
<x-copy>, so the administrator can paste it into the provider’s dashboard:
Step 5: Test it
1
Configure the gateway
Enter sandbox credentials, enable it, and confirm it appears on the checkout page for a paid plan.
2
Complete a payment
Buy a one-time plan in the provider’s sandbox. You should land on the receipt page with the order marked paid, and the workspace should receive its credits.
3
Abandon a payment
Start a checkout and cancel at the provider. You should return to the billing page, with the order still unpaid and no credits granted.
4
Force a failure
Use an invalid API key. Checkout should show your error message, not a
500.Orders are only fulfilled after the provider confirms the payment.