Integration Guide
This guide walks you through the four primary integration flows: Payin (Collections), Payout, Onramp, and Offramp. Each flow follows a similar pattern -- create a user, handle compliance, fetch rates, and create an order.
All flows begin with user creation and KYC verification. From there, the steps diverge depending on the payment direction and whether you are working with fiat-only or fiat-to-crypto conversion.
Typical Payin (Collection) Flow
Collect fiat payments from end users. Funds can be settled via batch, instant crypto, or instant fiat.
The response includes a paymentUrl. Redirect the user there to complete payment in the PayItFast widget.
Listen for the fund_settled webhook event to confirm the payment was received.
1. POST /v2/users/individual → Create user
2. POST /v2/kyc/standard → Initiate KYC (user completes widget)
3. GET /v2/supported-currencies → Get available currencies
4. GET /v2/payment-methods → Get payment methods for currency
5. GET /v2/exchange-rates/deposit → Get rate + quoteId
6. POST /v2/orders/deposit → Create order (pass quoteId)
7. Redirect user to paymentUrl → User completes payment
8. Receive webhook (fund_settled) → Confirm payment
9. GET /v2/orders/{orderId} → (Optional) poll for status
Payin Order Status Flow
Typical Payout Flow
Disburse fiat payouts to bank accounts or local wallets of end users or businesses.
Prefunding is required before initiating any payout. You must have sufficient balance in your account. Use the crypto or fiat prefunding endpoints, or the sandbox prefunding endpoint for testing.
Listen for the fund_settled webhook event to confirm delivery to the recipient.
1. POST /v2/users/individual → Create recipient
2. POST /v2/prefunds/create-crypto-prefund → Fund your balance
3. GET /v2/supported-currencies → Get available currencies
4. GET /v2/payment-methods → Get payment methods + field requirements
5. GET /v2/exchange-rates/withdraw → Get rate + quoteId
6. POST /v2/payout/orders → Create payout (with bank details)
7. Receive webhook (fund_settled) → Confirm delivery
Payout Order Status Flow
Typical Onramp Flow
Enable users to deposit fiat currency and receive stablecoins (USDC, USDT) in their crypto wallet.
Onramp does not support quote caching (quoteId). The rate is determined at order creation time.
Use the standard payin endpoint with withdrawDetails containing the crypto wallet:
The user completes the fiat payment in the PayItFast widget.
Listen for the asset_settled webhook event confirming crypto delivery to the user's wallet.
1. POST /v2/users/individual → Create user
2. POST /v2/kyc/standard → Complete KYC
3. GET /v2/config/list-tokens → Get crypto tokens
4. GET /v2/exchange-rates/fiat-to-crypto → Get conversion quote
5. POST /v2/orders/deposit → Create order with withdrawDetails (crypto wallet)
6. Redirect user to paymentUrl → User pays fiat
7. Receive webhook (asset_settled) → Crypto delivered to wallet
Onramp Order Example
{
"paymentType": "bank_transfer",
"purposeCode": "expense_or_medical_reimbursement",
"amount": 100,
"currency": "EUR",
"email": "john@example.com",
"redirectUrl": "https://www.example.com",
"sourceUrl": "https://example.com",
"withdrawDetails": {
"cryptoTicker": "USDC",
"walletAddress": "0xcf2888157e35d8595cba5abd7970f94a43f0d2d2"
}
}
Onramp Order Status Flow
Typical Offramp Flow
Enable users to sell stablecoins (USDC, USDT) and receive fiat in their bank account or local wallet.
Use the payout endpoint with depositDetails containing the user's crypto wallet:
The response includes a walletAddress. The user sends stablecoins to this address.
Listen for the asset_deposited event confirming crypto was received.
Listen for the fund_settled event confirming fiat was sent to the user's bank account.
1. POST /v2/users/individual → Create user
2. POST /v2/kyc/standard → Complete KYC
3. GET /v2/exchange-rates/crypto-to-fiat → Get conversion quote
4. POST /v2/payout/orders → Create order with depositDetails (crypto wallet)
5. User sends stablecoin to walletAddress → From response
6. Receive webhook (asset_deposited) → Crypto received
7. Receive webhook (fund_settled) → Fiat delivered to bank
Offramp Order Status Flow
Widget vs Headless Integration
PayItFast supports two integration modes. Choose based on your desired level of UI control.
Widget Mode (Default)
Set headlessMode: false (or omit it). The API returns a paymentUrl that redirects users to the PayItFast payment widget.
- Fastest integration path
- PayItFast handles payment UI
- Can embed via iframe
- Automatic payment method rendering
Headless Mode (API-only)
Set headlessMode: true. Full API-only integration where you control the entire user interface.
- Complete UI control
- Must provide
deviceDetails - Must provide
additionalDetails - Fields defined per payment method
When using headless mode, you must include deviceDetails (IP address + user agent) and all fields listed in the additionalDetails object returned by the /v2/payment-methods endpoint for the chosen payment method.
iFrame Embedding
To embed the payment widget directly in your page, use the paymentUrl from the order creation response in an iframe:
<html>
<head>
<meta name="viewport"
content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no" />
</head>
<body style="margin: 0; padding: 0; width: 100%;
height: 100%; overflow: hidden">
<iframe
src="PAYITFAST_PAYMENT_URL"
allow="payment"
style="width: 100%; height: 100%; border: none;
position: fixed; top: 0; left: 0;
right: 0; bottom: 0;"
></iframe>
</body>
</html>
Replace PAYITFAST_PAYMENT_URL with the paymentUrl value from the order creation response.
Sandbox Testing Tips
Use the sandbox environment to develop and test your integration before going live.
All sandbox requests should use: https://sandbox-api.payitfast.com
Simulating KYC Failure
To test KYC rejection flows, create a user with an email address ending in @kycfailure.sandbox. For example: testuser@kycfailure.sandbox. The KYC submission will automatically be rejected, allowing you to test failure handling.
Adding Test Balances
Use the sandbox-only prefunding endpoint to add dummy balances for payout testing. This is not available in production.
Quote Validity
Exchange rate quotes are valid for 1 minute. When testing, make sure to create the order within this window after fetching a rate. Expired quotes will return a QUOTES_EXPIRED error.