PayFast provider, Pay online page, amount checks on payments

- PayFast (custom integration): signed form (PHP-style encoding, checked
  against a real sandbox), ITN checks (signature over all posted fields,
  PayFast host, VALID from /eng/query/validate, amount vs checkout).
- ProviderCheckout records every checkout (amount, metadata, request);
  webhooks match payments to it and hold a different amount for review
  (ProviderTransaction.note).
- /pay/<id>: payers choose a provider when several are on, and the
  browser posts PayFast's form from there, so payment links work for
  every provider.
- Site settings → Payments: PayFast card (merchant ID/key, encrypted
  passphrase, sandbox/live) while PayFast is enabled.
- Payer-facing wording no longer names Yoco; legal pages name both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 14:25:49 +02:00
co-authored by Claude Opus 5.5
parent 25e3e9d3a6
commit f2b51dbd88
42 changed files with 1220 additions and 109 deletions
@@ -1010,6 +1010,8 @@ const createCheckout = async (req, res) => {
amountCents: amountInCents,
metadata: { userId, eventId, eventTitle: event.title, type: 'donation', isDonation: true },
lineItems: [{ name: `Donation to ${event.title}`, quantity: 1, unitCents: amountInCents }],
description: `Donation to ${event.title}`,
payer: { name: req.user.name || '', email: req.user.email || '' },
successUrl, cancelUrl, failureUrl,
idempotencyKey: `don_${eventId}_${amountInCents}_${Date.now()}`,
});