SwitchLock Docs
Payments / EFT Checkout

EFT Checkout

Card-funded escrow via the HyperPay (Oppwa) gateway. Buyers pay with a debit or credit card instead of a pre-funded SwitchLock wallet.

How EFT checkout fits in

Standard payment links draw funds from the buyer's existing SwitchLock wallet balance. EFT checkout is an alternative provider that lets buyers fund escrow directly with a card — no pre-existing wallet balance required.

Standard flow (MOCK_BANK)
1 Your server generates a payment link
2 Buyer requests OTP on their WhatsApp number
3 Buyer submits OTP — wallet balance deducted, escrow funded
EFT flow (EFT_PAY)
1 Your server generates a payment link
2 Buyer requests OTP (same identity check)
3 accept-payment returns a checkoutId
4 Frontend renders the HyperPay widget with that ID
5 Buyer enters card details on the HyperPay widget
6 HyperPay calls your webhook — escrow is funded

EFT checkout requires gateway credentials from Oppwa/HyperPay. Contact support@switchlock.co.zw to have EFT_PAY enabled on your company account. Attempting these endpoints without credentials will return a gateway configuration error.

Step 1 — Initiate an Oppwa checkout session

Call POST /v1/payments/eft-pay/initiate with the payment link's slug. This endpoint is idempotent — if a checkout session already exists for this link, it returns the existing checkoutId without calling the gateway again.

curl -X POST "https://api.switchlock.co.zw/v1/payments/eft-pay/initiate" \
  -H "Content-Type: application/json" \
  -d '{
    "paymentSlug": "aB3xK9mN2p"
  }'
Response
{
  "checkoutId": "8ac7a49c8f4e3b1a018f6e4c2a3b0042"
}
FieldRequiredNotes
paymentSlugYesThe secureUrlHash from the payment link response

Step 2 — Render the HyperPay widget

Pass the checkoutId to the HyperPay JavaScript widget on your checkout page. The buyer enters their card details directly on the HyperPay-hosted form — card data never touches your servers.

HTML — HyperPay widget embed
<!-- Load the HyperPay widget script -->
<script
  src="https://eu-test.oppwa.com/v1/paymentWidgets.js?checkoutId=8ac7a49c8f4e3b1a018f6e4c2a3b0042"
  async>
</script>

<!-- Render the payment form -->
<form
  action="https://yoursite.com/payment-result"
  class="paymentWidgets"
  data-brands="VISA MASTER">
</form>

Replace eu-test.oppwa.com with oppwa.com for production. Your HyperPay entity ID and test/live mode are configured server-side — your frontend only needs the checkoutId.

After the buyer submits the form, HyperPay redirects to your action URL with a resourcePath query parameter. Pass that path to the verify endpoint to confirm the payment and fund escrow.

Step 3 — Verify and fund escrow

Call POST /v1/payments/eft-pay/verify from your server once HyperPay redirects the buyer back. The API queries the gateway server-to-server, confirms the amount and currency match, then moves funds into escrow and marks the link PAID.

curl -X POST "https://api.switchlock.co.zw/v1/payments/eft-pay/verify" \
  -H "Content-Type: application/json" \
  -d '{
    "resourcePath": "/v1/checkouts/8ac7a49c8f4e3b1a018f6e4c2a3b0042/payment"
  }'
Response — success
{
  "status": "SUCCESS",
  "escrow": {
    "id": "esc_01HFUND...",
    "status": "FUNDED",
    "totalAmount": "35000",
    "currency": "USD"
  }
}
Response — already paid (idempotent)
{
  "status": "ALREADY_PAID"
}
ErrorCause
400 — payment not successfulGateway returned a non-success result code. The buyer may have declined or the card was rejected.
400 — amount mismatchThe amount the gateway recorded differs from the stored payment link amount.
400 — currency mismatchGateway currency does not match the payment link currency.
404 — link not foundNo payment link exists with the checkout ID embedded in the resource path.

If the gateway verification throws (e.g. the Oppwa session expired), the API clears providerCheckoutId from the payment link so a fresh session can be generated by calling /eft-pay/initiate again.

Webhook — eft-pay/webhook

Oppwa can send payment events directly to your webhook URL as a fallback for cases where the browser redirect does not complete. Configure https://api.switchlock.co.zw/v1/payments/eft-pay/webhook as the notification URL in your HyperPay merchant dashboard.

Oppwa webhook payload shape
{
  "id": "8ac7a49c8f4e3b1a018f6e4c2a3b0042",
  "payload": {
    "id": "8ac7a49c8f4e3b1a018f6e4c2a3b0042"
  }
}
Always returns 200 OK

The webhook endpoint always returns 200 OK to prevent Oppwa from retrying. Business logic errors are swallowed and logged internally. If you see a payment stuck, check server logs rather than relying on webhook response codes.

Idempotent verification

The webhook runs the same verification logic as /eft-pay/verify. If the payment was already processed via the redirect path, the webhook call returns ALREADY_PAID silently.

Checking payment status

Poll the link details endpoint to check whether the EFT payment has been confirmed. Once status is PAID, escrow is active.

Public — no API key
GET https://api.switchlock.co.zw/v1/payments/link-details/aB3xK9mN2p

Do not poll more than once every 5 seconds. For production, rely on the webhook rather than polling — the webhook fires as soon as Oppwa notifies the server.

Next steps