FeesPaymentsPricingDevelopersAbout
Get early access
  • Fees
  • Payments
  • Pricing
  • Developers
  • About
Get early access

Switching

Switch gateways by changing a few lines.

Re-integrating is the reason most shops never switch. So rano speaks PayFast and Yoco: point your existing code at us, swap your keys, and your payment form, checkout and notifications keep working.

From PayFastFrom Yoco

On this page

  1. 1From PayFast
  2. 2From Yoco
  3. 3From Peach Payments
  4. 4What happens underneath

From PayFast

For shops using PayFast’s custom integration: a form that posts to /eng/process and an ITN handler on your notify_url.

1. Create credentials

In the rano dashboard, open Developers → Switching and create PayFast credentials. You get a merchant_id and merchant_key. Enter your current PayFast passphrase and your signing code doesn’t change at all.

2. Change the form

The action URL and the two credentials. Everything else, signature included, stays as it is.

Diffcheckout.php
- <form action="https://www.payfast.co.za/eng/process" method="post">+ <form action="https://api.rano.co.za/compat/payfast/eng/process" method="post">-   <input type="hidden" name="merchant_id" value="10000100">-   <input type="hidden" name="merchant_key" value="46f0cd694581a">+   <input type="hidden" name="merchant_id" value="48213307">+   <input type="hidden" name="merchant_key" value="k3v9q2m7x1c8n5b4">    <input type="hidden" name="amount" value="386.00">    <input type="hidden" name="item_name" value="Order #2048">    <input type="hidden" name="notify_url" value="https://shop.example/itn">    <input type="hidden" name="signature" value="<?= $signature ?>">

3. Point your ITN checks at rano

ITNs arrive at your notify_url in PayFast’s format, signed with your passphrase the way PayFast signs them. Your signature and amount checks work unchanged. Change the server confirmation URL, and drop the check that the request came from PayFast’s addresses: rano doesn’t send from a fixed list of addresses yet, and the signature plus server confirmation already prove the ITN is genuine.

Diffitn.php
  // Your ITN handler: the signature check and amount check stay as they are.  $check1 = pfValidSignature($pfData, $pfParamString, $passphrase);- $check2 = pfValidIP();  $check3 = pfValidPaymentData($cartTotal, $pfData);  $check4 = pfValidServerConfirmation($pfParamString, $pfHost);   function pfValidServerConfirmation($pfParamString, $pfHost) {-   $url = 'https://'. $pfHost .'/eng/query/validate';+   $url = 'https://api.rano.co.za/compat/payfast/eng/query/validate';

What isn’t supported

  • Once-off payments only. Subscriptions, tokenization (subscription_type) and split payments (setup) are refused with a clear error rather than ignored.
  • The onsite payment modal (engine.js) isn't supported; use the redirect form.
  • Every form must be signed with a passphrase. If your shop doesn't use one yet, rano makes one for you when you create credentials.
  • Customers pay by PayShap or EFT on rano's page. payment_method=eft is honoured; other values let the customer choose. Cards join when rano's card processing goes live.
  • PayFast's query and refund APIs aren't translated. Use the rano API for refunds and lookups.
  • ITNs carry COMPLETE when the payment succeeds and CANCELLED when it ends unpaid. A declined bank request reopens the page for another try, so the ITN only goes out once the payment has ended for good. Blank fields are left out.

From Yoco

For shops using Yoco’s Checkout API. No new credentials: your rano secret key goes where your Yoco secret key was.

1. Change the base URL and key

Requests and responses keep Yoco’s shape, including redirectUrl, Idempotency-Key and the success, cancel and failure URLs.

Diffcheckout.ts
- const YOCO_URL = "https://payments.yoco.com/api";+ const YOCO_URL = "https://api.rano.co.za/compat/yoco/api";- const SECRET_KEY = process.env.YOCO_SECRET_KEY;+ const SECRET_KEY = process.env.RANO_SECRET_KEY; // sk_test_… in the sandbox   const res = await fetch(`${YOCO_URL}/checkouts`, {    method: "POST",    headers: { Authorization: `Bearer ${SECRET_KEY}`, "Content-Type": "application/json" },    body: JSON.stringify({ amount: 38600, currency: "ZAR", successUrl, cancelUrl, failureUrl }),  });  const { id, redirectUrl } = await res.json(); // send the customer to redirectUrl

2. Register your webhook again

Events are signed the Standard Webhooks way, like Yoco’s (webhook-id, webhook-timestamp, webhook-signature), so your verification code stays. Only the secret is new.

Diffterminal
- curl https://payments.yoco.com/api/webhooks \-   -H "Authorization: Bearer $YOCO_SECRET_KEY" \+ curl https://api.rano.co.za/compat/yoco/api/webhooks \+   -H "Authorization: Bearer $RANO_SECRET_KEY" \    -H "Content-Type: application/json" \    -d '{"name": "orders", "url": "https://shop.example/yoco/webhook"}'  # Save the whsec_ secret it returns; your verification code doesn't change.

What isn’t supported

  • Checkouts and webhook subscriptions only. Refunds and the other Yoco APIs aren't translated; use the rano API.
  • Events are payment.succeeded and payment.failed, sent once the checkout has ended for good (rano sends payment.failed when it's canceled or the customer runs out of tries). paymentMethodDetails.type is payshap or eft.
  • paymentId in the checkout response and payload.id in events are rano payment IDs (pay_…). Checkout IDs start ycko_ rather than ch_.

From Peach Payments

Not yet. Peach’s checkout needs an OAuth token exchange, per-entity configuration and encrypted webhooks, and most Peach shops run on plugins whose URLs can’t be changed. A two-line switch isn’t possible there, so for now Peach shops integrate with the rano API directly.

What happens underneath

Every payment that comes in this way is an ordinary rano payment. It shows in your dashboard with the fee on it, moves through the same ledger, and fires the usual rano webhooks if you add them later. When you’re ready, move to the rano API at your own pace; both work side by side.

  • Your customer pays on rano’s page, then lands on the return, success, cancel or failure URL you already send.
  • Notifications retry for about three days if your server doesn’t answer with a 2xx in time, so one can arrive more than once: ignore a repeat of a pf_payment_id or Yoco webhook-id you’ve already handled.
  • Test it first: test credentials and sk_test_ keys only reach rano’s bank simulator. Live payments start once your account is activated.

Be one of our first merchants.

We’re onboarding a small group of South African businesses first. Leave your email and we’ll be in touch.

Payments for South African businesses, with the fee on the receipt.

Get early access

Product

How fees workPayment methodsPricingCalculator

Developers

API docsTest modeWebhooksErrorsSwitch from PayFast or YocoStatus

Company

AboutSecurityContactEarly access

Legal

Terms of usePrivacyCookiesPAIA manualAcceptable useMerchant terms

rano is in early access and is not yet processing live payments. The fees for your business are confirmed in your merchant agreement.

© 2026 rano · Built in South Africa