Skip to main content

Key Requirements

Retrieve your API keys from your dashboard by following the steps on our Authentication page. Use your public API key for all card collection requests.
Set the following headers on every request:
Make sure your webhook URL is saved on the dashboard and configured to accept POST requests. See our Webhooks guide for setup instructions.

Supported currencies

Card collections are supported for both NGN and USD.
For NGN cards, the pin parameter is required in the Card Charge request.

How card collections work

Card payments on Payaza can follow one of two flows depending on whether the card is enrolled in 3D Secure (3DS):
  1. Your server calls Card Charge with the customer and card details. 2. The response returns do3dsAuth: false and paymentCompleted: true. 3. If a callback_url was provided, the customer is redirected to it with the final payment result in the POST body. 4. If no callback_url was provided, handle the result in the same page via the window.message postMessage event listener.
  1. (Optional) Call Check 3DS Availability upfront to determine if the card requires 3DS.
  2. Your server calls Card Charge with the customer and card details.
  3. The response returns do3dsAuth: true along with threeDsUrl, formData, and threeDsHtml.
  4. Your frontend injects the threeDsHtml into the DOM — this auto-submits a form inside an iframe that redirects the customer to the card issuer’s 3DS challenge page.
  5. The customer completes the bank OTP or authentication challenge.
  6. If callback_url was provided: the issuer redirects the customer back to your callback_url via a POST request containing the final payment result.
  7. If no callback_url was provided: the result is posted back to your page via window.postMessage and captured by a window.addEventListener("message", ...) listener on the parent page.
The threeDsHtml field contains a self-submitting HTML form that must be rendered directly in the DOM — do not strip the <script> tag or render it in a sandboxed context. Keep the iframe on the same page as your message event listener so the notification can post back correctly.

Step 1 — Card Charge

Initiate a card payment. The response differs based on whether 3DS is required.
transaction_reference has a recommended maximum length of 15 characters**.

Response types

Card Charge returns one of three response shapes. Always check do3dsAuth first, then statusOk and paymentCompleted. Response 1 — 3DS required This is returned immediately from the Card Charge endpoint when the card requires 3DS authentication. The payment is not yet complete — you must render the threeDsHtml to proceed.
Response 2 — Payment successful This is the final success response. It is delivered in one of two ways depending on your integration:
  • With callback_url: POSTed to your callback_url after 3DS completes, or returned directly for non-3DS cards. Your server receives this and redirects/updates the customer accordingly.
  • Without callback_url: Posted to the parent page via window.postMessage and captured by your message event listener.
Kindly note that webhook notifications are only sent for successful card transactions.
Response 3 — Payment failed Delivered the same way as a success response — either POSTed to callback_url or via postMessage. Always check statusOk: false and read debugMessage for the failure reason.
When waitForNotification: true appears in a success response, it means the payment is confirmed but a final webhook notification will also follow. Never fulfil an order based on the initial Card Charge response alone — always wait for the final result via callback_url, postMessage, or the webhook before completing business logic.
API reference: Card Charge

Handling the payment result

After a card charge, the final payment result is delivered differently depending on whether you included a callback_url in the request.

Path A — With callback_url

When a callback_url is provided, Payaza POSTs the final payment result to that URL after the 3DS challenge completes (or immediately for non-3DS cards). The customer is redirected to your callback_url page. Your callback_url endpoint must accept POST requests. Parse the body for statusOk and paymentCompleted to determine the outcome and complete your business logic (e.g. update the order, redirect the customer to a success or failure page). Sample POST body received at callback_url
Handling the callback (Node.js / Express)

Path B — Without callback_url (postMessage)

When no callback_url is included in the Card Charge request, the final payment result is posted back to the parent page from the 3DS iframe using the browser’s window.postMessage API. Your page must have a message event listener in place before the charge is initiated. Sample postMessage payload received in the browser
postMessage event listener

3DS challenge HTML document

This is the complete HTML document used exclusively for processing 3DS transactions. It handles the full charge request, renders the authentication challenge, and listens for the payment result — all in a single page. Use this as your reference implementation when building a 3DS-enabled checkout. Replace the card details and API key with your own values.
This document does not include a callback_url in the charge request. The final payment result is therefore delivered via the internal window.postMessage listener at the bottom of the script. If you add a callback_url, the result will be POSTed to that URL instead — see Path A above.
3DS transaction page
Key points about this document:
  • The iframe (challengeFrame) renders the card issuer’s 3DS authentication page — the customer sees their bank’s OTP or biometric prompt inside it.
  • result.formData maps to the creq (challenge request) value that the ACS (Access Control Server) expects. Do not modify it.
  • result.threeDsUrl is the ACS URL generated by Payaza for that specific transaction. It changes with every charge.
  • Replace alert(...) with your actual UI logic — redirect the customer, update the order status, or render a success/failure component.

Step 2 — Check Transaction Status

Retrieve the final status of a card transaction by its transaction_reference. Use this as a server-side fallback when a webhook is not received within your expected timeout.
Sample response
API reference: Check Transaction Status

Step 3 — Initiate Refund

Refund a completed card transaction — either the full amount or a partial amount.
Refunds can only be initiated for transactions with transaction_status: "Completed". Attempting to refund a failed or pending transaction will return an error.
Kindly note that when performing partial refunds. Ensure that the amounts being refunded doesn’t exceed the original amount that was collected.
Sample response
Save the refund_transaction_reference from the response. This is the reference you will need to check the refund status in Step 4.
API reference: Initiate Refund

Step 4 — Check Refund Status

Verify the current status of a refund using the refund_transaction_reference returned when the refund was initiated.
Sample response
API reference: Check Refund Status

Step 5 — Fetch Refund History

Retrieve a paginated list of all refund transactions for your account. Results can be filtered by date range, currency, and refund status.
Query parameters Sample response
API reference: Fetch Refund History

Webhooks

Payaza fires webhook events for only completed card transactions. Webhook notifications are used in conjunction with TSQ API to get the status of card transactions Sample Successful Card Collection payload
Always verify the webhook signature before processing the payload. See the Webhooks guide for verification steps.

Error handling


Developer notes

  • Always generate a unique transaction_reference per charge. The recommended maximum length is 15 characters.
  • For NGN card collections, the card pin field is required. For all other currencies, omit pin.
  • Choosing your result delivery method: Include callback_url in the request if you want the customer redirected to a page you control after payment. Omit it if you are building a single-page checkout and want to handle the result in the browser via postMessage.
  • When do3dsAuth: true, the payment is not yet complete — render the 3DS challenge before expecting any result. The final outcome arrives only after the customer completes the bank authentication.
  • When waitForNotification: true appears in a success response, it signals that a webhook notification will also follow. Fulfil the order only after receiving the final result — via callback_url, postMessage, or a webhook — not based on the initial Card Charge response alone.
  • Save refund_transaction_reference from every Initiate Refund response — it is the only way to check refund status later.
  • The valueAmount in a successful response is the settlement amount after fees, and may differ from amountPaid. Use amountPaid for display to customers.
  • Use Fetch Refund History with date range filters for reconciliation — it includes the original transaction details nested inside each refund record.