Merchant Payments API
Drop-in South African payments. Create a charge on your server, open our popup, get a webhook when it clears.
Integration kit
GitHub-style pack: OpenAPI spec, Postman collection, PHP, Node, Python, WooCommerce starter, checkout HTML.
How it works
- Your server creates a payment with
sk_live_…(never in the browser). - The browser opens
SmgPay.open— a Social Media Guru popup. PayFast runs only on our domain. - We POST
payment.paidto your webhook. That is the source of truth. - You request an EFT payout from the merchant dashboard when you want to withdraw.
Fees
- Cards (Visa, Mastercard, debit, Apple/Samsung/Google Pay): 6% + R2.00 excl. VAT, then 15% VAT on the fee. R100 → R9.20 fee → R90.80 net.
- Capitec Pay, Instant EFT, SnapScan, Zapper, other: 6% + 15% VAT, minimum R2.00 + VAT (R2.30). R100 → R6.90 fee → R93.10 net. R30 → R2.30 fee → R27.70 net.
- Create responses include both quotes in
fees.cardandfees.other. We settle from PayFast'spayment_method. If the method is missing or unknown, the card rate (6% + R2 + VAT) applies. - Minimum R10.00. Same amount cannot be charged again within 15 minutes.
Create a payment
curl -X POST https://www.socialmediaguru.co.za/api/v1/payments \
-H "Authorization: Bearer sk_live_YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"amount": 199.00,
"merchant_ref": "ORD-1001",
"customer": {
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "0713743360"
},
"return_url": "https://yourstore.co.za/order/1001/thanks",
"cancel_url": "https://yourstore.co.za/order/1001/cancel"
}'Open the PayFast popup
Do not load PayFast engine.js on the merchant site and do not iframe our pay page.
<script src="https://www.socialmediaguru.co.za/js/smg-pay.js"></script>
<script>
SmgPay.open({
payment_url: data.payment_url,
onSuccess: function () { window.location = "/thanks"; },
onCancel: function () {}
});
</script>Webhook
Header X-SMG-Signature = HMAC-SHA256 of the raw JSON body with the webhook secret. Event: payment.paid.
$raw = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_SMG_SIGNATURE'] ?? '';
if (!hash_equals(hash_hmac('sha256', $raw, $webhookSecret), $sig)) {
http_response_code(401);
exit;
}Endpoints
| Method | Path | Notes |
|---|---|---|
| POST | /api/v1/payments | Create (idempotent on merchant_ref) |
| GET | /api/v1/payments | List ?status=&limit= |
| GET | /api/v1/payments/{id} | id, SMG-P- number, or merchant_ref |
| POST | /api/v1/payments/{id} | { "action": "cancel" } |
| GET | /api/v1/balance | Available balance |